arrays.rs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  1. // SPDX-License-Identifier: Apache-2.0
  2. use parity_scale_codec::{Decode, Encode};
  3. use primitive_types::U256;
  4. use rand::Rng;
  5. use crate::build_solidity;
  6. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  7. struct Val32(u32);
  8. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  9. struct Val8(u8);
  10. #[test]
  11. fn const_array_array() {
  12. let mut runtime = build_solidity(
  13. r##"
  14. contract foo {
  15. int8[8] constant bar = [ int8(1), 2, 3, 4, 5, 6, 7, 8 ];
  16. function f(uint32 i1) public returns (int8) {
  17. return bar[i1];
  18. }
  19. }"##,
  20. );
  21. runtime.function("f", Val32(1).encode());
  22. assert_eq!(runtime.output(), Val8(2).encode());
  23. }
  24. #[test]
  25. fn votes() {
  26. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  27. struct Votes([bool; 11]);
  28. let mut runtime = build_solidity(
  29. r##"
  30. contract foo {
  31. /// In a jury, do the ayes have it?
  32. function f(bool[11] votes) public pure returns (bool) {
  33. uint32 i;
  34. uint32 ayes = 0;
  35. for (i=0; i<votes.length; i++) {
  36. if (votes[i]) {
  37. ayes += 1;
  38. }
  39. }
  40. return ayes > votes.length / 2;
  41. }
  42. }"##,
  43. );
  44. runtime.function(
  45. "f",
  46. Votes([
  47. true, true, true, true, true, true, false, false, false, false, false,
  48. ])
  49. .encode(),
  50. );
  51. assert_eq!(runtime.output(), true.encode());
  52. runtime.function(
  53. "f",
  54. Votes([
  55. true, true, true, true, true, false, false, false, false, false, false,
  56. ])
  57. .encode(),
  58. );
  59. assert_eq!(runtime.output(), false.encode());
  60. }
  61. #[test]
  62. fn return_array() {
  63. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  64. struct Res([u64; 4]);
  65. let mut runtime = build_solidity(
  66. r##"
  67. contract foo {
  68. function array() pure public returns (int64[4]) {
  69. return [ int64(4), 84564, 31213, 1312 ];
  70. }
  71. }"##,
  72. );
  73. runtime.function("array", Vec::new());
  74. assert_eq!(runtime.output(), Res([4, 84564, 31213, 1312]).encode());
  75. }
  76. #[test]
  77. fn storage_arrays() {
  78. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  79. struct Val(i32);
  80. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  81. struct SetArg(u32, i32);
  82. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  83. struct GetArg(u32);
  84. let mut runtime = build_solidity(
  85. r##"
  86. contract foo {
  87. int32[type(uint32).max] bigarray;
  88. function set(uint32 index, int32 val) public {
  89. bigarray[index] = val;
  90. }
  91. function get(uint32 index) public returns (int32) {
  92. return bigarray[index];
  93. }
  94. }"##,
  95. );
  96. let mut rng = rand::thread_rng();
  97. let mut vals = Vec::new();
  98. for _ in 0..100 {
  99. let index = rng.gen::<u32>();
  100. let val = rng.gen::<i32>();
  101. runtime.function("set", SetArg(index, val).encode());
  102. vals.push((index, val));
  103. }
  104. for val in vals {
  105. runtime.function("get", GetArg(val.0).encode());
  106. assert_eq!(runtime.output(), Val(val.1).encode());
  107. }
  108. }
  109. #[test]
  110. fn enum_arrays() {
  111. #[derive(Encode, Decode)]
  112. struct Arg([u8; 100]);
  113. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  114. struct Ret(u32);
  115. let mut runtime = build_solidity(
  116. r##"
  117. contract enum_array {
  118. enum Foo { Bar1, Bar2, Bar3, Bar4 }
  119. function count_bar2(Foo[100] calldata foos) public returns (uint32) {
  120. uint32 count = 0;
  121. uint32 i;
  122. for (i = 0; i < foos.length; i++) {
  123. if (foos[i] == Foo.Bar2) {
  124. count++;
  125. }
  126. }
  127. return count;
  128. }
  129. }"##,
  130. );
  131. let mut rng = rand::thread_rng();
  132. let mut a = [0u8; 100];
  133. let mut count = 0;
  134. #[allow(clippy::needless_range_loop)]
  135. for i in 0..a.len() {
  136. a[i] = rng.gen::<u8>() % 4;
  137. if a[i] == 1 {
  138. count += 1;
  139. }
  140. }
  141. runtime.function("count_bar2", Arg(a).encode());
  142. assert_eq!(runtime.output(), Ret(count).encode());
  143. }
  144. #[test]
  145. fn storage_ref_arg() {
  146. let mut runtime = build_solidity(
  147. r##"
  148. contract storage_refs {
  149. int32[10] a;
  150. int32[10] b;
  151. function set(int32[10] storage array, uint8 index, int32 val) private {
  152. array[index] = val;
  153. }
  154. function test() public {
  155. set(a, 2, 5);
  156. set(b, 2, 102);
  157. assert(a[2] == 5);
  158. assert(b[2] == 102);
  159. }
  160. }"##,
  161. );
  162. runtime.function("test", Vec::new());
  163. }
  164. #[test]
  165. fn storage_ref_var() {
  166. let mut runtime = build_solidity(
  167. r##"
  168. contract storage_refs {
  169. int32[10] a;
  170. int32[10] b;
  171. function set(int32[10] storage array, uint8 index, int32 val) private {
  172. array[index] = val;
  173. }
  174. function test() public {
  175. int32[10] storage ref = a;
  176. set(ref, 2, 5);
  177. ref = b;
  178. set(ref, 2, 102);
  179. assert(a[2] == 5);
  180. assert(b[2] == 102);
  181. }
  182. }"##,
  183. );
  184. runtime.function("test", Vec::new());
  185. }
  186. #[test]
  187. fn storage_ref_returns() {
  188. let mut runtime = build_solidity(
  189. r##"
  190. contract storage_refs {
  191. int32[10] a;
  192. int32[10] b;
  193. function a_or_b(bool want_a) private returns (int32[10] storage) {
  194. if (want_a) {
  195. return a;
  196. }
  197. return b;
  198. }
  199. function set(int32[10] storage array, uint8 index, int32 val) private {
  200. array[index] = val;
  201. }
  202. function test() public {
  203. int32[10] storage ref = a_or_b(true);
  204. set(ref, 2, 5);
  205. ref = a_or_b(false);
  206. set(ref, 2, 102);
  207. assert(a[2] == 5);
  208. assert(b[2] == 102);
  209. }
  210. }"##,
  211. );
  212. runtime.function("test", Vec::new());
  213. }
  214. #[test]
  215. fn storage_to_memory() {
  216. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  217. struct Ret([u32; 10]);
  218. let mut runtime = build_solidity(
  219. r##"
  220. contract storage_refs {
  221. uint32[10] a;
  222. function test() public returns (uint32[10]) {
  223. for (uint32 i = 0; i < 10; ) {
  224. uint32 index = i;
  225. a[index] = 7 * ++i;
  226. }
  227. return a;
  228. }
  229. }"##,
  230. );
  231. runtime.function("test", Vec::new());
  232. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  233. assert_eq!(runtime.output(), val.encode());
  234. }
  235. #[test]
  236. fn memory_to_storage() {
  237. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  238. struct Ret([u32; 10]);
  239. let mut runtime = build_solidity(
  240. r##"
  241. contract storage_refs {
  242. int32[10] a;
  243. function test() public returns (int32[10]) {
  244. int32[10] b = [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 70 ];
  245. a = b;
  246. return a;
  247. }
  248. }"##,
  249. );
  250. runtime.function("test", Vec::new());
  251. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  252. assert_eq!(runtime.output(), val.encode());
  253. }
  254. #[test]
  255. fn array_dimensions() {
  256. let mut runtime = build_solidity(
  257. r##"
  258. contract storage_refs {
  259. int32[32] a;
  260. function test() public {
  261. assert(a.length == 32);
  262. }
  263. }"##,
  264. );
  265. runtime.function("test", Vec::new());
  266. }
  267. #[test]
  268. fn array_in_struct() {
  269. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  270. struct Ret([u32; 10]);
  271. let mut runtime = build_solidity(
  272. r##"
  273. contract storage_refs {
  274. struct foo {
  275. int32[10] f1;
  276. }
  277. function test() public returns (int32[10]) {
  278. foo a = foo({f1: [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 0 ]});
  279. assert(a.f1[1] == 14);
  280. a.f1[9] = 70;
  281. return a.f1;
  282. }
  283. }"##,
  284. );
  285. runtime.function("test", Vec::new());
  286. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  287. assert_eq!(runtime.output(), val.encode());
  288. }
  289. #[test]
  290. fn struct_in_array() {
  291. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  292. struct S(u64, bool);
  293. let mut runtime = build_solidity(
  294. r##"
  295. struct S {
  296. uint64 f1;
  297. bool f2;
  298. }
  299. contract foo {
  300. S[] store;
  301. function set(S[] memory n) public {
  302. store = n;
  303. }
  304. function copy() public returns (S[] memory) {
  305. return store;
  306. }
  307. }"##,
  308. );
  309. let val = vec![S(102, true), S(u64::MAX, false)];
  310. runtime.function("set", val.encode());
  311. runtime.function("copy", vec![]);
  312. assert_eq!(runtime.output(), val.encode());
  313. }
  314. #[test]
  315. fn struct_in_fixed_array() {
  316. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  317. struct S(u64, bool);
  318. let mut runtime = build_solidity(
  319. r##"
  320. struct S {
  321. uint64 f1;
  322. bool f2;
  323. }
  324. contract foo {
  325. S[2] store;
  326. function set(S[2] memory n) public {
  327. store = n;
  328. }
  329. function copy() public returns (S[2] memory) {
  330. return store;
  331. }
  332. }"##,
  333. );
  334. let val = [S(102, true), S(u64::MAX, false)];
  335. runtime.function("set", val.encode());
  336. runtime.function("copy", vec![]);
  337. assert_eq!(runtime.output(), val.encode());
  338. }
  339. #[test]
  340. fn struct_array_struct() {
  341. let mut runtime = build_solidity(
  342. r##"
  343. contract flipper {
  344. struct bool_struct {
  345. bool foo_bool;
  346. }
  347. struct struct_bool_struct_array {
  348. bool_struct[1] foo_struct_array;
  349. }
  350. function get_memory() public pure returns (bool) {
  351. bool_struct memory foo = bool_struct({foo_bool: true});
  352. bool_struct[1] memory foo_array = [foo];
  353. struct_bool_struct_array memory foo_struct = struct_bool_struct_array({foo_struct_array: foo_array});
  354. /* return foo_array[0].foo_bool; */
  355. return foo_struct.foo_struct_array[0].foo_bool;
  356. }
  357. }"##,
  358. );
  359. runtime.function("get_memory", Vec::new());
  360. assert_eq!(runtime.output(), true.encode());
  361. }
  362. #[test]
  363. fn struct_array_struct_abi() {
  364. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  365. struct Foo {
  366. f1: u32,
  367. f2: bool,
  368. }
  369. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  370. struct Bar {
  371. bars: [Foo; 10],
  372. }
  373. let mut runtime = build_solidity(
  374. r##"
  375. contract flipper {
  376. struct foo {
  377. int32 f1;
  378. bool f2;
  379. }
  380. struct bar {
  381. foo[10] bars;
  382. }
  383. bar s;
  384. function get_bar() public returns (bar) {
  385. bar memory a = bar({ bars: [
  386. foo({ f1: 1, f2: true}),
  387. foo({ f1: 2, f2: true}),
  388. foo({ f1: 3, f2: true}),
  389. foo({ f1: 4, f2: true}),
  390. foo({ f1: 5, f2: true}),
  391. foo({ f1: 6, f2: true}),
  392. foo({ f1: 7, f2: false}),
  393. foo({ f1: 8, f2: true}),
  394. foo({ f1: 9, f2: true}),
  395. foo({ f1: 10, f2: true})
  396. ]});
  397. s = a;
  398. return a;
  399. }
  400. function set_bar(bar memory a) public {
  401. for (uint32 i = 0; i < 10; i++) {
  402. assert(a.bars[i].f1 == i + 1);
  403. assert(a.bars[i].f2 == (i != 6));
  404. }
  405. a = s;
  406. }
  407. }"##,
  408. );
  409. let b = Bar {
  410. bars: [
  411. Foo { f1: 1, f2: true },
  412. Foo { f1: 2, f2: true },
  413. Foo { f1: 3, f2: true },
  414. Foo { f1: 4, f2: true },
  415. Foo { f1: 5, f2: true },
  416. Foo { f1: 6, f2: true },
  417. Foo { f1: 7, f2: false },
  418. Foo { f1: 8, f2: true },
  419. Foo { f1: 9, f2: true },
  420. Foo { f1: 10, f2: true },
  421. ],
  422. };
  423. runtime.function("get_bar", Vec::new());
  424. assert_eq!(runtime.output(), b.encode());
  425. runtime.function("set_bar", b.encode());
  426. }
  427. #[test]
  428. fn memory_dynamic_array_new() {
  429. let mut runtime = build_solidity(
  430. r#"
  431. contract foo {
  432. function test() public {
  433. int32[] memory a = new int32[](5);
  434. assert(a.length == 5);
  435. }
  436. }"#,
  437. );
  438. runtime.function("test", Vec::new());
  439. // The Ethereum Foundation solc allows you to create arrays of length 0
  440. let mut runtime = build_solidity(
  441. r#"
  442. contract foo {
  443. function test() public {
  444. bool[] memory a = new bool[](0);
  445. assert(a.length == 0);
  446. }
  447. }"#,
  448. );
  449. runtime.function("test", Vec::new());
  450. }
  451. #[test]
  452. fn memory_dynamic_array_deref() {
  453. // The Ethereum Foundation solc allows you to create arrays of length 0
  454. let mut runtime = build_solidity(
  455. r#"
  456. contract foo {
  457. function test() public {
  458. int32[] memory a = new int32[](5);
  459. assert(a.length == 5);
  460. a[0] = 102;
  461. a[1] = -5;
  462. a[4] = 0x7cafeeed;
  463. assert(a[0] == 102);
  464. assert(a[1] == -5);
  465. assert(a[4] == 0x7cafeeed);
  466. }
  467. }"#,
  468. );
  469. runtime.function("test", Vec::new());
  470. }
  471. #[test]
  472. fn array_bounds_dynamic_array() {
  473. let mut runtime = build_solidity(
  474. r#"
  475. contract foo {
  476. function test() public returns (int32) {
  477. int32[] memory a = new int32[](5);
  478. a[5] = 102;
  479. return a[3];
  480. }
  481. }"#,
  482. );
  483. runtime.function_expect_failure("test", Vec::new());
  484. }
  485. #[test]
  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_expect_failure("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. fn dynamic_array_pop_empty_array() {
  739. let mut runtime = build_solidity(
  740. r#"
  741. pragma solidity 0;
  742. contract foo {
  743. function test() public returns (int) {
  744. int[] bar = new int[](0);
  745. return bar.pop();
  746. }
  747. }"#,
  748. );
  749. runtime.function_expect_failure("test", Vec::new());
  750. }
  751. #[test]
  752. fn dynamic_array_pop_bounds() {
  753. let mut runtime = build_solidity(
  754. r#"
  755. pragma solidity 0;
  756. contract foo {
  757. function test() public {
  758. int[] bar = new int[](1);
  759. bar[0] = 12;
  760. bar.pop();
  761. assert(bar[0] == 12);
  762. }
  763. }"#,
  764. );
  765. runtime.function_expect_failure("test", Vec::new());
  766. }
  767. #[test]
  768. fn storage_dynamic_array_push() {
  769. let mut runtime = build_solidity(
  770. r#"
  771. pragma solidity 0;
  772. contract foo {
  773. int32[] bar;
  774. function test() public {
  775. assert(bar.length == 0);
  776. bar.push(102);
  777. assert(bar[0] == 102);
  778. assert(bar.length == 1);
  779. bar.push();
  780. assert(bar[1] == 0);
  781. assert(bar.length == 2);
  782. }
  783. }"#,
  784. );
  785. runtime.function("test", Vec::new());
  786. // push() returns a reference to the thing
  787. let mut runtime = build_solidity(
  788. r#"
  789. pragma solidity 0;
  790. contract foo {
  791. struct s {
  792. int32 f1;
  793. bool f2;
  794. }
  795. s[] bar;
  796. function test() public {
  797. s storage n = bar.push();
  798. n.f1 = 102;
  799. n.f2 = true;
  800. assert(bar[0].f1 == 102);
  801. }
  802. }"#,
  803. );
  804. runtime.function("test", Vec::new());
  805. }
  806. #[test]
  807. fn storage_dynamic_array_pop() {
  808. let mut runtime = build_solidity(
  809. r#"
  810. pragma solidity 0;
  811. contract foo {
  812. int32[] bar;
  813. function test() public {
  814. assert(bar.length == 0);
  815. bar.push(102);
  816. assert(bar[0] == 102);
  817. assert(bar.length == 1);
  818. int32 v = bar.pop();
  819. assert(bar.length == 0);
  820. assert(v == 102);
  821. }
  822. }"#,
  823. );
  824. runtime.function("test", Vec::new());
  825. // We should have one entry for the length; pop should have removed the 102 entry
  826. assert_eq!(runtime.storage().len(), 1);
  827. // ensure that structs and fixed arrays are wiped by pop
  828. let mut runtime = build_solidity(
  829. r#"
  830. pragma solidity 0;
  831. contract foo {
  832. enum enum1 { val1, val2, val3 }
  833. struct s {
  834. bool f1;
  835. bytes3 f2;
  836. enum1 f3;
  837. uint64 f4;
  838. int64[2] f5;
  839. }
  840. s[] bar;
  841. function test() public {
  842. s storage first = bar.push();
  843. first.f1 = true;
  844. first.f2 = "abc";
  845. first.f3 = enum1.val2;
  846. first.f4 = 65536;
  847. first.f5[0] = -1;
  848. first.f5[1] = 5;
  849. assert(bar[0].f5[1] == 5);
  850. // now erase it again
  851. bar.pop();
  852. }
  853. }"#,
  854. );
  855. runtime.function("test", Vec::new());
  856. // We should have one entry for the length; pop should have removed the 102 entry
  857. assert_eq!(runtime.storage().len(), 1);
  858. }
  859. #[test]
  860. fn storage_delete() {
  861. // ensure that structs and fixed arrays are wiped by pop
  862. let mut runtime = build_solidity(
  863. r#"
  864. pragma solidity 0;
  865. contract foo {
  866. uint64 bar;
  867. function test() public {
  868. bar = 0xdeaddeaddeaddead;
  869. delete bar;
  870. }
  871. }"#,
  872. );
  873. runtime.function("test", Vec::new());
  874. // We should have one entry for the length; pop should have removed the 102 entry
  875. assert!(runtime.storage().is_empty());
  876. // ensure that structs and fixed arrays are wiped by delete
  877. let mut runtime = build_solidity(
  878. r#"
  879. pragma solidity 0;
  880. contract foo {
  881. enum enum1 { val1, val2, val3 }
  882. struct s {
  883. bool f1;
  884. bytes3 f2;
  885. enum1 f3;
  886. uint64 f4;
  887. int64[2] f5;
  888. }
  889. s[] bar;
  890. function test() public {
  891. s storage first = bar.push();
  892. first.f1 = true;
  893. first.f2 = "abc";
  894. first.f3 = enum1.val2;
  895. first.f4 = 65536;
  896. first.f5[0] = -1;
  897. first.f5[1] = 5;
  898. assert(bar[0].f5[1] == 5);
  899. // now erase it again
  900. delete bar[0];
  901. }
  902. }"#,
  903. );
  904. runtime.function("test", Vec::new());
  905. // We should have one entry for the length; delete should have removed the entry
  906. assert_eq!(runtime.storage().len(), 1);
  907. // ensure that structs and fixed arrays are wiped by delete
  908. let mut runtime = build_solidity(
  909. r#"
  910. pragma solidity 0;
  911. contract foo {
  912. int[] bar;
  913. function setup() public {
  914. bar.push(102);
  915. bar.push(305);
  916. }
  917. function clear() public {
  918. delete bar;
  919. }
  920. }"#,
  921. );
  922. runtime.function("setup", Vec::new());
  923. assert_eq!(runtime.storage().len(), 3);
  924. runtime.function("clear", Vec::new());
  925. assert_eq!(runtime.storage().len(), 0);
  926. // our delete operator has to iterate over the dynamic array. Ensure it works if the array is empty
  927. runtime.function("clear", Vec::new());
  928. assert_eq!(runtime.storage().len(), 0);
  929. }
  930. #[test]
  931. fn storage_dynamic_copy() {
  932. let mut runtime = build_solidity(
  933. r#"
  934. contract c {
  935. int32[] foo;
  936. constructor() public {
  937. for (int32 i = 0; i <11; i++) {
  938. foo.push(i * 3);
  939. }
  940. }
  941. function storage_to_memory() view public {
  942. int32[] memory bar = foo;
  943. assert(bar.length == 11);
  944. for (int32 i = 0; i <11; i++) {
  945. assert(bar[uint32(i)] == i * 3);
  946. }
  947. }
  948. function memory_to_storage() public {
  949. int32[] memory bar = new int32[](5);
  950. for (int32 i = 0; i < 5; i++) {
  951. bar[uint32(i)] = 5 * (i + 7);
  952. }
  953. foo = bar;
  954. assert(foo.length == 5);
  955. for (int32 i = 0; i < 5; i++) {
  956. assert(foo[uint32(i)] == 5 * (i + 7));
  957. }
  958. }
  959. }
  960. "#,
  961. );
  962. runtime.constructor(0, Vec::new());
  963. runtime.function("storage_to_memory", Vec::new());
  964. runtime.function("memory_to_storage", Vec::new());
  965. assert_eq!(runtime.storage().len(), 6);
  966. }
  967. #[test]
  968. fn abi_encode_dynamic_array() {
  969. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  970. struct Int32Array(Vec<i32>);
  971. let mut runtime = build_solidity(
  972. r#"
  973. contract c {
  974. function encode() pure public returns (int32[]) {
  975. int32[] memory bar = new int32[](11);
  976. for (int32 i = 0; i <11; i++) {
  977. bar[uint32(i)] = i * 3;
  978. }
  979. return bar;
  980. }
  981. }
  982. "#,
  983. );
  984. runtime.constructor(0, Vec::new());
  985. runtime.function("encode", Vec::new());
  986. assert_eq!(
  987. runtime.output(),
  988. Int32Array(vec!(0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30)).encode()
  989. );
  990. }
  991. #[test]
  992. fn abi_decode_dynamic_array() {
  993. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  994. struct Int32Array(Vec<i32>);
  995. let mut runtime = build_solidity(
  996. r#"
  997. contract c {
  998. function decode(int32[] bar) pure public {
  999. assert(bar.length == 11);
  1000. for (int32 i = 0; i <11; i++) {
  1001. assert(bar[uint32(i)] == i * 3);
  1002. }
  1003. }
  1004. function decode_empty(int32[] bar) pure public {
  1005. assert(bar.length == 0);
  1006. }
  1007. }
  1008. "#,
  1009. );
  1010. runtime.constructor(0, Vec::new());
  1011. runtime.function(
  1012. "decode",
  1013. Int32Array(vec![0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]).encode(),
  1014. );
  1015. runtime.function("decode_empty", Int32Array(vec![]).encode());
  1016. }
  1017. #[test]
  1018. fn abi_encode_dynamic_array2() {
  1019. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1020. struct Array(Vec<(bool, u32)>);
  1021. let mut runtime = build_solidity(
  1022. r#"
  1023. contract structs {
  1024. struct foo {
  1025. bool x;
  1026. uint32 y;
  1027. }
  1028. function test() public returns (foo[]) {
  1029. foo[] x = new foo[](3);
  1030. x[0] = foo({x: true, y: 64});
  1031. x[1] = foo({x: false, y: 102});
  1032. x[2] = foo({x: true, y: 0x800});
  1033. return x;
  1034. }
  1035. }
  1036. "#,
  1037. );
  1038. runtime.constructor(0, Vec::new());
  1039. runtime.function("test", Vec::new());
  1040. assert_eq!(
  1041. runtime.output(),
  1042. Array(vec!((true, 64), (false, 102), (true, 0x800))).encode()
  1043. );
  1044. }
  1045. #[test]
  1046. fn abi_encode_dynamic_array3() {
  1047. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1048. struct Array(Vec<(bool, u32, String)>);
  1049. let mut runtime = build_solidity(
  1050. r#"
  1051. contract structs {
  1052. struct foo {
  1053. bool x;
  1054. uint32 y;
  1055. string z;
  1056. }
  1057. function test() public returns (foo[]) {
  1058. foo[] x = new foo[](3);
  1059. x[0] = foo({x: true, y: 64, z: "abc"});
  1060. x[1] = foo({x: false, y: 102, z: "a"});
  1061. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1062. return x;
  1063. }
  1064. }
  1065. "#,
  1066. );
  1067. runtime.constructor(0, Vec::new());
  1068. runtime.function("test", Vec::new());
  1069. assert_eq!(
  1070. runtime.output(),
  1071. Array(vec!(
  1072. (true, 64, "abc".to_owned()),
  1073. (false, 102, "a".to_owned()),
  1074. (true, 0x800, "abcdef".to_owned())
  1075. ))
  1076. .encode()
  1077. );
  1078. }
  1079. #[test]
  1080. fn abi_encode_dynamic_array4() {
  1081. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1082. struct Array([(bool, u32, String); 3]);
  1083. let mut runtime = build_solidity(
  1084. r#"
  1085. contract structs {
  1086. struct foo {
  1087. bool x;
  1088. uint32 y;
  1089. string z;
  1090. }
  1091. function test() public returns (foo[3]) {
  1092. foo[3] x;
  1093. x[0] = foo({x: true, y: 64, z: "abc"});
  1094. x[1] = foo({x: false, y: 102, z: "a"});
  1095. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1096. return x;
  1097. }
  1098. }
  1099. "#,
  1100. );
  1101. runtime.constructor(0, Vec::new());
  1102. runtime.function("test", Vec::new());
  1103. runtime.heap_verify();
  1104. assert_eq!(
  1105. runtime.output(),
  1106. Array([
  1107. (true, 64, "abc".to_owned()),
  1108. (false, 102, "a".to_owned()),
  1109. (true, 0x800, "abcdef".to_owned())
  1110. ])
  1111. .encode()
  1112. );
  1113. }
  1114. #[test]
  1115. fn abi_encode_dynamic_array5() {
  1116. let uint_str_0 = "201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201";
  1117. let uint_val_0 = U256::from_str_radix(uint_str_0, 16).unwrap();
  1118. let uint_str_1 = "dbb85cf1ffefee258d1bdf7bc573838c30a6bc5a64fdc5c708280f56e4972fe7";
  1119. let uint_val_1 = U256::from_str_radix(uint_str_1, 16).unwrap();
  1120. let mut runtime = build_solidity(&format!(
  1121. "contract Test {{
  1122. function test() external pure returns (uint256[] memory _amounts) {{
  1123. _amounts = new uint256[](2);
  1124. _amounts[0] = 0x{};
  1125. _amounts[1] = 0x{};
  1126. }}
  1127. }}",
  1128. uint_str_0, uint_str_1
  1129. ));
  1130. runtime.function("test", Vec::new());
  1131. assert_eq!(runtime.output(), vec![uint_val_0, uint_val_1].encode());
  1132. }
  1133. #[test]
  1134. fn abi_encode_dynamic_array6() {
  1135. let mut runtime = build_solidity(
  1136. r#"contract Test {
  1137. function test(uint256[] _init) external pure returns (uint256[] memory _amounts) {
  1138. _amounts = new uint256[](_init.length);
  1139. for (uint i = 0; i<_init.length; i++) {
  1140. _amounts[i] = _init[i];
  1141. }
  1142. }
  1143. }"#,
  1144. );
  1145. let max_array_length = 128;
  1146. let mut r = rand::thread_rng();
  1147. let mut values = Vec::with_capacity(max_array_length);
  1148. for _ in 0..max_array_length {
  1149. let val = U256::from_big_endian(&r.gen::<[u8; 32]>());
  1150. println!("{val}");
  1151. values.push(val);
  1152. let identity = values.encode();
  1153. runtime.function("test", identity.to_vec());
  1154. assert_eq!(runtime.output(), identity);
  1155. }
  1156. }
  1157. #[test]
  1158. fn large_index_ty_in_bounds() {
  1159. let mut runtime = build_solidity(
  1160. r#"
  1161. contract foo {
  1162. uint128 storage_index;
  1163. function test(uint128 index) public returns (uint16) {
  1164. uint16[] memory a = new uint16[](16);
  1165. storage_index = index;
  1166. return a[storage_index];
  1167. }
  1168. }"#,
  1169. );
  1170. runtime.constructor(0, Vec::new());
  1171. runtime.function("test", 15u128.encode());
  1172. runtime.function_expect_failure("test", 17u128.encode());
  1173. runtime.function_expect_failure("test", 0xfffffffffffffu128.encode());
  1174. }
  1175. #[test]
  1176. fn alloc_size_from_storage() {
  1177. let mut runtime = build_solidity(
  1178. r#"
  1179. contract Test {
  1180. uint32 length = 1;
  1181. function contfunc() public view returns (uint64[] memory) {
  1182. uint64[] memory values = new uint64[](length);
  1183. return values;
  1184. }
  1185. }"#,
  1186. );
  1187. runtime.constructor(0, Vec::new());
  1188. runtime.function("contfunc", Vec::new());
  1189. assert_eq!(runtime.output(), vec![0u64].encode());
  1190. }
  1191. #[test]
  1192. fn fixed_bytes() {
  1193. let mut runtime = build_solidity(
  1194. r#"
  1195. contract Storage {
  1196. bytes32[] data;
  1197. constructor() {
  1198. data.push(hex"0000000000000000000000000000000000000000000000000000000000000000");
  1199. data.push(hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
  1200. }
  1201. function uploadData(uint8 i, uint8 j) public view returns(bytes1) {
  1202. return(data[j][i]);
  1203. }
  1204. }
  1205. "#,
  1206. );
  1207. runtime.constructor(0, vec![]);
  1208. for i in 0..32u8 {
  1209. runtime.function("uploadData", vec![i, 0]);
  1210. assert_eq!(runtime.output()[..], [0]);
  1211. runtime.function("uploadData", vec![i, 1]);
  1212. assert_eq!(runtime.output()[..], [i]);
  1213. }
  1214. let mut runtime = build_solidity(
  1215. r#"
  1216. contract Memory {
  1217. constructor() {
  1218. }
  1219. function uploadData(uint8 i, uint8 j) public view returns(bytes1) {
  1220. bytes32[] data = new bytes32[](2);
  1221. data[0] = hex"0000000000000000000000000000000000000000000000000000000000000000";
  1222. data[1] = hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
  1223. return(data[j][i]);
  1224. }
  1225. }
  1226. "#,
  1227. );
  1228. runtime.constructor(0, vec![]);
  1229. for i in 0..32u8 {
  1230. runtime.function("uploadData", vec![i, 0]);
  1231. assert_eq!(runtime.output()[..], [0]);
  1232. runtime.function("uploadData", vec![i, 1]);
  1233. assert_eq!(runtime.output()[..], [i]);
  1234. }
  1235. }
  1236. #[test]
  1237. fn abi_decode_dynamic_array2() {
  1238. let mut runtime = build_solidity(
  1239. r#"
  1240. contract c {
  1241. function decode() pure public {
  1242. bytes enc = hex"2c000000000300000006000000090000000c0000000f0000001200000015000000180000001b0000001e000000";
  1243. int32[] bar = abi.decode(enc, (int32[]));
  1244. assert(bar.length == 11);
  1245. for (int32 i = 0; i <11; i++) {
  1246. assert(bar[uint32(i)] == i * 3);
  1247. }
  1248. }
  1249. function decode_empty() pure public {
  1250. bytes enc = hex"00";
  1251. int32[] bar = abi.decode(enc, (int32[]));
  1252. assert(bar.length == 0);
  1253. }
  1254. }
  1255. "#,
  1256. );
  1257. runtime.function("decode", vec![]);
  1258. runtime.function("decode_empty", vec![]);
  1259. }
  1260. #[test]
  1261. fn abi_decode_dynamic_array3() {
  1262. let mut runtime = build_solidity(
  1263. r#"
  1264. contract Arr {
  1265. function decode() pure public {
  1266. bytes enc = hex"14140001020304140102030405140203040506140304050607140405060708";
  1267. uint8[][] bar = abi.decode(enc, (uint8[][]));
  1268. assert(bar.length == 5);
  1269. for (uint8 i = 0; i <5; i++) {
  1270. for (uint8 j = 0; j <5; j++) {
  1271. assert(bar[uint32(i)][uint32(j)] == i + j);
  1272. }
  1273. }
  1274. }
  1275. function decode_empty() pure public {
  1276. bytes enc = hex"00";
  1277. uint8[][] bar = abi.decode(enc, (uint8[][]));
  1278. assert(bar.length == 0);
  1279. }
  1280. }
  1281. "#,
  1282. );
  1283. // The array in the first function was generated like this:
  1284. // let mut matrix = vec![];
  1285. // for i in 0..5 {
  1286. // matrix.push(vec![]);
  1287. // for j in 0..5 {
  1288. // matrix[i].push((i + j) as u8);
  1289. // }
  1290. // }
  1291. runtime.function("decode", vec![]);
  1292. runtime.function("decode_empty", vec![]);
  1293. }