calls.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{build_solidity, build_solidity_with_options};
  3. use parity_scale_codec::{Decode, Encode};
  4. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  5. struct RevertReturn(u32, String);
  6. #[test]
  7. fn revert() {
  8. let mut runtime = build_solidity(
  9. r##"
  10. contract bar {
  11. function test() public {
  12. revert("yo!");
  13. }
  14. function a() public {
  15. b();
  16. }
  17. function b() public {
  18. c();
  19. }
  20. function c() public {
  21. d();
  22. }
  23. function d() public {
  24. revert("revert value has to be passed down the stack");
  25. }
  26. }"##,
  27. );
  28. runtime.function_expect_failure("test", Vec::new());
  29. assert_eq!(runtime.vm.output.len(), 0);
  30. runtime.function_expect_failure("a", Vec::new());
  31. assert_eq!(runtime.vm.output.len(), 0);
  32. let mut runtime = build_solidity(
  33. r##"
  34. contract c {
  35. function test() public {
  36. revert();
  37. }
  38. }"##,
  39. );
  40. runtime.function_expect_failure("test", Vec::new());
  41. assert_eq!(runtime.vm.output.len(), 0);
  42. }
  43. #[test]
  44. fn require() {
  45. let mut runtime = build_solidity(
  46. r##"
  47. contract c {
  48. function test1() public {
  49. require(false, "Program testing can be used to show the presence of bugs, but never to show their absence!");
  50. }
  51. function test2() public {
  52. require(true, "Program testing can be used to show the presence of bugs, but never to show their absence!");
  53. }
  54. }"##,
  55. );
  56. runtime.function_expect_failure("test1", Vec::new());
  57. // The reason is lost
  58. assert_eq!(runtime.vm.output.len(), 0);
  59. runtime.function("test2", Vec::new());
  60. assert_eq!(runtime.vm.output.len(), 0);
  61. }
  62. #[test]
  63. fn input_wrong_size() {
  64. let mut runtime = build_solidity(
  65. r##"
  66. contract c {
  67. function test(int32 x) public {
  68. }
  69. }"##,
  70. );
  71. runtime.function_expect_failure("test", b"A".to_vec());
  72. // the decoder does check if there is too much data
  73. runtime.function_expect_failure("test", b"ABCDE".to_vec());
  74. }
  75. #[test]
  76. fn external_call_not_exist() {
  77. let mut runtime = build_solidity(
  78. r##"
  79. contract c {
  80. function test() public {
  81. other o = other(address(102));
  82. o.test();
  83. }
  84. }
  85. contract other {
  86. function test() public {
  87. }
  88. }"##,
  89. );
  90. runtime.function_expect_failure("test", Vec::new());
  91. }
  92. #[test]
  93. fn contract_already_exists() {
  94. let mut runtime = build_solidity(
  95. r##"
  96. contract c {
  97. function test() public {
  98. other o = new other{salt: 0}();
  99. other t = new other{salt: 0}();
  100. }
  101. }
  102. contract other {
  103. function test() public {
  104. }
  105. }"##,
  106. );
  107. runtime.function_expect_failure("test", Vec::new());
  108. let mut runtime = build_solidity(
  109. r##"
  110. contract c {
  111. function test() public {
  112. other o = new other();
  113. other t = new other();
  114. }
  115. }
  116. contract other {
  117. function test() public {
  118. }
  119. }"##,
  120. );
  121. runtime.function("test", Vec::new());
  122. }
  123. #[test]
  124. fn try_catch_external_calls() {
  125. let mut runtime = build_solidity(
  126. r##"
  127. contract c {
  128. function test() public {
  129. other o = new other();
  130. int32 x = 0;
  131. try o.test() returns (int32 y, bool) {
  132. x = y;
  133. } catch (bytes) {
  134. x = 2;
  135. }
  136. assert(x == 102);
  137. }
  138. }
  139. contract other {
  140. function test() public returns (int32, bool) {
  141. return (102, true);
  142. }
  143. }
  144. "##,
  145. );
  146. runtime.function("test", Vec::new());
  147. let mut runtime = build_solidity(
  148. r##"
  149. contract c {
  150. function test() public {
  151. other o = new other();
  152. int32 x = 0;
  153. try o.test() returns (int32 y, bool) {
  154. x = y;
  155. } catch (bytes c) {
  156. assert(c == hex"a079c3080c666f6f");
  157. x = 2;
  158. }
  159. assert(x == 2);
  160. }
  161. }
  162. contract other {
  163. function test() public returns (int32, bool) {
  164. revert("foo");
  165. }
  166. }
  167. "##,
  168. );
  169. runtime.function_expect_failure("test", Vec::new());
  170. let mut runtime = build_solidity(
  171. r##"
  172. contract c {
  173. function test() public {
  174. other o = new other();
  175. try o.test(1) {
  176. print("shouldn't be here");
  177. assert(false);
  178. } catch Error(string foo) {
  179. print(foo);
  180. assert(foo == "yes");
  181. } catch (bytes c) {
  182. print("shouldn't be here");
  183. assert(false);
  184. }
  185. try o.test(2) {
  186. print("shouldn't be here");
  187. assert(false);
  188. } catch Error(string foo) {
  189. print(foo);
  190. assert(foo == "no");
  191. } catch (bytes c) {
  192. print("shouldn't be here");
  193. assert(false);
  194. }
  195. try o.test(3) {
  196. print("shouldn't be here");
  197. assert(false);
  198. } catch Error(string foo) {
  199. print("shouldn't be here");
  200. assert(false);
  201. } catch (bytes c) {
  202. assert(c.length == 0);
  203. }
  204. }
  205. }
  206. contract other {
  207. function test(int x) public {
  208. if (x == 1) {
  209. revert("yes");
  210. } else if (x == 2) {
  211. revert("no");
  212. } else {
  213. revert();
  214. }
  215. }
  216. }
  217. "##,
  218. );
  219. runtime.function_expect_failure("test", Vec::new());
  220. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  221. struct Ret(u32);
  222. let mut runtime = build_solidity(
  223. r##"
  224. contract dominator {
  225. child c;
  226. function create_child() public {
  227. c = (new child)();
  228. }
  229. function call_child() public view returns (int64) {
  230. return c.get_a();
  231. }
  232. function test() public pure returns (int32) {
  233. try c.go_bang() returns (int32 l) {
  234. print("try call success");
  235. return 8000;
  236. }
  237. catch Error(string l) {
  238. print("try error path");
  239. print(l);
  240. return 4000;
  241. }
  242. catch {
  243. print("try catch path");
  244. return 2000;
  245. }
  246. }
  247. }
  248. contract child {
  249. int64 a;
  250. constructor() public {
  251. a = 102;
  252. }
  253. function get_a() public view returns (int64) {
  254. return a;
  255. }
  256. function set_a(int64 l) public {
  257. a = l;
  258. }
  259. function go_bang() public pure returns (int32) {
  260. revert("gone bang in child");
  261. }
  262. }"##,
  263. );
  264. runtime.function("create_child", Vec::new());
  265. runtime.function_expect_failure("test", Vec::new());
  266. }
  267. #[test]
  268. fn try_catch_constructor() {
  269. let mut runtime = build_solidity(
  270. r##"
  271. contract c {
  272. function test() public {
  273. int x;
  274. try (new other)() {
  275. x = 102;
  276. } catch (bytes) {
  277. x = 2;
  278. }
  279. assert(x == 102);
  280. }
  281. }
  282. contract other {
  283. function test() public returns (int32, bool) {
  284. return (102, true);
  285. }
  286. }
  287. "##,
  288. );
  289. runtime.function("test", Vec::new());
  290. let mut runtime = build_solidity(
  291. r##"
  292. contract c {
  293. function test() public {
  294. int x;
  295. try new other({foo: true}) returns (other o) {
  296. (x, bool yata) = o.test();
  297. } catch (bytes) {
  298. x = 2;
  299. }
  300. assert(x == 102);
  301. }
  302. }
  303. contract other {
  304. constructor(bool foo) public {
  305. //
  306. }
  307. function test() public returns (int32, bool) {
  308. return (102, true);
  309. }
  310. }
  311. "##,
  312. );
  313. runtime.function("test", Vec::new());
  314. let mut runtime = build_solidity(
  315. r##"
  316. contract c {
  317. function test() public {
  318. int32 x = 0;
  319. try new other(true) {
  320. x = 1;
  321. } catch (bytes c) {
  322. assert(c == hex"a079c3080c666f6f");
  323. x = 2;
  324. }
  325. assert(x == 2);
  326. }
  327. }
  328. contract other {
  329. constructor(bool foo) public {
  330. revert("foo");
  331. }
  332. function _ext() public {}
  333. }
  334. "##,
  335. );
  336. runtime.function_expect_failure("test", Vec::new());
  337. }
  338. #[test]
  339. fn local_destructure_call() {
  340. let mut runtime = build_solidity(
  341. r##"
  342. contract c {
  343. function test() public {
  344. (, bytes32 b, string s) = foo();
  345. assert(b == "0123");
  346. assert(s == "abcd");
  347. }
  348. function foo() public returns (bool, bytes32, string) {
  349. return (true, "0123", "abcd");
  350. }
  351. }
  352. "##,
  353. );
  354. runtime.function("test", Vec::new());
  355. }
  356. #[test]
  357. fn payable_constructors() {
  358. // no contructors means constructor is not payable
  359. // however there is no check for value transfers on constructor so endowment can be received
  360. let mut runtime = build_solidity(
  361. r##"
  362. contract c {
  363. function test(string a) public {
  364. }
  365. }"##,
  366. );
  367. runtime.vm.value = 1;
  368. runtime.constructor(0, Vec::new());
  369. // contructors w/o payable means can't send value
  370. // however there is no check for value transfers on constructor so endowment can be received
  371. let mut runtime = build_solidity(
  372. r##"
  373. contract c {
  374. constructor() public {
  375. int32 a = 0;
  376. }
  377. function test(string a) public {
  378. }
  379. }"##,
  380. );
  381. runtime.vm.value = 1;
  382. runtime.constructor(0, Vec::new());
  383. // contructors w/ payable means can send value
  384. let mut runtime = build_solidity(
  385. r##"
  386. contract c {
  387. constructor() public payable {
  388. int32 a = 0;
  389. }
  390. function test(string a) public {
  391. }
  392. }"##,
  393. );
  394. runtime.vm.value = 1;
  395. runtime.constructor(0, Vec::new());
  396. }
  397. #[test]
  398. fn payable_functions() {
  399. // function w/o payable means can't send value
  400. let mut runtime = build_solidity(
  401. r##"
  402. contract c {
  403. function test() public {
  404. }
  405. }"##,
  406. );
  407. runtime.constructor(0, Vec::new());
  408. runtime.vm.value = 1;
  409. runtime.function_expect_failure("test", Vec::new());
  410. // test both
  411. let mut runtime = build_solidity(
  412. r##"
  413. contract c {
  414. function test() payable public {
  415. }
  416. function test2() public {
  417. }
  418. }"##,
  419. );
  420. runtime.constructor(0, Vec::new());
  421. runtime.vm.value = 1;
  422. runtime.function_expect_failure("test2", Vec::new());
  423. runtime.vm.value = 1;
  424. runtime.function("test", Vec::new());
  425. // test fallback and receive
  426. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  427. struct Ret(u32);
  428. let mut runtime = build_solidity(
  429. r##"
  430. contract c {
  431. int32 x;
  432. function get_x() public returns (int32) {
  433. return x;
  434. }
  435. function test() payable public {
  436. x = 1;
  437. }
  438. fallback() external {
  439. x = 2;
  440. }
  441. receive() payable external {
  442. x = 3;
  443. }
  444. }"##,
  445. );
  446. runtime.constructor(0, Vec::new());
  447. runtime.vm.value = 1;
  448. runtime.raw_function(b"abde".to_vec());
  449. runtime.vm.value = 0;
  450. runtime.function("get_x", Vec::new());
  451. assert_eq!(runtime.vm.output, Ret(3).encode());
  452. runtime.vm.value = 0;
  453. runtime.raw_function(b"abde".to_vec());
  454. runtime.function("get_x", Vec::new());
  455. assert_eq!(runtime.vm.output, Ret(2).encode());
  456. let mut runtime = build_solidity(
  457. r##"
  458. contract c {
  459. int32 x;
  460. function get_x() public returns (int32) {
  461. return x;
  462. }
  463. function test() payable public {
  464. x = 1;
  465. }
  466. receive() payable external {
  467. x = 3;
  468. }
  469. }"##,
  470. );
  471. runtime.constructor(0, Vec::new());
  472. runtime.vm.value = 1;
  473. runtime.raw_function(b"abde".to_vec());
  474. runtime.vm.value = 0;
  475. runtime.function("get_x", Vec::new());
  476. assert_eq!(runtime.vm.output, Ret(3).encode());
  477. runtime.vm.value = 0;
  478. runtime.raw_function_failure(b"abde".to_vec());
  479. let mut runtime = build_solidity(
  480. r##"
  481. contract c {
  482. int32 x;
  483. function get_x() public returns (int32) {
  484. return x;
  485. }
  486. function test() payable public {
  487. x = 1;
  488. }
  489. fallback() external {
  490. x = 2;
  491. }
  492. }"##,
  493. );
  494. runtime.constructor(0, Vec::new());
  495. runtime.vm.value = 1;
  496. runtime.raw_function_failure(b"abde".to_vec());
  497. runtime.vm.value = 0;
  498. runtime.raw_function(b"abde".to_vec());
  499. runtime.function("get_x", Vec::new());
  500. assert_eq!(runtime.vm.output, Ret(2).encode());
  501. }
  502. #[test]
  503. fn hash_tests() {
  504. let mut runtime = build_solidity(
  505. r##"
  506. contract tester {
  507. function test() public {
  508. bytes32 hash = keccak256("Hello, World!");
  509. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  510. }
  511. }"##,
  512. );
  513. runtime.function("test", Vec::new());
  514. let mut runtime = build_solidity(
  515. r##"
  516. contract tester {
  517. function test() public {
  518. bytes memory s = "Hello, World!";
  519. bytes32 hash = keccak256(s);
  520. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  521. }
  522. }"##,
  523. );
  524. runtime.function("test", Vec::new());
  525. let mut runtime = build_solidity(
  526. r##"
  527. contract tester {
  528. bytes s = "Hello, World!";
  529. function test() public {
  530. bytes32 hash = keccak256(s);
  531. assert(hash == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  532. }
  533. }"##,
  534. );
  535. runtime.constructor(0, Vec::new());
  536. runtime.function("test", Vec::new());
  537. let mut runtime = build_solidity(
  538. r##"
  539. contract tester {
  540. function test() public {
  541. bytes32 hash = sha256("Hello, World!");
  542. assert(hash == hex"dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f");
  543. }
  544. }"##,
  545. );
  546. runtime.function("test", Vec::new());
  547. let mut runtime = build_solidity(
  548. r##"
  549. contract tester {
  550. function test() public {
  551. bytes32 hash = blake2_256("Hello, World!");
  552. assert(hash == hex"511bc81dde11180838c562c82bb35f3223f46061ebde4a955c27b3f489cf1e03");
  553. }
  554. }"##,
  555. );
  556. runtime.function("test", Vec::new());
  557. let mut runtime = build_solidity(
  558. r##"
  559. contract tester {
  560. function test() public {
  561. bytes16 hash = blake2_128("Hello, World!");
  562. assert(hash == hex"3895c59e4aeb0903396b5be3fbec69fe");
  563. }
  564. }"##,
  565. );
  566. runtime.function("test", Vec::new());
  567. let mut runtime = build_solidity(
  568. r##"
  569. contract tester {
  570. function test() public {
  571. bytes20 hash = ripemd160("Hello, World!");
  572. assert(hash == hex"527a6a4b9a6da75607546842e0e00105350b1aaf");
  573. }
  574. }"##,
  575. );
  576. runtime.function("test", Vec::new());
  577. }
  578. #[test]
  579. fn try_catch_reachable() {
  580. // ensure that implicit return gets added correctly if catch reachable not
  581. let _ = build_solidity(
  582. r##"
  583. contract AddNumbers { function add(uint256 a, uint256 b) external returns (uint256 c) {c = a + b;} }
  584. contract Example {
  585. AddNumbers addContract;
  586. event StringFailure(string stringFailure);
  587. event BytesFailure(bytes bytesFailure);
  588. function exampleFunction(uint256 _a, uint256 _b) public returns (uint256 _c) {
  589. try addContract.add(_a, _b) returns (uint256 _value) {
  590. return (_value);
  591. } catch Error(string memory _err) {
  592. // This may occur if there is an overflow with the two numbers and the `AddNumbers` contract explicitly fails with a `revert()`
  593. emit StringFailure(_err);
  594. } catch (bytes memory _err) {
  595. emit BytesFailure(_err);
  596. }
  597. _c = 1;
  598. }
  599. }"##,
  600. );
  601. let _ = build_solidity(
  602. r##"
  603. contract AddNumbers { function add(uint256 a, uint256 b) external returns (uint256 c) {c = a + b;} }
  604. contract Example {
  605. AddNumbers addContract;
  606. event StringFailure(string stringFailure);
  607. event BytesFailure(bytes bytesFailure);
  608. function exampleFunction(uint256 _a, uint256 _b) public returns (uint256 _c) {
  609. try addContract.add(_a, _b) returns (uint256 _value) {
  610. return (_value);
  611. } catch Error(string memory _err) {
  612. // This may occur if there is an overflow with the two numbers and the `AddNumbers` contract explicitly fails with a `revert()`
  613. emit StringFailure(_err);
  614. } catch (bytes memory _err) {
  615. emit BytesFailure(_err);
  616. return;
  617. }
  618. _c = 1;
  619. }
  620. }"##,
  621. );
  622. }
  623. #[test]
  624. fn log_api_call_return_values_works() {
  625. let mut runtime = build_solidity_with_options(
  626. r##"
  627. contract Test {
  628. constructor () payable {}
  629. function test() public {
  630. try new Other() returns (Other o) {
  631. o.foo();
  632. }
  633. catch {}
  634. }
  635. }
  636. contract Other {
  637. function foo() public pure {
  638. print("hi!");
  639. }
  640. }
  641. "##,
  642. false,
  643. true,
  644. false,
  645. );
  646. runtime.function("test", vec![]);
  647. assert_eq!(
  648. &runtime.printbuf,
  649. "seal_instantiate=0hi!seal_debug_message=0seal_call=0"
  650. );
  651. }