builtins.rs 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. use parity_scale_codec::Encode;
  2. use parity_scale_codec_derive::{Decode, Encode};
  3. use crate::{build_solidity, first_error, first_warning, no_errors, parse_and_resolve};
  4. use solang::Target;
  5. #[test]
  6. fn abi_decode() {
  7. let ns = parse_and_resolve(
  8. r#"
  9. contract printer {
  10. function test() public {
  11. (int a) = abi.decode(hex"00", feh);
  12. }
  13. }"#,
  14. Target::Substrate {
  15. address_length: 32,
  16. value_length: 16,
  17. },
  18. );
  19. assert_eq!(first_error(ns.diagnostics), "type ‘feh’ not found");
  20. let ns = parse_and_resolve(
  21. r#"
  22. contract printer {
  23. function test() public {
  24. (int a) = abi.decode(hex"00", (int storage));
  25. }
  26. }"#,
  27. Target::Substrate {
  28. address_length: 32,
  29. value_length: 16,
  30. },
  31. );
  32. assert_eq!(
  33. first_error(ns.diagnostics),
  34. "storage modifier ‘storage’ not allowed"
  35. );
  36. let ns = parse_and_resolve(
  37. r#"
  38. contract printer {
  39. function test() public {
  40. (int a) = abi.decode(hex"00", (int feh));
  41. }
  42. }"#,
  43. Target::Substrate {
  44. address_length: 32,
  45. value_length: 16,
  46. },
  47. );
  48. assert_eq!(
  49. first_error(ns.diagnostics),
  50. "unexpected identifier ‘feh’ in type"
  51. );
  52. let ns = parse_and_resolve(
  53. r#"
  54. contract printer {
  55. function test() public {
  56. (int a) = abi.decode(hex"00", (int,));
  57. }
  58. }"#,
  59. Target::Substrate {
  60. address_length: 32,
  61. value_length: 16,
  62. },
  63. );
  64. assert_eq!(first_error(ns.diagnostics), "missing type");
  65. let ns = parse_and_resolve(
  66. r#"
  67. contract printer {
  68. function test() public {
  69. (int a) = abi.decode(hex"00", (int,mapping(uint[] => address)));
  70. }
  71. }"#,
  72. Target::Substrate {
  73. address_length: 32,
  74. value_length: 16,
  75. },
  76. );
  77. assert_eq!(
  78. first_error(ns.diagnostics),
  79. "key of mapping cannot be array type"
  80. );
  81. let mut runtime = build_solidity(
  82. r##"
  83. contract bar {
  84. function test() public {
  85. (int16 a, bool b) = abi.decode(hex"7f0001", (int16, bool));
  86. assert(a == 127);
  87. assert(b == true);
  88. }
  89. }"##,
  90. );
  91. runtime.function("test", Vec::new());
  92. let mut runtime = build_solidity(
  93. r##"
  94. contract bar {
  95. function test() public {
  96. uint8 a = abi.decode(hex"40", (uint8));
  97. assert(a == 64);
  98. }
  99. }"##,
  100. );
  101. runtime.function("test", Vec::new());
  102. }
  103. #[test]
  104. fn abi_encode() {
  105. let mut runtime = build_solidity(
  106. r##"
  107. struct s {
  108. int32 f1;
  109. uint8 f2;
  110. string f3;
  111. uint16[2] f4;
  112. }
  113. contract bar {
  114. function test() public {
  115. uint16 a = 0xfd01;
  116. assert(abi.encode(a) == hex"01fd");
  117. uint32 b = 0xaabbccdd;
  118. assert(abi.encode(true, b, false) == hex"01ddccbbaa00");
  119. }
  120. function test2() public {
  121. string b = "foobar";
  122. assert(abi.encode(b) == hex"18666f6f626172");
  123. assert(abi.encode("foobar") == hex"18666f6f626172");
  124. }
  125. function test3() public {
  126. s x = s({ f1: 511, f2: 0xf7, f3: "testie", f4: [ uint16(4), 5 ] });
  127. assert(abi.encode(x) == hex"ff010000f71874657374696504000500");
  128. }
  129. }"##,
  130. );
  131. runtime.function("test", Vec::new());
  132. runtime.heap_verify();
  133. runtime.function("test2", Vec::new());
  134. runtime.heap_verify();
  135. runtime.function("test3", Vec::new());
  136. runtime.heap_verify();
  137. }
  138. #[test]
  139. fn abi_encode_packed() {
  140. let mut runtime = build_solidity(
  141. r##"
  142. struct s {
  143. int32 f1;
  144. uint8 f2;
  145. string f3;
  146. uint16[2] f4;
  147. }
  148. contract bar {
  149. function test() public {
  150. uint16 a = 0xfd01;
  151. assert(abi.encodePacked(a) == hex"01fd");
  152. uint32 b = 0xaabbccdd;
  153. assert(abi.encodePacked(true, b, false) == hex"01ddccbbaa00");
  154. }
  155. function test2() public {
  156. string b = "foobar";
  157. assert(abi.encodePacked(b) == "foobar");
  158. assert(abi.encodePacked("foobar") == "foobar");
  159. assert(abi.encodePacked("foo", "bar") == "foobar");
  160. }
  161. function test3() public {
  162. s x = s({ f1: 511, f2: 0xf7, f3: "testie", f4: [ uint16(4), 5 ] });
  163. assert(abi.encodePacked(x) == hex"ff010000f774657374696504000500");
  164. }
  165. }"##,
  166. );
  167. runtime.function("test", Vec::new());
  168. runtime.function("test2", Vec::new());
  169. runtime.function("test3", Vec::new());
  170. }
  171. #[test]
  172. fn abi_encode_with_selector() {
  173. let ns = parse_and_resolve(
  174. r#"
  175. contract printer {
  176. function test() public {
  177. bytes x = abi.encodeWithSelector();
  178. }
  179. }"#,
  180. Target::Substrate {
  181. address_length: 32,
  182. value_length: 16,
  183. },
  184. );
  185. assert_eq!(
  186. first_error(ns.diagnostics),
  187. "function requires one ‘bytes4’ selector argument"
  188. );
  189. let mut runtime = build_solidity(
  190. r##"
  191. contract bar {
  192. function test1() public {
  193. uint16 a = 0xfd01;
  194. assert(abi.encodeWithSelector(hex"44332211", a) == hex"4433221101fd");
  195. uint32 b = 0xaabbccdd;
  196. assert(abi.encodeWithSelector(hex"aabbccdd", true, b, false) == hex"aabbccdd01ddccbbaa00");
  197. assert(abi.encodeWithSelector(hex"aabbccdd") == hex"aabbccdd");
  198. }
  199. function test2() public {
  200. uint8[] arr = new uint8[](3);
  201. arr[0] = 0xfe;
  202. arr[1] = 0xfc;
  203. arr[2] = 0xf8;
  204. assert(abi.encodeWithSelector(hex"01020304", arr) == hex"010203040cfefcf8");
  205. }
  206. }"##,
  207. );
  208. runtime.function("test1", Vec::new());
  209. runtime.function("test2", Vec::new());
  210. }
  211. #[test]
  212. fn abi_encode_with_signature() {
  213. let ns = parse_and_resolve(
  214. r#"
  215. contract printer {
  216. function test() public {
  217. bytes x = abi.encodeWithSignature();
  218. }
  219. }"#,
  220. Target::Substrate {
  221. address_length: 32,
  222. value_length: 16,
  223. },
  224. );
  225. assert_eq!(
  226. first_error(ns.diagnostics),
  227. "function requires one ‘string’ signature argument"
  228. );
  229. let mut runtime = build_solidity(
  230. r##"
  231. contract bar {
  232. string bla = "Hello, World!";
  233. function test1() public {
  234. assert(keccak256("Hello, World!") == hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  235. assert(abi.encodeWithSignature("Hello, World!") == hex"acaf3289");
  236. assert(abi.encodeWithSignature(bla) == hex"acaf3289");
  237. }
  238. function test2() public {
  239. uint8[] arr = new uint8[](3);
  240. arr[0] = 0xfe;
  241. arr[1] = 0xfc;
  242. arr[2] = 0xf8;
  243. assert(abi.encodeWithSelector(hex"01020304", arr) == hex"010203040cfefcf8");
  244. }
  245. }"##,
  246. );
  247. runtime.constructor(0, Vec::new());
  248. runtime.function("test1", Vec::new());
  249. runtime.function("test2", Vec::new());
  250. }
  251. #[test]
  252. fn call() {
  253. let ns = parse_and_resolve(
  254. r#"
  255. contract main {
  256. function test() public {
  257. address x = address(0);
  258. x.delegatecall(hex"1222");
  259. }
  260. }"#,
  261. Target::Substrate {
  262. address_length: 32,
  263. value_length: 16,
  264. },
  265. );
  266. assert_eq!(
  267. first_error(ns.diagnostics),
  268. "method ‘delegatecall’ does not exist"
  269. );
  270. let ns = parse_and_resolve(
  271. r#"
  272. contract main {
  273. function test() public {
  274. address x = address(0);
  275. x.staticcall(hex"1222");
  276. }
  277. }"#,
  278. Target::Substrate {
  279. address_length: 32,
  280. value_length: 16,
  281. },
  282. );
  283. assert_eq!(
  284. first_error(ns.diagnostics),
  285. "method ‘staticcall’ does not exist"
  286. );
  287. let ns = parse_and_resolve(
  288. r#"
  289. contract superior {
  290. function test() public {
  291. inferior i = new inferior();
  292. bytes x = address(i).call(hex"1222");
  293. }
  294. }
  295. contract inferior {
  296. function baa() public {
  297. print("Baa!");
  298. }
  299. }"#,
  300. Target::Substrate {
  301. address_length: 32,
  302. value_length: 16,
  303. },
  304. );
  305. assert_eq!(
  306. first_error(ns.diagnostics),
  307. "destucturing statement needed for function that returns multiple values"
  308. );
  309. let ns = parse_and_resolve(
  310. r#"
  311. contract superior {
  312. function test() public {
  313. inferior i = new inferior();
  314. (bytes x, bool y) = address(i).call(hex"1222");
  315. }
  316. }
  317. contract inferior {
  318. function baa() public {
  319. print("Baa!");
  320. }
  321. }"#,
  322. Target::Substrate {
  323. address_length: 32,
  324. value_length: 16,
  325. },
  326. );
  327. assert_eq!(
  328. first_error(ns.diagnostics),
  329. "conversion from bool to bytes not possible"
  330. );
  331. let mut runtime = build_solidity(
  332. r##"
  333. contract superior {
  334. function test1() public {
  335. inferior i = new inferior();
  336. i.test1();
  337. assert(keccak256("test1()") == hex"6b59084dfb7dcf1c687dd12ad5778be120c9121b21ef90a32ff73565a36c9cd3");
  338. bytes bs;
  339. bool success;
  340. (success, bs) = address(i).call(hex"6b59084d");
  341. assert(success == true);
  342. assert(bs == hex"");
  343. }
  344. function test2() public {
  345. inferior i = new inferior();
  346. assert(i.test2(257) == 256);
  347. assert(keccak256("test2(uint64)") == hex"296dacf0801def8823747fbd751fbc1444af573e88de40d29c4d01f6013bf095");
  348. bytes bs;
  349. bool success;
  350. (success, bs) = address(i).call(hex"296dacf0_0101_0000__0000_0000");
  351. assert(success == true);
  352. assert(bs == hex"0001_0000__0000_0000");
  353. }
  354. }
  355. contract inferior {
  356. function test1() public {
  357. print("Baa!");
  358. }
  359. function test2(uint64 x) public returns (uint64) {
  360. return x ^ 1;
  361. }
  362. }"##,
  363. );
  364. runtime.function("test1", Vec::new());
  365. runtime.function("test2", Vec::new());
  366. let mut runtime = build_solidity(
  367. r##"
  368. contract superior {
  369. function test1() public {
  370. inferior i = new inferior();
  371. assert(keccak256("test1()") == hex"6b59084dfb7dcf1c687dd12ad5778be120c9121b21ef90a32ff73565a36c9cd3");
  372. bytes bs;
  373. bool success;
  374. (success, bs) = address(i).call(abi.encodeWithSelector(hex"6b59084d"));
  375. assert(success == true);
  376. assert(bs == hex"");
  377. (success, bs) = address(i).call(abi.encodeWithSignature("test1()"));
  378. assert(success == true);
  379. assert(bs == hex"");
  380. }
  381. function test2() public {
  382. inferior i = new inferior();
  383. assert(keccak256("test2(uint64)") == hex"296dacf0801def8823747fbd751fbc1444af573e88de40d29c4d01f6013bf095");
  384. bytes bs;
  385. bool success;
  386. (success, bs) = address(i).call(abi.encodeWithSelector(hex"296dacf0", uint64(257)));
  387. assert(success == true);
  388. assert(abi.decode(bs, (uint64)) == 256);
  389. (success, bs) = address(i).call(abi.encodeWithSignature("test2(uint64)", uint64(0xfeec)));
  390. assert(success == true);
  391. assert(abi.decode(bs, (uint64)) == 0xfeed);
  392. }
  393. }
  394. contract inferior {
  395. function test1() public {
  396. print("Baa!");
  397. }
  398. function test2(uint64 x) public returns (uint64) {
  399. return x ^ 1;
  400. }
  401. }"##,
  402. );
  403. runtime.function("test1", Vec::new());
  404. runtime.function("test2", Vec::new());
  405. }
  406. #[test]
  407. fn block() {
  408. let mut runtime = build_solidity(
  409. r##"
  410. contract bar {
  411. function test() public {
  412. uint64 b = block.number;
  413. assert(b == 950_119_597);
  414. }
  415. }"##,
  416. );
  417. runtime.function("test", Vec::new());
  418. let ns = parse_and_resolve(
  419. r#"
  420. contract bar {
  421. function test() public {
  422. int64 b = block.number;
  423. assert(b == 14_250_083_331_950_119_597);
  424. }
  425. }"#,
  426. Target::Substrate {
  427. address_length: 32,
  428. value_length: 16,
  429. },
  430. );
  431. assert_eq!(
  432. first_error(ns.diagnostics),
  433. "implicit conversion would change sign from uint64 to int64"
  434. );
  435. let mut runtime = build_solidity(
  436. r##"
  437. contract bar {
  438. function test() public {
  439. uint64 b = block.timestamp;
  440. assert(b == 1594035638);
  441. }
  442. }"##,
  443. );
  444. runtime.function("test", Vec::new());
  445. let ns = parse_and_resolve(
  446. r#"
  447. contract bar {
  448. function test() public {
  449. int64 b = block.timestamp;
  450. assert(b == 14_250_083_331_950_119_597);
  451. }
  452. }"#,
  453. Target::Substrate {
  454. address_length: 32,
  455. value_length: 16,
  456. },
  457. );
  458. assert_eq!(
  459. first_error(ns.diagnostics),
  460. "implicit conversion would change sign from uint64 to int64"
  461. );
  462. let mut runtime = build_solidity(
  463. r##"
  464. contract bar {
  465. function test() public {
  466. uint128 b = block.tombstone_deposit;
  467. assert(b == 93_603_701_976_053);
  468. }
  469. }"##,
  470. );
  471. runtime.function("test", Vec::new());
  472. let ns = parse_and_resolve(
  473. r#"
  474. contract bar {
  475. function test() public {
  476. int64 b = block.tombstone_deposit;
  477. assert(b == 93_603_701_976_053);
  478. }
  479. }"#,
  480. Target::Substrate {
  481. address_length: 32,
  482. value_length: 16,
  483. },
  484. );
  485. assert_eq!(
  486. first_error(ns.diagnostics),
  487. "implicit conversion would change sign from uint128 to int64"
  488. );
  489. let mut runtime = build_solidity(
  490. r##"
  491. contract bar {
  492. function test() public {
  493. uint128 b = block.minimum_balance;
  494. assert(b == 500);
  495. }
  496. }"##,
  497. );
  498. runtime.function("test", Vec::new());
  499. let ns = parse_and_resolve(
  500. r#"
  501. contract bar {
  502. function test() public {
  503. int64 b = block.minimum_balance;
  504. assert(b == 93_603_701_976_053);
  505. }
  506. }"#,
  507. Target::Substrate {
  508. address_length: 32,
  509. value_length: 16,
  510. },
  511. );
  512. assert_eq!(
  513. first_error(ns.diagnostics),
  514. "implicit conversion would change sign from uint128 to int64"
  515. );
  516. let ns = parse_and_resolve(
  517. r#"
  518. contract bar {
  519. function test() public {
  520. int64 b = block.coinbase;
  521. assert(b == 93_603_701_976_053);
  522. }
  523. }"#,
  524. Target::Substrate {
  525. address_length: 32,
  526. value_length: 16,
  527. },
  528. );
  529. assert_eq!(
  530. first_error(ns.diagnostics),
  531. "builtin ‘block.coinbase’ does not exist"
  532. );
  533. let ns = parse_and_resolve(
  534. r#"
  535. contract bar {
  536. function test() public {
  537. int64 b = block.gaslimit;
  538. assert(b == 93_603_701_976_053);
  539. }
  540. }"#,
  541. Target::Substrate {
  542. address_length: 32,
  543. value_length: 16,
  544. },
  545. );
  546. assert_eq!(
  547. first_error(ns.diagnostics),
  548. "builtin ‘block.gaslimit’ does not exist"
  549. );
  550. let ns = parse_and_resolve(
  551. r#"
  552. contract bar {
  553. function test() public {
  554. int64 b = block.difficulty;
  555. assert(b == 93_603_701_976_053);
  556. }
  557. }"#,
  558. Target::Substrate {
  559. address_length: 32,
  560. value_length: 16,
  561. },
  562. );
  563. assert_eq!(
  564. first_error(ns.diagnostics),
  565. "builtin ‘block.difficulty’ does not exist"
  566. );
  567. }
  568. #[test]
  569. fn tx() {
  570. let mut runtime = build_solidity(
  571. r##"
  572. contract bar {
  573. function test() public {
  574. uint128 b = tx.gasprice(1);
  575. assert(b == 59_541_253_813_967);
  576. }
  577. }"##,
  578. );
  579. runtime.function("test", Vec::new());
  580. let mut runtime = build_solidity(
  581. r##"
  582. contract bar {
  583. function test() public {
  584. uint128 b = tx.gasprice(1000);
  585. assert(b == 59_541_253_813_967_000);
  586. }
  587. }"##,
  588. );
  589. runtime.function("test", Vec::new());
  590. let ns = parse_and_resolve(
  591. r#"
  592. contract bar {
  593. function test() public {
  594. int128 b = tx.gasprice;
  595. }
  596. }"#,
  597. Target::Substrate {
  598. address_length: 32,
  599. value_length: 16,
  600. },
  601. );
  602. assert_eq!(
  603. first_error(ns.diagnostics),
  604. "use the function ‘tx.gasprice(gas)’ in stead, as ‘tx.gasprice’ may round down to zero. See https://solang.readthedocs.io/en/latest/language.html#gasprice"
  605. );
  606. let ns = parse_and_resolve(
  607. r#"
  608. contract bar {
  609. function test() public {
  610. int128 b = tx.gasprice(4-3);
  611. }
  612. }"#,
  613. Target::Substrate {
  614. address_length: 32,
  615. value_length: 16,
  616. },
  617. );
  618. assert_eq!(
  619. first_warning(ns.diagnostics),
  620. "the function call ‘tx.gasprice(1)’ may round down to zero. See https://solang.readthedocs.io/en/latest/language.html#gasprice"
  621. );
  622. let ns = parse_and_resolve(
  623. r#"
  624. contract bar {
  625. function test() public {
  626. int64 b = tx.gasprice(100);
  627. assert(b == 14_250_083_331_950_119_597);
  628. }
  629. }"#,
  630. Target::Substrate {
  631. address_length: 32,
  632. value_length: 16,
  633. },
  634. );
  635. assert_eq!(
  636. first_error(ns.diagnostics),
  637. "implicit conversion would change sign from uint128 to int64"
  638. );
  639. let ns = parse_and_resolve(
  640. r#"
  641. contract bar {
  642. function test() public {
  643. int64 b = tx.origin;
  644. assert(b == 93_603_701_976_053);
  645. }
  646. }"#,
  647. Target::Substrate {
  648. address_length: 32,
  649. value_length: 16,
  650. },
  651. );
  652. assert_eq!(
  653. first_error(ns.diagnostics),
  654. "builtin ‘tx.origin’ does not exist"
  655. );
  656. }
  657. #[test]
  658. fn msg() {
  659. let mut runtime = build_solidity(
  660. r##"
  661. contract bar {
  662. function test() public payable {
  663. uint128 b = msg.value;
  664. assert(b == 145_594_775_678_703_046_797_448_357_509_034_994_219);
  665. }
  666. }"##,
  667. );
  668. runtime.vm.value = 145_594_775_678_703_046_797_448_357_509_034_994_219;
  669. runtime.function("test", Vec::new());
  670. let ns = parse_and_resolve(
  671. r#"
  672. contract bar {
  673. function test() public {
  674. int64 b = msg.value;
  675. assert(b == 14_250_083_331_950_119_597);
  676. }
  677. }"#,
  678. Target::Substrate {
  679. address_length: 32,
  680. value_length: 16,
  681. },
  682. );
  683. assert_eq!(
  684. first_error(ns.diagnostics),
  685. "implicit conversion would change sign from uint128 to int64"
  686. );
  687. let ns = parse_and_resolve(
  688. r#"
  689. contract bar {
  690. function test(uint128 v) public returns (bool) {
  691. return msg.value > v;
  692. }
  693. }"#,
  694. Target::Substrate {
  695. address_length: 32,
  696. value_length: 16,
  697. },
  698. );
  699. no_errors(ns.diagnostics);
  700. let mut runtime = build_solidity(
  701. r##"
  702. contract c {
  703. function test() public {
  704. other o = new other();
  705. address foo = o.test();
  706. assert(foo == address(this));
  707. }
  708. }
  709. contract other {
  710. function test() public returns (address) {
  711. return msg.sender;
  712. }
  713. }
  714. "##,
  715. );
  716. runtime.function("test", Vec::new());
  717. }
  718. #[test]
  719. fn functions() {
  720. let mut runtime = build_solidity(
  721. r##"
  722. contract bar {
  723. function test() public {
  724. uint64 b = gasleft();
  725. assert(b == 2_224_097_461);
  726. }
  727. }"##,
  728. );
  729. runtime.function("test", Vec::new());
  730. let ns = parse_and_resolve(
  731. r#"
  732. contract bar {
  733. function test() public {
  734. int64 b = gasleft();
  735. assert(b == 14_250_083_331_950_119_597);
  736. }
  737. }"#,
  738. Target::Substrate {
  739. address_length: 32,
  740. value_length: 16,
  741. },
  742. );
  743. assert_eq!(
  744. first_error(ns.diagnostics),
  745. "implicit conversion would change sign from uint64 to int64"
  746. );
  747. let ns = parse_and_resolve(
  748. r#"
  749. contract bar {
  750. function test() public {
  751. int64 b = gasleft(1);
  752. assert(b == 14_250_083_331_950_119_597);
  753. }
  754. }"#,
  755. Target::Substrate {
  756. address_length: 32,
  757. value_length: 16,
  758. },
  759. );
  760. assert_eq!(
  761. first_error(ns.diagnostics),
  762. "builtin function ‘gasleft’ expects 0 arguments, 1 provided"
  763. );
  764. let ns = parse_and_resolve(
  765. r#"
  766. contract bar {
  767. function test() public {
  768. bytes32 b = blockhash(1);
  769. }
  770. }"#,
  771. Target::Substrate {
  772. address_length: 32,
  773. value_length: 16,
  774. },
  775. );
  776. assert_eq!(
  777. first_error(ns.diagnostics),
  778. "unknown function or type ‘blockhash’"
  779. );
  780. let mut runtime = build_solidity(
  781. r##"
  782. contract c {
  783. function test() public {
  784. bytes32 o = random(
  785. "abcd"
  786. );
  787. assert(o == hex"429ccf3ebce07f0c6d7cd0d1dead74459f753cdf53ed8359e42728042a91c39c");
  788. }
  789. }"##,
  790. );
  791. runtime.function("test", Vec::new());
  792. }
  793. #[test]
  794. fn data() {
  795. #[derive(Debug, PartialEq, Encode, Decode)]
  796. struct Uint32(u32);
  797. #[derive(Debug, PartialEq, Encode, Decode)]
  798. struct String(Vec<u8>);
  799. let mut runtime = build_solidity(
  800. r##"
  801. contract bar {
  802. constructor(string memory s) public {
  803. assert(msg.data == hex"88eaeb6c18666f6f626172");
  804. assert(msg.sig == hex"88ea_eb6c");
  805. }
  806. function test(uint32 x) public {
  807. assert(msg.data == hex"e3cff634addeadde");
  808. assert(msg.sig == hex"e3cf_f634");
  809. }
  810. }"##,
  811. );
  812. runtime.constructor(0, String(b"foobar".to_vec()).encode());
  813. runtime.function("test", Uint32(0xdeaddead).encode());
  814. }
  815. #[test]
  816. fn addmod() {
  817. // does it work with small numbers
  818. let mut runtime = build_solidity(
  819. r##"
  820. contract x {
  821. function test() public {
  822. assert(addmod(500, 100, 3) == 200);
  823. }
  824. }"##,
  825. );
  826. runtime.function("test", Vec::new());
  827. // divide by zero
  828. let mut runtime = build_solidity(
  829. r##"
  830. contract x {
  831. function test() public {
  832. assert(addmod(500, 100, 0) == 200);
  833. }
  834. }"##,
  835. );
  836. runtime.function_expect_failure("test", Vec::new());
  837. // bigger numbers (64 bit)
  838. let mut runtime = build_solidity(
  839. r##"
  840. contract x {
  841. function test() public {
  842. // 8_163_321_534_310_945_187 * 16_473_784_705_703_234_153 = 134_480_801_439_669_508_040_541_782_812_209_371_611
  843. assert(addmod(
  844. 0,
  845. 134_480_801_439_669_508_040_541_782_812_209_371_611,
  846. 16_473_784_705_703_234_153) == 8_163_321_534_310_945_187);
  847. }
  848. }"##,
  849. );
  850. runtime.function("test", Vec::new());
  851. // bigger numbers (128 bit)
  852. let mut runtime = build_solidity(
  853. r##"
  854. contract x {
  855. function test() public {
  856. // 254_765_928_331_839_140_628_748_569_208_536_440_801 * 148_872_967_607_295_528_830_315_866_466_318_446_379 = 37_927_759_795_988_462_606_362_647_643_228_779_300_269_446_446_871_437_380_583_919_404_728_626_309_579
  857. assert(addmod(
  858. 0,
  859. 37_927_759_795_988_462_606_362_647_643_228_779_300_269_446_446_871_437_380_583_919_404_728_626_309_579,
  860. 148_872_967_607_295_528_830_315_866_466_318_446_379) == 254_765_928_331_839_140_628_748_569_208_536_440_801);
  861. }
  862. }"##,
  863. );
  864. runtime.function("test", Vec::new());
  865. // bigger numbers (256 bit)
  866. let mut runtime = build_solidity(
  867. r##"
  868. contract x {
  869. function test() public {
  870. assert(addmod(
  871. 109802613191917590715814365746623394364442484359636492253827647701845853490667,
  872. 49050800785888222684575674817707208319566972397745729319314900174750088808217,
  873. 233) == 681774308917621516739871418731032629545104964623958032502757716208566275960);
  874. }
  875. }"##,
  876. );
  877. runtime.function("test", Vec::new());
  878. let mut runtime = build_solidity(
  879. r##"
  880. contract x {
  881. function test() public {
  882. assert(addmod(
  883. 109802613191917590715814365746623394364442484359636492253827647701845853490667,
  884. 109802613191917590715814365746623394364442484359636492253827647701845853490667,
  885. 2) == 109802613191917590715814365746623394364442484359636492253827647701845853490667);
  886. }
  887. }"##,
  888. );
  889. runtime.function("test", Vec::new());
  890. }
  891. #[test]
  892. fn mulmod() {
  893. // does it work with small numbers
  894. let mut runtime = build_solidity(
  895. r##"
  896. contract x {
  897. function test() public {
  898. assert(mulmod(500, 100, 5) == 10000);
  899. }
  900. }"##,
  901. );
  902. runtime.function("test", Vec::new());
  903. // divide by zero
  904. let mut runtime = build_solidity(
  905. r##"
  906. contract x {
  907. function test() public {
  908. assert(mulmod(500, 100, 0) == 200);
  909. }
  910. }"##,
  911. );
  912. runtime.function_expect_failure("test", Vec::new());
  913. // bigger numbers
  914. let mut runtime = build_solidity(
  915. r##"
  916. contract x {
  917. function test() public {
  918. assert(mulmod(50000, 10000, 5) == 10000_0000);
  919. }
  920. }"##,
  921. );
  922. runtime.function("test", Vec::new());
  923. let mut runtime = build_solidity(
  924. r##"
  925. contract x {
  926. function test() public {
  927. assert(mulmod(18446744073709551616, 18446744073709550403, 1024) == 332306998946228946374486373068439552);
  928. }
  929. }"##,
  930. );
  931. runtime.function("test", Vec::new());
  932. // 2^127 = 170141183460469231731687303715884105728
  933. let mut runtime = build_solidity(
  934. r##"
  935. contract x {
  936. function test() public {
  937. assert(mulmod(170141183460469231731687303715884105728, 170141183460469231731687303715884105728, 170141183460469231731687303715884105728) == 170141183460469231731687303715884105728);
  938. }
  939. }"##,
  940. );
  941. runtime.function("test", Vec::new());
  942. // 2^128 = 340282366920938463463374607431768211456
  943. let mut runtime = build_solidity(
  944. r##"
  945. contract x {
  946. function test() public {
  947. assert(mulmod(340282366920938463463374607431768211456, 340282366920938463463374607431768211456, 340282366920938463463374607431768211456) == 340282366920938463463374607431768211456);
  948. }
  949. }"##,
  950. );
  951. runtime.function("test", Vec::new());
  952. // 2^240 = 1766847064778384329583297500742918515827483896875618958121606201292619776
  953. let mut runtime = build_solidity(
  954. r##"
  955. contract x {
  956. function test() public {
  957. assert(mulmod(1766847064778384329583297500742918515827483896875618958121606201292619776,
  958. 1766847064778384329583297500742918515827483896875618958121606201292619776,
  959. 1766847064778384329583297500742918515827483896875618958121606201292619776)
  960. == 1766847064778384329583297500742918515827483896875618958121606201292619776);
  961. }
  962. }"##,
  963. );
  964. runtime.function("test", Vec::new());
  965. // 240 bit prime: 824364134751099588297822369420176791913922347811791536817152126684405253
  966. let mut runtime = build_solidity(
  967. r##"
  968. contract x {
  969. function test() public {
  970. assert(mulmod(824364134751099588297822369420176791913922347811791536817152126684405253,
  971. 824364134751099588297822369420176791913922347811791536817152126684405253,
  972. 824364134751099588297822369420176791913922347811791536817152126684405253)
  973. == 824364134751099588297822369420176791913922347811791536817152126684405253);
  974. }
  975. }"##,
  976. );
  977. runtime.function("test", Vec::new());
  978. // 256 bit prime: 113477814626329405513123655892059150026234290706112418221315641434319827527851
  979. let mut runtime = build_solidity(
  980. r##"
  981. contract x {
  982. function test() public {
  983. assert(mulmod(113477814626329405513123655892059150026234290706112418221315641434319827527851,
  984. 113477814626329405513123655892059150026234290706112418221315641434319827527851,
  985. 113477814626329405513123655892059150026234290706112418221315641434319827527851)
  986. == 113477814626329405513123655892059150026234290706112418221315641434319827527851);
  987. }
  988. }"##,
  989. );
  990. runtime.function("test", Vec::new());
  991. }