functions.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. // SPDX-License-Identifier: Apache-2.0
  2. use parity_scale_codec::{Decode, Encode};
  3. use crate::{build_solidity, build_wasm, load_abi};
  4. #[test]
  5. fn constructors() {
  6. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  7. struct Val(u64);
  8. // parse
  9. let mut runtime = build_solidity(
  10. "
  11. contract test {
  12. uint64 result;
  13. constructor() public {
  14. result = 1;
  15. }
  16. function get() public returns (uint64) {
  17. return result;
  18. }
  19. }",
  20. );
  21. runtime.constructor(0, Vec::new());
  22. runtime.function("get", Vec::new());
  23. assert_eq!(runtime.output(), Val(1).encode());
  24. // parse
  25. let mut runtime = build_solidity(
  26. "
  27. contract test {
  28. uint64 result;
  29. constructor(uint64 x) public {
  30. result = x;
  31. }
  32. function get() public returns (uint64) {
  33. return result;
  34. }
  35. }",
  36. );
  37. runtime.constructor(0, Val(0xaa_bb_cc_dd).encode());
  38. runtime.function("get", Vec::new());
  39. assert_eq!(runtime.output(), Val(0xaa_bb_cc_dd).encode());
  40. }
  41. #[test]
  42. fn constructor_wrong_selector() {
  43. let mut runtime = build_solidity(
  44. "
  45. contract test {
  46. uint64 result;
  47. constructor(uint64 x) public {
  48. result = x;
  49. }
  50. function get() public returns (uint64) {
  51. return result;
  52. }
  53. }",
  54. );
  55. runtime.raw_constructor_failure(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  56. runtime.function("get", Vec::new());
  57. }
  58. #[test]
  59. fn constructor_override_selector() {
  60. let mut runtime = build_solidity(
  61. r#"
  62. contract test {
  63. uint64 result;
  64. @selector([1, 2, 3, 4])
  65. constructor(uint64 x) {
  66. result = x;
  67. }
  68. function get() public returns (uint64) {
  69. return result;
  70. }
  71. }"#,
  72. );
  73. let mut input: Vec<u8> = vec![1, 2, 3, 4];
  74. input.extend(0xaa_bb_cc_ddu64.encode());
  75. runtime.raw_constructor(input);
  76. runtime.function("get", Vec::new());
  77. assert_eq!(runtime.output(), 0xaa_bb_cc_ddu64.encode());
  78. }
  79. #[test]
  80. fn function_override_selector() {
  81. let mut runtime = build_solidity(
  82. r#"
  83. contract test {
  84. uint64 result;
  85. constructor() {
  86. result = 1;
  87. }
  88. @selector([1, 2, 3, 4])
  89. function set(uint64 x) public {
  90. result = x;
  91. }
  92. function get() public returns (uint64) {
  93. return result;
  94. }
  95. }"#,
  96. );
  97. let mut input: Vec<u8> = vec![1, 2, 3, 4];
  98. input.extend(0xaa_bb_cc_ddu64.encode());
  99. runtime.raw_function(input);
  100. runtime.function("get", Vec::new());
  101. assert_eq!(runtime.output(), 0xaa_bb_cc_ddu64.encode());
  102. }
  103. #[test]
  104. fn fallback() {
  105. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  106. struct Val(u64);
  107. // parse
  108. let mut runtime = build_solidity(
  109. "
  110. contract test {
  111. int64 result = 102;
  112. function get() public returns (int64) {
  113. return result;
  114. }
  115. fallback() external {
  116. result = 356;
  117. }
  118. }",
  119. );
  120. runtime.raw_function([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  121. runtime.function("get", Vec::new());
  122. assert_eq!(runtime.output(), Val(356).encode());
  123. }
  124. #[test]
  125. fn function_wrong_selector() {
  126. let mut runtime = build_solidity(
  127. "
  128. contract test {
  129. uint64 result;
  130. constructor(uint64 x) public {
  131. result = x;
  132. }
  133. function get() public returns (uint64) {
  134. return result;
  135. }
  136. }",
  137. );
  138. runtime.raw_function_failure(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  139. }
  140. #[test]
  141. fn nofallback() {
  142. // parse
  143. let mut runtime = build_solidity(
  144. "
  145. contract test {
  146. int64 result = 102;
  147. function get() public returns (int64) {
  148. return result;
  149. }
  150. }",
  151. );
  152. runtime.constructor(0, vec![]);
  153. runtime.raw_function_failure([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  154. runtime.function("get", Vec::new());
  155. assert_eq!(runtime.output(), 102i64.encode());
  156. }
  157. #[test]
  158. fn test_overloading() {
  159. // parse
  160. let mut runtime = build_solidity(
  161. "
  162. contract test {
  163. uint32 public result = 1;
  164. constructor() public {
  165. foo(true);
  166. assert(result == 102);
  167. foo(500);
  168. assert(result == 510);
  169. }
  170. function foo(bool x) private {
  171. if (x) {
  172. result = 102;
  173. }
  174. }
  175. function foo(uint32 x) private {
  176. result = x + 10;
  177. }
  178. }",
  179. );
  180. runtime.constructor(0, Vec::new());
  181. }
  182. #[test]
  183. fn shadowing() {
  184. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  185. struct Val(u64);
  186. let src = "
  187. contract test {
  188. uint64 result;
  189. function goodset(uint64 val) public {
  190. result = val;
  191. }
  192. function badset(uint64 val) public {
  193. uint64 result = val;
  194. }
  195. function get() public returns (uint64) {
  196. return result;
  197. }
  198. }";
  199. // parse
  200. let mut runtime = build_solidity(src);
  201. runtime.constructor(0, Vec::new());
  202. runtime.function("goodset", Val(0x1234_5678_9abc_def0).encode());
  203. runtime.function("get", Vec::new());
  204. assert_eq!(runtime.output(), Val(0x1234_5678_9abc_def0).encode());
  205. runtime.function("badset", Val(1).encode());
  206. runtime.function("get", Vec::new());
  207. assert_eq!(runtime.output(), Val(0x1234_5678_9abc_def0).encode());
  208. }
  209. #[test]
  210. fn test_loops() {
  211. // parse
  212. let mut runtime = build_solidity(
  213. "
  214. contract test {
  215. uint32 public result = 1;
  216. constructor() public {
  217. uint32 n = 0;
  218. for (uint32 i = 0; i < 1000; i += 100) {
  219. n += 1;
  220. }
  221. assert(n == 10);
  222. n = 0;
  223. for (uint32 i = 0; i < 1000; i += 100) {
  224. if (true)
  225. continue;
  226. n += 1;
  227. }
  228. assert(n == 0);
  229. n = 0;
  230. for (uint32 i = 0; i < 1000; i += 100) {
  231. n += 1;
  232. break;
  233. }
  234. assert(n == 1);
  235. n = 0;
  236. while (n < 10) {
  237. n += 9;
  238. }
  239. assert(n == 18);
  240. n = 0;
  241. while (false) {
  242. n += 1000;
  243. }
  244. assert(n == 0);
  245. do {
  246. n += 9;
  247. }
  248. while(false);
  249. assert(n == 9);
  250. }
  251. }",
  252. );
  253. runtime.constructor(0, Vec::new());
  254. }
  255. #[test]
  256. fn test_example() {
  257. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  258. struct Val32(i32);
  259. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  260. struct Val64(i64);
  261. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  262. struct ValBool(bool);
  263. // parse
  264. let src = include_str!("../../examples/example.sol");
  265. let mut runtime = build_solidity(src);
  266. runtime.constructor(0, Val32(102).encode());
  267. runtime.function("is_zombie_reaper", Vec::new());
  268. assert_eq!(runtime.output(), ValBool(false).encode());
  269. runtime.function("reap_processes", Vec::new());
  270. runtime.function("run_queue", Vec::new());
  271. }
  272. #[test]
  273. fn test_large_vals() {
  274. // parse
  275. let src = "
  276. contract test {
  277. function large() public returns (int) {
  278. return 102;
  279. }
  280. function large2(int x) public returns (int) {
  281. return x + 100;
  282. }
  283. function doda() public {
  284. int x = large();
  285. assert(large2(10) == 110);
  286. }
  287. }";
  288. let mut runtime = build_solidity(src);
  289. runtime.constructor(0, Vec::new());
  290. runtime.function("doda", Vec::new());
  291. }
  292. #[test]
  293. fn args_and_returns() {
  294. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  295. struct Val32(i32);
  296. let mut runtime = build_solidity(
  297. "
  298. contract foobar {
  299. function foo1() public returns (int32 a) {
  300. a = -102;
  301. }
  302. function foo2() public returns (int32 a) {
  303. a = -102;
  304. return 553;
  305. }
  306. }",
  307. );
  308. runtime.function("foo1", Vec::new());
  309. assert_eq!(runtime.output(), Val32(-102).encode());
  310. runtime.function("foo2", Vec::new());
  311. assert_eq!(runtime.output(), Val32(553).encode());
  312. }
  313. #[test]
  314. fn named_argument_call() {
  315. let mut runtime = build_solidity(
  316. "
  317. contract foobar {
  318. function foo1(bool x) public returns (int32 a) {
  319. return 2;
  320. }
  321. function foo1(uint32 x) public returns (int32 a) {
  322. a = bar({});
  323. }
  324. function bar() private returns (int32) {
  325. return 1;
  326. }
  327. function test() public {
  328. assert(foo1({ x: true }) == 2);
  329. assert(foo1({ x: 102 }) == 1);
  330. }
  331. }",
  332. );
  333. runtime.function("test", Vec::new());
  334. }
  335. #[test]
  336. fn positional_argument_call() {
  337. let mut runtime = build_solidity(
  338. "
  339. contract foobar {
  340. function foo1(bool x) public returns (int32 a) {
  341. return 2;
  342. }
  343. function foo1(uint32 x) public returns (int32 a) {
  344. return 1;
  345. }
  346. function test() public {
  347. assert(foo1(true) == 2);
  348. assert(foo1(102) == 1);
  349. }
  350. }",
  351. );
  352. runtime.function("test", Vec::new());
  353. }
  354. #[test]
  355. fn print() {
  356. let mut runtime = build_solidity(
  357. r#"
  358. contract foobar {
  359. function test() public {
  360. print("Hello, world");
  361. }
  362. }"#,
  363. );
  364. runtime.function("test", Vec::new());
  365. }
  366. #[test]
  367. fn destructuring_call() {
  368. let mut runtime = build_solidity(
  369. r#"
  370. contract c {
  371. function func1() public returns (int32, bool) {
  372. return (102, true);
  373. }
  374. function test() public {
  375. (int32 a, bool b) = func1();
  376. assert(a == 102 && b == true);
  377. }
  378. }"#,
  379. );
  380. runtime.constructor(0, Vec::new());
  381. runtime.function("test", Vec::new());
  382. let mut runtime = build_solidity(
  383. r#"
  384. contract c {
  385. function func1(int32 x) public returns (int32, bool) {
  386. return (102 + x, true);
  387. }
  388. function test() public {
  389. (int32 a, bool b) = func1({x: 5});
  390. assert(a == 107 && b == true);
  391. }
  392. }"#,
  393. );
  394. runtime.constructor(0, Vec::new());
  395. runtime.function("test", Vec::new());
  396. let mut runtime = build_solidity(
  397. r#"
  398. contract c {
  399. function test() public {
  400. b x = new b();
  401. (int32 a, bool b) = x.func1({x: 5});
  402. assert(a == 107 && b == true);
  403. (a, b) = x.func1(-1);
  404. assert(a == 101 && b == true);
  405. }
  406. }
  407. contract b {
  408. function func1(int32 x) public returns (int32, bool) {
  409. return (102 + x, true);
  410. }
  411. }"#,
  412. );
  413. runtime.constructor(0, Vec::new());
  414. runtime.function("test", Vec::new());
  415. }
  416. #[test]
  417. fn global_functions() {
  418. let mut runtime = build_solidity(
  419. r#"
  420. function global_function() pure returns (uint32) {
  421. return 102;
  422. }
  423. contract c {
  424. function test() public {
  425. uint64 x = global_function();
  426. assert(x == 102);
  427. }
  428. }"#,
  429. );
  430. runtime.function("test", Vec::new());
  431. let mut runtime = build_solidity(
  432. r#"
  433. function global_function() pure returns (uint32) {
  434. return 102;
  435. }
  436. function global_function2() pure returns (uint32) {
  437. return global_function() + 5;
  438. }
  439. contract c {
  440. function test() public {
  441. uint64 x = global_function2();
  442. assert(x == 107);
  443. }
  444. }"#,
  445. );
  446. runtime.function("test", Vec::new());
  447. let mut runtime = build_solidity(
  448. r#"
  449. function global_function() pure returns (uint32) {
  450. return 102;
  451. }
  452. function global_function2() pure returns (uint32) {
  453. return global_function() + 5;
  454. }
  455. contract c {
  456. function test() public {
  457. function() internal returns (uint32) ftype = global_function2;
  458. uint64 x = ftype();
  459. assert(x == 107);
  460. }
  461. }"#,
  462. );
  463. runtime.function("test", Vec::new());
  464. }
  465. #[test]
  466. fn virtual_function_member_access() {
  467. let src = r##"
  468. interface IERC1155Receiver {
  469. @selector([1, 2, 3, 4])
  470. function onERC1155Received() external returns (bytes4);
  471. }
  472. abstract contract ERC1155 {
  473. function _doSafeTransferAcceptanceCheck() internal pure returns (bytes4) {
  474. return IERC1155Receiver.onERC1155Received.selector;
  475. }
  476. }
  477. contract C is ERC1155 {
  478. function create() public pure returns (bytes4) {
  479. return _doSafeTransferAcceptanceCheck();
  480. }
  481. }"##;
  482. // The create function is the only one appearing in the metadata.
  483. let abi = load_abi(&build_wasm(src, false, false)[0].1);
  484. let messages = abi.spec().messages();
  485. assert_eq!(messages.len(), 1);
  486. assert_eq!(messages[0].label(), "create");
  487. // The create function returns the selector of IERC1155Receiver.onERC1155Received
  488. let mut runtime = build_solidity(src);
  489. runtime.function("create", vec![]);
  490. assert_eq!(runtime.output(), vec![1, 2, 3, 4]);
  491. }