mod.rs 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. use parity_scale_codec::Encode;
  2. use parity_scale_codec_derive::{Decode, Encode};
  3. use rand::Rng;
  4. use super::{build_solidity, first_error};
  5. use solang::{parse_and_resolve, 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 (_, errors) = parse_and_resolve(
  13. r#"
  14. contract foo {
  15. function foo() public returns (uint) {
  16. uint8[4] memory bar = [ 1, 2, 3, 4 ];
  17. return bar[];
  18. }
  19. }"#,
  20. &Target::Substrate,
  21. );
  22. assert_eq!(first_error(errors), "expected expression before ‘]’ token");
  23. let (_, errors) = parse_and_resolve(
  24. r#"
  25. contract foo {
  26. function foo() public returns (uint8) {
  27. uint8[4] memory bar = [ 1, 2, 3, 4, 5 ];
  28. return bar[0];
  29. }
  30. }"#,
  31. &Target::Substrate,
  32. );
  33. assert_eq!(
  34. first_error(errors),
  35. "conversion from uint8[5] to uint8[4] not possible"
  36. );
  37. }
  38. #[test]
  39. fn const_array_array() {
  40. let (runtime, mut store) = build_solidity(
  41. r##"
  42. contract foo {
  43. int8[8] constant bar = [ int8(1), 2, 3, 4, 5, 6, 7, 8 ];
  44. function f(uint32 i1) public returns (int8) {
  45. return bar[i1];
  46. }
  47. }"##,
  48. );
  49. runtime.function(&mut store, "f", Val32(1).encode());
  50. assert_eq!(store.scratch, Val8(2).encode());
  51. }
  52. #[test]
  53. fn votes() {
  54. #[derive(Debug, PartialEq, Encode, Decode)]
  55. struct Votes([bool; 11]);
  56. let (runtime, mut store) = build_solidity(
  57. r##"
  58. contract foo {
  59. /// In a jury, do the ayes have it?
  60. function f(bool[11] votes) public pure returns (bool) {
  61. uint32 i;
  62. uint32 ayes = 0;
  63. for (i=0; i<votes.length; i++) {
  64. if (votes[i]) {
  65. ayes += 1;
  66. }
  67. }
  68. return ayes > votes.length / 2;
  69. }
  70. }"##,
  71. );
  72. runtime.function(
  73. &mut store,
  74. "f",
  75. Votes([
  76. true, true, true, true, true, true, false, false, false, false, false,
  77. ])
  78. .encode(),
  79. );
  80. assert_eq!(store.scratch, true.encode());
  81. runtime.function(
  82. &mut store,
  83. "f",
  84. Votes([
  85. true, true, true, true, true, false, false, false, false, false, false,
  86. ])
  87. .encode(),
  88. );
  89. assert_eq!(store.scratch, false.encode());
  90. }
  91. #[test]
  92. fn return_array() {
  93. #[derive(Debug, PartialEq, Encode, Decode)]
  94. struct Res([u64; 4]);
  95. let (runtime, mut store) = build_solidity(
  96. r##"
  97. contract foo {
  98. function array() pure public returns (int64[4]) {
  99. return [ int64(4), 84564, 31213, 1312 ];
  100. }
  101. }"##,
  102. );
  103. runtime.function(&mut store, "array", Vec::new());
  104. assert_eq!(store.scratch, Res([4, 84564, 31213, 1312]).encode());
  105. }
  106. #[test]
  107. fn storage_arrays() {
  108. #[derive(Debug, PartialEq, Encode, Decode)]
  109. struct Val(i32);
  110. #[derive(Debug, PartialEq, Encode, Decode)]
  111. struct SetArg(u64, i32);
  112. #[derive(Debug, PartialEq, Encode, Decode)]
  113. struct GetArg(u64);
  114. let (runtime, mut store) = build_solidity(
  115. r##"
  116. contract foo {
  117. int32[8589934592] bigarray;
  118. function set(uint64 index, int32 val) public {
  119. bigarray[index] = val;
  120. }
  121. function get(uint64 index) public returns (int32) {
  122. return bigarray[index];
  123. }
  124. }"##,
  125. );
  126. let mut rng = rand::thread_rng();
  127. let mut vals = Vec::new();
  128. for _ in 0..100 {
  129. let index = rng.gen::<u64>() % 0x2_000_000;
  130. let val = rng.gen::<i32>();
  131. runtime.function(&mut store, "set", SetArg(index, val).encode());
  132. vals.push((index, val));
  133. }
  134. for val in vals {
  135. runtime.function(&mut store, "get", GetArg(val.0).encode());
  136. assert_eq!(store.scratch, Val(val.1).encode());
  137. }
  138. }
  139. #[test]
  140. fn enum_arrays() {
  141. #[derive(Encode, Decode)]
  142. struct Arg([u8; 100]);
  143. #[derive(Debug, PartialEq, Encode, Decode)]
  144. struct Ret(u32);
  145. let (runtime, mut store) = build_solidity(
  146. r##"
  147. contract enum_array {
  148. enum Foo { Bar1, Bar2, Bar3, Bar4 }
  149. function count_bar2(Foo[100] calldata foos) public returns (uint32) {
  150. uint32 count = 0;
  151. uint32 i;
  152. for (i = 0; i < foos.length; i++) {
  153. if (foos[i] == Foo.Bar2) {
  154. count++;
  155. }
  156. }
  157. return count;
  158. }
  159. }"##,
  160. );
  161. let mut rng = rand::thread_rng();
  162. let mut a = [0u8; 100];
  163. let mut count = 0;
  164. #[allow(clippy::needless_range_loop)]
  165. for i in 0..a.len() {
  166. a[i] = rng.gen::<u8>() % 4;
  167. if a[i] == 1 {
  168. count += 1;
  169. }
  170. }
  171. runtime.function(&mut store, "count_bar2", Arg(a).encode());
  172. assert_eq!(store.scratch, Ret(count).encode());
  173. }
  174. #[test]
  175. fn data_locations() {
  176. let (_, errors) = parse_and_resolve(
  177. r#"
  178. contract foo {
  179. function bar(uint storage) public returns () {
  180. }
  181. }"#,
  182. &Target::Substrate,
  183. );
  184. assert_eq!(
  185. first_error(errors),
  186. "data location ‘storage’ can only be specified for array, struct or mapping"
  187. );
  188. let (_, errors) = parse_and_resolve(
  189. r#"
  190. contract foo {
  191. function bar(uint calldata x) public returns () {
  192. }
  193. }"#,
  194. &Target::Substrate,
  195. );
  196. assert_eq!(
  197. first_error(errors),
  198. "data location ‘calldata’ can only be specified for array, struct or mapping"
  199. );
  200. let (_, errors) = parse_and_resolve(
  201. r#"
  202. contract foo {
  203. enum foo2 { bar1, bar2 }
  204. function bar(foo2 memory x) public returns () {
  205. }
  206. }"#,
  207. &Target::Substrate,
  208. );
  209. assert_eq!(
  210. first_error(errors),
  211. "data location ‘memory’ can only be specified for array, struct or mapping"
  212. );
  213. let (_, errors) = parse_and_resolve(
  214. r#"
  215. contract foo {
  216. enum foo2 { bar1, bar2 }
  217. function bar(foo2 x) public returns (uint calldata) {
  218. }
  219. }"#,
  220. &Target::Substrate,
  221. );
  222. assert_eq!(
  223. first_error(errors),
  224. "data location ‘calldata’ can only be specified for array, struct or mapping"
  225. );
  226. let (_, errors) = parse_and_resolve(
  227. r#"
  228. contract foo {
  229. enum foo2 { bar1, bar2 }
  230. function bar(foo2 x) public returns (bool calldata) {
  231. }
  232. }"#,
  233. &Target::Substrate,
  234. );
  235. assert_eq!(
  236. first_error(errors),
  237. "data location ‘calldata’ can only be specified for array, struct or mapping"
  238. );
  239. let (_, errors) = parse_and_resolve(
  240. r#"
  241. contract foo {
  242. enum foo2 { bar1, bar2 }
  243. function bar(foo2 x) public returns (int storage) {
  244. }
  245. }"#,
  246. &Target::Substrate,
  247. );
  248. assert_eq!(
  249. first_error(errors),
  250. "data location ‘storage’ can only be specified for array, struct or mapping"
  251. );
  252. let (_, errors) = parse_and_resolve(
  253. r#"
  254. contract foo {
  255. enum foo2 { bar1, bar2 }
  256. function bar(int[10] storage x) public returns (int) {
  257. }
  258. }"#,
  259. &Target::Substrate,
  260. );
  261. assert_eq!(
  262. first_error(errors),
  263. "parameter of type ‘storage’ not allowed public or external functions"
  264. );
  265. let (_, errors) = parse_and_resolve(
  266. r#"
  267. contract foo {
  268. enum foo2 { bar1, bar2 }
  269. function bar() public returns (int[10] storage x) {
  270. }
  271. }"#,
  272. &Target::Substrate,
  273. );
  274. assert_eq!(
  275. first_error(errors),
  276. "return type of type ‘storage’ not allowed public or external functions"
  277. );
  278. let (_, errors) = parse_and_resolve(
  279. r#"
  280. contract foo {
  281. enum foo2 { bar1, bar2 }
  282. function bar() public returns (foo2[10] storage x) {
  283. }
  284. }"#,
  285. &Target::Substrate,
  286. );
  287. assert_eq!(
  288. first_error(errors),
  289. "return type of type ‘storage’ not allowed public or external functions"
  290. );
  291. }
  292. #[test]
  293. fn storage_ref_arg() {
  294. let (runtime, mut store) = build_solidity(
  295. r##"
  296. contract storage_refs {
  297. int32[10] a;
  298. int32[10] b;
  299. function set(int32[10] storage array, uint8 index, int32 val) private {
  300. array[index] = val;
  301. }
  302. function test() public {
  303. set(a, 2, 5);
  304. set(b, 2, 102);
  305. assert(a[2] == 5);
  306. assert(b[2] == 102);
  307. }
  308. }"##,
  309. );
  310. runtime.function(&mut store, "test", Vec::new());
  311. }
  312. #[test]
  313. fn storage_ref_var() {
  314. let (runtime, mut store) = build_solidity(
  315. r##"
  316. contract storage_refs {
  317. int32[10] a;
  318. int32[10] b;
  319. function set(int32[10] storage array, uint8 index, int32 val) private {
  320. array[index] = val;
  321. }
  322. function test() public {
  323. int32[10] storage ref = a;
  324. set(ref, 2, 5);
  325. ref = b;
  326. set(ref, 2, 102);
  327. assert(a[2] == 5);
  328. assert(b[2] == 102);
  329. }
  330. }"##,
  331. );
  332. runtime.function(&mut store, "test", Vec::new());
  333. }
  334. #[test]
  335. fn storage_ref_returns() {
  336. let (runtime, mut store) = build_solidity(
  337. r##"
  338. contract storage_refs {
  339. int32[10] a;
  340. int32[10] b;
  341. function a_or_b(bool want_a) private returns (int32[10] storage) {
  342. if (want_a) {
  343. return a;
  344. }
  345. return b;
  346. }
  347. function set(int32[10] storage array, uint8 index, int32 val) private {
  348. array[index] = val;
  349. }
  350. function test() public {
  351. int32[10] storage ref = a_or_b(true);
  352. set(ref, 2, 5);
  353. ref = a_or_b(false);
  354. set(ref, 2, 102);
  355. assert(a[2] == 5);
  356. assert(b[2] == 102);
  357. }
  358. }"##,
  359. );
  360. runtime.function(&mut store, "test", Vec::new());
  361. }
  362. #[test]
  363. fn storage_to_memory() {
  364. #[derive(Debug, PartialEq, Encode, Decode)]
  365. struct Ret([u32; 10]);
  366. let (runtime, mut store) = build_solidity(
  367. r##"
  368. contract storage_refs {
  369. uint32[10] a;
  370. function test() public returns (uint32[10]) {
  371. for (uint32 i = 0; i < 10; ) {
  372. uint32 index = i;
  373. a[index] = 7 * ++i;
  374. }
  375. return a;
  376. }
  377. }"##,
  378. );
  379. runtime.function(&mut store, "test", Vec::new());
  380. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  381. assert_eq!(store.scratch, val.encode());
  382. }
  383. #[test]
  384. fn memory_to_storage() {
  385. #[derive(Debug, PartialEq, Encode, Decode)]
  386. struct Ret([u32; 10]);
  387. let (runtime, mut store) = build_solidity(
  388. r##"
  389. contract storage_refs {
  390. int32[10] a;
  391. function test() public returns (int32[10]) {
  392. int32[10] b = [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 70 ];
  393. a = b;
  394. return a;
  395. }
  396. }"##,
  397. );
  398. runtime.function(&mut store, "test", Vec::new());
  399. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  400. assert_eq!(store.scratch, val.encode());
  401. }
  402. #[test]
  403. fn array_dimensions() {
  404. let (_, errors) = parse_and_resolve(
  405. r#"
  406. contract foo {
  407. bool[10 - 10] x;
  408. }"#,
  409. &Target::Substrate,
  410. );
  411. assert_eq!(first_error(errors), "zero size of array declared");
  412. let (_, errors) = parse_and_resolve(
  413. r#"
  414. contract foo {
  415. bool[-10 + 10] x;
  416. }"#,
  417. &Target::Substrate,
  418. );
  419. assert_eq!(first_error(errors), "zero size of array declared");
  420. let (_, errors) = parse_and_resolve(
  421. r#"
  422. contract foo {
  423. bool[1 / 10] x;
  424. }"#,
  425. &Target::Substrate,
  426. );
  427. assert_eq!(first_error(errors), "zero size of array declared");
  428. let (_, errors) = parse_and_resolve(
  429. r#"
  430. contract foo {
  431. enum e { e1, e2, e3 }
  432. e[1 / 0] x;
  433. }"#,
  434. &Target::Substrate,
  435. );
  436. assert_eq!(first_error(errors), "divide by zero");
  437. let (_, errors) = parse_and_resolve(
  438. r#"
  439. contract foo {
  440. struct bar {
  441. int32 x;
  442. }
  443. bar[1 % 0] x;
  444. }"#,
  445. &Target::Substrate,
  446. );
  447. assert_eq!(first_error(errors), "divide by zero");
  448. let (runtime, mut store) = build_solidity(
  449. r##"
  450. contract storage_refs {
  451. int32[2**16] a;
  452. function test() public {
  453. assert(a.length == 65536);
  454. }
  455. }"##,
  456. );
  457. runtime.function(&mut store, "test", Vec::new());
  458. }
  459. #[test]
  460. fn array_in_struct() {
  461. #[derive(Debug, PartialEq, Encode, Decode)]
  462. struct Ret([u32; 10]);
  463. let (runtime, mut store) = build_solidity(
  464. r##"
  465. contract storage_refs {
  466. struct foo {
  467. int32[10] f1;
  468. }
  469. function test() public returns (int32[10]) {
  470. foo a = foo({f1: [ int32(7), 14, 21, 28, 35, 42, 49, 56, 63, 0 ]});
  471. assert(a.f1[1] == 14);
  472. a.f1[9] = 70;
  473. return a.f1;
  474. }
  475. }"##,
  476. );
  477. runtime.function(&mut store, "test", Vec::new());
  478. let val = Ret([7, 14, 21, 28, 35, 42, 49, 56, 63, 70]);
  479. assert_eq!(store.scratch, val.encode());
  480. }
  481. #[test]
  482. fn struct_array_struct() {
  483. let (runtime, mut store) = build_solidity(
  484. r##"
  485. contract flipper {
  486. struct bool_struct {
  487. bool foo_bool;
  488. }
  489. struct struct_bool_struct_array {
  490. bool_struct[1] foo_struct_array;
  491. }
  492. function get_memory() public pure returns (bool) {
  493. bool_struct memory foo = bool_struct({foo_bool: true});
  494. bool_struct[1] memory foo_array = [foo];
  495. struct_bool_struct_array memory foo_struct = struct_bool_struct_array({foo_struct_array: foo_array});
  496. /* return foo_array[0].foo_bool; */
  497. return foo_struct.foo_struct_array[0].foo_bool;
  498. }
  499. }"##,
  500. );
  501. runtime.function(&mut store, "get_memory", Vec::new());
  502. assert_eq!(store.scratch, true.encode());
  503. }
  504. #[test]
  505. fn struct_array_struct_abi() {
  506. #[derive(Debug, PartialEq, Encode, Decode)]
  507. struct Foo {
  508. f1: u32,
  509. f2: bool,
  510. }
  511. #[derive(Debug, PartialEq, Encode, Decode)]
  512. struct Bar {
  513. bars: [Foo; 10],
  514. }
  515. let (runtime, mut store) = build_solidity(
  516. r##"
  517. contract flipper {
  518. struct foo {
  519. int32 f1;
  520. bool f2;
  521. }
  522. struct bar {
  523. foo[10] bars;
  524. }
  525. bar s;
  526. function get_bar() public returns (bar) {
  527. bar memory a = bar({ bars: [
  528. foo({ f1: 1, f2: true}),
  529. foo({ f1: 2, f2: true}),
  530. foo({ f1: 3, f2: true}),
  531. foo({ f1: 4, f2: true}),
  532. foo({ f1: 5, f2: true}),
  533. foo({ f1: 6, f2: true}),
  534. foo({ f1: 7, f2: false}),
  535. foo({ f1: 8, f2: true}),
  536. foo({ f1: 9, f2: true}),
  537. foo({ f1: 10, f2: true})
  538. ]});
  539. s = a;
  540. return a;
  541. }
  542. function set_bar(bar memory a) public {
  543. for (uint32 i = 0; i < 10; i++) {
  544. assert(a.bars[i].f1 == i + 1);
  545. assert(a.bars[i].f2 == (i != 6));
  546. }
  547. a = s;
  548. }
  549. }"##,
  550. );
  551. let b = Bar {
  552. bars: [
  553. Foo { f1: 1, f2: true },
  554. Foo { f1: 2, f2: true },
  555. Foo { f1: 3, f2: true },
  556. Foo { f1: 4, f2: true },
  557. Foo { f1: 5, f2: true },
  558. Foo { f1: 6, f2: true },
  559. Foo { f1: 7, f2: false },
  560. Foo { f1: 8, f2: true },
  561. Foo { f1: 9, f2: true },
  562. Foo { f1: 10, f2: true },
  563. ],
  564. };
  565. runtime.function(&mut store, "get_bar", Vec::new());
  566. assert_eq!(store.scratch, b.encode());
  567. runtime.function(&mut store, "set_bar", b.encode());
  568. }
  569. #[test]
  570. fn memory_dynamic_array_new() {
  571. let (_, errors) = parse_and_resolve(
  572. r#"
  573. contract foo {
  574. function test() public {
  575. int32[] memory a = new int32[]();
  576. assert(a.length == 5);
  577. }
  578. }"#,
  579. &Target::Substrate,
  580. );
  581. assert_eq!(
  582. first_error(errors),
  583. "new dynamic array should have a single length argument"
  584. );
  585. let (_, errors) = parse_and_resolve(
  586. r#"
  587. contract foo {
  588. function test() public {
  589. int32[] memory a = new int32[](1, 2);
  590. assert(a.length == 5);
  591. }
  592. }"#,
  593. &Target::Substrate,
  594. );
  595. assert_eq!(
  596. first_error(errors),
  597. "new dynamic array should have a single length argument"
  598. );
  599. let (_, errors) = parse_and_resolve(
  600. r#"
  601. contract foo {
  602. function test() public {
  603. int32[] memory a = new int32[](hex"ab");
  604. assert(a.length == 5);
  605. }
  606. }"#,
  607. &Target::Substrate,
  608. );
  609. assert_eq!(
  610. first_error(errors),
  611. "new size argument must be unsigned integer, not ‘bytes1’"
  612. );
  613. let (_, errors) = parse_and_resolve(
  614. r#"
  615. contract foo {
  616. function test() public {
  617. int32[] memory a = new int32[](-1);
  618. assert(a.length == 5);
  619. }
  620. }"#,
  621. &Target::Substrate,
  622. );
  623. assert_eq!(
  624. first_error(errors),
  625. "new size argument must be unsigned integer, not ‘int8’"
  626. );
  627. let (_, errors) = parse_and_resolve(
  628. r#"
  629. contract foo {
  630. function test() public {
  631. int32[] memory a = new bool(1);
  632. assert(a.length == 5);
  633. }
  634. }"#,
  635. &Target::Substrate,
  636. );
  637. assert_eq!(first_error(errors), "new cannot allocate type ‘bool’");
  638. let (runtime, mut store) = build_solidity(
  639. r#"
  640. contract foo {
  641. function test() public {
  642. int32[] memory a = new int32[](5);
  643. assert(a.length == 5);
  644. }
  645. }"#,
  646. );
  647. runtime.function(&mut store, "test", Vec::new());
  648. // The Ethereum Foundation solc allows you to create arrays of length 0
  649. let (runtime, mut store) = build_solidity(
  650. r#"
  651. contract foo {
  652. function test() public {
  653. bool[] memory a = new bool[](0);
  654. assert(a.length == 0);
  655. }
  656. }"#,
  657. );
  658. runtime.function(&mut store, "test", Vec::new());
  659. }
  660. #[test]
  661. fn memory_dynamic_array_deref() {
  662. let (_, errors) = parse_and_resolve(
  663. r#"
  664. contract foo {
  665. function test() public {
  666. int32[] memory a = new int32[](2);
  667. a[-1] = 5;
  668. }
  669. }"#,
  670. &Target::Substrate,
  671. );
  672. assert_eq!(
  673. first_error(errors),
  674. "array subscript must be an unsigned integer, not ‘int8’"
  675. );
  676. let (_, errors) = parse_and_resolve(
  677. r#"
  678. contract foo {
  679. function test() public {
  680. int32[] memory a = new int32[](2);
  681. int32 i = 1;
  682. a[i] = 5;
  683. }
  684. }"#,
  685. &Target::Substrate,
  686. );
  687. assert_eq!(
  688. first_error(errors),
  689. "array subscript must be an unsigned integer, not ‘int32’"
  690. );
  691. // The Ethereum Foundation solc allows you to create arrays of length 0
  692. let (runtime, mut store) = build_solidity(
  693. r#"
  694. contract foo {
  695. function test() public {
  696. int32[] memory a = new int32[](5);
  697. assert(a.length == 5);
  698. a[0] = 102;
  699. a[1] = -5;
  700. a[4] = 0x7cafeeed;
  701. assert(a[0] == 102);
  702. assert(a[1] == -5);
  703. assert(a[4] == 0x7cafeeed);
  704. }
  705. }"#,
  706. );
  707. runtime.function(&mut store, "test", Vec::new());
  708. }
  709. #[test]
  710. #[should_panic]
  711. fn array_bounds_dynamic_array() {
  712. let (runtime, mut store) = build_solidity(
  713. r#"
  714. contract foo {
  715. function test() public {
  716. int32[] memory a = new int32[](5);
  717. a[5] = 102;
  718. }
  719. }"#,
  720. );
  721. runtime.function(&mut store, "test", Vec::new());
  722. }
  723. #[test]
  724. #[should_panic]
  725. fn empty_array_bounds_dynamic_array() {
  726. let (runtime, mut store) = build_solidity(
  727. r#"
  728. contract foo {
  729. function test() public {
  730. bytes32[] memory a = new bytes32[](0);
  731. a[0] = "yo";
  732. }
  733. }"#,
  734. );
  735. runtime.function(&mut store, "test", Vec::new());
  736. }
  737. #[test]
  738. fn memory_dynamic_array_types_call_return() {
  739. let (runtime, mut store) = build_solidity(
  740. r#"
  741. contract foo {
  742. function a(bool cond) public returns (bytes27[]) {
  743. bytes27[] foo;
  744. foo = new bytes27[](5);
  745. foo[1] = "cond was true";
  746. return foo;
  747. }
  748. function b(bytes27[] x) private {
  749. x[1] = "b was called";
  750. x = new bytes27[](3);
  751. x[1] = "should not be";
  752. }
  753. function test() public {
  754. bytes27[] x = a(true);
  755. assert(x.length == 5);
  756. assert(x[1] == "cond was true");
  757. b(x);
  758. assert(x.length == 5);
  759. assert(x[1] == "b was called");
  760. }
  761. }"#,
  762. );
  763. runtime.function(&mut store, "test", Vec::new());
  764. }
  765. #[test]
  766. fn dynamic_arrays_need_phi_node() {
  767. let (runtime, mut store) = build_solidity(
  768. r#"
  769. pragma solidity 0;
  770. contract foo {
  771. enum bar { bar1, bar2, bar3, bar4 }
  772. function a(bool cond) public returns (bar[] memory) {
  773. bar[] memory foo;
  774. if (cond) {
  775. foo = new bar[](5);
  776. foo[1] = bar.bar2;
  777. } else {
  778. foo = new bar[](3);
  779. foo[1] = bar.bar3;
  780. }
  781. return foo;
  782. }
  783. function test() public {
  784. bar[] memory x = a(true);
  785. assert(x.length == 5);
  786. assert(x[1] == bar.bar2);
  787. x = a(false);
  788. assert(x.length == 3);
  789. assert(x[1] == bar.bar3);
  790. }
  791. }"#,
  792. );
  793. runtime.function(&mut store, "test", Vec::new());
  794. }
  795. // test:
  796. // alignment of array elements
  797. // arrays of other structs/arrays/darrays
  798. // nil pointer should fail
  799. // dynamic storage arrays
  800. // copy to/from storage <=> memory
  801. // abi encode/decode
  802. // push/pop on dynamic storage array
  803. // string/bytes
  804. #[test]
  805. fn storage_dynamic_array_length() {
  806. let (runtime, mut store) = build_solidity(
  807. r#"
  808. pragma solidity 0;
  809. contract foo {
  810. int32[] bar;
  811. function test() public {
  812. assert(bar.length == 0);
  813. }
  814. }"#,
  815. );
  816. runtime.function(&mut store, "test", Vec::new());
  817. }
  818. #[test]
  819. fn storage_dynamic_array_push() {
  820. let (_, errors) = parse_and_resolve(
  821. r#"
  822. contract foo {
  823. int32[] bar;
  824. function test() public {
  825. assert(bar.length == 0);
  826. bar.push(102, 20);
  827. }
  828. }"#,
  829. &Target::Substrate,
  830. );
  831. assert_eq!(first_error(errors), "method ‘push()’ takes 1 argument");
  832. let (_, errors) = parse_and_resolve(
  833. r#"
  834. contract foo {
  835. int32[4] bar;
  836. function test() public {
  837. bar.push(102);
  838. }
  839. }"#,
  840. &Target::Substrate,
  841. );
  842. assert_eq!(
  843. first_error(errors),
  844. "method ‘push()’ not allowed on fixed length array"
  845. );
  846. let (runtime, mut store) = build_solidity(
  847. r#"
  848. pragma solidity 0;
  849. contract foo {
  850. int32[] bar;
  851. function test() public {
  852. assert(bar.length == 0);
  853. bar.push(102);
  854. assert(bar[0] == 102);
  855. assert(bar.length == 1);
  856. }
  857. }"#,
  858. );
  859. runtime.function(&mut store, "test", Vec::new());
  860. }