arrays.rs 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124
  1. use parity_scale_codec::Encode;
  2. use parity_scale_codec_derive::{Decode, Encode};
  3. use rand::Rng;
  4. use crate::{build_solidity, first_error, no_errors, parse_and_resolve};
  5. use solang::Target;
  6. #[derive(Debug, PartialEq, Encode, Decode)]
  7. struct Val32(u32);
  8. #[derive(Debug, PartialEq, Encode, Decode)]
  9. struct Val8(u8);
  10. #[test]
  11. fn missing_array_index() {
  12. let ns = parse_and_resolve(
  13. r#"
  14. contract c {
  15. function foo() public returns (uint) {
  16. uint8[4] memory bar = [ 1, 2, 3, 4 ];
  17. return bar[];
  18. }
  19. }"#,
  20. Target::Substrate {
  21. address_length: 32,
  22. value_length: 16,
  23. },
  24. );
  25. assert_eq!(
  26. first_error(ns.diagnostics),
  27. "expected expression before ‘]’ token"
  28. );
  29. let ns = parse_and_resolve(
  30. r#"
  31. contract c {
  32. function foo() public returns (uint8) {
  33. uint8[4] memory bar = [ 1, 2, 3, 4, 5 ];
  34. return bar[0];
  35. }
  36. }"#,
  37. Target::Substrate {
  38. address_length: 32,
  39. value_length: 16,
  40. },
  41. );
  42. assert_eq!(
  43. first_error(ns.diagnostics),
  44. "conversion from uint8[5] to uint8[4] not possible"
  45. );
  46. }
  47. #[test]
  48. fn const_array_array() {
  49. let mut runtime = build_solidity(
  50. r##"
  51. contract foo {
  52. int8[8] constant bar = [ int8(1), 2, 3, 4, 5, 6, 7, 8 ];
  53. function f(uint32 i1) public returns (int8) {
  54. return bar[i1];
  55. }
  56. }"##,
  57. );
  58. runtime.function("f", Val32(1).encode());
  59. assert_eq!(runtime.vm.output, Val8(2).encode());
  60. }
  61. #[test]
  62. fn votes() {
  63. #[derive(Debug, PartialEq, Encode, Decode)]
  64. struct Votes([bool; 11]);
  65. let mut runtime = build_solidity(
  66. r##"
  67. contract foo {
  68. /// In a jury, do the ayes have it?
  69. function f(bool[11] votes) public pure returns (bool) {
  70. uint32 i;
  71. uint32 ayes = 0;
  72. for (i=0; i<votes.length; i++) {
  73. if (votes[i]) {
  74. ayes += 1;
  75. }
  76. }
  77. return ayes > votes.length / 2;
  78. }
  79. }"##,
  80. );
  81. runtime.function(
  82. "f",
  83. Votes([
  84. true, true, true, true, true, true, false, false, false, false, false,
  85. ])
  86. .encode(),
  87. );
  88. assert_eq!(runtime.vm.output, true.encode());
  89. runtime.function(
  90. "f",
  91. Votes([
  92. true, true, true, true, true, false, false, false, false, false, false,
  93. ])
  94. .encode(),
  95. );
  96. assert_eq!(runtime.vm.output, false.encode());
  97. }
  98. #[test]
  99. fn return_array() {
  100. #[derive(Debug, PartialEq, Encode, Decode)]
  101. struct Res([u64; 4]);
  102. let mut runtime = build_solidity(
  103. r##"
  104. contract foo {
  105. function array() pure public returns (int64[4]) {
  106. return [ int64(4), 84564, 31213, 1312 ];
  107. }
  108. }"##,
  109. );
  110. runtime.function("array", Vec::new());
  111. assert_eq!(runtime.vm.output, Res([4, 84564, 31213, 1312]).encode());
  112. }
  113. #[test]
  114. fn storage_arrays() {
  115. #[derive(Debug, PartialEq, Encode, Decode)]
  116. struct Val(i32);
  117. #[derive(Debug, PartialEq, Encode, Decode)]
  118. struct SetArg(u64, i32);
  119. #[derive(Debug, PartialEq, Encode, Decode)]
  120. struct GetArg(u64);
  121. let mut runtime = build_solidity(
  122. r##"
  123. contract foo {
  124. int32[8589934592] bigarray;
  125. function set(uint64 index, int32 val) public {
  126. bigarray[index] = val;
  127. }
  128. function get(uint64 index) public returns (int32) {
  129. return bigarray[index];
  130. }
  131. }"##,
  132. );
  133. let mut rng = rand::thread_rng();
  134. let mut vals = Vec::new();
  135. for _ in 0..100 {
  136. let index = rng.gen::<u64>() % 0x200_0000;
  137. let val = rng.gen::<i32>();
  138. runtime.function("set", SetArg(index, val).encode());
  139. vals.push((index, val));
  140. }
  141. for val in vals {
  142. runtime.function("get", GetArg(val.0).encode());
  143. assert_eq!(runtime.vm.output, Val(val.1).encode());
  144. }
  145. }
  146. #[test]
  147. fn enum_arrays() {
  148. #[derive(Encode, Decode)]
  149. struct Arg([u8; 100]);
  150. #[derive(Debug, PartialEq, Encode, Decode)]
  151. struct Ret(u32);
  152. let mut runtime = build_solidity(
  153. r##"
  154. contract enum_array {
  155. enum Foo { Bar1, Bar2, Bar3, Bar4 }
  156. function count_bar2(Foo[100] calldata foos) public returns (uint32) {
  157. uint32 count = 0;
  158. uint32 i;
  159. for (i = 0; i < foos.length; i++) {
  160. if (foos[i] == Foo.Bar2) {
  161. count++;
  162. }
  163. }
  164. return count;
  165. }
  166. }"##,
  167. );
  168. let mut rng = rand::thread_rng();
  169. let mut a = [0u8; 100];
  170. let mut count = 0;
  171. #[allow(clippy::needless_range_loop)]
  172. for i in 0..a.len() {
  173. a[i] = rng.gen::<u8>() % 4;
  174. if a[i] == 1 {
  175. count += 1;
  176. }
  177. }
  178. runtime.function("count_bar2", Arg(a).encode());
  179. assert_eq!(runtime.vm.output, Ret(count).encode());
  180. }
  181. #[test]
  182. fn data_locations() {
  183. let ns = parse_and_resolve(
  184. r#"
  185. contract foo {
  186. function bar(uint storage) public returns () {
  187. }
  188. }"#,
  189. Target::Substrate {
  190. address_length: 32,
  191. value_length: 16,
  192. },
  193. );
  194. assert_eq!(
  195. first_error(ns.diagnostics),
  196. "data location ‘storage’ can only be specified for array, struct or mapping"
  197. );
  198. let ns = parse_and_resolve(
  199. r#"
  200. contract foo {
  201. function bar(uint calldata x) public returns () {
  202. }
  203. }"#,
  204. Target::Substrate {
  205. address_length: 32,
  206. value_length: 16,
  207. },
  208. );
  209. assert_eq!(
  210. first_error(ns.diagnostics),
  211. "data location ‘calldata’ can only be specified for array, struct or mapping"
  212. );
  213. let ns = parse_and_resolve(
  214. r#"
  215. contract foo {
  216. enum foo2 { bar1, bar2 }
  217. function bar(foo2 memory x) public returns () {
  218. }
  219. }"#,
  220. Target::Substrate {
  221. address_length: 32,
  222. value_length: 16,
  223. },
  224. );
  225. assert_eq!(
  226. first_error(ns.diagnostics),
  227. "data location ‘memory’ can only be specified for array, struct or mapping"
  228. );
  229. let ns = parse_and_resolve(
  230. r#"
  231. contract foo {
  232. enum foo2 { bar1, bar2 }
  233. function bar(foo2 x) public returns (uint calldata) {
  234. }
  235. }"#,
  236. Target::Substrate {
  237. address_length: 32,
  238. value_length: 16,
  239. },
  240. );
  241. assert_eq!(
  242. first_error(ns.diagnostics),
  243. "data location ‘calldata’ can only be specified for array, struct or mapping"
  244. );
  245. let ns = parse_and_resolve(
  246. r#"
  247. contract foo {
  248. enum foo2 { bar1, bar2 }
  249. function bar(foo2 x) public returns (bool calldata) {
  250. }
  251. }"#,
  252. Target::Substrate {
  253. address_length: 32,
  254. value_length: 16,
  255. },
  256. );
  257. assert_eq!(
  258. first_error(ns.diagnostics),
  259. "data location ‘calldata’ can only be specified for array, struct or mapping"
  260. );
  261. let ns = parse_and_resolve(
  262. r#"
  263. contract foo {
  264. enum foo2 { bar1, bar2 }
  265. function bar(foo2 x) public returns (int storage) {
  266. }
  267. }"#,
  268. Target::Substrate {
  269. address_length: 32,
  270. value_length: 16,
  271. },
  272. );
  273. assert_eq!(
  274. first_error(ns.diagnostics),
  275. "data location ‘storage’ can only be specified for array, struct or mapping"
  276. );
  277. let ns = parse_and_resolve(
  278. r#"
  279. contract foo {
  280. enum foo2 { bar1, bar2 }
  281. function bar(int[10] storage x) public returns (int) {
  282. }
  283. }"#,
  284. Target::Substrate {
  285. address_length: 32,
  286. value_length: 16,
  287. },
  288. );
  289. assert_eq!(
  290. first_error(ns.diagnostics),
  291. "parameter of type ‘storage’ not allowed public or external functions"
  292. );
  293. let ns = parse_and_resolve(
  294. r#"
  295. contract foo {
  296. enum foo2 { bar1, bar2 }
  297. function bar() public returns (int[10] storage x) {
  298. }
  299. }"#,
  300. Target::Substrate {
  301. address_length: 32,
  302. value_length: 16,
  303. },
  304. );
  305. assert_eq!(
  306. first_error(ns.diagnostics),
  307. "return type of type ‘storage’ not allowed public or external functions"
  308. );
  309. let ns = parse_and_resolve(
  310. r#"
  311. contract foo {
  312. enum foo2 { bar1, bar2 }
  313. function bar() public returns (foo2[10] storage x) {
  314. }
  315. }"#,
  316. Target::Substrate {
  317. address_length: 32,
  318. value_length: 16,
  319. },
  320. );
  321. assert_eq!(
  322. first_error(ns.diagnostics),
  323. "return type of type ‘storage’ not allowed public or external functions"
  324. );
  325. }
  326. #[test]
  327. fn storage_ref_arg() {
  328. let mut runtime = build_solidity(
  329. r##"
  330. contract storage_refs {
  331. int32[10] a;
  332. int32[10] b;
  333. function set(int32[10] storage array, uint8 index, int32 val) private {
  334. array[index] = val;
  335. }
  336. function test() public {
  337. set(a, 2, 5);
  338. set(b, 2, 102);
  339. assert(a[2] == 5);
  340. assert(b[2] == 102);
  341. }
  342. }"##,
  343. );
  344. runtime.function("test", Vec::new());
  345. }
  346. #[test]
  347. fn storage_ref_var() {
  348. let mut runtime = build_solidity(
  349. r##"
  350. contract storage_refs {
  351. int32[10] a;
  352. int32[10] b;
  353. function set(int32[10] storage array, uint8 index, int32 val) private {
  354. array[index] = val;
  355. }
  356. function test() public {
  357. int32[10] storage ref = a;
  358. set(ref, 2, 5);
  359. ref = b;
  360. set(ref, 2, 102);
  361. assert(a[2] == 5);
  362. assert(b[2] == 102);
  363. }
  364. }"##,
  365. );
  366. runtime.function("test", Vec::new());
  367. }
  368. #[test]
  369. fn storage_ref_returns() {
  370. let mut runtime = build_solidity(
  371. r##"
  372. contract storage_refs {
  373. int32[10] a;
  374. int32[10] b;
  375. function a_or_b(bool want_a) private returns (int32[10] storage) {
  376. if (want_a) {
  377. return a;
  378. }
  379. return b;
  380. }
  381. function set(int32[10] storage array, uint8 index, int32 val) private {
  382. array[index] = val;
  383. }
  384. function test() public {
  385. int32[10] storage ref = a_or_b(true);
  386. set(ref, 2, 5);
  387. ref = a_or_b(false);
  388. set(ref, 2, 102);
  389. assert(a[2] == 5);
  390. assert(b[2] == 102);
  391. }
  392. }"##,
  393. );
  394. runtime.function("test", Vec::new());
  395. }
  396. #[test]
  397. fn storage_to_memory() {
  398. #[derive(Debug, PartialEq, Encode, Decode)]
  399. struct Ret([u32; 10]);
  400. let mut runtime = build_solidity(
  401. r##"
  402. contract storage_refs {
  403. uint32[10] a;
  404. function test() public returns (uint32[10]) {
  405. for (uint32 i = 0; i < 10; ) {
  406. uint32 index = i;
  407. a[index] = 7 * ++i;
  408. }
  409. return a;
  410. }
  411. }"##,
  412. );
  413. runtime.function("test", Vec::new());
  414. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  415. assert_eq!(runtime.vm.output, val.encode());
  416. }
  417. #[test]
  418. fn memory_to_storage() {
  419. #[derive(Debug, PartialEq, Encode, Decode)]
  420. struct Ret([u32; 10]);
  421. let mut runtime = build_solidity(
  422. r##"
  423. contract storage_refs {
  424. int32[10] a;
  425. function test() public returns (int32[10]) {
  426. int32[10] b = [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 70 ];
  427. a = b;
  428. return a;
  429. }
  430. }"##,
  431. );
  432. runtime.function("test", Vec::new());
  433. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  434. assert_eq!(runtime.vm.output, val.encode());
  435. }
  436. #[test]
  437. fn array_dimensions() {
  438. let ns = parse_and_resolve(
  439. r#"
  440. contract foo {
  441. bool[10 - 10] x;
  442. }"#,
  443. Target::Substrate {
  444. address_length: 32,
  445. value_length: 16,
  446. },
  447. );
  448. assert_eq!(first_error(ns.diagnostics), "zero size array not permitted");
  449. let ns = parse_and_resolve(
  450. r#"
  451. contract foo {
  452. bool[-10 + 10] x;
  453. }"#,
  454. Target::Substrate {
  455. address_length: 32,
  456. value_length: 16,
  457. },
  458. );
  459. assert_eq!(
  460. first_error(ns.diagnostics),
  461. "negative literal -10 not allowed for unsigned type ‘uint256’"
  462. );
  463. let ns = parse_and_resolve(
  464. r#"
  465. contract foo {
  466. bool[1 / 10] x;
  467. }"#,
  468. Target::Substrate {
  469. address_length: 32,
  470. value_length: 16,
  471. },
  472. );
  473. assert_eq!(first_error(ns.diagnostics), "zero size array not permitted");
  474. let ns = parse_and_resolve(
  475. r#"
  476. contract foo {
  477. enum e { e1, e2, e3 }
  478. e[1 / 0] x;
  479. }"#,
  480. Target::Substrate {
  481. address_length: 32,
  482. value_length: 16,
  483. },
  484. );
  485. assert_eq!(first_error(ns.diagnostics), "divide by zero");
  486. let ns = parse_and_resolve(
  487. r#"
  488. contract foo {
  489. struct bar {
  490. int32 x;
  491. }
  492. bar[1 % 0] x;
  493. }"#,
  494. Target::Substrate {
  495. address_length: 32,
  496. value_length: 16,
  497. },
  498. );
  499. assert_eq!(first_error(ns.diagnostics), "divide by zero");
  500. let mut runtime = build_solidity(
  501. r##"
  502. contract storage_refs {
  503. int32[2**16] a;
  504. function test() public {
  505. assert(a.length == 65536);
  506. }
  507. }"##,
  508. );
  509. runtime.function("test", Vec::new());
  510. }
  511. #[test]
  512. fn array_in_struct() {
  513. #[derive(Debug, PartialEq, Encode, Decode)]
  514. struct Ret([u32; 10]);
  515. let mut runtime = build_solidity(
  516. r##"
  517. contract storage_refs {
  518. struct foo {
  519. int32[10] f1;
  520. }
  521. function test() public returns (int32[10]) {
  522. foo a = foo({f1: [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 0 ]});
  523. assert(a.f1[1] == 14);
  524. a.f1[9] = 70;
  525. return a.f1;
  526. }
  527. }"##,
  528. );
  529. runtime.function("test", Vec::new());
  530. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  531. assert_eq!(runtime.vm.output, val.encode());
  532. }
  533. #[test]
  534. fn struct_in_array() {
  535. #[derive(Debug, PartialEq, Encode, Decode)]
  536. struct S(u64, bool);
  537. let mut runtime = build_solidity(
  538. r##"
  539. struct S {
  540. uint64 f1;
  541. bool f2;
  542. }
  543. contract foo {
  544. S[] store;
  545. function set(S[] memory n) public {
  546. store = n;
  547. }
  548. function copy() public returns (S[] memory) {
  549. return store;
  550. }
  551. }"##,
  552. );
  553. let val = vec![S(102, true), S(u64::MAX, false)];
  554. runtime.function("set", val.encode());
  555. runtime.function("copy", vec![]);
  556. assert_eq!(runtime.vm.output, val.encode());
  557. }
  558. #[test]
  559. fn struct_in_fixed_array() {
  560. #[derive(Debug, PartialEq, Encode, Decode)]
  561. struct S(u64, bool);
  562. let mut runtime = build_solidity(
  563. r##"
  564. struct S {
  565. uint64 f1;
  566. bool f2;
  567. }
  568. contract foo {
  569. S[2] store;
  570. function set(S[2] memory n) public {
  571. store = n;
  572. }
  573. function copy() public returns (S[2] memory) {
  574. return store;
  575. }
  576. }"##,
  577. );
  578. let val = [S(102, true), S(u64::MAX, false)];
  579. runtime.function("set", val.encode());
  580. runtime.function("copy", vec![]);
  581. assert_eq!(runtime.vm.output, val.encode());
  582. }
  583. #[test]
  584. fn struct_array_struct() {
  585. let mut runtime = build_solidity(
  586. r##"
  587. contract flipper {
  588. struct bool_struct {
  589. bool foo_bool;
  590. }
  591. struct struct_bool_struct_array {
  592. bool_struct[1] foo_struct_array;
  593. }
  594. function get_memory() public pure returns (bool) {
  595. bool_struct memory foo = bool_struct({foo_bool: true});
  596. bool_struct[1] memory foo_array = [foo];
  597. struct_bool_struct_array memory foo_struct = struct_bool_struct_array({foo_struct_array: foo_array});
  598. /* return foo_array[0].foo_bool; */
  599. return foo_struct.foo_struct_array[0].foo_bool;
  600. }
  601. }"##,
  602. );
  603. runtime.function("get_memory", Vec::new());
  604. assert_eq!(runtime.vm.output, true.encode());
  605. }
  606. #[test]
  607. fn struct_array_struct_abi() {
  608. #[derive(Debug, PartialEq, Encode, Decode)]
  609. struct Foo {
  610. f1: u32,
  611. f2: bool,
  612. }
  613. #[derive(Debug, PartialEq, Encode, Decode)]
  614. struct Bar {
  615. bars: [Foo; 10],
  616. }
  617. let mut runtime = build_solidity(
  618. r##"
  619. contract flipper {
  620. struct foo {
  621. int32 f1;
  622. bool f2;
  623. }
  624. struct bar {
  625. foo[10] bars;
  626. }
  627. bar s;
  628. function get_bar() public returns (bar) {
  629. bar memory a = bar({ bars: [
  630. foo({ f1: 1, f2: true}),
  631. foo({ f1: 2, f2: true}),
  632. foo({ f1: 3, f2: true}),
  633. foo({ f1: 4, f2: true}),
  634. foo({ f1: 5, f2: true}),
  635. foo({ f1: 6, f2: true}),
  636. foo({ f1: 7, f2: false}),
  637. foo({ f1: 8, f2: true}),
  638. foo({ f1: 9, f2: true}),
  639. foo({ f1: 10, f2: true})
  640. ]});
  641. s = a;
  642. return a;
  643. }
  644. function set_bar(bar memory a) public {
  645. for (uint32 i = 0; i < 10; i++) {
  646. assert(a.bars[i].f1 == i + 1);
  647. assert(a.bars[i].f2 == (i != 6));
  648. }
  649. a = s;
  650. }
  651. }"##,
  652. );
  653. let b = Bar {
  654. bars: [
  655. Foo { f1: 1, f2: true },
  656. Foo { f1: 2, f2: true },
  657. Foo { f1: 3, f2: true },
  658. Foo { f1: 4, f2: true },
  659. Foo { f1: 5, f2: true },
  660. Foo { f1: 6, f2: true },
  661. Foo { f1: 7, f2: false },
  662. Foo { f1: 8, f2: true },
  663. Foo { f1: 9, f2: true },
  664. Foo { f1: 10, f2: true },
  665. ],
  666. };
  667. runtime.function("get_bar", Vec::new());
  668. assert_eq!(runtime.vm.output, b.encode());
  669. runtime.function("set_bar", b.encode());
  670. }
  671. #[test]
  672. fn memory_dynamic_array_new() {
  673. let ns = parse_and_resolve(
  674. r#"
  675. contract foo {
  676. function test() public {
  677. int32[] memory a = new int32[]();
  678. assert(a.length == 5);
  679. }
  680. }"#,
  681. Target::Substrate {
  682. address_length: 32,
  683. value_length: 16,
  684. },
  685. );
  686. assert_eq!(
  687. first_error(ns.diagnostics),
  688. "new dynamic array should have a single length argument"
  689. );
  690. let ns = parse_and_resolve(
  691. r#"
  692. contract foo {
  693. function test() public {
  694. int32[] memory a = new int32[](1, 2);
  695. assert(a.length == 5);
  696. }
  697. }"#,
  698. Target::Substrate {
  699. address_length: 32,
  700. value_length: 16,
  701. },
  702. );
  703. assert_eq!(
  704. first_error(ns.diagnostics),
  705. "new dynamic array should have a single length argument"
  706. );
  707. let ns = parse_and_resolve(
  708. r#"
  709. contract foo {
  710. function test() public {
  711. int32[] memory a = new int32[](hex"ab");
  712. assert(a.length == 5);
  713. }
  714. }"#,
  715. Target::Substrate {
  716. address_length: 32,
  717. value_length: 16,
  718. },
  719. );
  720. assert_eq!(
  721. first_error(ns.diagnostics),
  722. "implicit conversion to uint32 from bytes1 not allowed"
  723. );
  724. let ns = parse_and_resolve(
  725. r#"
  726. contract foo {
  727. function test() public {
  728. int32[] memory a = new int32[](-1);
  729. assert(a.length == 5);
  730. }
  731. }"#,
  732. Target::Substrate {
  733. address_length: 32,
  734. value_length: 16,
  735. },
  736. );
  737. assert_eq!(
  738. first_error(ns.diagnostics),
  739. "negative literal -1 not allowed for unsigned type ‘uint32’"
  740. );
  741. let ns = parse_and_resolve(
  742. r#"
  743. contract foo {
  744. function test() public {
  745. int32[] memory a = new bool(1);
  746. assert(a.length == 5);
  747. }
  748. }"#,
  749. Target::Substrate {
  750. address_length: 32,
  751. value_length: 16,
  752. },
  753. );
  754. assert_eq!(
  755. first_error(ns.diagnostics),
  756. "new cannot allocate type ‘bool’"
  757. );
  758. let mut runtime = build_solidity(
  759. r#"
  760. contract foo {
  761. function test() public {
  762. int32[] memory a = new int32[](5);
  763. assert(a.length == 5);
  764. }
  765. }"#,
  766. );
  767. runtime.function("test", Vec::new());
  768. // The Ethereum Foundation solc allows you to create arrays of length 0
  769. let mut runtime = build_solidity(
  770. r#"
  771. contract foo {
  772. function test() public {
  773. bool[] memory a = new bool[](0);
  774. assert(a.length == 0);
  775. }
  776. }"#,
  777. );
  778. runtime.function("test", Vec::new());
  779. }
  780. #[test]
  781. fn memory_dynamic_array_deref() {
  782. let ns = parse_and_resolve(
  783. r#"
  784. contract foo {
  785. function test() public {
  786. int32[] memory a = new int32[](2);
  787. a[-1] = 5;
  788. }
  789. }"#,
  790. Target::Substrate {
  791. address_length: 32,
  792. value_length: 16,
  793. },
  794. );
  795. assert_eq!(
  796. first_error(ns.diagnostics),
  797. "negative literal -1 not allowed for unsigned type ‘uint32’"
  798. );
  799. let ns = parse_and_resolve(
  800. r#"
  801. contract foo {
  802. function test() public {
  803. int32[] memory a = new int32[](2);
  804. int32 i = 1;
  805. a[i] = 5;
  806. }
  807. }"#,
  808. Target::Substrate {
  809. address_length: 32,
  810. value_length: 16,
  811. },
  812. );
  813. assert_eq!(
  814. first_error(ns.diagnostics),
  815. "array subscript must be an unsigned integer, not ‘int32’"
  816. );
  817. // The Ethereum Foundation solc allows you to create arrays of length 0
  818. let mut runtime = build_solidity(
  819. r#"
  820. contract foo {
  821. function test() public {
  822. int32[] memory a = new int32[](5);
  823. assert(a.length == 5);
  824. a[0] = 102;
  825. a[1] = -5;
  826. a[4] = 0x7cafeeed;
  827. assert(a[0] == 102);
  828. assert(a[1] == -5);
  829. assert(a[4] == 0x7cafeeed);
  830. }
  831. }"#,
  832. );
  833. runtime.function("test", Vec::new());
  834. }
  835. #[test]
  836. #[should_panic]
  837. fn array_bounds_dynamic_array() {
  838. let mut runtime = build_solidity(
  839. r#"
  840. contract foo {
  841. function test() public returns (int32) {
  842. int32[] memory a = new int32[](5);
  843. a[5] = 102;
  844. return a[3];
  845. }
  846. }"#,
  847. );
  848. runtime.function("test", Vec::new());
  849. }
  850. #[test]
  851. #[should_panic]
  852. fn empty_array_bounds_dynamic_array() {
  853. let mut runtime = build_solidity(
  854. r#"
  855. contract foo {
  856. function test() public returns (bytes32) {
  857. bytes32[] memory a = new bytes32[](0);
  858. a[0] = "yo";
  859. return a[0];
  860. }
  861. }"#,
  862. );
  863. runtime.function("test", Vec::new());
  864. }
  865. #[test]
  866. fn memory_dynamic_array_types_call_return() {
  867. let mut runtime = build_solidity(
  868. r#"
  869. contract foo {
  870. function a(bool cond) public returns (bytes27[]) {
  871. bytes27[] foo;
  872. foo = new bytes27[](5);
  873. foo[1] = "cond was true";
  874. return foo;
  875. }
  876. function b(bytes27[] x) private {
  877. x[1] = "b was called";
  878. x = new bytes27[](3);
  879. x[1] = "should not be";
  880. }
  881. function test() public {
  882. bytes27[] x = a(true);
  883. assert(x.length == 5);
  884. assert(x[1] == "cond was true");
  885. b(x);
  886. assert(x.length == 5);
  887. assert(x[1] == "b was called");
  888. }
  889. }"#,
  890. );
  891. runtime.function("test", Vec::new());
  892. }
  893. #[test]
  894. fn dynamic_arrays_need_phi_node() {
  895. let mut runtime = build_solidity(
  896. r#"
  897. pragma solidity 0;
  898. contract foo {
  899. enum bar { bar1, bar2, bar3, bar4 }
  900. function a(bool cond) public returns (bar[] memory) {
  901. bar[] memory foo;
  902. if (cond) {
  903. foo = new bar[](5);
  904. foo[1] = bar.bar2;
  905. } else {
  906. foo = new bar[](3);
  907. foo[1] = bar.bar3;
  908. }
  909. return foo;
  910. }
  911. function test() public {
  912. bar[] memory x = a(true);
  913. assert(x.length == 5);
  914. assert(x[1] == bar.bar2);
  915. x = a(false);
  916. assert(x.length == 3);
  917. assert(x[1] == bar.bar3);
  918. }
  919. }"#,
  920. );
  921. runtime.function("test", Vec::new());
  922. }
  923. // test:
  924. // alignment of array elements
  925. // arrays of other structs/arrays/darrays
  926. // nil pointer should fail
  927. // copy to/from storage <=> memory
  928. // abi encode/decode
  929. // string/bytes
  930. #[test]
  931. fn storage_dynamic_array_length() {
  932. let mut runtime = build_solidity(
  933. r#"
  934. pragma solidity 0;
  935. contract foo {
  936. int32[] bar;
  937. function test() public {
  938. assert(bar.length == 0);
  939. }
  940. }"#,
  941. );
  942. runtime.function("test", Vec::new());
  943. }
  944. #[test]
  945. fn dynamic_array_push() {
  946. let ns = parse_and_resolve(
  947. r#"
  948. contract foo {
  949. function test() public {
  950. int[] bar = new int[](2);
  951. assert(bar.length == 0);
  952. bar.push(102, 20);
  953. }
  954. }"#,
  955. Target::Substrate {
  956. address_length: 32,
  957. value_length: 16,
  958. },
  959. );
  960. assert_eq!(
  961. first_error(ns.diagnostics),
  962. "method ‘push()’ takes at most 1 argument"
  963. );
  964. let mut runtime = build_solidity(
  965. r#"
  966. pragma solidity 0;
  967. contract foo {
  968. function test() public {
  969. int[] bar = new int[](1);
  970. bar[0] = 128;
  971. bar.push(64);
  972. assert(bar.length == 2);
  973. assert(bar[1] == 64);
  974. }
  975. }
  976. "#,
  977. );
  978. runtime.function("test", Vec::new());
  979. let mut runtime = build_solidity(
  980. r#"
  981. pragma solidity 0;
  982. contract foo {
  983. function test() public {
  984. bytes bar = new bytes(1);
  985. bar[0] = 128;
  986. bar.push(64);
  987. assert(bar.length == 2);
  988. assert(bar[1] == 64);
  989. }
  990. }
  991. "#,
  992. );
  993. runtime.function("test", Vec::new());
  994. let mut runtime = build_solidity(
  995. r#"
  996. pragma solidity 0;
  997. contract foo {
  998. struct s {
  999. int32 f1;
  1000. bool f2;
  1001. }
  1002. function test() public {
  1003. s[] bar = new s[](1);
  1004. bar[0] = s({f1: 0, f2: false});
  1005. bar.push(s({f1: 1, f2: true}));
  1006. assert(bar.length == 2);
  1007. assert(bar[1].f1 == 1);
  1008. assert(bar[1].f2 == true);
  1009. }
  1010. }
  1011. "#,
  1012. );
  1013. runtime.function("test", Vec::new());
  1014. let mut runtime = build_solidity(
  1015. r#"
  1016. pragma solidity 0;
  1017. contract foo {
  1018. enum enum1 { val1, val2, val3 }
  1019. function test() public {
  1020. enum1[] bar = new enum1[](1);
  1021. bar[0] = enum1.val1;
  1022. bar.push(enum1.val2);
  1023. assert(bar.length == 2);
  1024. assert(bar[1] == enum1.val2);
  1025. }
  1026. }
  1027. "#,
  1028. );
  1029. runtime.function("test", Vec::new());
  1030. // push() returns a reference to the thing
  1031. let mut runtime = build_solidity(
  1032. r#"
  1033. pragma solidity 0;
  1034. contract foo {
  1035. struct s {
  1036. int32 f1;
  1037. bool f2;
  1038. }
  1039. function test() public {
  1040. s[] bar = new s[](0);
  1041. s memory n = bar.push();
  1042. n.f1 = 102;
  1043. n.f2 = true;
  1044. assert(bar[0].f1 == 102);
  1045. assert(bar[0].f2 == true);
  1046. }
  1047. }"#,
  1048. );
  1049. runtime.function("test", Vec::new());
  1050. }
  1051. #[test]
  1052. fn dynamic_array_pop() {
  1053. let ns = parse_and_resolve(
  1054. r#"
  1055. contract foo {
  1056. function test() public {
  1057. int[] bar = new int[](1);
  1058. bar.pop(102);
  1059. }
  1060. }"#,
  1061. Target::Substrate {
  1062. address_length: 32,
  1063. value_length: 16,
  1064. },
  1065. );
  1066. assert_eq!(
  1067. first_error(ns.diagnostics),
  1068. "method ‘pop()’ does not take any arguments"
  1069. );
  1070. let mut runtime = build_solidity(
  1071. r#"
  1072. pragma solidity 0;
  1073. contract foo {
  1074. function test() public {
  1075. int[] bar = new int[](1);
  1076. bar[0] = 128;
  1077. assert(bar.length == 1);
  1078. assert(128 == bar.pop());
  1079. assert(bar.length == 0);
  1080. }
  1081. }
  1082. "#,
  1083. );
  1084. runtime.function("test", Vec::new());
  1085. let mut runtime = build_solidity(
  1086. r#"
  1087. pragma solidity 0;
  1088. contract foo {
  1089. function test() public {
  1090. bytes bar = new bytes(1);
  1091. bar[0] = 128;
  1092. assert(bar.length == 1);
  1093. assert(128 == bar.pop());
  1094. assert(bar.length == 0);
  1095. }
  1096. }
  1097. "#,
  1098. );
  1099. runtime.function("test", Vec::new());
  1100. let mut runtime = build_solidity(
  1101. r#"
  1102. pragma solidity 0;
  1103. contract foo {
  1104. struct s {
  1105. int32 f1;
  1106. bool f2;
  1107. }
  1108. function test() public {
  1109. s[] bar = new s[](1);
  1110. bar[0] = s(128, true);
  1111. assert(bar.length == 1);
  1112. s baz = bar.pop();
  1113. assert(baz.f1 == 128);
  1114. assert(baz.f2 == true);
  1115. assert(bar.length == 0);
  1116. }
  1117. }
  1118. "#,
  1119. );
  1120. runtime.function("test", Vec::new());
  1121. let mut runtime = build_solidity(
  1122. r#"
  1123. pragma solidity 0;
  1124. contract foo {
  1125. enum enum1 { val1, val2, val3 }
  1126. function test() public {
  1127. enum1[] bar = new enum1[](1);
  1128. bar[0] = enum1.val2;
  1129. assert(bar.length == 1);
  1130. assert(enum1.val2 == bar.pop());
  1131. assert(bar.length == 0);
  1132. }
  1133. }
  1134. "#,
  1135. );
  1136. runtime.function("test", Vec::new());
  1137. }
  1138. #[test]
  1139. #[should_panic]
  1140. fn dynamic_array_pop_empty_array() {
  1141. let mut runtime = build_solidity(
  1142. r#"
  1143. pragma solidity 0;
  1144. contract foo {
  1145. function test() public {
  1146. int[] bar = new int[](0);
  1147. bar.pop();
  1148. }
  1149. }"#,
  1150. );
  1151. runtime.function("test", Vec::new());
  1152. }
  1153. #[test]
  1154. #[should_panic]
  1155. fn dynamic_array_pop_bounds() {
  1156. let mut runtime = build_solidity(
  1157. r#"
  1158. pragma solidity 0;
  1159. contract foo {
  1160. function test() public {
  1161. int[] bar = new int[](1);
  1162. bar[0] = 12;
  1163. bar.pop();
  1164. assert(bar[0] == 12);
  1165. }
  1166. }"#,
  1167. );
  1168. runtime.function("test", Vec::new());
  1169. }
  1170. #[test]
  1171. fn storage_dynamic_array_push() {
  1172. let ns = parse_and_resolve(
  1173. r#"
  1174. contract foo {
  1175. int32[] bar;
  1176. function test() public {
  1177. assert(bar.length == 0);
  1178. bar.push(102, 20);
  1179. }
  1180. }"#,
  1181. Target::Substrate {
  1182. address_length: 32,
  1183. value_length: 16,
  1184. },
  1185. );
  1186. assert_eq!(
  1187. first_error(ns.diagnostics),
  1188. "method ‘push()’ takes at most 1 argument"
  1189. );
  1190. let ns = parse_and_resolve(
  1191. r#"
  1192. contract foo {
  1193. int32[4] bar;
  1194. function test() public {
  1195. bar.push(102);
  1196. }
  1197. }"#,
  1198. Target::Substrate {
  1199. address_length: 32,
  1200. value_length: 16,
  1201. },
  1202. );
  1203. assert_eq!(
  1204. first_error(ns.diagnostics),
  1205. "method ‘push()’ not allowed on fixed length array"
  1206. );
  1207. let mut runtime = build_solidity(
  1208. r#"
  1209. pragma solidity 0;
  1210. contract foo {
  1211. int32[] bar;
  1212. function test() public {
  1213. assert(bar.length == 0);
  1214. bar.push(102);
  1215. assert(bar[0] == 102);
  1216. assert(bar.length == 1);
  1217. bar.push();
  1218. assert(bar[1] == 0);
  1219. assert(bar.length == 2);
  1220. }
  1221. }"#,
  1222. );
  1223. runtime.function("test", Vec::new());
  1224. // push() returns a reference to the thing
  1225. let mut runtime = build_solidity(
  1226. r#"
  1227. pragma solidity 0;
  1228. contract foo {
  1229. struct s {
  1230. int32 f1;
  1231. bool f2;
  1232. }
  1233. s[] bar;
  1234. function test() public {
  1235. s storage n = bar.push();
  1236. n.f1 = 102;
  1237. n.f2 = true;
  1238. assert(bar[0].f1 == 102);
  1239. }
  1240. }"#,
  1241. );
  1242. runtime.function("test", Vec::new());
  1243. let ns = parse_and_resolve(
  1244. r#"
  1245. contract foo {
  1246. struct s {
  1247. int32 f1;
  1248. bool f2;
  1249. }
  1250. s[] bar;
  1251. function test() public {
  1252. s storage n = bar.push(s(-1, false));
  1253. }
  1254. }"#,
  1255. Target::Substrate {
  1256. address_length: 32,
  1257. value_length: 16,
  1258. },
  1259. );
  1260. assert_eq!(
  1261. first_error(ns.diagnostics),
  1262. "function or method does not return a value"
  1263. );
  1264. }
  1265. #[test]
  1266. fn storage_dynamic_array_pop() {
  1267. let ns = parse_and_resolve(
  1268. r#"
  1269. contract foo {
  1270. int32[] bar;
  1271. function test() public {
  1272. assert(bar.length == 0);
  1273. bar.pop(102);
  1274. }
  1275. }"#,
  1276. Target::Substrate {
  1277. address_length: 32,
  1278. value_length: 16,
  1279. },
  1280. );
  1281. assert_eq!(
  1282. first_error(ns.diagnostics),
  1283. "method ‘pop()’ does not take any arguments"
  1284. );
  1285. let ns = parse_and_resolve(
  1286. r#"
  1287. contract foo {
  1288. int32[4] bar;
  1289. function test() public {
  1290. bar.pop();
  1291. }
  1292. }"#,
  1293. Target::Substrate {
  1294. address_length: 32,
  1295. value_length: 16,
  1296. },
  1297. );
  1298. assert_eq!(
  1299. first_error(ns.diagnostics),
  1300. "method ‘pop()’ not allowed on fixed length array"
  1301. );
  1302. let mut runtime = build_solidity(
  1303. r#"
  1304. pragma solidity 0;
  1305. contract foo {
  1306. int32[] bar;
  1307. function test() public {
  1308. assert(bar.length == 0);
  1309. bar.push(102);
  1310. assert(bar[0] == 102);
  1311. assert(bar.length == 1);
  1312. int32 v = bar.pop();
  1313. assert(bar.length == 0);
  1314. assert(v == 102);
  1315. }
  1316. }"#,
  1317. );
  1318. runtime.function("test", Vec::new());
  1319. // We should have one entry for the length; pop should have removed the 102 entry
  1320. assert_eq!(runtime.store.len(), 1);
  1321. // ensure that structs and fixed arrays are wiped by pop
  1322. let mut runtime = build_solidity(
  1323. r#"
  1324. pragma solidity 0;
  1325. contract foo {
  1326. enum enum1 { val1, val2, val3 }
  1327. struct s {
  1328. bool f1;
  1329. bytes3 f2;
  1330. enum1 f3;
  1331. uint64 f4;
  1332. int64[2] f5;
  1333. }
  1334. s[] bar;
  1335. function test() public {
  1336. s storage first = bar.push();
  1337. first.f1 = true;
  1338. first.f2 = "abc";
  1339. first.f3 = enum1.val2;
  1340. first.f4 = 65536;
  1341. first.f5[0] = -1;
  1342. first.f5[1] = 5;
  1343. assert(bar[0].f5[1] == 5);
  1344. // now erase it again
  1345. bar.pop();
  1346. }
  1347. }"#,
  1348. );
  1349. runtime.function("test", Vec::new());
  1350. // We should have one entry for the length; pop should have removed the 102 entry
  1351. assert_eq!(runtime.store.len(), 1);
  1352. // pop returns the dereferenced value, not a reference to storage
  1353. let ns = parse_and_resolve(
  1354. r#"
  1355. contract foo {
  1356. struct s {
  1357. bool f1;
  1358. int32 f2;
  1359. }
  1360. s[] bar;
  1361. function test() public {
  1362. s storage x = bar.pop();
  1363. }
  1364. }"#,
  1365. Target::Substrate {
  1366. address_length: 32,
  1367. value_length: 16,
  1368. },
  1369. );
  1370. assert_eq!(
  1371. first_error(ns.diagnostics),
  1372. "conversion from struct foo.s to struct foo.s storage not possible"
  1373. );
  1374. }
  1375. #[test]
  1376. fn storage_delete() {
  1377. let ns = parse_and_resolve(
  1378. r#"
  1379. contract foo {
  1380. int32[] bar;
  1381. function test() public {
  1382. delete 102;
  1383. }
  1384. }"#,
  1385. Target::Substrate {
  1386. address_length: 32,
  1387. value_length: 16,
  1388. },
  1389. );
  1390. assert_eq!(
  1391. first_error(ns.diagnostics),
  1392. "argument to ‘delete’ should be storage reference"
  1393. );
  1394. let ns = parse_and_resolve(
  1395. r#"
  1396. contract foo {
  1397. int32[] bar;
  1398. function test() public {
  1399. int32 x = delete bar;
  1400. }
  1401. }"#,
  1402. Target::Substrate {
  1403. address_length: 32,
  1404. value_length: 16,
  1405. },
  1406. );
  1407. assert_eq!(
  1408. first_error(ns.diagnostics),
  1409. "delete not allowed in expression"
  1410. );
  1411. // ensure that structs and fixed arrays are wiped by pop
  1412. let mut runtime = build_solidity(
  1413. r#"
  1414. pragma solidity 0;
  1415. contract foo {
  1416. uint64 bar;
  1417. function test() public {
  1418. bar = 0xdeaddeaddeaddead;
  1419. delete bar;
  1420. }
  1421. }"#,
  1422. );
  1423. runtime.function("test", Vec::new());
  1424. // We should have one entry for the length; pop should have removed the 102 entry
  1425. assert!(runtime.store.is_empty());
  1426. // ensure that structs and fixed arrays are wiped by delete
  1427. let mut runtime = build_solidity(
  1428. r#"
  1429. pragma solidity 0;
  1430. contract foo {
  1431. enum enum1 { val1, val2, val3 }
  1432. struct s {
  1433. bool f1;
  1434. bytes3 f2;
  1435. enum1 f3;
  1436. uint64 f4;
  1437. int64[2] f5;
  1438. }
  1439. s[] bar;
  1440. function test() public {
  1441. s storage first = bar.push();
  1442. first.f1 = true;
  1443. first.f2 = "abc";
  1444. first.f3 = enum1.val2;
  1445. first.f4 = 65536;
  1446. first.f5[0] = -1;
  1447. first.f5[1] = 5;
  1448. assert(bar[0].f5[1] == 5);
  1449. // now erase it again
  1450. delete bar[0];
  1451. }
  1452. }"#,
  1453. );
  1454. runtime.function("test", Vec::new());
  1455. // We should have one entry for the length; delete should have removed the entry
  1456. assert_eq!(runtime.store.len(), 1);
  1457. // ensure that structs and fixed arrays are wiped by delete
  1458. let mut runtime = build_solidity(
  1459. r#"
  1460. pragma solidity 0;
  1461. contract foo {
  1462. int[] bar;
  1463. function setup() public {
  1464. bar.push(102);
  1465. bar.push(305);
  1466. }
  1467. function clear() public {
  1468. delete bar;
  1469. }
  1470. }"#,
  1471. );
  1472. runtime.function("setup", Vec::new());
  1473. assert_eq!(runtime.store.len(), 3);
  1474. runtime.function("clear", Vec::new());
  1475. assert_eq!(runtime.store.len(), 0);
  1476. // our delete operator has to iterate over the dynamic array. Ensure it works if the array is empty
  1477. runtime.function("clear", Vec::new());
  1478. assert_eq!(runtime.store.len(), 0);
  1479. }
  1480. #[test]
  1481. fn storage_dynamic_copy() {
  1482. let mut runtime = build_solidity(
  1483. r#"
  1484. contract c {
  1485. int32[] foo;
  1486. constructor() public {
  1487. for (int32 i = 0; i <11; i++) {
  1488. foo.push(i * 3);
  1489. }
  1490. }
  1491. function storage_to_memory() view public {
  1492. int32[] memory bar = foo;
  1493. assert(bar.length == 11);
  1494. for (int32 i = 0; i <11; i++) {
  1495. assert(bar[uint32(i)] == i * 3);
  1496. }
  1497. }
  1498. function memory_to_storage() public {
  1499. int32[] memory bar = new int32[](5);
  1500. for (int32 i = 0; i < 5; i++) {
  1501. bar[uint32(i)] = 5 * (i + 7);
  1502. }
  1503. foo = bar;
  1504. assert(foo.length == 5);
  1505. for (int32 i = 0; i < 5; i++) {
  1506. assert(foo[uint32(i)] == 5 * (i + 7));
  1507. }
  1508. }
  1509. }
  1510. "#,
  1511. );
  1512. runtime.constructor(0, Vec::new());
  1513. runtime.function("storage_to_memory", Vec::new());
  1514. runtime.function("memory_to_storage", Vec::new());
  1515. assert_eq!(runtime.store.len(), 6);
  1516. }
  1517. #[test]
  1518. fn abi_encode_dynamic_array() {
  1519. #[derive(Debug, PartialEq, Encode, Decode)]
  1520. struct Int32Array(Vec<i32>);
  1521. let mut runtime = build_solidity(
  1522. r#"
  1523. contract c {
  1524. function encode() pure public returns (int32[]) {
  1525. int32[] memory bar = new int32[](11);
  1526. for (int32 i = 0; i <11; i++) {
  1527. bar[uint32(i)] = i * 3;
  1528. }
  1529. return bar;
  1530. }
  1531. }
  1532. "#,
  1533. );
  1534. runtime.constructor(0, Vec::new());
  1535. runtime.function("encode", Vec::new());
  1536. assert_eq!(
  1537. runtime.vm.output,
  1538. Int32Array(vec!(0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30)).encode()
  1539. );
  1540. }
  1541. #[test]
  1542. fn abi_decode_dynamic_array() {
  1543. #[derive(Debug, PartialEq, Encode, Decode)]
  1544. struct Int32Array(Vec<i32>);
  1545. let mut runtime = build_solidity(
  1546. r#"
  1547. contract c {
  1548. function decode(int32[] bar) pure public {
  1549. assert(bar.length == 11);
  1550. for (int32 i = 0; i <11; i++) {
  1551. assert(bar[uint32(i)] == i * 3);
  1552. }
  1553. }
  1554. function decode_empty(int32[] bar) pure public {
  1555. assert(bar.length == 0);
  1556. }
  1557. }
  1558. "#,
  1559. );
  1560. runtime.constructor(0, Vec::new());
  1561. runtime.function(
  1562. "decode",
  1563. Int32Array(vec![0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]).encode(),
  1564. );
  1565. runtime.function("decode_empty", Int32Array(vec![]).encode());
  1566. }
  1567. #[test]
  1568. fn abi_encode_dynamic_array2() {
  1569. #[derive(Debug, PartialEq, Encode, Decode)]
  1570. struct Array(Vec<(bool, u32)>);
  1571. let mut runtime = build_solidity(
  1572. r#"
  1573. contract structs {
  1574. struct foo {
  1575. bool x;
  1576. uint32 y;
  1577. }
  1578. function test() public returns (foo[]) {
  1579. foo[] x = new foo[](3);
  1580. x[0] = foo({x: true, y: 64});
  1581. x[1] = foo({x: false, y: 102});
  1582. x[2] = foo({x: true, y: 0x800});
  1583. return x;
  1584. }
  1585. }
  1586. "#,
  1587. );
  1588. runtime.constructor(0, Vec::new());
  1589. runtime.function("test", Vec::new());
  1590. assert_eq!(
  1591. runtime.vm.output,
  1592. Array(vec!((true, 64), (false, 102), (true, 0x800))).encode()
  1593. );
  1594. }
  1595. #[test]
  1596. fn abi_encode_dynamic_array3() {
  1597. #[derive(Debug, PartialEq, Encode, Decode)]
  1598. struct Array(Vec<(bool, u32, String)>);
  1599. let mut runtime = build_solidity(
  1600. r#"
  1601. contract structs {
  1602. struct foo {
  1603. bool x;
  1604. uint32 y;
  1605. string z;
  1606. }
  1607. function test() public returns (foo[]) {
  1608. foo[] x = new foo[](3);
  1609. x[0] = foo({x: true, y: 64, z: "abc"});
  1610. x[1] = foo({x: false, y: 102, z: "a"});
  1611. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1612. return x;
  1613. }
  1614. }
  1615. "#,
  1616. );
  1617. runtime.constructor(0, Vec::new());
  1618. runtime.function("test", Vec::new());
  1619. assert_eq!(
  1620. runtime.vm.output,
  1621. Array(vec!(
  1622. (true, 64, "abc".to_owned()),
  1623. (false, 102, "a".to_owned()),
  1624. (true, 0x800, "abcdef".to_owned())
  1625. ))
  1626. .encode()
  1627. );
  1628. }
  1629. #[test]
  1630. fn abi_encode_dynamic_array4() {
  1631. #[derive(Debug, PartialEq, Encode, Decode)]
  1632. struct Array([(bool, u32, String); 3]);
  1633. let mut runtime = build_solidity(
  1634. r#"
  1635. contract structs {
  1636. struct foo {
  1637. bool x;
  1638. uint32 y;
  1639. string z;
  1640. }
  1641. function test() public returns (foo[3]) {
  1642. foo[3] x;
  1643. x[0] = foo({x: true, y: 64, z: "abc"});
  1644. x[1] = foo({x: false, y: 102, z: "a"});
  1645. x[2] = foo({x: true, y: 0x800, z: "abcdef"});
  1646. return x;
  1647. }
  1648. }
  1649. "#,
  1650. );
  1651. runtime.constructor(0, Vec::new());
  1652. runtime.function("test", Vec::new());
  1653. runtime.heap_verify();
  1654. assert_eq!(
  1655. runtime.vm.output,
  1656. Array([
  1657. (true, 64, "abc".to_owned()),
  1658. (false, 102, "a".to_owned()),
  1659. (true, 0x800, "abcdef".to_owned())
  1660. ])
  1661. .encode()
  1662. );
  1663. }
  1664. #[test]
  1665. fn large_index_ty_in_bounds() {
  1666. let mut runtime = build_solidity(
  1667. r#"
  1668. contract foo {
  1669. uint128 storage_index;
  1670. function test(uint128 index) public returns (uint16) {
  1671. uint16[] memory a = new uint16[](16);
  1672. storage_index = index;
  1673. return a[storage_index];
  1674. }
  1675. }"#,
  1676. );
  1677. runtime.constructor(0, Vec::new());
  1678. runtime.function("test", 15u128.encode());
  1679. runtime.function_expect_failure("test", 17u128.encode());
  1680. runtime.function_expect_failure("test", 0xfffffffffffffu128.encode());
  1681. }
  1682. #[test]
  1683. fn alloc_size_from_storage() {
  1684. let mut runtime = build_solidity(
  1685. r#"
  1686. contract Test {
  1687. uint32 length = 1;
  1688. function contfunc() public view returns (uint64[] memory) {
  1689. uint64[] memory values = new uint64[](length);
  1690. return values;
  1691. }
  1692. }"#,
  1693. );
  1694. runtime.constructor(0, Vec::new());
  1695. runtime.function("contfunc", Vec::new());
  1696. assert_eq!(runtime.vm.output, vec![0u64].encode());
  1697. }
  1698. #[test]
  1699. fn lucas() {
  1700. let ns = parse_and_resolve(
  1701. r#"contract Test {
  1702. bytes byteArr;
  1703. bytes32 baRR;
  1704. function get() public {
  1705. string memory s = "Test";
  1706. byteArr = bytes(s);
  1707. uint16 a = 1;
  1708. uint8 b;
  1709. b = uint8(a);
  1710. uint256 c;
  1711. c = b;
  1712. bytes32 b32;
  1713. b32 = bytes32(byteArr);
  1714. baRR = bytes32(c);
  1715. uint i1 = 1;
  1716. uint i2 = 1;
  1717. assert(b32[(i1*i2)-i1] == bytes1(baRR));
  1718. }
  1719. }
  1720. "#,
  1721. Target::Substrate {
  1722. address_length: 32,
  1723. value_length: 16,
  1724. },
  1725. );
  1726. no_errors(ns.diagnostics);
  1727. }