expressions.rs 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{build_solidity, build_solidity_with_options};
  3. use num_bigint::{BigInt, BigUint, RandBigInt, Sign};
  4. use parity_scale_codec::{Decode, Encode};
  5. use rand::seq::SliceRandom;
  6. use rand::Rng;
  7. use std::ops::Add;
  8. use std::ops::Div;
  9. use std::ops::Mul;
  10. use std::ops::Sub;
  11. #[test]
  12. fn celcius_and_fahrenheit() {
  13. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  14. struct Val(u32);
  15. // parse
  16. let mut runtime = build_solidity(
  17. "
  18. contract test {
  19. function celcius2fahrenheit(int32 celcius) pure public returns (int32) {
  20. int32 fahrenheit = celcius * 9 / 5 + 32;
  21. return fahrenheit;
  22. }
  23. function fahrenheit2celcius(uint32 fahrenheit) pure public returns (uint32) {
  24. return (fahrenheit - 32) * 5 / 9;
  25. }
  26. }",
  27. );
  28. runtime.function("celcius2fahrenheit", Val(10).encode());
  29. assert_eq!(runtime.output(), Val(50).encode());
  30. runtime.function("fahrenheit2celcius", Val(50).encode());
  31. assert_eq!(runtime.output(), Val(10).encode());
  32. }
  33. #[test]
  34. fn digits() {
  35. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  36. struct Val32(u32);
  37. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  38. struct Val64(u64);
  39. // parse
  40. let mut runtime = build_solidity(
  41. "
  42. contract test {
  43. function digitslen(uint64 val) pure public returns (uint32) {
  44. uint32 count = 0;
  45. while (val > 0) {
  46. count++;
  47. val /= 10;
  48. }
  49. if (count == 0) {
  50. count = 1;
  51. }
  52. return count;
  53. }
  54. function sumdigits(int64 val) pure public returns (uint32) {
  55. uint32 sum = 0;
  56. while (val > 0) {
  57. sum += uint32(val % 10);
  58. val= val / 10;
  59. }
  60. return sum;
  61. }
  62. }",
  63. );
  64. runtime.function("digitslen", Val64(1234567).encode());
  65. assert_eq!(runtime.output(), Val32(7).encode());
  66. runtime.function("sumdigits", Val64(123456789).encode());
  67. assert_eq!(runtime.output(), Val32(45).encode());
  68. }
  69. #[test]
  70. fn large_loops() {
  71. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  72. struct Val32(u32);
  73. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  74. struct Val64(u64);
  75. // parse
  76. let mut runtime = build_solidity(
  77. "
  78. contract test {
  79. function foo(uint val) pure public returns (uint) {
  80. for (uint i =0 ; i < 100; i++ ) {
  81. val += i + 10;
  82. }
  83. return val;
  84. }
  85. function baz(int val) pure public returns (int) {
  86. return val * 1000_000;
  87. }
  88. function bar() public {
  89. assert(foo(10) == 5960);
  90. assert(baz(7_000_123) == 7_000_123_000_000);
  91. assert(baz(7_000_123_456_678) == 7_000_123_456_678_000_000);
  92. }
  93. }",
  94. );
  95. runtime.function("bar", Vec::new());
  96. let mut args = Val64(7000).encode();
  97. args.resize(32, 0);
  98. runtime.function("baz", args);
  99. let mut rets = Val64(7000000000).encode();
  100. rets.resize(32, 0);
  101. assert_eq!(runtime.output(), rets);
  102. }
  103. #[test]
  104. fn expressions() {
  105. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  106. struct Val16(u16);
  107. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  108. struct Val8(u8);
  109. // parse
  110. let mut runtime = build_solidity("
  111. contract test {
  112. // this is 2^254
  113. int constant large_value = 14474011154664524427946373126085988481658748083205070504932198000989141204992;
  114. function add_100(uint16 a) pure public returns (uint16) {
  115. unchecked {
  116. a -= 200;
  117. a += 300;
  118. }
  119. return a;
  120. }
  121. function clear_digit(uint8 a) pure public returns (uint8) {
  122. a /= 10;
  123. a *= 10;
  124. return a;
  125. }
  126. function low_digit(uint8 a) pure public returns (uint8) {
  127. a %= 10;
  128. return a;
  129. }
  130. function test_comparisons() pure public {
  131. {
  132. // test comparisons work, if will work even if sign/unsigned is broken
  133. uint64 left = 102;
  134. uint64 right = 103;
  135. assert(left < right);
  136. assert(left <= right);
  137. assert(left != right);
  138. assert(right > left);
  139. assert(right >= left);
  140. assert(right == 103);
  141. assert(left >= 102);
  142. assert(right <= 103);
  143. assert(!(right <= 102));
  144. }
  145. {
  146. // check if unsigned compare works correctly (will fail if signed compare is done)
  147. uint16 left = 102;
  148. uint16 right = 0x8001;
  149. assert(left < right);
  150. assert(left <= right);
  151. assert(left != right);
  152. assert(right > left);
  153. assert(right >= left);
  154. assert(right == 0x8001);
  155. assert(left >= 102);
  156. assert(right <= 0x8001);
  157. assert(!(right <= 102));
  158. }
  159. {
  160. // check if signed compare works correctly (will fail if unsigned compare is done)
  161. int left = -102;
  162. int right = large_value;
  163. assert(left < right);
  164. assert(left <= right);
  165. assert(left != right);
  166. assert(right > left);
  167. assert(right >= left);
  168. assert(right == large_value);
  169. assert(left >= -102);
  170. assert(right <= large_value);
  171. assert(!(right <= -102));
  172. }
  173. }
  174. function increments() public {
  175. uint a = 1;
  176. assert(a-- == 1);
  177. assert(a == 0);
  178. assert(a++ == 0);
  179. assert(a == 1);
  180. assert(--a == 0);
  181. assert(a == 0);
  182. assert(++a == 1);
  183. assert(a == 1);
  184. }
  185. }",
  186. );
  187. runtime.function("add_100", Val16(0xffc0).encode());
  188. assert_eq!(runtime.output(), Val16(36).encode());
  189. runtime.function("clear_digit", Val8(25).encode());
  190. assert_eq!(runtime.output(), Val8(20).encode());
  191. runtime.function("low_digit", Val8(25).encode());
  192. assert_eq!(runtime.output(), Val8(5).encode());
  193. runtime.function("test_comparisons", Vec::new());
  194. runtime.function("increments", Vec::new());
  195. }
  196. #[test]
  197. #[should_panic(expected = "IntegerDivisionByZero")]
  198. fn divisions_by_zero() {
  199. // parse
  200. let mut runtime = build_solidity(
  201. "
  202. contract test {
  203. uint256 divisor = 0;
  204. function do_test() public returns (uint256 result){
  205. result = 100 / divisor;
  206. }
  207. }",
  208. );
  209. runtime.function_expect_failure("do_test", Vec::new());
  210. }
  211. #[test]
  212. fn divisions() {
  213. // parse
  214. let mut runtime = build_solidity(
  215. "
  216. contract test {
  217. uint constant large = 101213131318098987934191741;
  218. function do_test() public returns (uint) {
  219. assert(large / 1 == large);
  220. assert(large / (large + 102) == 0);
  221. assert(large / large == 1);
  222. assert(large % 1 == 0);
  223. assert(large % (large + 102) == large);
  224. assert(large % large == 0);
  225. return 0;
  226. }
  227. }",
  228. );
  229. runtime.function("do_test", Vec::new());
  230. }
  231. #[test]
  232. fn divisions64() {
  233. // parse
  234. let mut runtime = build_solidity(
  235. "
  236. contract test {
  237. uint64 constant large = 101213131318098987;
  238. function do_test() public returns (uint) {
  239. assert(large / 1 == large);
  240. assert(large / (large + 102) == 0);
  241. assert(large / large == 1);
  242. assert(large % 1 == 0);
  243. assert(large % (large + 102) == large);
  244. assert(large % large == 0);
  245. return 0;
  246. }
  247. }",
  248. );
  249. runtime.function("do_test", Vec::new());
  250. }
  251. #[test]
  252. fn divisions128() {
  253. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  254. struct Args(i128, i128);
  255. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  256. struct Rets(i128);
  257. // parse
  258. let mut runtime = build_solidity(
  259. "
  260. contract test {
  261. uint128 constant large = 101213131318098987;
  262. uint128 constant small = 99;
  263. int128 constant signed_large = 101213131318098987;
  264. int128 constant neg_signed_large = -101213131318098987;
  265. int128 constant signed_small = 99;
  266. function do_test() public returns (uint) {
  267. assert(large / 1 == large);
  268. assert(large / (large + 102) == 0);
  269. assert(large / large == 1);
  270. assert(large % 1 == 0);
  271. assert(large % (large + 102) == large);
  272. assert(large % large == 0);
  273. assert(small / 10 == 9);
  274. assert(small % 10 == 9);
  275. assert(large / 100000 == 1012131313180);
  276. assert(large % 100000 == 98987);
  277. return 0;
  278. }
  279. function do_signed_test() public returns (uint) {
  280. assert(signed_large / 1 == signed_large);
  281. assert(signed_large / (signed_large + 102) == 0);
  282. assert(signed_large / signed_large == 1);
  283. assert(signed_large % 1 == 0);
  284. assert(signed_large % (signed_large + 102) == signed_large);
  285. assert(signed_large % signed_large == 0);
  286. assert(signed_small / 10 == 9);
  287. assert(signed_small % 10 == 9);
  288. assert(signed_large / 100000 == 1012131313180);
  289. assert(signed_large % 100000 == 98987);
  290. assert(neg_signed_large / -100000 == 1012131313180);
  291. assert(signed_large / -100000 == -1012131313180);
  292. assert(-signed_large / 100000 == -1012131313180);
  293. assert(signed_large % -100000 == 98987);
  294. assert(-signed_large % 100000 == -98987);
  295. assert(-signed_large % -100000 == -98987);
  296. return 0;
  297. }
  298. function do_div(int128 x, int128 y) public returns (int128) {
  299. return x / y;
  300. }
  301. function return_neg() public returns (int128) {
  302. return -100;
  303. }
  304. function return_pos() public returns (int128) {
  305. return 255;
  306. }
  307. }",
  308. );
  309. runtime.function("do_test", Vec::new());
  310. runtime.function("return_neg", Vec::new());
  311. if let Ok(Rets(r)) = Rets::decode(&mut &runtime.output()[..]) {
  312. assert_eq!(r, -100);
  313. } else {
  314. panic!();
  315. }
  316. runtime.function("return_pos", Vec::new());
  317. if let Ok(Rets(r)) = Rets::decode(&mut &runtime.output()[..]) {
  318. assert_eq!(r, 255);
  319. } else {
  320. panic!();
  321. }
  322. runtime.function("do_div", Args(-9900, -100).encode());
  323. if let Ok(Rets(r)) = Rets::decode(&mut &runtime.output()[..]) {
  324. assert_eq!(r, 99);
  325. } else {
  326. panic!();
  327. }
  328. runtime.function("do_div", Args(-101213131318098987, -100000).encode());
  329. if let Ok(Rets(r)) = Rets::decode(&mut &runtime.output()[..]) {
  330. assert_eq!(r, 1012131313180);
  331. } else {
  332. panic!();
  333. }
  334. runtime.function("do_signed_test", Vec::new());
  335. }
  336. #[test]
  337. fn divisions256() {
  338. // parse
  339. let mut runtime = build_solidity(
  340. "
  341. contract test {
  342. uint256 constant large = 101213131318098987;
  343. uint256 constant small = 99;
  344. function do_test() public returns (uint) {
  345. assert(large / 1 == large);
  346. assert(large / (large + 102) == 0);
  347. assert(large / large == 1);
  348. assert(large % 1 == 0);
  349. assert(large % (large + 102) == large);
  350. assert(large % large == 0);
  351. assert(small / 10 == 9);
  352. assert(small % 10 == 9);
  353. assert(large / 100000 == 1012131313180);
  354. assert(large % 100000 == 98987);
  355. return 0;
  356. }
  357. }",
  358. );
  359. runtime.function("do_test", Vec::new());
  360. }
  361. #[test]
  362. fn complement() {
  363. // parse
  364. let mut runtime = build_solidity(
  365. "
  366. contract test {
  367. function do_test() public {
  368. uint8 x1 = 0;
  369. assert(~x1 == 255);
  370. int32 x2 = 0x7fefabcd;
  371. assert(uint32(~x2) == 0x80105432);
  372. }
  373. function do_complement(uint256 foo) public returns (uint) {
  374. return ~foo;
  375. }
  376. }",
  377. );
  378. runtime.function("do_test", Vec::new());
  379. let mut args = Vec::new();
  380. args.resize(32, 0);
  381. runtime.function("do_complement", args);
  382. let ret = runtime.output();
  383. assert!(ret.len() == 32);
  384. assert!(ret.into_iter().filter(|x| *x == 255).count() == 32);
  385. }
  386. #[test]
  387. fn bitwise() {
  388. // parse
  389. let mut runtime = build_solidity(
  390. "
  391. contract test {
  392. function do_test() public {
  393. uint8 x1 = 0xf0;
  394. uint8 x2 = 0x0f;
  395. assert(x1 | x2 == 0xff);
  396. assert(x1 ^ x2 == 0xff);
  397. assert(x1 & x2 == 0x00);
  398. assert(x1 ^ 0 == x1);
  399. int32 x3 = 0x7fefabcd;
  400. assert(x3 & 0xffff == 0xabcd);
  401. }
  402. function do_or(uint256 a, uint256 b) public returns (uint) {
  403. return a | b;
  404. }
  405. function do_and(uint256 a, uint256 b) public returns (uint) {
  406. return a & b;
  407. }
  408. function do_xor(uint256 a, uint256 b) public returns (uint) {
  409. return a ^ b;
  410. }
  411. }",
  412. );
  413. runtime.function("do_test", Vec::new());
  414. let mut args = Vec::new();
  415. args.resize(32, 0);
  416. args.resize(64, 0xff);
  417. runtime.function("do_xor", args);
  418. let ret = &runtime.output();
  419. assert!(ret.len() == 32);
  420. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  421. let mut args = Vec::new();
  422. args.resize(32, 0);
  423. args.resize(64, 0xff);
  424. runtime.function("do_or", args);
  425. let ret = &runtime.output();
  426. assert!(ret.len() == 32);
  427. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  428. let mut args = Vec::new();
  429. args.resize(32, 0);
  430. args.resize(64, 0xff);
  431. runtime.function("do_and", args);
  432. let ret = &runtime.output();
  433. assert!(ret.len() == 32);
  434. assert!(ret.iter().filter(|x| **x == 0).count() == 32);
  435. }
  436. #[test]
  437. fn shift() {
  438. // parse
  439. let mut runtime = build_solidity(
  440. "
  441. contract test {
  442. function do_test() public {
  443. uint8 x1 = 0xf0;
  444. uint8 x2 = 0x0f;
  445. assert(x1 >> 4 == 0x0f);
  446. assert(x2 << 4 == 0xf0);
  447. int x3 = -16;
  448. assert(x3 >> 2 == -4);
  449. uint x5 = 0xdead_0000_0000_0000_0000;
  450. assert(x5 >> 64 == 0xdead);
  451. x5 = 0xdead;
  452. assert(x5 << 64 == 0xdead_0000_0000_0000_0000);
  453. }
  454. }",
  455. );
  456. runtime.function("do_test", Vec::new());
  457. }
  458. #[test]
  459. fn assign_bitwise() {
  460. // parse
  461. let mut runtime = build_solidity(
  462. "
  463. contract test {
  464. function do_test() public {
  465. uint8 x1 = 0xf0;
  466. uint8 x2 = 0x0f;
  467. x1 |= x2;
  468. assert(x1 == 0xff);
  469. x1 = 0xf0; x2 = 0x0f;
  470. x1 ^= x2;
  471. assert(x1 == 0xff);
  472. x1 = 0xf0; x2 = 0x0f;
  473. x1 &= x2;
  474. assert(x1 == 0x00);
  475. x1 = 0xf0; x2 = 0x0f;
  476. x1 ^= 0;
  477. assert(x1 == x1);
  478. int32 x3 = 0x7fefabcd;
  479. x3 &= 0xffff;
  480. assert(x3 == 0xabcd);
  481. }
  482. function do_or(uint256 a, uint256 b) public returns (uint) {
  483. a |= b;
  484. return a;
  485. }
  486. function do_and(uint256 a, uint256 b) public returns (uint) {
  487. a &= b;
  488. return a;
  489. }
  490. function do_xor(uint256 a, uint256 b) public returns (uint) {
  491. a ^= b;
  492. return a;
  493. }
  494. }",
  495. );
  496. runtime.function("do_test", Vec::new());
  497. let mut args = Vec::new();
  498. args.resize(32, 0);
  499. args.resize(64, 0xff);
  500. runtime.function("do_xor", args);
  501. let ret = &runtime.output();
  502. assert!(ret.len() == 32);
  503. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  504. let mut args = Vec::new();
  505. args.resize(32, 0);
  506. args.resize(64, 0xff);
  507. runtime.function("do_or", args);
  508. let ret = &runtime.output();
  509. assert!(ret.len() == 32);
  510. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  511. let mut args = Vec::new();
  512. args.resize(32, 0);
  513. args.resize(64, 0xff);
  514. runtime.function("do_and", args);
  515. let ret = &runtime.output();
  516. assert!(ret.len() == 32);
  517. assert!(ret.iter().filter(|x| **x == 0).count() == 32);
  518. }
  519. #[test]
  520. fn assign_shift() {
  521. // parse
  522. let mut runtime = build_solidity(
  523. "
  524. contract test {
  525. function do_test() public {
  526. uint8 x1 = 0xf0;
  527. uint8 x2 = 0x0f;
  528. x1 >>= 4;
  529. x2 <<= 4;
  530. assert(x1 == 0x0f);
  531. assert(x2 == 0xf0);
  532. int x3 = -16;
  533. x3 >>= 2;
  534. assert(x3 == -4);
  535. uint x5 = 0xdead_0000_0000_0000_0000;
  536. x5 >>= 64;
  537. assert(x5 == 0xdead);
  538. x5 = 0xdead;
  539. x5 <<= 64;
  540. assert(x5 == 0xdead_0000_0000_0000_0000);
  541. }
  542. }",
  543. );
  544. runtime.function("do_test", Vec::new());
  545. }
  546. #[test]
  547. fn ternary() {
  548. // parse
  549. let mut runtime = build_solidity(
  550. "
  551. contract test {
  552. function do_test() public {
  553. uint8 x1 = 0xf0;
  554. uint8 x2 = 0x0f;
  555. assert((false ? x1 : x2) == x2);
  556. assert((true ? x1 : x2) == x1);
  557. }
  558. }",
  559. );
  560. runtime.function("do_test", Vec::new());
  561. }
  562. #[test]
  563. fn short_circuit_or() {
  564. // parse
  565. let mut runtime = build_solidity(
  566. "
  567. contract test {
  568. uint32 counter;
  569. function increase_counter() private returns (bool) {
  570. counter += 1;
  571. return true;
  572. }
  573. function increase_counter2() private returns (bool) {
  574. counter++;
  575. return true;
  576. }
  577. function do_test() public {
  578. assert(counter == 0);
  579. // if left of or is true, right is not evaluated
  580. assert(true || increase_counter());
  581. assert(counter == 0);
  582. assert(false || increase_counter2());
  583. assert(counter == 1);
  584. false && increase_counter();
  585. assert(counter == 1);
  586. true && increase_counter();
  587. assert(counter == 2);
  588. }
  589. }",
  590. );
  591. runtime.function("do_test", Vec::new());
  592. }
  593. #[test]
  594. fn short_circuit_and() {
  595. // parse
  596. let mut runtime = build_solidity(
  597. "
  598. contract test {
  599. uint32 counter;
  600. function increase_counter() private returns (bool) {
  601. counter |= 1;
  602. return false;
  603. }
  604. function increase_counter2() private returns (bool) {
  605. ++counter;
  606. return false;
  607. }
  608. function do_test() public {
  609. assert(counter == 0);
  610. increase_counter2();
  611. increase_counter2();
  612. assert(counter == 2);
  613. increase_counter();
  614. assert(counter == 3);
  615. counter = 0;
  616. // if left hand side is false, right hand side is not evaluated
  617. assert(!(false && increase_counter()));
  618. assert(counter == 0);
  619. assert(!(true && increase_counter2()));
  620. assert(counter == 1);
  621. false && increase_counter2();
  622. assert(counter == 1);
  623. counter = 0;
  624. true && increase_counter();
  625. assert(counter == 1);
  626. }
  627. }",
  628. );
  629. runtime.function("do_test", Vec::new());
  630. }
  631. #[test]
  632. fn power() {
  633. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  634. struct Val(u64);
  635. // parse
  636. let mut runtime = build_solidity(
  637. "
  638. contract c {
  639. function power(uint64 base, uint64 exp) public returns (uint64) {
  640. return base ** exp;
  641. }
  642. function power_with_cast() public returns (uint64) {
  643. return uint64(2 ** 32);
  644. }
  645. }",
  646. );
  647. // 4**5 = 1024
  648. let args = Val(4).encode().into_iter().chain(Val(5).encode()).collect();
  649. runtime.function("power", args);
  650. assert_eq!(runtime.output(), Val(1024).encode());
  651. // n ** 1 = n
  652. let args = Val(2345)
  653. .encode()
  654. .into_iter()
  655. .chain(Val(1).encode())
  656. .collect();
  657. runtime.function("power", args);
  658. assert_eq!(runtime.output(), Val(2345).encode());
  659. // n ** 0 = 0
  660. let args = Val(0xdead_beef)
  661. .encode()
  662. .into_iter()
  663. .chain(Val(0).encode())
  664. .collect();
  665. runtime.function("power", args);
  666. assert_eq!(runtime.output(), Val(1).encode());
  667. // 0 ** n = 0
  668. let args = Val(0)
  669. .encode()
  670. .into_iter()
  671. .chain(Val(0xdead_beef).encode())
  672. .collect();
  673. runtime.function("power", args);
  674. assert_eq!(runtime.output(), Val(0).encode());
  675. runtime.function("power_with_cast", Vec::new());
  676. assert_eq!(runtime.output(), Val(0x1_0000_0000).encode());
  677. }
  678. #[test]
  679. fn large_power() {
  680. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  681. struct Val(u128);
  682. // parse
  683. let mut runtime = build_solidity(
  684. "
  685. contract c {
  686. function power(uint128 base, uint128 exp) public returns (uint128) {
  687. return base ** exp;
  688. }
  689. }",
  690. );
  691. // 4**5 = 1024
  692. let args = Val(4).encode().into_iter().chain(Val(5).encode()).collect();
  693. runtime.function("power", args);
  694. assert_eq!(runtime.output(), Val(1024).encode());
  695. // n ** 1 = n
  696. let args = Val(2345)
  697. .encode()
  698. .into_iter()
  699. .chain(Val(1).encode())
  700. .collect();
  701. runtime.function("power", args);
  702. assert_eq!(runtime.output(), Val(2345).encode());
  703. // n ** 0 = 0
  704. let args = Val(0xdeadbeef)
  705. .encode()
  706. .into_iter()
  707. .chain(Val(0).encode())
  708. .collect();
  709. runtime.function("power", args);
  710. assert_eq!(runtime.output(), Val(1).encode());
  711. // 0 ** n = 0
  712. let args = Val(0)
  713. .encode()
  714. .into_iter()
  715. .chain(Val(0xdeadbeef).encode())
  716. .collect();
  717. runtime.function("power", args);
  718. assert_eq!(runtime.output(), Val(0).encode());
  719. // 10 ** 36 = 1000000000000000000000000000000000000
  720. let args = Val(10)
  721. .encode()
  722. .into_iter()
  723. .chain(Val(36).encode())
  724. .collect();
  725. runtime.function("power", args);
  726. assert_eq!(
  727. runtime.output(),
  728. Val(1000000000000000000000000000000000000).encode()
  729. );
  730. }
  731. #[test]
  732. fn test_power_overflow_boundaries() {
  733. for width in (8..=256).step_by(8) {
  734. let src = r#"
  735. contract test {
  736. function pow(uintN a, uintN b) public returns (uintN) {
  737. return a ** b;
  738. }
  739. }"#
  740. .replace("intN", &format!("int{width}"));
  741. let mut contract = build_solidity_with_options(&src, false, false);
  742. let base = BigUint::from(2_u32);
  743. let mut base_data = base.to_bytes_le();
  744. let exp = BigUint::from(width - 1);
  745. let mut exp_data = exp.to_bytes_le();
  746. let width_rounded = (width / 8usize).next_power_of_two();
  747. base_data.resize(width_rounded, 0);
  748. exp_data.resize(width_rounded, 0);
  749. contract.function(
  750. "pow",
  751. base_data.clone().into_iter().chain(exp_data).collect(),
  752. );
  753. let res = BigUint::from(2_usize).pow((width - 1).try_into().unwrap());
  754. let mut res_data = res.to_bytes_le();
  755. res_data.resize(width / 8, 0);
  756. assert_eq!(contract.output()[..width / 8], res_data);
  757. let exp = exp.add(1_usize);
  758. let mut exp_data = exp.to_bytes_le();
  759. exp_data.resize(width_rounded, 0);
  760. contract.function_expect_failure("pow", base_data.into_iter().chain(exp_data).collect());
  761. }
  762. }
  763. #[test]
  764. fn multiply() {
  765. let mut rng = rand::thread_rng();
  766. let size = 32;
  767. let mut runtime = build_solidity(
  768. "
  769. contract c {
  770. function multiply(uint a, uint b) public returns (uint) {
  771. unchecked {
  772. return a * b;
  773. }
  774. }
  775. function multiply_with_cast() public returns (uint64) {
  776. return uint64(255 * 255);
  777. }
  778. }",
  779. );
  780. runtime.function("multiply_with_cast", Vec::new());
  781. assert_eq!(runtime.output(), 65025u64.encode());
  782. let mut rand = || -> (BigInt, Vec<u8>) {
  783. let length = rng.gen::<usize>() % size;
  784. let mut data = Vec::new();
  785. data.resize_with(length + 1, || rng.gen());
  786. data.resize(size, 0);
  787. (BigInt::from_bytes_le(Sign::Plus, &data), data)
  788. };
  789. for _ in 0..1000 {
  790. let (a, a_data) = rand();
  791. let (b, b_data) = rand();
  792. println!("in: a:{a_data:?} b:{b_data:?}");
  793. runtime.function("multiply", a_data.into_iter().chain(b_data).collect());
  794. println!("out: res:{:?}", runtime.output());
  795. let res = BigInt::from_bytes_le(Sign::Plus, &runtime.output());
  796. println!("{res} = {a} * {b}");
  797. // the result is truncated to $size bytes. We do this here by converting to Vec<u8> and truncating
  798. // it. A truncating bigint multiply would be nicer.
  799. let (_, mut res) = (a * b).to_bytes_le();
  800. res.resize(size, 0);
  801. assert_eq!(res, runtime.output());
  802. }
  803. }
  804. #[test]
  805. fn test_mul_within_range_signed() {
  806. // We generate a random value that fits N bits. Then, we multiply that value by 1, -1 or 0.
  807. let mut rng = rand::thread_rng();
  808. for width in (8..=256).step_by(8) {
  809. let src = r#"
  810. contract test {
  811. function mul(intN a, intN b) public returns (intN) {
  812. return a * b;
  813. }
  814. }"#
  815. .replace("intN", &format!("int{width}"));
  816. let width_rounded = (width / 8_usize).next_power_of_two();
  817. let mut runtime = build_solidity(&src);
  818. let upper_bound = BigInt::from(2).pow(width as u32 - 1); // Upper bound is exclusive
  819. let lower_bound = upper_bound.clone().mul(-1);
  820. let a = rng.gen_bigint_range(&lower_bound, &upper_bound);
  821. let a_sign = a.sign();
  822. let mut a_data = a.to_signed_bytes_le();
  823. let side = [-1, 0, 1];
  824. let b = BigInt::from(*side.choose(&mut rng).unwrap());
  825. let b_sign = b.sign();
  826. let mut b_data = b.to_signed_bytes_le();
  827. a_data.resize(width_rounded, sign_extend(a_sign));
  828. b_data.resize(width_rounded, sign_extend(b_sign));
  829. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  830. let value = a * b;
  831. let value_sign = value.sign();
  832. let mut value_data = value.to_signed_bytes_le();
  833. value_data.resize(width / 8, sign_extend(value_sign));
  834. assert_eq!(value_data, runtime.output()[..width / 8]);
  835. }
  836. }
  837. #[test]
  838. fn test_mul_within_range() {
  839. let mut rng = rand::thread_rng();
  840. for width in (8..=256).step_by(8) {
  841. let src = r#"
  842. contract test {
  843. function mul(uintN a, uintN b) public returns (uintN) {
  844. return a * b;
  845. }
  846. }"#
  847. .replace("intN", &format!("int{width}"));
  848. let width_rounded = (width / 8usize).next_power_of_two();
  849. let mut runtime = build_solidity(&src);
  850. // The range of values that can be held in unsigned N bits is [0, 2^N-1]. Here we generate a random number within this range and multiply it by 1
  851. let a = rng.gen_biguint((width).try_into().unwrap());
  852. let mut a_data = a.to_bytes_le();
  853. let b = BigUint::from(1_u32);
  854. let mut b_data = b.to_bytes_le();
  855. a_data.resize(width_rounded, 0);
  856. b_data.resize(width_rounded, 0);
  857. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  858. let value = a * b;
  859. let mut value_data = value.to_bytes_le();
  860. value_data.resize(width / 8, 0);
  861. assert_eq!(value_data, runtime.output()[..width / 8]);
  862. }
  863. }
  864. #[test]
  865. fn test_overflow_boundaries() {
  866. for width in (8..=256).step_by(8) {
  867. let src = r#"
  868. contract test {
  869. function mul(intN a, intN b) public returns (intN) {
  870. return a * b;
  871. }
  872. }"#
  873. .replace("intN", &format!("int{width}"));
  874. let mut contract = build_solidity_with_options(&src, false, false);
  875. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1]. We generate these boundaries:
  876. let upper_boundary = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  877. let mut up_data = upper_boundary.to_signed_bytes_le();
  878. let lower_boundary = BigInt::from(2_u32).pow(width - 1).mul(-1_i32);
  879. let mut low_data = lower_boundary.to_signed_bytes_le();
  880. let second_op = BigInt::from(1_u32);
  881. let mut sec_data = second_op.to_signed_bytes_le();
  882. let width_rounded = (width as usize / 8).next_power_of_two();
  883. up_data.resize(width_rounded, 0);
  884. low_data.resize(width_rounded, 255);
  885. sec_data.resize(width_rounded, 0);
  886. // Multiply the boundaries by 1.
  887. contract.function(
  888. "mul",
  889. up_data
  890. .clone()
  891. .into_iter()
  892. .chain(sec_data.clone())
  893. .collect(),
  894. );
  895. let res = upper_boundary.clone().mul(1_u32);
  896. let mut res_data = res.to_signed_bytes_le();
  897. res_data.resize((width / 8) as usize, 0);
  898. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  899. contract.function(
  900. "mul",
  901. low_data
  902. .clone()
  903. .into_iter()
  904. .chain(sec_data.clone())
  905. .collect(),
  906. );
  907. let res = lower_boundary.clone().mul(1_u32);
  908. let mut res_data = res.to_signed_bytes_le();
  909. res_data.resize((width / 8) as usize, 0);
  910. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  911. let upper_boundary_plus_one = BigInt::from(2_u32).pow(width - 1);
  912. // We subtract 2 instead of one to make the number even, so that no rounding occurs when we divide by 2 later on.
  913. let lower_boundary_minus_two = BigInt::from(2_u32).pow(width - 1).mul(-1_i32).sub(2_i32);
  914. let upper_second_op = upper_boundary_plus_one.div(2_u32);
  915. let mut upper_second_op_data = upper_second_op.to_signed_bytes_le();
  916. let lower_second_op = lower_boundary_minus_two.div(2_u32);
  917. let mut lower_second_op_data = lower_second_op.to_signed_bytes_le();
  918. let mut two_data = BigInt::from(2_u32).to_signed_bytes_le();
  919. upper_second_op_data.resize(width_rounded, 0);
  920. two_data.resize(width_rounded, 0);
  921. lower_second_op_data.resize(width_rounded, 255);
  922. // This will generate a value more than the upper boundary.
  923. contract.function_expect_failure(
  924. "mul",
  925. upper_second_op_data
  926. .clone()
  927. .into_iter()
  928. .chain(two_data.clone())
  929. .collect(),
  930. );
  931. // Generate a value less than the lower boundary
  932. contract.function_expect_failure(
  933. "mul",
  934. lower_second_op_data
  935. .clone()
  936. .into_iter()
  937. .chain(two_data.clone())
  938. .collect(),
  939. );
  940. // Upper boundary * Upper boundary
  941. contract.function_expect_failure(
  942. "mul",
  943. up_data.clone().into_iter().chain(up_data.clone()).collect(),
  944. );
  945. // Lower boundary * Lower boundary
  946. contract.function_expect_failure(
  947. "mul",
  948. low_data
  949. .clone()
  950. .into_iter()
  951. .chain(low_data.clone())
  952. .collect(),
  953. );
  954. // Lower boundary * Upper boundary
  955. contract.function_expect_failure(
  956. "mul",
  957. low_data
  958. .clone()
  959. .into_iter()
  960. .chain(up_data.clone())
  961. .collect(),
  962. );
  963. }
  964. }
  965. #[test]
  966. fn test_overflow_detect_signed() {
  967. let mut rng = rand::thread_rng();
  968. for width in (8..=256).step_by(8) {
  969. let src = r#"
  970. contract test {
  971. function mul(intN a, intN b) public returns (intN) {
  972. return a * b;
  973. }
  974. }"#
  975. .replace("intN", &format!("int{width}"));
  976. let mut contract = build_solidity_with_options(&src, false, false);
  977. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1] .Generate a value that will overflow this range:
  978. let limit = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  979. // Generate a random number within the the range [(2^N-1)/2, (2^N-1) -1]
  980. let first_operand_rand =
  981. rng.gen_bigint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  982. let first_op_sign = first_operand_rand.sign();
  983. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  984. let width_rounded = (width as usize / 8).next_power_of_two();
  985. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  986. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  987. let second_operand_rand = rng.gen_bigint_range(&BigInt::from(2usize), &limit);
  988. let second_op_sign = second_operand_rand.sign();
  989. let mut second_op_data = second_operand_rand.to_signed_bytes_le();
  990. second_op_data.resize(width_rounded, sign_extend(second_op_sign));
  991. contract.function_expect_failure(
  992. "mul",
  993. first_op_data
  994. .into_iter()
  995. .chain(second_op_data.clone())
  996. .collect(),
  997. );
  998. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1] .
  999. let lower_limit = BigInt::from(2_u32).pow(width - 1).sub(1usize).mul(-1_i32);
  1000. // Generate a random number within the the range [-(2^N-1), -(2^N-1)/2]
  1001. let first_operand_rand =
  1002. rng.gen_bigint_range(&lower_limit, &(lower_limit.clone().div(2usize)).add(1usize));
  1003. let first_op_sign = first_operand_rand.sign();
  1004. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  1005. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  1006. contract.function_expect_failure(
  1007. "mul",
  1008. first_op_data.into_iter().chain(second_op_data).collect(),
  1009. );
  1010. }
  1011. }
  1012. #[test]
  1013. fn test_overflow_detect_unsigned() {
  1014. let mut rng = rand::thread_rng();
  1015. for width in (8..=256).step_by(8) {
  1016. let src = r#"
  1017. contract test {
  1018. function mul(uintN a, uintN b) public returns (uintN) {
  1019. return a * b;
  1020. }
  1021. }"#
  1022. .replace("intN", &format!("int{width}"));
  1023. let mut contract = build_solidity_with_options(&src, false, false);
  1024. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1].
  1025. let limit = BigUint::from(2_u32).pow(width).sub(1_u32);
  1026. // Generate a random number within the the range [(2^N-1)/2, 2^N -1]
  1027. let first_operand_rand =
  1028. rng.gen_biguint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  1029. let mut first_op_data = first_operand_rand.to_bytes_le();
  1030. let width_rounded = (width as usize / 8).next_power_of_two();
  1031. first_op_data.resize(width_rounded, 0);
  1032. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  1033. let second_operand_rand = rng.gen_biguint_range(&BigUint::from(2usize), &limit);
  1034. let mut second_op_data = second_operand_rand.to_bytes_le();
  1035. second_op_data.resize(width_rounded, 0);
  1036. contract.function_expect_failure(
  1037. "mul",
  1038. first_op_data.into_iter().chain(second_op_data).collect(),
  1039. );
  1040. }
  1041. }
  1042. #[test]
  1043. fn bytes_bitwise() {
  1044. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1045. struct Bytes3([u8; 3]);
  1046. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1047. struct Bytes5([u8; 5]);
  1048. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1049. struct BytesArray([u8; 7], u32);
  1050. // parse
  1051. let mut runtime = build_solidity(
  1052. "
  1053. contract c {
  1054. function or(bytes5 x) public returns (bytes5 y) {
  1055. y = x | hex\"80808080\";
  1056. }
  1057. function and(bytes5 x) public returns (bytes5) {
  1058. return x & hex\"FFFF\";
  1059. }
  1060. function xor(bytes5 x) public returns (bytes5) {
  1061. x ^= 0xFF00000000;
  1062. return x;
  1063. }
  1064. function shift_left(bytes3 a) public returns (bytes5 b) {
  1065. b = bytes5(a) << 8;
  1066. }
  1067. function shift_right(bytes3 a) public returns (bytes5 b) {
  1068. b = bytes5(a) >> 8;
  1069. }
  1070. function shift_left2(bytes3 a) public returns (bytes5 b) {
  1071. b = bytes5(a);
  1072. b <<= 8;
  1073. }
  1074. function shift_right2(bytes3 a) public returns (bytes5 b) {
  1075. b = bytes5(a);
  1076. b >>= 8;
  1077. }
  1078. function bytes_length() public {
  1079. bytes4 b4;
  1080. assert(b4.length == 4);
  1081. }
  1082. function complement(bytes3 a) public returns (bytes3) {
  1083. return ~a;
  1084. }
  1085. function bytes_array(bytes7 foo, uint32 index) public returns (bytes1) {
  1086. return foo[index];
  1087. }
  1088. }",
  1089. );
  1090. runtime.function("or", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1091. assert_eq!(
  1092. runtime.output(),
  1093. Bytes5([0x81, 0x81, 0x81, 0x81, 0x01]).encode()
  1094. );
  1095. runtime.function("and", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1096. assert_eq!(runtime.output(), Bytes5([0x01, 0x01, 0, 0, 0]).encode());
  1097. runtime.function("xor", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1098. assert_eq!(
  1099. runtime.output(),
  1100. Bytes5([0xfe, 0x01, 0x01, 0x01, 0x01]).encode()
  1101. );
  1102. // shifty-shift
  1103. runtime.function("shift_left", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1104. assert_eq!(
  1105. runtime.output(),
  1106. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1107. );
  1108. runtime.function("shift_right", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1109. assert_eq!(
  1110. runtime.output(),
  1111. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1112. );
  1113. // assignment versions
  1114. runtime.function("shift_left2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1115. assert_eq!(
  1116. runtime.output(),
  1117. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1118. );
  1119. runtime.function("shift_right2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1120. assert_eq!(
  1121. runtime.output(),
  1122. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1123. );
  1124. // check length
  1125. runtime.function("bytes_length", Vec::new());
  1126. // complement
  1127. runtime.function("complement", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1128. assert_eq!(runtime.output(), Bytes3([0x0c, 0x82, 0xfc]).encode());
  1129. // array access
  1130. let bytes7 = *b"NAWABRA";
  1131. for i in 0..6 {
  1132. runtime.function("bytes_array", BytesArray(bytes7, i).encode());
  1133. assert_eq!(runtime.output(), [bytes7[i as usize]]);
  1134. }
  1135. }
  1136. #[test]
  1137. fn bytesn_underflow_index_acccess() {
  1138. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1139. struct BytesArray([u8; 7], i32);
  1140. // parse
  1141. let mut runtime = build_solidity(
  1142. "
  1143. contract test {
  1144. function bytes_array(bytes7 foo, int32 index) public returns (bytes1) {
  1145. return foo[uint(index)];
  1146. }
  1147. }",
  1148. );
  1149. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", -1).encode());
  1150. }
  1151. #[test]
  1152. fn bytesn_overflow_index_acccess() {
  1153. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1154. struct BytesArray([u8; 7], i32);
  1155. // parse
  1156. let mut runtime = build_solidity(
  1157. "
  1158. contract test {
  1159. function bytes_array(bytes7 foo, int32 index) public returns (byte) {
  1160. return foo[uint(index)];
  1161. }
  1162. }",
  1163. );
  1164. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", 7).encode());
  1165. }
  1166. #[test]
  1167. fn negation_and_subtract() {
  1168. // The minus sign can be a unary negative or subtract.
  1169. let mut runtime = build_solidity(
  1170. r#"
  1171. contract c {
  1172. function test() public {
  1173. uint32 x = 10-10;
  1174. assert(x == 0);
  1175. int32 y = -10-10;
  1176. assert(y == -20);
  1177. }
  1178. }"#,
  1179. );
  1180. runtime.function("test", Vec::new());
  1181. }
  1182. #[test]
  1183. fn div() {
  1184. // The minus sign can be a unary negative or subtract.
  1185. let mut runtime = build_solidity(
  1186. r#"
  1187. contract c {
  1188. function test1() public {
  1189. // see https://solidity.readthedocs.io/en/latest/types.html#modulo
  1190. assert(int256(5) % int256(2) == int256(1));
  1191. assert(int256(5) % int256(-2) == int256(1));
  1192. assert(int256(-5) % int256(2) == int256(-1));
  1193. assert(int256(-5) % int256(-2) == int256(-1));
  1194. assert(int64(5) % int64(2) == int64(1));
  1195. assert(int64(5) % int64(-2) == int64(1));
  1196. assert(int64(-5) % int64(2) == int64(-1));
  1197. assert(int64(-5) % int64(-2) == int64(-1));
  1198. }
  1199. function test2() public {
  1200. // see https://github.com/hyperledger/burrow/pull/1367#issue-399914366
  1201. assert(int256(7) / int256(3) == int256(2));
  1202. assert(int256(7) / int256(-3) == int256(-2));
  1203. assert(int256(-7) / int256(3) == int256(-2));
  1204. assert(int256(-7) / int256(-3) == int256(2));
  1205. assert(int256(7) % int256(3) == int256(1));
  1206. assert(int256(7) % int256(-3) == int256(1));
  1207. assert(int256(-7) % int256(3) == int256(-1));
  1208. assert(int256(-7) % int256(-3) == int256(-1));
  1209. assert(int64(7) / int64(3) == int64(2));
  1210. assert(int64(7) / int64(-3) == int64(-2));
  1211. assert(int64(-7) / int64(3) == int64(-2));
  1212. assert(int64(-7) / int64(-3) == int64(2));
  1213. assert(int64(7) % int64(3) == int64(1));
  1214. assert(int64(7) % int64(-3) == int64(1));
  1215. assert(int64(-7) % int64(3) == int64(-1));
  1216. assert(int64(-7) % int64(-3) == int64(-1));
  1217. }
  1218. }"#,
  1219. );
  1220. runtime.function("test1", Vec::new());
  1221. runtime.function("test2", Vec::new());
  1222. }
  1223. #[test]
  1224. fn destructure() {
  1225. // The minus sign can be a unary negative or subtract.
  1226. let mut runtime = build_solidity(
  1227. r#"
  1228. contract c {
  1229. function test() public {
  1230. int a;
  1231. int b;
  1232. // test one
  1233. (a, b) = (102, 3);
  1234. assert(b == 3 && a == 102);
  1235. // test missing one
  1236. (a, , b) = (1, 2, 3);
  1237. assert(a == 1 && b == 3);
  1238. // test single one
  1239. (a) = 5;
  1240. assert(a == 5);
  1241. // or like so
  1242. (a) = (105);
  1243. assert(a == 105);
  1244. }
  1245. function swap() public {
  1246. int32 a;
  1247. int32 b;
  1248. // test one
  1249. (a, b) = (102, 3);
  1250. // test swap
  1251. (b, a) = (a, b);
  1252. assert(a == 3 && b == 102);
  1253. }
  1254. }"#,
  1255. );
  1256. runtime.function("test", Vec::new());
  1257. runtime.function("swap", Vec::new());
  1258. // The minus sign can be a unary negative or subtract.
  1259. let mut runtime = build_solidity(
  1260. r#"
  1261. contract c {
  1262. function test() public {
  1263. // test one
  1264. (int32 a, int32 b) = (102, 3);
  1265. assert(b == 3 && a == 102);
  1266. // test missing one
  1267. (a, , b) = (1, 2, 3);
  1268. assert(a == 1 && b == 3);
  1269. // test single one
  1270. (a) = 5;
  1271. assert(a == 5);
  1272. // or like so
  1273. (a) = (105);
  1274. assert(a == 105);
  1275. }
  1276. }"#,
  1277. );
  1278. runtime.function("test", Vec::new());
  1279. }
  1280. #[test]
  1281. fn addition_overflow() {
  1282. let mut runtime = build_solidity_with_options(
  1283. r#"
  1284. contract overflow {
  1285. function foo(uint8 x) internal returns (uint8) {
  1286. uint8 y = x + 1;
  1287. return y;
  1288. }
  1289. function bar() public {
  1290. foo(255);
  1291. }
  1292. }
  1293. "#,
  1294. false,
  1295. false,
  1296. );
  1297. runtime.function_expect_failure("bar", Vec::new());
  1298. }
  1299. #[test]
  1300. fn unchecked_addition_overflow() {
  1301. let mut runtime = build_solidity_with_options(
  1302. r#"
  1303. contract overflow {
  1304. function foo(uint8 x) internal returns (uint8) {
  1305. unchecked {
  1306. uint8 y = x + 1;
  1307. return y;
  1308. }
  1309. }
  1310. function bar() public {
  1311. foo(255);
  1312. }
  1313. }
  1314. "#,
  1315. false,
  1316. false,
  1317. );
  1318. runtime.function("bar", Vec::new());
  1319. }
  1320. #[test]
  1321. fn subtraction_underflow() {
  1322. let mut runtime = build_solidity_with_options(
  1323. r#"
  1324. contract underflow {
  1325. function foo(uint64 x) internal returns (uint64) {
  1326. uint64 y = x - 1;
  1327. return y;
  1328. }
  1329. function bar() public {
  1330. foo(0);
  1331. }
  1332. }
  1333. "#,
  1334. false,
  1335. false,
  1336. );
  1337. runtime.function_expect_failure("bar", Vec::new());
  1338. }
  1339. #[test]
  1340. fn unchecked_subtraction_underflow() {
  1341. let mut runtime = build_solidity_with_options(
  1342. r#"
  1343. contract underflow {
  1344. function foo(uint64 x) internal returns (uint64) {
  1345. unchecked {
  1346. uint64 y = x - 1;
  1347. return y;
  1348. }
  1349. }
  1350. function bar() public {
  1351. foo(0);
  1352. }
  1353. }
  1354. "#,
  1355. false,
  1356. false,
  1357. );
  1358. runtime.function("bar", Vec::new());
  1359. }
  1360. #[test]
  1361. fn multiplication_overflow() {
  1362. let mut runtime = build_solidity_with_options(
  1363. r#"
  1364. contract overflow {
  1365. function foo(int8 x) internal returns (int8) {
  1366. int8 y = x * int8(64);
  1367. return y;
  1368. }
  1369. function bar() public {
  1370. foo(8);
  1371. }
  1372. }
  1373. "#,
  1374. false,
  1375. false,
  1376. );
  1377. runtime.function_expect_failure("bar", Vec::new());
  1378. }
  1379. #[test]
  1380. fn unchecked_multiplication_overflow() {
  1381. let mut runtime = build_solidity_with_options(
  1382. r#"
  1383. contract overflow {
  1384. function foo(int8 x) internal returns (int8) {
  1385. unchecked {
  1386. int8 y = x * int8(64);
  1387. return y;
  1388. }
  1389. }
  1390. function bar() public {
  1391. foo(8);
  1392. }
  1393. }
  1394. "#,
  1395. false,
  1396. false,
  1397. );
  1398. runtime.function("bar", Vec::new());
  1399. }
  1400. #[test]
  1401. fn address_compare() {
  1402. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1403. struct Args([u8; 32], [u8; 32]);
  1404. let mut runtime = build_solidity(
  1405. r#"
  1406. contract addr {
  1407. function bar() public {
  1408. address left = address(1);
  1409. address right = address(2);
  1410. assert(left < right);
  1411. assert(left <= right);
  1412. assert(right > left);
  1413. assert(right >= left);
  1414. }
  1415. function order(address tokenA, address tokenB) external returns (address token0, address token1) {
  1416. require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
  1417. (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
  1418. }
  1419. }"#,
  1420. );
  1421. runtime.function("bar", Vec::new());
  1422. let address0: [u8; 32] = [
  1423. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1424. 0, 1,
  1425. ];
  1426. let address1: [u8; 32] = [
  1427. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1428. 0, 2,
  1429. ];
  1430. runtime.function("order", Args(address0, address1).encode());
  1431. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1432. runtime.function("order", Args(address1, address0).encode());
  1433. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1434. }
  1435. #[test]
  1436. fn address_pass_by_value() {
  1437. let mut runtime = build_solidity(
  1438. r#"
  1439. contract addr {
  1440. function bar() public {
  1441. address left = address(1);
  1442. foo(left);
  1443. assert(left == address(1));
  1444. }
  1445. function foo(address a) internal {
  1446. a = address(2);
  1447. }
  1448. }"#,
  1449. );
  1450. runtime.function("bar", Vec::new());
  1451. }
  1452. fn sign_extend(sign: Sign) -> u8 {
  1453. if sign == Sign::Minus {
  1454. 255
  1455. } else {
  1456. 0
  1457. }
  1458. }