expressions.rs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864
  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 a = rng.gen_bigint((width - 1).try_into().unwrap()).sub(1_u32);
  819. let a_sign = a.sign();
  820. let mut a_data = a.to_signed_bytes_le();
  821. let side = [-1, 0, 1];
  822. let b = BigInt::from(*side.choose(&mut rng).unwrap());
  823. let b_sign = b.sign();
  824. let mut b_data = b.to_signed_bytes_le();
  825. a_data.resize(width_rounded, sign_extend(a_sign));
  826. b_data.resize(width_rounded, sign_extend(b_sign));
  827. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  828. let value = a * b;
  829. let value_sign = value.sign();
  830. let mut value_data = value.to_signed_bytes_le();
  831. value_data.resize(width / 8, sign_extend(value_sign));
  832. assert_eq!(value_data, runtime.output()[..width / 8]);
  833. }
  834. }
  835. #[test]
  836. fn test_mul_within_range() {
  837. let mut rng = rand::thread_rng();
  838. for width in (8..=256).step_by(8) {
  839. let src = r#"
  840. contract test {
  841. function mul(uintN a, uintN b) public returns (uintN) {
  842. return a * b;
  843. }
  844. }"#
  845. .replace("intN", &format!("int{width}"));
  846. let width_rounded = (width / 8usize).next_power_of_two();
  847. let mut runtime = build_solidity(&src);
  848. // 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
  849. let a = rng.gen_biguint((width).try_into().unwrap());
  850. let mut a_data = a.to_bytes_le();
  851. let b = BigUint::from(1_u32);
  852. let mut b_data = b.to_bytes_le();
  853. a_data.resize(width_rounded, 0);
  854. b_data.resize(width_rounded, 0);
  855. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  856. let value = a * b;
  857. let mut value_data = value.to_bytes_le();
  858. value_data.resize(width / 8, 0);
  859. assert_eq!(value_data, runtime.output()[..width / 8]);
  860. }
  861. }
  862. #[test]
  863. fn test_overflow_boundaries() {
  864. for width in (8..=256).step_by(8) {
  865. let src = r#"
  866. contract test {
  867. function mul(intN a, intN b) public returns (intN) {
  868. return a * b;
  869. }
  870. }"#
  871. .replace("intN", &format!("int{width}"));
  872. let mut contract = build_solidity_with_options(&src, false, false);
  873. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1]. We generate these boundaries:
  874. let upper_boundary = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  875. let mut up_data = upper_boundary.to_signed_bytes_le();
  876. let lower_boundary = BigInt::from(2_u32).pow(width - 1).mul(-1_i32);
  877. let mut low_data = lower_boundary.to_signed_bytes_le();
  878. let second_op = BigInt::from(1_u32);
  879. let mut sec_data = second_op.to_signed_bytes_le();
  880. let width_rounded = (width as usize / 8).next_power_of_two();
  881. up_data.resize(width_rounded, 0);
  882. low_data.resize(width_rounded, 255);
  883. sec_data.resize(width_rounded, 0);
  884. // Multiply the boundaries by 1.
  885. contract.function(
  886. "mul",
  887. up_data
  888. .clone()
  889. .into_iter()
  890. .chain(sec_data.clone())
  891. .collect(),
  892. );
  893. let res = upper_boundary.clone().mul(1_u32);
  894. let mut res_data = res.to_signed_bytes_le();
  895. res_data.resize((width / 8) as usize, 0);
  896. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  897. contract.function(
  898. "mul",
  899. low_data
  900. .clone()
  901. .into_iter()
  902. .chain(sec_data.clone())
  903. .collect(),
  904. );
  905. let res = lower_boundary.clone().mul(1_u32);
  906. let mut res_data = res.to_signed_bytes_le();
  907. res_data.resize((width / 8) as usize, 0);
  908. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  909. let upper_boundary_plus_one = BigInt::from(2_u32).pow(width - 1);
  910. // We subtract 2 instead of one to make the number even, so that no rounding occurs when we divide by 2 later on.
  911. let lower_boundary_minus_two = BigInt::from(2_u32).pow(width - 1).mul(-1_i32).sub(2_i32);
  912. let upper_second_op = upper_boundary_plus_one.div(2_u32);
  913. let mut upper_second_op_data = upper_second_op.to_signed_bytes_le();
  914. let lower_second_op = lower_boundary_minus_two.div(2_u32);
  915. let mut lower_second_op_data = lower_second_op.to_signed_bytes_le();
  916. let mut two_data = BigInt::from(2_u32).to_signed_bytes_le();
  917. upper_second_op_data.resize(width_rounded, 0);
  918. two_data.resize(width_rounded, 0);
  919. lower_second_op_data.resize(width_rounded, 255);
  920. // This will generate a value more than the upper boundary.
  921. contract.function_expect_failure(
  922. "mul",
  923. upper_second_op_data
  924. .clone()
  925. .into_iter()
  926. .chain(two_data.clone())
  927. .collect(),
  928. );
  929. // Generate a value less than the lower boundary
  930. contract.function_expect_failure(
  931. "mul",
  932. lower_second_op_data
  933. .clone()
  934. .into_iter()
  935. .chain(two_data.clone())
  936. .collect(),
  937. );
  938. // Upper boundary * Upper boundary
  939. contract.function_expect_failure(
  940. "mul",
  941. up_data.clone().into_iter().chain(up_data.clone()).collect(),
  942. );
  943. // Lower boundary * Lower boundary
  944. contract.function_expect_failure(
  945. "mul",
  946. low_data
  947. .clone()
  948. .into_iter()
  949. .chain(low_data.clone())
  950. .collect(),
  951. );
  952. // Lower boundary * Upper boundary
  953. contract.function_expect_failure(
  954. "mul",
  955. low_data
  956. .clone()
  957. .into_iter()
  958. .chain(up_data.clone())
  959. .collect(),
  960. );
  961. }
  962. }
  963. #[test]
  964. fn test_overflow_detect_signed() {
  965. let mut rng = rand::thread_rng();
  966. for width in (8..=256).step_by(8) {
  967. let src = r#"
  968. contract test {
  969. function mul(intN a, intN b) public returns (intN) {
  970. return a * b;
  971. }
  972. }"#
  973. .replace("intN", &format!("int{width}"));
  974. let mut contract = build_solidity_with_options(&src, false, false);
  975. // 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:
  976. let limit = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  977. // Generate a random number within the the range [(2^N-1)/2, (2^N-1) -1]
  978. let first_operand_rand =
  979. rng.gen_bigint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  980. let first_op_sign = first_operand_rand.sign();
  981. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  982. let width_rounded = (width as usize / 8).next_power_of_two();
  983. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  984. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  985. let second_operand_rand = rng.gen_bigint_range(&BigInt::from(2usize), &limit);
  986. let second_op_sign = second_operand_rand.sign();
  987. let mut second_op_data = second_operand_rand.to_signed_bytes_le();
  988. second_op_data.resize(width_rounded, sign_extend(second_op_sign));
  989. contract.function_expect_failure(
  990. "mul",
  991. first_op_data
  992. .into_iter()
  993. .chain(second_op_data.clone())
  994. .collect(),
  995. );
  996. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1] .
  997. let lower_limit = BigInt::from(2_u32).pow(width - 1).sub(1usize).mul(-1_i32);
  998. // Generate a random number within the the range [-(2^N-1), -(2^N-1)/2]
  999. let first_operand_rand =
  1000. rng.gen_bigint_range(&lower_limit, &(lower_limit.clone().div(2usize)).add(1usize));
  1001. let first_op_sign = first_operand_rand.sign();
  1002. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  1003. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  1004. contract.function_expect_failure(
  1005. "mul",
  1006. first_op_data.into_iter().chain(second_op_data).collect(),
  1007. );
  1008. }
  1009. }
  1010. #[test]
  1011. fn test_overflow_detect_unsigned() {
  1012. let mut rng = rand::thread_rng();
  1013. for width in (8..=256).step_by(8) {
  1014. let src = r#"
  1015. contract test {
  1016. function mul(uintN a, uintN b) public returns (uintN) {
  1017. return a * b;
  1018. }
  1019. }"#
  1020. .replace("intN", &format!("int{width}"));
  1021. let mut contract = build_solidity_with_options(&src, false, false);
  1022. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1].
  1023. let limit = BigUint::from(2_u32).pow(width).sub(1_u32);
  1024. // Generate a random number within the the range [(2^N-1)/2, 2^N -1]
  1025. let first_operand_rand =
  1026. rng.gen_biguint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  1027. let mut first_op_data = first_operand_rand.to_bytes_le();
  1028. let width_rounded = (width as usize / 8).next_power_of_two();
  1029. first_op_data.resize(width_rounded, 0);
  1030. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  1031. let second_operand_rand = rng.gen_biguint_range(&BigUint::from(2usize), &limit);
  1032. let mut second_op_data = second_operand_rand.to_bytes_le();
  1033. second_op_data.resize(width_rounded, 0);
  1034. contract.function_expect_failure(
  1035. "mul",
  1036. first_op_data.into_iter().chain(second_op_data).collect(),
  1037. );
  1038. }
  1039. }
  1040. #[test]
  1041. fn bytes_bitwise() {
  1042. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1043. struct Bytes3([u8; 3]);
  1044. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1045. struct Bytes5([u8; 5]);
  1046. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1047. struct BytesArray([u8; 7], u32);
  1048. // parse
  1049. let mut runtime = build_solidity(
  1050. "
  1051. contract c {
  1052. function or(bytes5 x) public returns (bytes5 y) {
  1053. y = x | hex\"80808080\";
  1054. }
  1055. function and(bytes5 x) public returns (bytes5) {
  1056. return x & hex\"FFFF\";
  1057. }
  1058. function xor(bytes5 x) public returns (bytes5) {
  1059. x ^= 0xFF00000000;
  1060. return x;
  1061. }
  1062. function shift_left(bytes3 a) public returns (bytes5 b) {
  1063. b = bytes5(a) << 8;
  1064. }
  1065. function shift_right(bytes3 a) public returns (bytes5 b) {
  1066. b = bytes5(a) >> 8;
  1067. }
  1068. function shift_left2(bytes3 a) public returns (bytes5 b) {
  1069. b = bytes5(a);
  1070. b <<= 8;
  1071. }
  1072. function shift_right2(bytes3 a) public returns (bytes5 b) {
  1073. b = bytes5(a);
  1074. b >>= 8;
  1075. }
  1076. function bytes_length() public {
  1077. bytes4 b4;
  1078. assert(b4.length == 4);
  1079. }
  1080. function complement(bytes3 a) public returns (bytes3) {
  1081. return ~a;
  1082. }
  1083. function bytes_array(bytes7 foo, uint32 index) public returns (bytes1) {
  1084. return foo[index];
  1085. }
  1086. }",
  1087. );
  1088. runtime.function("or", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1089. assert_eq!(
  1090. runtime.output(),
  1091. Bytes5([0x81, 0x81, 0x81, 0x81, 0x01]).encode()
  1092. );
  1093. runtime.function("and", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1094. assert_eq!(runtime.output(), Bytes5([0x01, 0x01, 0, 0, 0]).encode());
  1095. runtime.function("xor", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1096. assert_eq!(
  1097. runtime.output(),
  1098. Bytes5([0xfe, 0x01, 0x01, 0x01, 0x01]).encode()
  1099. );
  1100. // shifty-shift
  1101. runtime.function("shift_left", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1102. assert_eq!(
  1103. runtime.output(),
  1104. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1105. );
  1106. runtime.function("shift_right", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1107. assert_eq!(
  1108. runtime.output(),
  1109. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1110. );
  1111. // assignment versions
  1112. runtime.function("shift_left2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1113. assert_eq!(
  1114. runtime.output(),
  1115. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1116. );
  1117. runtime.function("shift_right2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1118. assert_eq!(
  1119. runtime.output(),
  1120. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1121. );
  1122. // check length
  1123. runtime.function("bytes_length", Vec::new());
  1124. // complement
  1125. runtime.function("complement", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1126. assert_eq!(runtime.output(), Bytes3([0x0c, 0x82, 0xfc]).encode());
  1127. // array access
  1128. let bytes7 = *b"NAWABRA";
  1129. for i in 0..6 {
  1130. runtime.function("bytes_array", BytesArray(bytes7, i).encode());
  1131. assert_eq!(runtime.output(), [bytes7[i as usize]]);
  1132. }
  1133. }
  1134. #[test]
  1135. fn bytesn_underflow_index_acccess() {
  1136. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1137. struct BytesArray([u8; 7], i32);
  1138. // parse
  1139. let mut runtime = build_solidity(
  1140. "
  1141. contract test {
  1142. function bytes_array(bytes7 foo, int32 index) public returns (bytes1) {
  1143. return foo[uint(index)];
  1144. }
  1145. }",
  1146. );
  1147. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", -1).encode());
  1148. }
  1149. #[test]
  1150. fn bytesn_overflow_index_acccess() {
  1151. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1152. struct BytesArray([u8; 7], i32);
  1153. // parse
  1154. let mut runtime = build_solidity(
  1155. "
  1156. contract test {
  1157. function bytes_array(bytes7 foo, int32 index) public returns (byte) {
  1158. return foo[uint(index)];
  1159. }
  1160. }",
  1161. );
  1162. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", 7).encode());
  1163. }
  1164. #[test]
  1165. fn negation_and_subtract() {
  1166. // The minus sign can be a unary negative or subtract.
  1167. let mut runtime = build_solidity(
  1168. r#"
  1169. contract c {
  1170. function test() public {
  1171. uint32 x = 10-10;
  1172. assert(x == 0);
  1173. int32 y = -10-10;
  1174. assert(y == -20);
  1175. }
  1176. }"#,
  1177. );
  1178. runtime.function("test", Vec::new());
  1179. }
  1180. #[test]
  1181. fn div() {
  1182. // The minus sign can be a unary negative or subtract.
  1183. let mut runtime = build_solidity(
  1184. r#"
  1185. contract c {
  1186. function test1() public {
  1187. // see https://solidity.readthedocs.io/en/latest/types.html#modulo
  1188. assert(int256(5) % int256(2) == int256(1));
  1189. assert(int256(5) % int256(-2) == int256(1));
  1190. assert(int256(-5) % int256(2) == int256(-1));
  1191. assert(int256(-5) % int256(-2) == int256(-1));
  1192. assert(int64(5) % int64(2) == int64(1));
  1193. assert(int64(5) % int64(-2) == int64(1));
  1194. assert(int64(-5) % int64(2) == int64(-1));
  1195. assert(int64(-5) % int64(-2) == int64(-1));
  1196. }
  1197. function test2() public {
  1198. // see https://github.com/hyperledger/burrow/pull/1367#issue-399914366
  1199. assert(int256(7) / int256(3) == int256(2));
  1200. assert(int256(7) / int256(-3) == int256(-2));
  1201. assert(int256(-7) / int256(3) == int256(-2));
  1202. assert(int256(-7) / int256(-3) == int256(2));
  1203. assert(int256(7) % int256(3) == int256(1));
  1204. assert(int256(7) % int256(-3) == int256(1));
  1205. assert(int256(-7) % int256(3) == int256(-1));
  1206. assert(int256(-7) % int256(-3) == int256(-1));
  1207. assert(int64(7) / int64(3) == int64(2));
  1208. assert(int64(7) / int64(-3) == int64(-2));
  1209. assert(int64(-7) / int64(3) == int64(-2));
  1210. assert(int64(-7) / int64(-3) == int64(2));
  1211. assert(int64(7) % int64(3) == int64(1));
  1212. assert(int64(7) % int64(-3) == int64(1));
  1213. assert(int64(-7) % int64(3) == int64(-1));
  1214. assert(int64(-7) % int64(-3) == int64(-1));
  1215. }
  1216. }"#,
  1217. );
  1218. runtime.function("test1", Vec::new());
  1219. runtime.function("test2", Vec::new());
  1220. }
  1221. #[test]
  1222. fn destructure() {
  1223. // The minus sign can be a unary negative or subtract.
  1224. let mut runtime = build_solidity(
  1225. r#"
  1226. contract c {
  1227. function test() public {
  1228. int a;
  1229. int b;
  1230. // test one
  1231. (a, b) = (102, 3);
  1232. assert(b == 3 && a == 102);
  1233. // test missing one
  1234. (a, , b) = (1, 2, 3);
  1235. assert(a == 1 && b == 3);
  1236. // test single one
  1237. (a) = 5;
  1238. assert(a == 5);
  1239. // or like so
  1240. (a) = (105);
  1241. assert(a == 105);
  1242. }
  1243. function swap() public {
  1244. int32 a;
  1245. int32 b;
  1246. // test one
  1247. (a, b) = (102, 3);
  1248. // test swap
  1249. (b, a) = (a, b);
  1250. assert(a == 3 && b == 102);
  1251. }
  1252. }"#,
  1253. );
  1254. runtime.function("test", Vec::new());
  1255. runtime.function("swap", Vec::new());
  1256. // The minus sign can be a unary negative or subtract.
  1257. let mut runtime = build_solidity(
  1258. r#"
  1259. contract c {
  1260. function test() public {
  1261. // test one
  1262. (int32 a, int32 b) = (102, 3);
  1263. assert(b == 3 && a == 102);
  1264. // test missing one
  1265. (a, , b) = (1, 2, 3);
  1266. assert(a == 1 && b == 3);
  1267. // test single one
  1268. (a) = 5;
  1269. assert(a == 5);
  1270. // or like so
  1271. (a) = (105);
  1272. assert(a == 105);
  1273. }
  1274. }"#,
  1275. );
  1276. runtime.function("test", Vec::new());
  1277. }
  1278. #[test]
  1279. fn addition_overflow() {
  1280. let mut runtime = build_solidity_with_options(
  1281. r#"
  1282. contract overflow {
  1283. function foo(uint8 x) internal returns (uint8) {
  1284. uint8 y = x + 1;
  1285. return y;
  1286. }
  1287. function bar() public {
  1288. foo(255);
  1289. }
  1290. }
  1291. "#,
  1292. false,
  1293. false,
  1294. );
  1295. runtime.function_expect_failure("bar", Vec::new());
  1296. }
  1297. #[test]
  1298. fn unchecked_addition_overflow() {
  1299. let mut runtime = build_solidity_with_options(
  1300. r#"
  1301. contract overflow {
  1302. function foo(uint8 x) internal returns (uint8) {
  1303. unchecked {
  1304. uint8 y = x + 1;
  1305. return y;
  1306. }
  1307. }
  1308. function bar() public {
  1309. foo(255);
  1310. }
  1311. }
  1312. "#,
  1313. false,
  1314. false,
  1315. );
  1316. runtime.function("bar", Vec::new());
  1317. }
  1318. #[test]
  1319. fn subtraction_underflow() {
  1320. let mut runtime = build_solidity_with_options(
  1321. r#"
  1322. contract underflow {
  1323. function foo(uint64 x) internal returns (uint64) {
  1324. uint64 y = x - 1;
  1325. return y;
  1326. }
  1327. function bar() public {
  1328. foo(0);
  1329. }
  1330. }
  1331. "#,
  1332. false,
  1333. false,
  1334. );
  1335. runtime.function_expect_failure("bar", Vec::new());
  1336. }
  1337. #[test]
  1338. fn unchecked_subtraction_underflow() {
  1339. let mut runtime = build_solidity_with_options(
  1340. r#"
  1341. contract underflow {
  1342. function foo(uint64 x) internal returns (uint64) {
  1343. unchecked {
  1344. uint64 y = x - 1;
  1345. return y;
  1346. }
  1347. }
  1348. function bar() public {
  1349. foo(0);
  1350. }
  1351. }
  1352. "#,
  1353. false,
  1354. false,
  1355. );
  1356. runtime.function("bar", Vec::new());
  1357. }
  1358. #[test]
  1359. fn multiplication_overflow() {
  1360. let mut runtime = build_solidity_with_options(
  1361. r#"
  1362. contract overflow {
  1363. function foo(int8 x) internal returns (int8) {
  1364. int8 y = x * int8(64);
  1365. return y;
  1366. }
  1367. function bar() public {
  1368. foo(8);
  1369. }
  1370. }
  1371. "#,
  1372. false,
  1373. false,
  1374. );
  1375. runtime.function_expect_failure("bar", Vec::new());
  1376. }
  1377. #[test]
  1378. fn unchecked_multiplication_overflow() {
  1379. let mut runtime = build_solidity_with_options(
  1380. r#"
  1381. contract overflow {
  1382. function foo(int8 x) internal returns (int8) {
  1383. unchecked {
  1384. int8 y = x * int8(64);
  1385. return y;
  1386. }
  1387. }
  1388. function bar() public {
  1389. foo(8);
  1390. }
  1391. }
  1392. "#,
  1393. false,
  1394. false,
  1395. );
  1396. runtime.function("bar", Vec::new());
  1397. }
  1398. #[test]
  1399. fn address_compare() {
  1400. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1401. struct Args([u8; 32], [u8; 32]);
  1402. let mut runtime = build_solidity(
  1403. r#"
  1404. contract addr {
  1405. function bar() public {
  1406. address left = address(1);
  1407. address right = address(2);
  1408. assert(left < right);
  1409. assert(left <= right);
  1410. assert(right > left);
  1411. assert(right >= left);
  1412. }
  1413. function order(address tokenA, address tokenB) external returns (address token0, address token1) {
  1414. require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
  1415. (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
  1416. }
  1417. }"#,
  1418. );
  1419. runtime.function("bar", Vec::new());
  1420. let address0: [u8; 32] = [
  1421. 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,
  1422. 0, 1,
  1423. ];
  1424. let address1: [u8; 32] = [
  1425. 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,
  1426. 0, 2,
  1427. ];
  1428. runtime.function("order", Args(address0, address1).encode());
  1429. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1430. runtime.function("order", Args(address1, address0).encode());
  1431. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1432. }
  1433. #[test]
  1434. fn address_pass_by_value() {
  1435. let mut runtime = build_solidity(
  1436. r#"
  1437. contract addr {
  1438. function bar() public {
  1439. address left = address(1);
  1440. foo(left);
  1441. assert(left == address(1));
  1442. }
  1443. function foo(address a) internal {
  1444. a = address(2);
  1445. }
  1446. }"#,
  1447. );
  1448. runtime.function("bar", Vec::new());
  1449. }
  1450. fn sign_extend(sign: Sign) -> u8 {
  1451. if sign == Sign::Minus {
  1452. 255
  1453. } else {
  1454. 0
  1455. }
  1456. }