arrays.rs 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628
  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{uint_str_0};
  1125. _amounts[1] = 0x{uint_str_1};
  1126. }}
  1127. }}"
  1128. ));
  1129. runtime.function("test", Vec::new());
  1130. assert_eq!(runtime.output(), vec![uint_val_0, uint_val_1].encode());
  1131. }
  1132. #[test]
  1133. fn abi_encode_dynamic_array6() {
  1134. let mut runtime = build_solidity(
  1135. r#"contract Test {
  1136. function test(uint256[] _init) external pure returns (uint256[] memory _amounts) {
  1137. _amounts = new uint256[](_init.length);
  1138. for (uint i = 0; i<_init.length; i++) {
  1139. _amounts[i] = _init[i];
  1140. }
  1141. }
  1142. }"#,
  1143. );
  1144. let max_array_length = 128;
  1145. let mut r = rand::thread_rng();
  1146. let mut values = Vec::with_capacity(max_array_length);
  1147. for _ in 0..max_array_length {
  1148. let val = U256::from_big_endian(&r.gen::<[u8; 32]>());
  1149. println!("{val}");
  1150. values.push(val);
  1151. let identity = values.encode();
  1152. runtime.function("test", identity.to_vec());
  1153. assert_eq!(runtime.output(), identity);
  1154. }
  1155. }
  1156. #[test]
  1157. fn large_index_ty_in_bounds() {
  1158. let mut runtime = build_solidity(
  1159. r#"
  1160. contract foo {
  1161. uint128 storage_index;
  1162. function test(uint128 index) public returns (uint16) {
  1163. uint16[] memory a = new uint16[](16);
  1164. storage_index = index;
  1165. return a[storage_index];
  1166. }
  1167. }"#,
  1168. );
  1169. runtime.constructor(0, Vec::new());
  1170. runtime.function("test", 15u128.encode());
  1171. runtime.function_expect_failure("test", 17u128.encode());
  1172. runtime.function_expect_failure("test", 0xfffffffffffffu128.encode());
  1173. }
  1174. #[test]
  1175. fn alloc_size_from_storage() {
  1176. let mut runtime = build_solidity(
  1177. r#"
  1178. contract Test {
  1179. uint32 length = 1;
  1180. function contfunc() public view returns (uint64[] memory) {
  1181. uint64[] memory values = new uint64[](length);
  1182. return values;
  1183. }
  1184. }"#,
  1185. );
  1186. runtime.constructor(0, Vec::new());
  1187. runtime.function("contfunc", Vec::new());
  1188. assert_eq!(runtime.output(), vec![0u64].encode());
  1189. }
  1190. #[test]
  1191. fn fixed_bytes() {
  1192. let mut runtime = build_solidity(
  1193. r#"
  1194. contract Storage {
  1195. bytes32[] data;
  1196. constructor() {
  1197. data.push(hex"0000000000000000000000000000000000000000000000000000000000000000");
  1198. data.push(hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
  1199. }
  1200. function uploadData(uint8 i, uint8 j) public view returns(bytes1) {
  1201. return(data[j][i]);
  1202. }
  1203. }
  1204. "#,
  1205. );
  1206. runtime.constructor(0, vec![]);
  1207. for i in 0..32u8 {
  1208. runtime.function("uploadData", vec![i, 0]);
  1209. assert_eq!(runtime.output()[..], [0]);
  1210. runtime.function("uploadData", vec![i, 1]);
  1211. assert_eq!(runtime.output()[..], [i]);
  1212. }
  1213. let mut runtime = build_solidity(
  1214. r#"
  1215. contract Memory {
  1216. constructor() {
  1217. }
  1218. function uploadData(uint8 i, uint8 j) public view returns(bytes1) {
  1219. bytes32[] data = new bytes32[](2);
  1220. data[0] = hex"0000000000000000000000000000000000000000000000000000000000000000";
  1221. data[1] = hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
  1222. return(data[j][i]);
  1223. }
  1224. }
  1225. "#,
  1226. );
  1227. runtime.constructor(0, vec![]);
  1228. for i in 0..32u8 {
  1229. runtime.function("uploadData", vec![i, 0]);
  1230. assert_eq!(runtime.output()[..], [0]);
  1231. runtime.function("uploadData", vec![i, 1]);
  1232. assert_eq!(runtime.output()[..], [i]);
  1233. }
  1234. }
  1235. #[test]
  1236. fn abi_decode_dynamic_array2() {
  1237. let mut runtime = build_solidity(
  1238. r#"
  1239. contract c {
  1240. function decode() pure public {
  1241. bytes enc = hex"2c000000000300000006000000090000000c0000000f0000001200000015000000180000001b0000001e000000";
  1242. int32[] bar = abi.decode(enc, (int32[]));
  1243. assert(bar.length == 11);
  1244. for (int32 i = 0; i <11; i++) {
  1245. assert(bar[uint32(i)] == i * 3);
  1246. }
  1247. }
  1248. function decode_empty() pure public {
  1249. bytes enc = hex"00";
  1250. int32[] bar = abi.decode(enc, (int32[]));
  1251. assert(bar.length == 0);
  1252. }
  1253. }
  1254. "#,
  1255. );
  1256. runtime.function("decode", vec![]);
  1257. runtime.function("decode_empty", vec![]);
  1258. }
  1259. #[test]
  1260. fn abi_decode_dynamic_array3() {
  1261. let mut runtime = build_solidity(
  1262. r#"
  1263. contract Arr {
  1264. function decode() pure public {
  1265. bytes enc = hex"14140001020304140102030405140203040506140304050607140405060708";
  1266. uint8[][] bar = abi.decode(enc, (uint8[][]));
  1267. assert(bar.length == 5);
  1268. for (uint8 i = 0; i <5; i++) {
  1269. for (uint8 j = 0; j <5; j++) {
  1270. assert(bar[uint32(i)][uint32(j)] == i + j);
  1271. }
  1272. }
  1273. }
  1274. function decode_empty() pure public {
  1275. bytes enc = hex"00";
  1276. uint8[][] bar = abi.decode(enc, (uint8[][]));
  1277. assert(bar.length == 0);
  1278. }
  1279. }
  1280. "#,
  1281. );
  1282. // The array in the first function was generated like this:
  1283. // let mut matrix = vec![];
  1284. // for i in 0..5 {
  1285. // matrix.push(vec![]);
  1286. // for j in 0..5 {
  1287. // matrix[i].push((i + j) as u8);
  1288. // }
  1289. // }
  1290. runtime.function("decode", vec![]);
  1291. runtime.function("decode_empty", vec![]);
  1292. }