functions.rs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  1. use parity_scale_codec::Encode;
  2. use parity_scale_codec_derive::{Decode, Encode};
  3. use crate::{
  4. build_solidity, first_error, first_warning, no_warnings, no_warnings_errors, parse_and_resolve,
  5. };
  6. use solang::Target;
  7. #[test]
  8. fn constructors() {
  9. let ns = parse_and_resolve(
  10. r##"
  11. contract test {
  12. constructor() internal {}
  13. }"##,
  14. Target::Substrate {
  15. address_length: 32,
  16. value_length: 16,
  17. },
  18. );
  19. assert_eq!(
  20. first_warning(ns.diagnostics),
  21. "‘internal’: visibility for constructors is ignored"
  22. );
  23. let ns = parse_and_resolve(
  24. r##"
  25. contract test {
  26. constructor() virtual {}
  27. }"##,
  28. Target::Substrate {
  29. address_length: 32,
  30. value_length: 16,
  31. },
  32. );
  33. assert_eq!(
  34. first_error(ns.diagnostics),
  35. "constructors cannot be declared ‘virtual’"
  36. );
  37. #[derive(Debug, PartialEq, Encode, Decode)]
  38. struct Val(u64);
  39. // parse
  40. let mut runtime = build_solidity(
  41. "
  42. contract test {
  43. uint64 result;
  44. constructor() public {
  45. result = 1;
  46. }
  47. constructor(uint64 x) public {
  48. result = x;
  49. }
  50. function get() public returns (uint64) {
  51. return result;
  52. }
  53. }",
  54. );
  55. runtime.constructor(0, Vec::new());
  56. runtime.function("get", Vec::new());
  57. assert_eq!(runtime.vm.output, Val(1).encode());
  58. // parse
  59. let mut runtime = build_solidity(
  60. "
  61. contract test {
  62. uint64 result;
  63. constructor() public {
  64. result = 1;
  65. }
  66. constructor(uint64 x) public {
  67. result = x;
  68. }
  69. function get() public returns (uint64) {
  70. return result;
  71. }
  72. }",
  73. );
  74. runtime.constructor(1, Val(0xaa_bb_cc_dd).encode());
  75. runtime.function("get", Vec::new());
  76. assert_eq!(runtime.vm.output, Val(0xaa_bb_cc_dd).encode());
  77. }
  78. #[test]
  79. #[should_panic]
  80. fn constructor_wrong_selector() {
  81. let mut runtime = build_solidity(
  82. "
  83. contract test {
  84. uint64 result;
  85. constructor() public {
  86. result = 1;
  87. }
  88. constructor(uint64 x) public {
  89. result = x;
  90. }
  91. function get() public returns (uint64) {
  92. return result;
  93. }
  94. }",
  95. );
  96. runtime.raw_constructor(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  97. }
  98. #[test]
  99. fn fallback() {
  100. let ns = parse_and_resolve(
  101. r##"
  102. contract test {
  103. int64 result = 102;
  104. function get() public returns (int64) {
  105. return result;
  106. }
  107. function() external {
  108. result = 356;
  109. }
  110. }"##,
  111. Target::Substrate {
  112. address_length: 32,
  113. value_length: 16,
  114. },
  115. );
  116. assert_eq!(
  117. first_error(ns.diagnostics),
  118. "function is missing a name. did you mean ‘fallback() external {…}’ or ‘receive() external {…}’?"
  119. );
  120. #[derive(Debug, PartialEq, Encode, Decode)]
  121. struct Val(u64);
  122. // parse
  123. let mut runtime = build_solidity(
  124. "
  125. contract test {
  126. int64 result = 102;
  127. function get() public returns (int64) {
  128. return result;
  129. }
  130. fallback() external {
  131. result = 356;
  132. }
  133. }",
  134. );
  135. runtime.raw_function([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  136. runtime.function("get", Vec::new());
  137. assert_eq!(runtime.vm.output, Val(356).encode());
  138. }
  139. #[test]
  140. #[should_panic]
  141. fn function_wrong_selector() {
  142. let mut runtime = build_solidity(
  143. "
  144. contract test {
  145. uint64 result;
  146. constructor() public {
  147. result = 1;
  148. }
  149. constructor(uint64 x) public {
  150. result = x;
  151. }
  152. function get() public returns (uint64) {
  153. return result;
  154. }
  155. }",
  156. );
  157. runtime.raw_function(vec![0xaa, 0xbb, 0xcc, 0xdd]);
  158. }
  159. #[test]
  160. #[should_panic]
  161. fn nofallback() {
  162. #[derive(Debug, PartialEq, Encode, Decode)]
  163. struct Val(u64);
  164. // parse
  165. let mut runtime = build_solidity(
  166. "
  167. contract test {
  168. int64 result = 102;
  169. function get() public returns (int64) {
  170. return result;
  171. }
  172. }",
  173. );
  174. runtime.raw_function([0xaa, 0xbb, 0xcc, 0xdd, 0xff].to_vec());
  175. runtime.function("get", Vec::new());
  176. assert_eq!(runtime.vm.output, Val(356).encode());
  177. }
  178. #[test]
  179. fn test_overloading() {
  180. // parse
  181. let mut runtime = build_solidity(
  182. "
  183. contract test {
  184. uint32 result = 1;
  185. constructor() public {
  186. foo(true);
  187. assert(result == 102);
  188. foo(500);
  189. assert(result == 510);
  190. }
  191. function foo(bool x) private {
  192. if (x) {
  193. result = 102;
  194. }
  195. }
  196. function foo(uint32 x) private {
  197. result = x + 10;
  198. }
  199. }",
  200. );
  201. runtime.constructor(0, Vec::new());
  202. }
  203. #[test]
  204. fn mutability() {
  205. let ns = parse_and_resolve(
  206. "contract test {
  207. int64 foo = 1844674;
  208. function bar() public pure returns (int64) {
  209. return foo;
  210. }
  211. }",
  212. Target::Substrate {
  213. address_length: 32,
  214. value_length: 16,
  215. },
  216. );
  217. assert_eq!(
  218. first_error(ns.diagnostics),
  219. "function declared ‘pure’ but this expression reads from state"
  220. );
  221. let ns = parse_and_resolve(
  222. "contract test {
  223. function bar() public constant returns (int64) {
  224. return 102;
  225. }
  226. }",
  227. Target::Substrate {
  228. address_length: 32,
  229. value_length: 16,
  230. },
  231. );
  232. assert_eq!(
  233. first_warning(ns.diagnostics),
  234. "‘constant’ is deprecated. Use ‘view’ instead"
  235. );
  236. let ns = parse_and_resolve(
  237. "contract test {
  238. function bar(int64[] storage foo) private pure returns (int64) {
  239. return foo[0];
  240. }
  241. }",
  242. Target::Substrate {
  243. address_length: 32,
  244. value_length: 16,
  245. },
  246. );
  247. assert_eq!(
  248. first_error(ns.diagnostics),
  249. "function declared ‘pure’ but this expression reads from state"
  250. );
  251. let ns = parse_and_resolve(
  252. "contract test {
  253. int64 foo = 1844674;
  254. function bar() public view {
  255. foo = 102;
  256. }
  257. }",
  258. Target::Substrate {
  259. address_length: 32,
  260. value_length: 16,
  261. },
  262. );
  263. assert_eq!(
  264. first_error(ns.diagnostics),
  265. "function declared ‘view’ but this expression writes to state"
  266. );
  267. let ns = parse_and_resolve(
  268. "contract test {
  269. function bar(int[] storage foo) internal view {
  270. foo[0] = 102;
  271. }
  272. }",
  273. Target::Substrate {
  274. address_length: 32,
  275. value_length: 16,
  276. },
  277. );
  278. assert_eq!(
  279. first_error(ns.diagnostics),
  280. "function declared ‘view’ but this expression writes to state"
  281. );
  282. let ns = parse_and_resolve(
  283. r#"contract c {
  284. function add(address a) public view {
  285. (bool f, bytes memory res) = a.call(hex"0102");
  286. }
  287. }"#,
  288. Target::Substrate {
  289. address_length: 32,
  290. value_length: 16,
  291. },
  292. );
  293. assert_eq!(
  294. first_error(ns.diagnostics),
  295. "function declared ‘view’ but this expression writes to state"
  296. );
  297. let ns = parse_and_resolve(
  298. r#"contract c {
  299. function add(address a) public returns (bool f, bytes res) {
  300. (f, res) = a.call(hex"0102");
  301. }
  302. }"#,
  303. Target::Substrate {
  304. address_length: 32,
  305. value_length: 16,
  306. },
  307. );
  308. assert_eq!(ns.diagnostics.len(), 1);
  309. // ensure that we don't warn "function may be declared pure" if we can't parse it
  310. let ns = parse_and_resolve(
  311. r#"contract c {
  312. function add(address a) public returns (bool f, bytes res) {
  313. return true;
  314. }
  315. }"#,
  316. Target::Substrate {
  317. address_length: 32,
  318. value_length: 16,
  319. },
  320. );
  321. no_warnings(&ns.diagnostics);
  322. let ns = parse_and_resolve(
  323. "contract test {
  324. int64 foo = 1844674;
  325. function bar() public payable returns (int64) {
  326. return foo;
  327. }
  328. }",
  329. Target::Substrate {
  330. address_length: 32,
  331. value_length: 16,
  332. },
  333. );
  334. no_warnings_errors(ns.diagnostics);
  335. let ns = parse_and_resolve(
  336. "contract test {
  337. function bar() public payable returns (int64) {
  338. return 102;
  339. }
  340. }",
  341. Target::Substrate {
  342. address_length: 32,
  343. value_length: 16,
  344. },
  345. );
  346. no_warnings_errors(ns.diagnostics);
  347. let ns = parse_and_resolve(
  348. "contract test {
  349. function bar() public view returns (int64) {
  350. return 102;
  351. }
  352. }",
  353. Target::Substrate {
  354. address_length: 32,
  355. value_length: 16,
  356. },
  357. );
  358. assert_eq!(
  359. first_warning(ns.diagnostics),
  360. "function declared ‘view’ can be declared ‘pure’"
  361. );
  362. let ns = parse_and_resolve(
  363. "contract test {
  364. int64 constant public foo = 1844674;
  365. }",
  366. Target::Substrate {
  367. address_length: 32,
  368. value_length: 16,
  369. },
  370. );
  371. no_warnings_errors(ns.diagnostics);
  372. }
  373. #[test]
  374. fn shadowing() {
  375. #[derive(Debug, PartialEq, Encode, Decode)]
  376. struct Val(u64);
  377. let src = "
  378. contract test {
  379. uint64 result;
  380. function goodset(uint64 val) public {
  381. result = val;
  382. }
  383. function badset(uint64 val) public {
  384. uint64 result = val;
  385. }
  386. function get() public returns (uint64) {
  387. return result;
  388. }
  389. }";
  390. let ns = parse_and_resolve(
  391. src,
  392. Target::Substrate {
  393. address_length: 32,
  394. value_length: 16,
  395. },
  396. );
  397. assert_eq!(
  398. first_warning(ns.diagnostics),
  399. "declaration of ‘result’ shadows state variable"
  400. );
  401. // parse
  402. let mut runtime = build_solidity(src);
  403. runtime.constructor(0, Vec::new());
  404. runtime.function("goodset", Val(0x1234_5678_9abc_def0).encode());
  405. runtime.function("get", Vec::new());
  406. assert_eq!(runtime.vm.output, Val(0x1234_5678_9abc_def0).encode());
  407. runtime.function("badset", Val(1).encode());
  408. runtime.function("get", Vec::new());
  409. assert_eq!(runtime.vm.output, Val(0x1234_5678_9abc_def0).encode());
  410. }
  411. #[test]
  412. fn scopes() {
  413. #[derive(Debug, PartialEq, Encode, Decode)]
  414. struct Val(u64);
  415. let src = "
  416. contract test {
  417. function goodset() public returns (bool) {
  418. {
  419. bool a = true;
  420. }
  421. return a;
  422. }
  423. }";
  424. let ns = parse_and_resolve(
  425. src,
  426. Target::Substrate {
  427. address_length: 32,
  428. value_length: 16,
  429. },
  430. );
  431. assert_eq!(first_error(ns.diagnostics), "`a\' is not found");
  432. let src = "
  433. contract test {
  434. function goodset() public returns (uint) {
  435. for (uint i = 0; i < 10 ; i++) {
  436. bool a = true;
  437. }
  438. return i;
  439. }
  440. }";
  441. let ns = parse_and_resolve(
  442. src,
  443. Target::Substrate {
  444. address_length: 32,
  445. value_length: 16,
  446. },
  447. );
  448. assert_eq!(first_error(ns.diagnostics), "`i\' is not found");
  449. }
  450. #[test]
  451. fn for_forever() {
  452. let src = "
  453. contract test {
  454. function goodset() public returns (bool) {
  455. for (;;) {
  456. // ...
  457. }
  458. return;
  459. }
  460. }";
  461. let ns = parse_and_resolve(
  462. src,
  463. Target::Substrate {
  464. address_length: 32,
  465. value_length: 16,
  466. },
  467. );
  468. assert_eq!(first_error(ns.diagnostics), "unreachable statement");
  469. }
  470. #[test]
  471. fn test_loops() {
  472. // parse
  473. let mut runtime = build_solidity(
  474. "
  475. contract test {
  476. uint32 result = 1;
  477. constructor() public {
  478. uint32 n = 0;
  479. for (uint32 i = 0; i < 1000; i += 100) {
  480. n += 1;
  481. }
  482. assert(n == 10);
  483. n = 0;
  484. for (uint32 i = 0; i < 1000; i += 100) {
  485. if (true)
  486. continue;
  487. n += 1;
  488. }
  489. assert(n == 0);
  490. n = 0;
  491. for (uint32 i = 0; i < 1000; i += 100) {
  492. n += 1;
  493. break;
  494. }
  495. assert(n == 1);
  496. n = 0;
  497. while (n < 10) {
  498. n += 9;
  499. }
  500. assert(n == 18);
  501. n = 0;
  502. while (false) {
  503. n += 1000;
  504. }
  505. assert(n == 0);
  506. do {
  507. n += 9;
  508. }
  509. while(false);
  510. assert(n == 9);
  511. }
  512. }",
  513. );
  514. runtime.constructor(0, Vec::new());
  515. }
  516. #[test]
  517. fn test_full_example() {
  518. #[derive(Debug, PartialEq, Encode, Decode)]
  519. struct Val32(i32);
  520. #[derive(Debug, PartialEq, Encode, Decode)]
  521. struct Val64(i64);
  522. #[derive(Debug, PartialEq, Encode, Decode)]
  523. struct ValBool(bool);
  524. // parse
  525. let src = include_str!("../../examples/full_example.sol");
  526. let mut runtime = build_solidity(src);
  527. runtime.constructor(0, Val32(102).encode());
  528. runtime.function("is_zombie_reaper", Vec::new());
  529. assert_eq!(runtime.vm.output, ValBool(false).encode());
  530. runtime.function("reap_processes", Vec::new());
  531. runtime.function("run_queue", Vec::new());
  532. }
  533. #[test]
  534. fn test_large_vals() {
  535. // parse
  536. let src = "
  537. contract test {
  538. function large() public returns (int) {
  539. return 102;
  540. }
  541. function large2(int x) public returns (int) {
  542. return x + 100;
  543. }
  544. function doda() public {
  545. int x = large();
  546. assert(large2(10) == 110);
  547. }
  548. }";
  549. let mut runtime = build_solidity(src);
  550. runtime.constructor(0, Vec::new());
  551. runtime.function("doda", Vec::new());
  552. }
  553. #[test]
  554. fn args_and_returns() {
  555. #[derive(Debug, PartialEq, Encode, Decode)]
  556. struct Val32(i32);
  557. let src = "
  558. contract args {
  559. function foo(bool arg1, uint arg1) public {
  560. }
  561. }";
  562. let ns = parse_and_resolve(
  563. src,
  564. Target::Substrate {
  565. address_length: 32,
  566. value_length: 16,
  567. },
  568. );
  569. assert_eq!(first_error(ns.diagnostics), "arg1 is already declared");
  570. let src = "
  571. contract args {
  572. function foo(bool arg1, uint arg2) public returns (address arg2, uint) {
  573. }
  574. }";
  575. let ns = parse_and_resolve(
  576. src,
  577. Target::Substrate {
  578. address_length: 32,
  579. value_length: 16,
  580. },
  581. );
  582. assert_eq!(first_error(ns.diagnostics), "arg2 is already declared");
  583. let src = "
  584. contract args {
  585. function foo(bool arg1, uint arg2) public returns (address, uint) {
  586. }
  587. }";
  588. let ns = parse_and_resolve(
  589. src,
  590. Target::Substrate {
  591. address_length: 32,
  592. value_length: 16,
  593. },
  594. );
  595. assert_eq!(first_error(ns.diagnostics), "missing return statement");
  596. let src = "
  597. contract primitives {
  598. enum oper { add, sub, mul, div, mod, pow }
  599. function op_i64(oper op, int64 a, int64 b) pure public returns (int64) {
  600. if (op == oper.add) {
  601. return a + b;
  602. } else if (op == oper.sub) {
  603. return a - b;
  604. } else if (op == oper.mul) {
  605. return a * b;
  606. } else if (op == oper.div) {
  607. return a / b;
  608. } else if (op == oper.mod) {
  609. return a % b;
  610. }
  611. }
  612. }";
  613. let ns = parse_and_resolve(
  614. src,
  615. Target::Substrate {
  616. address_length: 32,
  617. value_length: 16,
  618. },
  619. );
  620. assert_eq!(first_error(ns.diagnostics), "missing return statement");
  621. let mut runtime = build_solidity(
  622. "
  623. contract foobar {
  624. function foo1() public returns (int32 a) {
  625. a = -102;
  626. }
  627. function foo2() public returns (int32 a) {
  628. a = -102;
  629. return 553;
  630. }
  631. }",
  632. );
  633. runtime.function("foo1", Vec::new());
  634. assert_eq!(runtime.vm.output, Val32(-102).encode());
  635. runtime.function("foo2", Vec::new());
  636. assert_eq!(runtime.vm.output, Val32(553).encode());
  637. }
  638. #[test]
  639. fn named_argument_call() {
  640. let src = "
  641. contract args {
  642. function foo(bool arg1, uint arg2) public {
  643. }
  644. function bar() private {
  645. foo({ arg1: false });
  646. }
  647. }";
  648. let ns = parse_and_resolve(
  649. src,
  650. Target::Substrate {
  651. address_length: 32,
  652. value_length: 16,
  653. },
  654. );
  655. assert_eq!(
  656. first_error(ns.diagnostics),
  657. "function expects 2 arguments, 1 provided"
  658. );
  659. let src = "
  660. contract args {
  661. function foo(bool arg1, uint arg2) public {
  662. }
  663. function bar() private {
  664. foo[1]({ arg1: false });
  665. }
  666. }";
  667. let ns = parse_and_resolve(
  668. src,
  669. Target::Substrate {
  670. address_length: 32,
  671. value_length: 16,
  672. },
  673. );
  674. assert_eq!(first_error(ns.diagnostics), "unexpected array type");
  675. let src = "
  676. contract args {
  677. function foo(bool arg1, uint arg2) public {
  678. }
  679. function bar() private {
  680. foo({ arg1: false, arg1: 203 });
  681. }
  682. }";
  683. let ns = parse_and_resolve(
  684. src,
  685. Target::Substrate {
  686. address_length: 32,
  687. value_length: 16,
  688. },
  689. );
  690. assert_eq!(
  691. first_error(ns.diagnostics),
  692. "duplicate argument with name ‘arg1’"
  693. );
  694. let src = "
  695. contract args {
  696. function foo(bool arg1, uint arg2) public {
  697. }
  698. function bar() private {
  699. foo({ arg1: false, arg3: 1 });
  700. }
  701. }";
  702. let ns = parse_and_resolve(
  703. src,
  704. Target::Substrate {
  705. address_length: 32,
  706. value_length: 16,
  707. },
  708. );
  709. assert_eq!(
  710. first_error(ns.diagnostics),
  711. "missing argument ‘arg2’ to function ‘foo’"
  712. );
  713. let src = "
  714. contract args {
  715. function foo(bool arg1, uint arg2) public {
  716. }
  717. function bar() private {
  718. foo({ arg1: false, arg2: true });
  719. }
  720. }";
  721. let ns = parse_and_resolve(
  722. src,
  723. Target::Substrate {
  724. address_length: 32,
  725. value_length: 16,
  726. },
  727. );
  728. assert_eq!(
  729. first_error(ns.diagnostics),
  730. "conversion from bool to uint256 not possible"
  731. );
  732. let mut runtime = build_solidity(
  733. "
  734. contract foobar {
  735. function foo1(bool x) public returns (int32 a) {
  736. return 2;
  737. }
  738. function foo1(uint32 x) public returns (int32 a) {
  739. a = bar({});
  740. }
  741. function bar() private returns (int32) {
  742. return 1;
  743. }
  744. function test() public {
  745. assert(foo1({ x: true }) == 2);
  746. assert(foo1({ x: 102 }) == 1);
  747. }
  748. }",
  749. );
  750. runtime.function("test", Vec::new());
  751. }
  752. #[test]
  753. fn positional_argument_call() {
  754. let src = "
  755. contract args {
  756. function foo(bool arg1, uint arg2) public {
  757. }
  758. function bar() private {
  759. foo(false);
  760. }
  761. }";
  762. let ns = parse_and_resolve(
  763. src,
  764. Target::Substrate {
  765. address_length: 32,
  766. value_length: 16,
  767. },
  768. );
  769. assert_eq!(
  770. first_error(ns.diagnostics),
  771. "function expects 2 arguments, 1 provided"
  772. );
  773. let src = "
  774. contract args {
  775. function foo(bool arg1, uint arg2) public {
  776. }
  777. function bar() private {
  778. foo[1](false, 1);
  779. }
  780. }";
  781. let ns = parse_and_resolve(
  782. src,
  783. Target::Substrate {
  784. address_length: 32,
  785. value_length: 16,
  786. },
  787. );
  788. assert_eq!(first_error(ns.diagnostics), "expression is not an array");
  789. let src = "
  790. contract args {
  791. function foo(bool arg1, uint arg2) public {
  792. }
  793. function bar() private {
  794. foo(1, false);
  795. }
  796. }";
  797. let ns = parse_and_resolve(
  798. src,
  799. Target::Substrate {
  800. address_length: 32,
  801. value_length: 16,
  802. },
  803. );
  804. assert_eq!(
  805. first_error(ns.diagnostics),
  806. "expected ‘bool’, found integer"
  807. );
  808. let mut runtime = build_solidity(
  809. "
  810. contract foobar {
  811. function foo1(bool x) public returns (int32 a) {
  812. return 2;
  813. }
  814. function foo1(uint32 x) public returns (int32 a) {
  815. return 1;
  816. }
  817. function test() public {
  818. assert(foo1(true) == 2);
  819. assert(foo1(102) == 1);
  820. }
  821. }",
  822. );
  823. runtime.function("test", Vec::new());
  824. }
  825. #[test]
  826. fn print() {
  827. let mut runtime = build_solidity(
  828. r#"
  829. contract foobar {
  830. function test() public {
  831. print("Hello, world");
  832. }
  833. }"#,
  834. );
  835. runtime.function("test", Vec::new());
  836. }
  837. #[test]
  838. fn destructuring_call() {
  839. let mut runtime = build_solidity(
  840. r#"
  841. contract c {
  842. function func1() public returns (int32, bool) {
  843. return (102, true);
  844. }
  845. function test() public {
  846. (int32 a, bool b) = func1();
  847. assert(a == 102 && b == true);
  848. }
  849. }"#,
  850. );
  851. runtime.function("test", Vec::new());
  852. let mut runtime = build_solidity(
  853. r#"
  854. contract c {
  855. function func1(int32 x) public returns (int32, bool) {
  856. return (102 + x, true);
  857. }
  858. function test() public {
  859. (int32 a, bool b) = func1({x: 5});
  860. assert(a == 107 && b == true);
  861. }
  862. }"#,
  863. );
  864. runtime.function("test", Vec::new());
  865. let mut runtime = build_solidity(
  866. r#"
  867. contract c {
  868. function test() public {
  869. b x = new b();
  870. (int32 a, bool b) = x.func1({x: 5});
  871. assert(a == 107 && b == true);
  872. (a, b) = x.func1(-1);
  873. assert(a == 101 && b == true);
  874. }
  875. }
  876. contract b {
  877. function func1(int32 x) public returns (int32, bool) {
  878. return (102 + x, true);
  879. }
  880. }"#,
  881. );
  882. runtime.function("test", Vec::new());
  883. }
  884. #[test]
  885. fn payable() {
  886. let src = r##"
  887. pragma solidity 0;
  888. contract c {
  889. int32 i = 0;
  890. function test() payable internal {
  891. i = 2;
  892. }
  893. }"##;
  894. let ns = parse_and_resolve(
  895. src,
  896. Target::Substrate {
  897. address_length: 32,
  898. value_length: 16,
  899. },
  900. );
  901. assert_eq!(
  902. first_error(ns.diagnostics),
  903. "internal or private function cannot be payable"
  904. );
  905. let src = r##"
  906. pragma solidity 0;
  907. contract c {
  908. int32 i = 0;
  909. function test() payable private {
  910. i = 2;
  911. }
  912. }"##;
  913. let ns = parse_and_resolve(
  914. src,
  915. Target::Substrate {
  916. address_length: 32,
  917. value_length: 16,
  918. },
  919. );
  920. assert_eq!(
  921. first_error(ns.diagnostics),
  922. "internal or private function cannot be payable"
  923. );
  924. let src = r##"
  925. pragma solidity 0;
  926. contract c {
  927. int32 i = 0;
  928. receive() external {
  929. i = 2;
  930. }
  931. }"##;
  932. let ns = parse_and_resolve(
  933. src,
  934. Target::Substrate {
  935. address_length: 32,
  936. value_length: 16,
  937. },
  938. );
  939. assert_eq!(
  940. first_error(ns.diagnostics),
  941. "receive function must be declared payable"
  942. );
  943. let src = r##"
  944. pragma solidity 0;
  945. contract c {
  946. int32 i = 0;
  947. fallback() external payable {
  948. i = 2;
  949. }
  950. }"##;
  951. let ns = parse_and_resolve(
  952. src,
  953. Target::Substrate {
  954. address_length: 32,
  955. value_length: 16,
  956. },
  957. );
  958. assert_eq!(
  959. first_error(ns.diagnostics),
  960. "fallback function must not be declare payable, use ‘receive() external payable’ instead"
  961. );
  962. let src = r##"
  963. contract c {
  964. constructor() public payable {
  965. }
  966. constructor(int32 x) public {
  967. }
  968. }"##;
  969. let ns = parse_and_resolve(
  970. src,
  971. Target::Substrate {
  972. address_length: 32,
  973. value_length: 16,
  974. },
  975. );
  976. assert_eq!(
  977. first_error(ns.diagnostics),
  978. "all constructors should be defined ‘payable’ or not"
  979. );
  980. let src = r##"
  981. contract c {
  982. constructor() public {
  983. }
  984. constructor(int32 x) public payable {
  985. }
  986. }"##;
  987. let ns = parse_and_resolve(
  988. src,
  989. Target::Substrate {
  990. address_length: 32,
  991. value_length: 16,
  992. },
  993. );
  994. assert_eq!(
  995. first_error(ns.diagnostics),
  996. "all constructors should be defined ‘payable’ or not"
  997. );
  998. }
  999. #[test]
  1000. fn global_functions() {
  1001. let ns = parse_and_resolve(
  1002. r##"
  1003. function() {}
  1004. "##,
  1005. Target::Substrate {
  1006. address_length: 32,
  1007. value_length: 16,
  1008. },
  1009. );
  1010. assert_eq!(first_error(ns.diagnostics), "missing function name");
  1011. let ns = parse_and_resolve(
  1012. r##"
  1013. function x();
  1014. "##,
  1015. Target::Substrate {
  1016. address_length: 32,
  1017. value_length: 16,
  1018. },
  1019. );
  1020. assert_eq!(first_error(ns.diagnostics), "missing function body");
  1021. let ns = parse_and_resolve(
  1022. r##"
  1023. function x() virtual {}
  1024. "##,
  1025. Target::Substrate {
  1026. address_length: 32,
  1027. value_length: 16,
  1028. },
  1029. );
  1030. assert_eq!(
  1031. first_error(ns.diagnostics),
  1032. "only functions in contracts can be virtual"
  1033. );
  1034. let ns = parse_and_resolve(
  1035. r##"
  1036. function x() override {}
  1037. "##,
  1038. Target::Substrate {
  1039. address_length: 32,
  1040. value_length: 16,
  1041. },
  1042. );
  1043. assert_eq!(
  1044. first_error(ns.diagnostics),
  1045. "only functions in contracts can override"
  1046. );
  1047. let ns = parse_and_resolve(
  1048. r##"
  1049. function x() feyla {}
  1050. "##,
  1051. Target::Substrate {
  1052. address_length: 32,
  1053. value_length: 16,
  1054. },
  1055. );
  1056. assert_eq!(
  1057. first_error(ns.diagnostics),
  1058. "function modifiers or base contracts are only allowed on functions in contracts"
  1059. );
  1060. let ns = parse_and_resolve(
  1061. r##"
  1062. function x() feyla {}
  1063. "##,
  1064. Target::Substrate {
  1065. address_length: 32,
  1066. value_length: 16,
  1067. },
  1068. );
  1069. assert_eq!(
  1070. first_error(ns.diagnostics),
  1071. "function modifiers or base contracts are only allowed on functions in contracts"
  1072. );
  1073. let ns = parse_and_resolve(
  1074. r##"
  1075. event foo(bool);
  1076. function x() pure { emit foo(true); }
  1077. "##,
  1078. Target::Substrate {
  1079. address_length: 32,
  1080. value_length: 16,
  1081. },
  1082. );
  1083. assert_eq!(
  1084. first_error(ns.diagnostics),
  1085. "function declared ‘pure’ but this expression writes to state"
  1086. );
  1087. let ns = parse_and_resolve(
  1088. r##"
  1089. function x(int[] storage x) pure returns (int) { return x[1]; }
  1090. "##,
  1091. Target::Substrate {
  1092. address_length: 32,
  1093. value_length: 16,
  1094. },
  1095. );
  1096. assert_eq!(
  1097. first_error(ns.diagnostics),
  1098. "function declared ‘pure’ but this expression reads from state"
  1099. );
  1100. let ns = parse_and_resolve(
  1101. r##"
  1102. struct S {
  1103. int32 f1;
  1104. int32 f2;
  1105. }
  1106. function x(S storage x) view { x.f1 = 102; }
  1107. "##,
  1108. Target::Substrate {
  1109. address_length: 32,
  1110. value_length: 16,
  1111. },
  1112. );
  1113. assert_eq!(
  1114. first_error(ns.diagnostics),
  1115. "function declared ‘view’ but this expression writes to state"
  1116. );
  1117. let ns = parse_and_resolve(
  1118. r##"
  1119. function x(int64) pure { return 102; }
  1120. function x(int128) pure { return 102; }
  1121. function x(int128) pure { return 132; }
  1122. "##,
  1123. Target::Substrate {
  1124. address_length: 32,
  1125. value_length: 16,
  1126. },
  1127. );
  1128. assert_eq!(
  1129. first_error(ns.diagnostics),
  1130. "overloaded function with this signature already exist"
  1131. );
  1132. let mut runtime = build_solidity(
  1133. r#"
  1134. function global_function() pure returns (uint32) {
  1135. return 102;
  1136. }
  1137. contract c {
  1138. function test() public {
  1139. uint64 x = global_function();
  1140. assert(x == 102);
  1141. }
  1142. }"#,
  1143. );
  1144. runtime.function("test", Vec::new());
  1145. let mut runtime = build_solidity(
  1146. r#"
  1147. function global_function() pure returns (uint32) {
  1148. return 102;
  1149. }
  1150. function global_function2() pure returns (uint32) {
  1151. return global_function() + 5;
  1152. }
  1153. contract c {
  1154. function test() public {
  1155. uint64 x = global_function2();
  1156. assert(x == 107);
  1157. }
  1158. }"#,
  1159. );
  1160. runtime.function("test", Vec::new());
  1161. let mut runtime = build_solidity(
  1162. r#"
  1163. function global_function() pure returns (uint32) {
  1164. return 102;
  1165. }
  1166. function global_function2() pure returns (uint32) {
  1167. return global_function() + 5;
  1168. }
  1169. contract c {
  1170. function test() public {
  1171. function() internal returns (uint32) ftype = global_function2;
  1172. uint64 x = ftype();
  1173. assert(x == 107);
  1174. }
  1175. }"#,
  1176. );
  1177. runtime.function("test", Vec::new());
  1178. }
  1179. #[test]
  1180. fn return_not_returns() {
  1181. let ns = parse_and_resolve(
  1182. "contract test {
  1183. function bar() public pure return (int64) {
  1184. return 1;
  1185. }
  1186. }",
  1187. Target::Substrate {
  1188. address_length: 32,
  1189. value_length: 16,
  1190. },
  1191. );
  1192. assert_eq!(
  1193. first_error(ns.diagnostics),
  1194. "‘return’ unexpected. Did you mean ‘returns’?"
  1195. );
  1196. }
  1197. #[test]
  1198. fn stray_semicolon() {
  1199. let ns = parse_and_resolve(
  1200. "struct a { uint32 f1; };",
  1201. Target::Substrate {
  1202. address_length: 32,
  1203. value_length: 16,
  1204. },
  1205. );
  1206. assert_eq!(first_error(ns.diagnostics), "stray semicolon");
  1207. let ns = parse_and_resolve(
  1208. "contract x { struct a { uint32 f1; }; }",
  1209. Target::Substrate {
  1210. address_length: 32,
  1211. value_length: 16,
  1212. },
  1213. );
  1214. assert_eq!(first_error(ns.diagnostics), "stray semicolon");
  1215. }