arrays.rs 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. use parity_scale_codec::{Decode, Encode};
  2. use rand::Rng;
  3. use crate::build_solidity;
  4. #[derive(Debug, PartialEq, Encode, Decode)]
  5. struct Val32(u32);
  6. #[derive(Debug, PartialEq, Encode, Decode)]
  7. struct Val8(u8);
  8. #[test]
  9. fn const_array_array() {
  10. let mut runtime = build_solidity(
  11. r##"
  12. contract foo {
  13. int8[8] constant bar = [ int8(1), 2, 3, 4, 5, 6, 7, 8 ];
  14. function f(uint32 i1) public returns (int8) {
  15. return bar[i1];
  16. }
  17. }"##,
  18. );
  19. runtime.function("f", Val32(1).encode());
  20. assert_eq!(runtime.vm.output, Val8(2).encode());
  21. }
  22. #[test]
  23. fn votes() {
  24. #[derive(Debug, PartialEq, Encode, Decode)]
  25. struct Votes([bool; 11]);
  26. let mut runtime = build_solidity(
  27. r##"
  28. contract foo {
  29. /// In a jury, do the ayes have it?
  30. function f(bool[11] votes) public pure returns (bool) {
  31. uint32 i;
  32. uint32 ayes = 0;
  33. for (i=0; i<votes.length; i++) {
  34. if (votes[i]) {
  35. ayes += 1;
  36. }
  37. }
  38. return ayes > votes.length / 2;
  39. }
  40. }"##,
  41. );
  42. runtime.function(
  43. "f",
  44. Votes([
  45. true, true, true, true, true, true, false, false, false, false, false,
  46. ])
  47. .encode(),
  48. );
  49. assert_eq!(runtime.vm.output, true.encode());
  50. runtime.function(
  51. "f",
  52. Votes([
  53. true, true, true, true, true, false, false, false, false, false, false,
  54. ])
  55. .encode(),
  56. );
  57. assert_eq!(runtime.vm.output, false.encode());
  58. }
  59. #[test]
  60. fn return_array() {
  61. #[derive(Debug, PartialEq, Encode, Decode)]
  62. struct Res([u64; 4]);
  63. let mut runtime = build_solidity(
  64. r##"
  65. contract foo {
  66. function array() pure public returns (int64[4]) {
  67. return [ int64(4), 84564, 31213, 1312 ];
  68. }
  69. }"##,
  70. );
  71. runtime.function("array", Vec::new());
  72. assert_eq!(runtime.vm.output, Res([4, 84564, 31213, 1312]).encode());
  73. }
  74. #[test]
  75. fn storage_arrays() {
  76. #[derive(Debug, PartialEq, Encode, Decode)]
  77. struct Val(i32);
  78. #[derive(Debug, PartialEq, Encode, Decode)]
  79. struct SetArg(u64, i32);
  80. #[derive(Debug, PartialEq, Encode, Decode)]
  81. struct GetArg(u64);
  82. let mut runtime = build_solidity(
  83. r##"
  84. contract foo {
  85. int32[8589934592] bigarray;
  86. function set(uint64 index, int32 val) public {
  87. bigarray[index] = val;
  88. }
  89. function get(uint64 index) public returns (int32) {
  90. return bigarray[index];
  91. }
  92. }"##,
  93. );
  94. let mut rng = rand::thread_rng();
  95. let mut vals = Vec::new();
  96. for _ in 0..100 {
  97. let index = rng.gen::<u64>() % 0x200_0000;
  98. let val = rng.gen::<i32>();
  99. runtime.function("set", SetArg(index, val).encode());
  100. vals.push((index, val));
  101. }
  102. for val in vals {
  103. runtime.function("get", GetArg(val.0).encode());
  104. assert_eq!(runtime.vm.output, Val(val.1).encode());
  105. }
  106. }
  107. #[test]
  108. fn enum_arrays() {
  109. #[derive(Encode, Decode)]
  110. struct Arg([u8; 100]);
  111. #[derive(Debug, PartialEq, Encode, Decode)]
  112. struct Ret(u32);
  113. let mut runtime = build_solidity(
  114. r##"
  115. contract enum_array {
  116. enum Foo { Bar1, Bar2, Bar3, Bar4 }
  117. function count_bar2(Foo[100] calldata foos) public returns (uint32) {
  118. uint32 count = 0;
  119. uint32 i;
  120. for (i = 0; i < foos.length; i++) {
  121. if (foos[i] == Foo.Bar2) {
  122. count++;
  123. }
  124. }
  125. return count;
  126. }
  127. }"##,
  128. );
  129. let mut rng = rand::thread_rng();
  130. let mut a = [0u8; 100];
  131. let mut count = 0;
  132. #[allow(clippy::needless_range_loop)]
  133. for i in 0..a.len() {
  134. a[i] = rng.gen::<u8>() % 4;
  135. if a[i] == 1 {
  136. count += 1;
  137. }
  138. }
  139. runtime.function("count_bar2", Arg(a).encode());
  140. assert_eq!(runtime.vm.output, Ret(count).encode());
  141. }
  142. #[test]
  143. fn storage_ref_arg() {
  144. let mut runtime = build_solidity(
  145. r##"
  146. contract storage_refs {
  147. int32[10] a;
  148. int32[10] b;
  149. function set(int32[10] storage array, uint8 index, int32 val) private {
  150. array[index] = val;
  151. }
  152. function test() public {
  153. set(a, 2, 5);
  154. set(b, 2, 102);
  155. assert(a[2] == 5);
  156. assert(b[2] == 102);
  157. }
  158. }"##,
  159. );
  160. runtime.function("test", Vec::new());
  161. }
  162. #[test]
  163. fn storage_ref_var() {
  164. let mut runtime = build_solidity(
  165. r##"
  166. contract storage_refs {
  167. int32[10] a;
  168. int32[10] b;
  169. function set(int32[10] storage array, uint8 index, int32 val) private {
  170. array[index] = val;
  171. }
  172. function test() public {
  173. int32[10] storage ref = a;
  174. set(ref, 2, 5);
  175. ref = b;
  176. set(ref, 2, 102);
  177. assert(a[2] == 5);
  178. assert(b[2] == 102);
  179. }
  180. }"##,
  181. );
  182. runtime.function("test", Vec::new());
  183. }
  184. #[test]
  185. fn storage_ref_returns() {
  186. let mut runtime = build_solidity(
  187. r##"
  188. contract storage_refs {
  189. int32[10] a;
  190. int32[10] b;
  191. function a_or_b(bool want_a) private returns (int32[10] storage) {
  192. if (want_a) {
  193. return a;
  194. }
  195. return b;
  196. }
  197. function set(int32[10] storage array, uint8 index, int32 val) private {
  198. array[index] = val;
  199. }
  200. function test() public {
  201. int32[10] storage ref = a_or_b(true);
  202. set(ref, 2, 5);
  203. ref = a_or_b(false);
  204. set(ref, 2, 102);
  205. assert(a[2] == 5);
  206. assert(b[2] == 102);
  207. }
  208. }"##,
  209. );
  210. runtime.function("test", Vec::new());
  211. }
  212. #[test]
  213. fn storage_to_memory() {
  214. #[derive(Debug, PartialEq, Encode, Decode)]
  215. struct Ret([u32; 10]);
  216. let mut runtime = build_solidity(
  217. r##"
  218. contract storage_refs {
  219. uint32[10] a;
  220. function test() public returns (uint32[10]) {
  221. for (uint32 i = 0; i < 10; ) {
  222. uint32 index = i;
  223. a[index] = 7 * ++i;
  224. }
  225. return a;
  226. }
  227. }"##,
  228. );
  229. runtime.function("test", Vec::new());
  230. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  231. assert_eq!(runtime.vm.output, val.encode());
  232. }
  233. #[test]
  234. fn memory_to_storage() {
  235. #[derive(Debug, PartialEq, Encode, Decode)]
  236. struct Ret([u32; 10]);
  237. let mut runtime = build_solidity(
  238. r##"
  239. contract storage_refs {
  240. int32[10] a;
  241. function test() public returns (int32[10]) {
  242. int32[10] b = [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 70 ];
  243. a = b;
  244. return a;
  245. }
  246. }"##,
  247. );
  248. runtime.function("test", Vec::new());
  249. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  250. assert_eq!(runtime.vm.output, val.encode());
  251. }
  252. #[test]
  253. fn array_dimensions() {
  254. let mut runtime = build_solidity(
  255. r##"
  256. contract storage_refs {
  257. int32[2**16] a;
  258. function test() public {
  259. assert(a.length == 65536);
  260. }
  261. }"##,
  262. );
  263. runtime.function("test", Vec::new());
  264. }
  265. #[test]
  266. fn array_in_struct() {
  267. #[derive(Debug, PartialEq, Encode, Decode)]
  268. struct Ret([u32; 10]);
  269. let mut runtime = build_solidity(
  270. r##"
  271. contract storage_refs {
  272. struct foo {
  273. int32[10] f1;
  274. }
  275. function test() public returns (int32[10]) {
  276. foo a = foo({f1: [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 0 ]});
  277. assert(a.f1[1] == 14);
  278. a.f1[9] = 70;
  279. return a.f1;
  280. }
  281. }"##,
  282. );
  283. runtime.function("test", Vec::new());
  284. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  285. assert_eq!(runtime.vm.output, val.encode());
  286. }
  287. #[test]
  288. fn struct_in_array() {
  289. #[derive(Debug, PartialEq, Encode, Decode)]
  290. struct S(u64, bool);
  291. let mut runtime = build_solidity(
  292. r##"
  293. struct S {
  294. uint64 f1;
  295. bool f2;
  296. }
  297. contract foo {
  298. S[] store;
  299. function set(S[] memory n) public {
  300. store = n;
  301. }
  302. function copy() public returns (S[] memory) {
  303. return store;
  304. }
  305. }"##,
  306. );
  307. let val = vec![S(102, true), S(u64::MAX, false)];
  308. runtime.function("set", val.encode());
  309. runtime.function("copy", vec![]);
  310. assert_eq!(runtime.vm.output, val.encode());
  311. }
  312. #[test]
  313. fn struct_in_fixed_array() {
  314. #[derive(Debug, PartialEq, Encode, Decode)]
  315. struct S(u64, bool);
  316. let mut runtime = build_solidity(
  317. r##"
  318. struct S {
  319. uint64 f1;
  320. bool f2;
  321. }
  322. contract foo {
  323. S[2] store;
  324. function set(S[2] memory n) public {
  325. store = n;
  326. }
  327. function copy() public returns (S[2] memory) {
  328. return store;
  329. }
  330. }"##,
  331. );
  332. let val = [S(102, true), S(u64::MAX, false)];
  333. runtime.function("set", val.encode());
  334. runtime.function("copy", vec![]);
  335. assert_eq!(runtime.vm.output, val.encode());
  336. }
  337. #[test]
  338. fn struct_array_struct() {
  339. let mut runtime = build_solidity(
  340. r##"
  341. contract flipper {
  342. struct bool_struct {
  343. bool foo_bool;
  344. }
  345. struct struct_bool_struct_array {
  346. bool_struct[1] foo_struct_array;
  347. }
  348. function get_memory() public pure returns (bool) {
  349. bool_struct memory foo = bool_struct({foo_bool: true});
  350. bool_struct[1] memory foo_array = [foo];
  351. struct_bool_struct_array memory foo_struct = struct_bool_struct_array({foo_struct_array: foo_array});
  352. /* return foo_array[0].foo_bool; */
  353. return foo_struct.foo_struct_array[0].foo_bool;
  354. }
  355. }"##,
  356. );
  357. runtime.function("get_memory", Vec::new());
  358. assert_eq!(runtime.vm.output, true.encode());
  359. }
  360. #[test]
  361. fn struct_array_struct_abi() {
  362. #[derive(Debug, PartialEq, Encode, Decode)]
  363. struct Foo {
  364. f1: u32,
  365. f2: bool,
  366. }
  367. #[derive(Debug, PartialEq, Encode, Decode)]
  368. struct Bar {
  369. bars: [Foo; 10],
  370. }
  371. let mut runtime = build_solidity(
  372. r##"
  373. contract flipper {
  374. struct foo {
  375. int32 f1;
  376. bool f2;
  377. }
  378. struct bar {
  379. foo[10] bars;
  380. }
  381. bar s;
  382. function get_bar() public returns (bar) {
  383. bar memory a = bar({ bars: [
  384. foo({ f1: 1, f2: true}),
  385. foo({ f1: 2, f2: true}),
  386. foo({ f1: 3, f2: true}),
  387. foo({ f1: 4, f2: true}),
  388. foo({ f1: 5, f2: true}),
  389. foo({ f1: 6, f2: true}),
  390. foo({ f1: 7, f2: false}),
  391. foo({ f1: 8, f2: true}),
  392. foo({ f1: 9, f2: true}),
  393. foo({ f1: 10, f2: true})
  394. ]});
  395. s = a;
  396. return a;
  397. }
  398. function set_bar(bar memory a) public {
  399. for (uint32 i = 0; i < 10; i++) {
  400. assert(a.bars[i].f1 == i + 1);
  401. assert(a.bars[i].f2 == (i != 6));
  402. }
  403. a = s;
  404. }
  405. }"##,
  406. );
  407. let b = Bar {
  408. bars: [
  409. Foo { f1: 1, f2: true },
  410. Foo { f1: 2, f2: true },
  411. Foo { f1: 3, f2: true },
  412. Foo { f1: 4, f2: true },
  413. Foo { f1: 5, f2: true },
  414. Foo { f1: 6, f2: true },
  415. Foo { f1: 7, f2: false },
  416. Foo { f1: 8, f2: true },
  417. Foo { f1: 9, f2: true },
  418. Foo { f1: 10, f2: true },
  419. ],
  420. };
  421. runtime.function("get_bar", Vec::new());
  422. assert_eq!(runtime.vm.output, b.encode());
  423. runtime.function("set_bar", b.encode());
  424. }
  425. #[test]
  426. fn memory_dynamic_array_new() {
  427. let mut runtime = build_solidity(
  428. r#"
  429. contract foo {
  430. function test() public {
  431. int32[] memory a = new int32[](5);
  432. assert(a.length == 5);
  433. }
  434. }"#,
  435. );
  436. runtime.function("test", Vec::new());
  437. // The Ethereum Foundation solc allows you to create arrays of length 0
  438. let mut runtime = build_solidity(
  439. r#"
  440. contract foo {
  441. function test() public {
  442. bool[] memory a = new bool[](0);
  443. assert(a.length == 0);
  444. }
  445. }"#,
  446. );
  447. runtime.function("test", Vec::new());
  448. }
  449. #[test]
  450. fn memory_dynamic_array_deref() {
  451. // The Ethereum Foundation solc allows you to create arrays of length 0
  452. let mut runtime = build_solidity(
  453. r#"
  454. contract foo {
  455. function test() public {
  456. int32[] memory a = new int32[](5);
  457. assert(a.length == 5);
  458. a[0] = 102;
  459. a[1] = -5;
  460. a[4] = 0x7cafeeed;
  461. assert(a[0] == 102);
  462. assert(a[1] == -5);
  463. assert(a[4] == 0x7cafeeed);
  464. }
  465. }"#,
  466. );
  467. runtime.function("test", Vec::new());
  468. }
  469. #[test]
  470. #[should_panic]
  471. fn array_bounds_dynamic_array() {
  472. let mut runtime = build_solidity(
  473. r#"
  474. contract foo {
  475. function test() public returns (int32) {
  476. int32[] memory a = new int32[](5);
  477. a[5] = 102;
  478. return a[3];
  479. }
  480. }"#,
  481. );
  482. runtime.function("test", Vec::new());
  483. }
  484. #[test]
  485. #[should_panic]
  486. fn empty_array_bounds_dynamic_array() {
  487. let mut runtime = build_solidity(
  488. r#"
  489. contract foo {
  490. function test() public returns (bytes32) {
  491. bytes32[] memory a = new bytes32[](0);
  492. a[0] = "yo";
  493. return a[0];
  494. }
  495. }"#,
  496. );
  497. runtime.function("test", Vec::new());
  498. }
  499. #[test]
  500. fn memory_dynamic_array_types_call_return() {
  501. let mut runtime = build_solidity(
  502. r#"
  503. contract foo {
  504. function a(bool cond) public returns (bytes27[]) {
  505. bytes27[] foo;
  506. foo = new bytes27[](5);
  507. foo[1] = "cond was true";
  508. return foo;
  509. }
  510. function b(bytes27[] x) private {
  511. x[1] = "b was called";
  512. x = new bytes27[](3);
  513. x[1] = "should not be";
  514. }
  515. function test() public {
  516. bytes27[] x = a(true);
  517. assert(x.length == 5);
  518. assert(x[1] == "cond was true");
  519. b(x);
  520. assert(x.length == 5);
  521. assert(x[1] == "b was called");
  522. }
  523. }"#,
  524. );
  525. runtime.function("test", Vec::new());
  526. }
  527. #[test]
  528. fn dynamic_arrays_need_phi_node() {
  529. let mut runtime = build_solidity(
  530. r#"
  531. pragma solidity 0;
  532. contract foo {
  533. enum bar { bar1, bar2, bar3, bar4 }
  534. function a(bool cond) public returns (bar[] memory) {
  535. bar[] memory foo;
  536. if (cond) {
  537. foo = new bar[](5);
  538. foo[1] = bar.bar2;
  539. } else {
  540. foo = new bar[](3);
  541. foo[1] = bar.bar3;
  542. }
  543. return foo;
  544. }
  545. function test() public {
  546. bar[] memory x = a(true);
  547. assert(x.length == 5);
  548. assert(x[1] == bar.bar2);
  549. x = a(false);
  550. assert(x.length == 3);
  551. assert(x[1] == bar.bar3);
  552. }
  553. }"#,
  554. );
  555. runtime.function("test", Vec::new());
  556. }
  557. // test:
  558. // alignment of array elements
  559. // arrays of other structs/arrays/darrays
  560. // nil pointer should fail
  561. // copy to/from storage <=> memory
  562. // abi encode/decode
  563. // string/bytes
  564. #[test]
  565. fn storage_dynamic_array_length() {
  566. let mut runtime = build_solidity(
  567. r#"
  568. pragma solidity 0;
  569. contract foo {
  570. int32[] bar;
  571. function test() public {
  572. assert(bar.length == 0);
  573. }
  574. }"#,
  575. );
  576. runtime.function("test", Vec::new());
  577. }
  578. #[test]
  579. fn dynamic_array_push() {
  580. let mut runtime = build_solidity(
  581. r#"
  582. pragma solidity 0;
  583. contract foo {
  584. function test() public {
  585. int[] bar = (new int[])(1);
  586. bar[0] = 128;
  587. bar.push(64);
  588. assert(bar.length == 2);
  589. assert(bar[1] == 64);
  590. }
  591. }
  592. "#,
  593. );
  594. runtime.function("test", Vec::new());
  595. let mut runtime = build_solidity(
  596. r#"
  597. pragma solidity 0;
  598. contract foo {
  599. function test() public {
  600. bytes bar = (new bytes)(1);
  601. bar[0] = 128;
  602. bar.push(64);
  603. assert(bar.length == 2);
  604. assert(bar[1] == 64);
  605. }
  606. }
  607. "#,
  608. );
  609. runtime.function("test", Vec::new());
  610. let mut runtime = build_solidity(
  611. r#"
  612. pragma solidity 0;
  613. contract foo {
  614. struct s {
  615. int32 f1;
  616. bool f2;
  617. }
  618. function test() public {
  619. s[] bar = new s[](1);
  620. bar[0] = s({f1: 0, f2: false});
  621. bar.push(s({f1: 1, f2: true}));
  622. assert(bar.length == 2);
  623. assert(bar[1].f1 == 1);
  624. assert(bar[1].f2 == true);
  625. }
  626. }
  627. "#,
  628. );
  629. runtime.function("test", Vec::new());
  630. let mut runtime = build_solidity(
  631. r#"
  632. pragma solidity 0;
  633. contract foo {
  634. enum enum1 { val1, val2, val3 }
  635. function test() public {
  636. enum1[] bar = new enum1[](1);
  637. bar[0] = enum1.val1;
  638. bar.push(enum1.val2);
  639. assert(bar.length == 2);
  640. assert(bar[1] == enum1.val2);
  641. }
  642. }
  643. "#,
  644. );
  645. runtime.function("test", Vec::new());
  646. // push() returns a reference to the thing
  647. let mut runtime = build_solidity(
  648. r#"
  649. pragma solidity 0;
  650. contract foo {
  651. struct s {
  652. int32 f1;
  653. bool f2;
  654. }
  655. function test() public {
  656. s[] bar = new s[](0);
  657. s memory n = bar.push();
  658. n.f1 = 102;
  659. n.f2 = true;
  660. assert(bar[0].f1 == 102);
  661. assert(bar[0].f2 == true);
  662. }
  663. }"#,
  664. );
  665. runtime.function("test", Vec::new());
  666. }
  667. #[test]
  668. fn dynamic_array_pop() {
  669. let mut runtime = build_solidity(
  670. r#"
  671. pragma solidity 0;
  672. contract foo {
  673. function test() public {
  674. int[] bar = new int[](1);
  675. bar[0] = 128;
  676. assert(bar.length == 1);
  677. assert(128 == bar.pop());
  678. assert(bar.length == 0);
  679. }
  680. }
  681. "#,
  682. );
  683. runtime.function("test", Vec::new());
  684. let mut runtime = build_solidity(
  685. r#"
  686. pragma solidity 0;
  687. contract foo {
  688. function test() public {
  689. bytes bar = new bytes(1);
  690. bar[0] = 128;
  691. assert(bar.length == 1);
  692. assert(128 == bar.pop());
  693. assert(bar.length == 0);
  694. }
  695. }
  696. "#,
  697. );
  698. runtime.function("test", Vec::new());
  699. let mut runtime = build_solidity(
  700. r#"
  701. pragma solidity 0;
  702. contract foo {
  703. struct s {
  704. int32 f1;
  705. bool f2;
  706. }
  707. function test() public {
  708. s[] bar = new s[](1);
  709. bar[0] = s(128, true);
  710. assert(bar.length == 1);
  711. s baz = bar.pop();
  712. assert(baz.f1 == 128);
  713. assert(baz.f2 == true);
  714. assert(bar.length == 0);
  715. }
  716. }
  717. "#,
  718. );
  719. runtime.function("test", Vec::new());
  720. let mut runtime = build_solidity(
  721. r#"
  722. pragma solidity 0;
  723. contract foo {
  724. enum enum1 { val1, val2, val3 }
  725. function test() public {
  726. enum1[] bar = new enum1[](1);
  727. bar[0] = enum1.val2;
  728. assert(bar.length == 1);
  729. assert(enum1.val2 == bar.pop());
  730. assert(bar.length == 0);
  731. }
  732. }
  733. "#,
  734. );
  735. runtime.function("test", Vec::new());
  736. }
  737. #[test]
  738. #[should_panic]
  739. fn dynamic_array_pop_empty_array() {
  740. let mut runtime = build_solidity(
  741. r#"
  742. pragma solidity 0;
  743. contract foo {
  744. function test() public {
  745. int[] bar = new int[](0);
  746. bar.pop();
  747. }
  748. }"#,
  749. );
  750. runtime.function("test", Vec::new());
  751. }
  752. #[test]
  753. #[should_panic]
  754. fn dynamic_array_pop_bounds() {
  755. let mut runtime = build_solidity(
  756. r#"
  757. pragma solidity 0;
  758. contract foo {
  759. function test() public {
  760. int[] bar = new int[](1);
  761. bar[0] = 12;
  762. bar.pop();
  763. assert(bar[0] == 12);
  764. }
  765. }"#,
  766. );
  767. runtime.function("test", Vec::new());
  768. }
  769. #[test]
  770. fn storage_dynamic_array_push() {
  771. let mut runtime = build_solidity(
  772. r#"
  773. pragma solidity 0;
  774. contract foo {
  775. int32[] bar;
  776. function test() public {
  777. assert(bar.length == 0);
  778. bar.push(102);
  779. assert(bar[0] == 102);
  780. assert(bar.length == 1);
  781. bar.push();
  782. assert(bar[1] == 0);
  783. assert(bar.length == 2);
  784. }
  785. }"#,
  786. );
  787. runtime.function("test", Vec::new());
  788. // push() returns a reference to the thing
  789. let mut runtime = build_solidity(
  790. r#"
  791. pragma solidity 0;
  792. contract foo {
  793. struct s {
  794. int32 f1;
  795. bool f2;
  796. }
  797. s[] bar;
  798. function test() public {
  799. s storage n = bar.push();
  800. n.f1 = 102;
  801. n.f2 = true;
  802. assert(bar[0].f1 == 102);
  803. }
  804. }"#,
  805. );
  806. runtime.function("test", Vec::new());
  807. }
  808. #[test]
  809. fn storage_dynamic_array_pop() {
  810. let mut runtime = build_solidity(
  811. r#"
  812. pragma solidity 0;
  813. contract foo {
  814. int32[] bar;
  815. function test() public {
  816. assert(bar.length == 0);
  817. bar.push(102);
  818. assert(bar[0] == 102);
  819. assert(bar.length == 1);
  820. int32 v = bar.pop();
  821. assert(bar.length == 0);
  822. assert(v == 102);
  823. }
  824. }"#,
  825. );
  826. runtime.function("test", Vec::new());
  827. // We should have one entry for the length; pop should have removed the 102 entry
  828. assert_eq!(runtime.store.len(), 1);
  829. // ensure that structs and fixed arrays are wiped by pop
  830. let mut runtime = build_solidity(
  831. r#"
  832. pragma solidity 0;
  833. contract foo {
  834. enum enum1 { val1, val2, val3 }
  835. struct s {
  836. bool f1;
  837. bytes3 f2;
  838. enum1 f3;
  839. uint64 f4;
  840. int64[2] f5;
  841. }
  842. s[] bar;
  843. function test() public {
  844. s storage first = bar.push();
  845. first.f1 = true;
  846. first.f2 = "abc";
  847. first.f3 = enum1.val2;
  848. first.f4 = 65536;
  849. first.f5[0] = -1;
  850. first.f5[1] = 5;
  851. assert(bar[0].f5[1] == 5);
  852. // now erase it again
  853. bar.pop();
  854. }
  855. }"#,
  856. );
  857. runtime.function("test", Vec::new());
  858. // We should have one entry for the length; pop should have removed the 102 entry
  859. assert_eq!(runtime.store.len(), 1);
  860. }
  861. #[test]
  862. fn storage_delete() {
  863. // ensure that structs and fixed arrays are wiped by pop
  864. let mut runtime = build_solidity(
  865. r#"
  866. pragma solidity 0;
  867. contract foo {
  868. uint64 bar;
  869. function test() public {
  870. bar = 0xdeaddeaddeaddead;
  871. delete bar;
  872. }
  873. }"#,
  874. );
  875. runtime.function("test", Vec::new());
  876. // We should have one entry for the length; pop should have removed the 102 entry
  877. assert!(runtime.store.is_empty());
  878. // ensure that structs and fixed arrays are wiped by delete
  879. let mut runtime = build_solidity(
  880. r#"
  881. pragma solidity 0;
  882. contract foo {
  883. enum enum1 { val1, val2, val3 }
  884. struct s {
  885. bool f1;
  886. bytes3 f2;
  887. enum1 f3;
  888. uint64 f4;
  889. int64[2] f5;
  890. }
  891. s[] bar;
  892. function test() public {
  893. s storage first = bar.push();
  894. first.f1 = true;
  895. first.f2 = "abc";
  896. first.f3 = enum1.val2;
  897. first.f4 = 65536;
  898. first.f5[0] = -1;
  899. first.f5[1] = 5;
  900. assert(bar[0].f5[1] == 5);
  901. // now erase it again
  902. delete bar[0];
  903. }
  904. }"#,
  905. );
  906. runtime.function("test", Vec::new());
  907. // We should have one entry for the length; delete should have removed the entry
  908. assert_eq!(runtime.store.len(), 1);
  909. // ensure that structs and fixed arrays are wiped by delete
  910. let mut runtime = build_solidity(
  911. r#"
  912. pragma solidity 0;
  913. contract foo {
  914. int[] bar;
  915. function setup() public {
  916. bar.push(102);
  917. bar.push(305);
  918. }
  919. function clear() public {
  920. delete bar;
  921. }
  922. }"#,
  923. );
  924. runtime.function("setup", Vec::new());
  925. assert_eq!(runtime.store.len(), 3);
  926. runtime.function("clear", Vec::new());
  927. assert_eq!(runtime.store.len(), 0);
  928. // our delete operator has to iterate over the dynamic array. Ensure it works if the array is empty
  929. runtime.function("clear", Vec::new());
  930. assert_eq!(runtime.store.len(), 0);
  931. }
  932. #[test]
  933. fn storage_dynamic_copy() {
  934. let mut runtime = build_solidity(
  935. r#"
  936. contract c {
  937. int32[] foo;
  938. constructor() public {
  939. for (int32 i = 0; i <11; i++) {
  940. foo.push(i * 3);
  941. }
  942. }
  943. function storage_to_memory() view public {
  944. int32[] memory bar = foo;
  945. assert(bar.length == 11);
  946. for (int32 i = 0; i <11; i++) {
  947. assert(bar[uint32(i)] == i * 3);
  948. }
  949. }
  950. function memory_to_storage() public {
  951. int32[] memory bar = new int32[](5);
  952. for (int32 i = 0; i < 5; i++) {
  953. bar[uint32(i)] = 5 * (i + 7);
  954. }
  955. foo = bar;
  956. assert(foo.length == 5);
  957. for (int32 i = 0; i < 5; i++) {
  958. assert(foo[uint32(i)] == 5 * (i + 7));
  959. }
  960. }
  961. }
  962. "#,
  963. );
  964. runtime.constructor(0, Vec::new());
  965. runtime.function("storage_to_memory", Vec::new());
  966. runtime.function("memory_to_storage", Vec::new());
  967. assert_eq!(runtime.store.len(), 6);
  968. }
  969. #[test]
  970. fn abi_encode_dynamic_array() {
  971. #[derive(Debug, PartialEq, Encode, Decode)]
  972. struct Int32Array(Vec<i32>);
  973. let mut runtime = build_solidity(
  974. r#"
  975. contract c {
  976. function encode() pure public returns (int32[]) {
  977. int32[] memory bar = new int32[](11);
  978. for (int32 i = 0; i <11; i++) {
  979. bar[uint32(i)] = i * 3;
  980. }
  981. return bar;
  982. }
  983. }
  984. "#,
  985. );
  986. runtime.constructor(0, Vec::new());
  987. runtime.function("encode", Vec::new());
  988. assert_eq!(
  989. runtime.vm.output,
  990. Int32Array(vec!(0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30)).encode()
  991. );
  992. }
  993. #[test]
  994. fn abi_decode_dynamic_array() {
  995. #[derive(Debug, PartialEq, Encode, Decode)]
  996. struct Int32Array(Vec<i32>);
  997. let mut runtime = build_solidity(
  998. r#"
  999. contract c {
  1000. function decode(int32[] bar) pure public {
  1001. assert(bar.length == 11);
  1002. for (int32 i = 0; i <11; i++) {
  1003. assert(bar[uint32(i)] == i * 3);
  1004. }
  1005. }
  1006. function decode_empty(int32[] bar) pure public {
  1007. assert(bar.length == 0);
  1008. }
  1009. }
  1010. "#,
  1011. );
  1012. runtime.constructor(0, Vec::new());
  1013. runtime.function(
  1014. "decode",
  1015. Int32Array(vec![0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]).encode(),
  1016. );
  1017. runtime.function("decode_empty", Int32Array(vec![]).encode());
  1018. }
  1019. #[test]
  1020. fn abi_encode_dynamic_array2() {
  1021. #[derive(Debug, PartialEq, Encode, Decode)]
  1022. struct Array(Vec<(bool, u32)>);
  1023. let mut runtime = build_solidity(
  1024. r#"
  1025. contract structs {
  1026. struct foo {
  1027. bool x;
  1028. uint32 y;
  1029. }
  1030. function test() public returns (foo[]) {
  1031. foo[] x = new foo[](3);
  1032. x[0] = foo({x: true, y: 64});
  1033. x[1] = foo({x: false, y: 102});
  1034. x[2] = foo({x: true, y: 0x800});
  1035. return x;
  1036. }
  1037. }
  1038. "#,
  1039. );
  1040. runtime.constructor(0, Vec::new());
  1041. runtime.function("test", Vec::new());
  1042. assert_eq!(
  1043. runtime.vm.output,
  1044. Array(vec!((true, 64), (false, 102), (true, 0x800))).encode()
  1045. );
  1046. }
  1047. #[test]
  1048. fn abi_encode_dynamic_array3() {
  1049. #[derive(Debug, PartialEq, Encode, Decode)]
  1050. struct Array(Vec<(bool, u32, String)>);
  1051. let mut runtime = build_solidity(
  1052. r#"
  1053. contract structs {
  1054. struct foo {
  1055. bool x;
  1056. uint32 y;
  1057. string z;
  1058. }
  1059. function test() public returns (foo[]) {
  1060. foo[] x = new foo[](3);
  1061. x[0] = foo({x: true, y: 64, z: "abc"});
  1062. x[1] = foo({x: false, y: 102, z: "a"});
  1063. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1064. return x;
  1065. }
  1066. }
  1067. "#,
  1068. );
  1069. runtime.constructor(0, Vec::new());
  1070. runtime.function("test", Vec::new());
  1071. assert_eq!(
  1072. runtime.vm.output,
  1073. Array(vec!(
  1074. (true, 64, "abc".to_owned()),
  1075. (false, 102, "a".to_owned()),
  1076. (true, 0x800, "abcdef".to_owned())
  1077. ))
  1078. .encode()
  1079. );
  1080. }
  1081. #[test]
  1082. fn abi_encode_dynamic_array4() {
  1083. #[derive(Debug, PartialEq, Encode, Decode)]
  1084. struct Array([(bool, u32, String); 3]);
  1085. let mut runtime = build_solidity(
  1086. r#"
  1087. contract structs {
  1088. struct foo {
  1089. bool x;
  1090. uint32 y;
  1091. string z;
  1092. }
  1093. function test() public returns (foo[3]) {
  1094. foo[3] x;
  1095. x[0] = foo({x: true, y: 64, z: "abc"});
  1096. x[1] = foo({x: false, y: 102, z: "a"});
  1097. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1098. return x;
  1099. }
  1100. }
  1101. "#,
  1102. );
  1103. runtime.constructor(0, Vec::new());
  1104. runtime.function("test", Vec::new());
  1105. runtime.heap_verify();
  1106. assert_eq!(
  1107. runtime.vm.output,
  1108. Array([
  1109. (true, 64, "abc".to_owned()),
  1110. (false, 102, "a".to_owned()),
  1111. (true, 0x800, "abcdef".to_owned())
  1112. ])
  1113. .encode()
  1114. );
  1115. }
  1116. #[test]
  1117. fn large_index_ty_in_bounds() {
  1118. let mut runtime = build_solidity(
  1119. r#"
  1120. contract foo {
  1121. uint128 storage_index;
  1122. function test(uint128 index) public returns (uint16) {
  1123. uint16[] memory a = new uint16[](16);
  1124. storage_index = index;
  1125. return a[storage_index];
  1126. }
  1127. }"#,
  1128. );
  1129. runtime.constructor(0, Vec::new());
  1130. runtime.function("test", 15u128.encode());
  1131. runtime.function_expect_failure("test", 17u128.encode());
  1132. runtime.function_expect_failure("test", 0xfffffffffffffu128.encode());
  1133. }
  1134. #[test]
  1135. fn alloc_size_from_storage() {
  1136. let mut runtime = build_solidity(
  1137. r#"
  1138. contract Test {
  1139. uint32 length = 1;
  1140. function contfunc() public view returns (uint64[] memory) {
  1141. uint64[] memory values = new uint64[](length);
  1142. return values;
  1143. }
  1144. }"#,
  1145. );
  1146. runtime.constructor(0, Vec::new());
  1147. runtime.function("contfunc", Vec::new());
  1148. assert_eq!(runtime.vm.output, vec![0u64].encode());
  1149. }