expressions.rs 51 KB

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