expressions.rs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882
  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 args = vec![0; 32];
  380. runtime.function("do_complement", args);
  381. let ret = runtime.output();
  382. assert!(ret.len() == 32);
  383. assert!(ret.into_iter().filter(|x| *x == 255).count() == 32);
  384. }
  385. #[test]
  386. fn bitwise() {
  387. // parse
  388. let mut runtime = build_solidity(
  389. "
  390. contract test {
  391. function do_test() public {
  392. uint8 x1 = 0xf0;
  393. uint8 x2 = 0x0f;
  394. assert(x1 | x2 == 0xff);
  395. assert(x1 ^ x2 == 0xff);
  396. assert(x1 & x2 == 0x00);
  397. assert(x1 ^ 0 == x1);
  398. int32 x3 = 0x7fefabcd;
  399. assert(x3 & 0xffff == 0xabcd);
  400. }
  401. function do_or(uint256 a, uint256 b) public returns (uint) {
  402. return a | b;
  403. }
  404. function do_and(uint256 a, uint256 b) public returns (uint) {
  405. return a & b;
  406. }
  407. function do_xor(uint256 a, uint256 b) public returns (uint) {
  408. return a ^ b;
  409. }
  410. }",
  411. );
  412. runtime.function("do_test", Vec::new());
  413. let mut args = vec![0; 32];
  414. args.resize(64, 0xff);
  415. runtime.function("do_xor", args);
  416. let ret = &runtime.output();
  417. assert!(ret.len() == 32);
  418. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  419. let mut args = vec![0; 32];
  420. args.resize(64, 0xff);
  421. runtime.function("do_or", args);
  422. let ret = &runtime.output();
  423. assert!(ret.len() == 32);
  424. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  425. let mut args = vec![0; 32];
  426. args.resize(64, 0xff);
  427. runtime.function("do_and", args);
  428. let ret = &runtime.output();
  429. assert!(ret.len() == 32);
  430. assert!(ret.iter().filter(|x| **x == 0).count() == 32);
  431. }
  432. #[test]
  433. fn shift() {
  434. // parse
  435. let mut runtime = build_solidity(
  436. "
  437. contract test {
  438. function do_test() public {
  439. uint8 x1 = 0xf0;
  440. uint8 x2 = 0x0f;
  441. assert(x1 >> 4 == 0x0f);
  442. assert(x2 << 4 == 0xf0);
  443. int x3 = -16;
  444. assert(x3 >> 2 == -4);
  445. uint x5 = 0xdead_0000_0000_0000_0000;
  446. assert(x5 >> 64 == 0xdead);
  447. x5 = 0xdead;
  448. assert(x5 << 64 == 0xdead_0000_0000_0000_0000);
  449. }
  450. }",
  451. );
  452. runtime.function("do_test", Vec::new());
  453. }
  454. #[test]
  455. fn assign_bitwise() {
  456. // parse
  457. let mut runtime = build_solidity(
  458. "
  459. contract test {
  460. function do_test() public {
  461. uint8 x1 = 0xf0;
  462. uint8 x2 = 0x0f;
  463. x1 |= x2;
  464. assert(x1 == 0xff);
  465. x1 = 0xf0; x2 = 0x0f;
  466. x1 ^= x2;
  467. assert(x1 == 0xff);
  468. x1 = 0xf0; x2 = 0x0f;
  469. x1 &= x2;
  470. assert(x1 == 0x00);
  471. x1 = 0xf0; x2 = 0x0f;
  472. x1 ^= 0;
  473. assert(x1 == x1);
  474. int32 x3 = 0x7fefabcd;
  475. x3 &= 0xffff;
  476. assert(x3 == 0xabcd);
  477. }
  478. function do_or(uint256 a, uint256 b) public returns (uint) {
  479. a |= b;
  480. return a;
  481. }
  482. function do_and(uint256 a, uint256 b) public returns (uint) {
  483. a &= b;
  484. return a;
  485. }
  486. function do_xor(uint256 a, uint256 b) public returns (uint) {
  487. a ^= b;
  488. return a;
  489. }
  490. }",
  491. );
  492. runtime.function("do_test", Vec::new());
  493. let mut args = vec![0; 32];
  494. args.resize(64, 0xff);
  495. runtime.function("do_xor", args);
  496. let ret = &runtime.output();
  497. assert!(ret.len() == 32);
  498. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  499. let mut args = vec![0; 32];
  500. args.resize(64, 0xff);
  501. runtime.function("do_or", args);
  502. let ret = &runtime.output();
  503. assert!(ret.len() == 32);
  504. assert!(ret.iter().filter(|x| **x == 255).count() == 32);
  505. let mut args = vec![0; 32];
  506. args.resize(64, 0xff);
  507. runtime.function("do_and", args);
  508. let ret = &runtime.output();
  509. assert!(ret.len() == 32);
  510. assert!(ret.iter().filter(|x| **x == 0).count() == 32);
  511. }
  512. #[test]
  513. fn assign_shift() {
  514. // parse
  515. let mut runtime = build_solidity(
  516. "
  517. contract test {
  518. function do_test() public {
  519. uint8 x1 = 0xf0;
  520. uint8 x2 = 0x0f;
  521. x1 >>= 4;
  522. x2 <<= 4;
  523. assert(x1 == 0x0f);
  524. assert(x2 == 0xf0);
  525. int x3 = -16;
  526. x3 >>= 2;
  527. assert(x3 == -4);
  528. uint x5 = 0xdead_0000_0000_0000_0000;
  529. x5 >>= 64;
  530. assert(x5 == 0xdead);
  531. x5 = 0xdead;
  532. x5 <<= 64;
  533. assert(x5 == 0xdead_0000_0000_0000_0000);
  534. }
  535. }",
  536. );
  537. runtime.function("do_test", Vec::new());
  538. }
  539. #[test]
  540. fn ternary() {
  541. // parse
  542. let mut runtime = build_solidity(
  543. "
  544. contract test {
  545. function do_test() public {
  546. uint8 x1 = 0xf0;
  547. uint8 x2 = 0x0f;
  548. assert((false ? x1 : x2) == x2);
  549. assert((true ? x1 : x2) == x1);
  550. }
  551. }",
  552. );
  553. runtime.function("do_test", Vec::new());
  554. }
  555. #[test]
  556. fn short_circuit_or() {
  557. // parse
  558. let mut runtime = build_solidity(
  559. "
  560. contract test {
  561. uint32 counter;
  562. function increase_counter() private returns (bool) {
  563. counter += 1;
  564. return true;
  565. }
  566. function increase_counter2() private returns (bool) {
  567. counter++;
  568. return true;
  569. }
  570. function do_test() public {
  571. assert(counter == 0);
  572. // if left of or is true, right is not evaluated
  573. assert(true || increase_counter());
  574. assert(counter == 0);
  575. assert(false || increase_counter2());
  576. assert(counter == 1);
  577. false && increase_counter();
  578. assert(counter == 1);
  579. true && increase_counter();
  580. assert(counter == 2);
  581. }
  582. }",
  583. );
  584. runtime.function("do_test", Vec::new());
  585. }
  586. #[test]
  587. fn short_circuit_and() {
  588. // parse
  589. let mut runtime = build_solidity(
  590. "
  591. contract test {
  592. uint32 counter;
  593. function increase_counter() private returns (bool) {
  594. counter |= 1;
  595. return false;
  596. }
  597. function increase_counter2() private returns (bool) {
  598. ++counter;
  599. return false;
  600. }
  601. function do_test() public {
  602. assert(counter == 0);
  603. increase_counter2();
  604. increase_counter2();
  605. assert(counter == 2);
  606. increase_counter();
  607. assert(counter == 3);
  608. counter = 0;
  609. // if left hand side is false, right hand side is not evaluated
  610. assert(!(false && increase_counter()));
  611. assert(counter == 0);
  612. assert(!(true && increase_counter2()));
  613. assert(counter == 1);
  614. false && increase_counter2();
  615. assert(counter == 1);
  616. counter = 0;
  617. true && increase_counter();
  618. assert(counter == 1);
  619. }
  620. }",
  621. );
  622. runtime.function("do_test", Vec::new());
  623. }
  624. #[test]
  625. fn power() {
  626. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  627. struct Val(u64);
  628. // parse
  629. let mut runtime = build_solidity(
  630. "
  631. contract c {
  632. function power(uint64 base, uint64 exp) public returns (uint64) {
  633. return base ** exp;
  634. }
  635. function power_with_cast() public returns (uint64) {
  636. return uint64(2 ** 32);
  637. }
  638. }",
  639. );
  640. // 4**5 = 1024
  641. let args = Val(4).encode().into_iter().chain(Val(5).encode()).collect();
  642. runtime.function("power", args);
  643. assert_eq!(runtime.output(), Val(1024).encode());
  644. // n ** 1 = n
  645. let args = Val(2345)
  646. .encode()
  647. .into_iter()
  648. .chain(Val(1).encode())
  649. .collect();
  650. runtime.function("power", args);
  651. assert_eq!(runtime.output(), Val(2345).encode());
  652. // n ** 0 = 0
  653. let args = Val(0xdead_beef)
  654. .encode()
  655. .into_iter()
  656. .chain(Val(0).encode())
  657. .collect();
  658. runtime.function("power", args);
  659. assert_eq!(runtime.output(), Val(1).encode());
  660. // 0 ** n = 0
  661. let args = Val(0)
  662. .encode()
  663. .into_iter()
  664. .chain(Val(0xdead_beef).encode())
  665. .collect();
  666. runtime.function("power", args);
  667. assert_eq!(runtime.output(), Val(0).encode());
  668. runtime.function("power_with_cast", Vec::new());
  669. assert_eq!(runtime.output(), Val(0x1_0000_0000).encode());
  670. }
  671. #[test]
  672. fn large_power() {
  673. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  674. struct Val(u128);
  675. // parse
  676. let mut runtime = build_solidity(
  677. "
  678. contract c {
  679. function power(uint128 base, uint128 exp) public returns (uint128) {
  680. return base ** exp;
  681. }
  682. }",
  683. );
  684. // 4**5 = 1024
  685. let args = Val(4).encode().into_iter().chain(Val(5).encode()).collect();
  686. runtime.function("power", args);
  687. assert_eq!(runtime.output(), Val(1024).encode());
  688. // n ** 1 = n
  689. let args = Val(2345)
  690. .encode()
  691. .into_iter()
  692. .chain(Val(1).encode())
  693. .collect();
  694. runtime.function("power", args);
  695. assert_eq!(runtime.output(), Val(2345).encode());
  696. // n ** 0 = 0
  697. let args = Val(0xdeadbeef)
  698. .encode()
  699. .into_iter()
  700. .chain(Val(0).encode())
  701. .collect();
  702. runtime.function("power", args);
  703. assert_eq!(runtime.output(), Val(1).encode());
  704. // 0 ** n = 0
  705. let args = Val(0)
  706. .encode()
  707. .into_iter()
  708. .chain(Val(0xdeadbeef).encode())
  709. .collect();
  710. runtime.function("power", args);
  711. assert_eq!(runtime.output(), Val(0).encode());
  712. // 10 ** 36 = 1000000000000000000000000000000000000
  713. let args = Val(10)
  714. .encode()
  715. .into_iter()
  716. .chain(Val(36).encode())
  717. .collect();
  718. runtime.function("power", args);
  719. assert_eq!(
  720. runtime.output(),
  721. Val(1000000000000000000000000000000000000).encode()
  722. );
  723. }
  724. #[test]
  725. fn test_power_overflow_boundaries() {
  726. for width in (8..=256).step_by(8) {
  727. let src = r#"
  728. contract test {
  729. function pow(uintN a, uintN b) public returns (uintN) {
  730. return a ** b;
  731. }
  732. }"#
  733. .replace("intN", &format!("int{width}"));
  734. let mut contract = build_solidity_with_options(&src, false);
  735. let base = BigUint::from(2_u32);
  736. let mut base_data = base.to_bytes_le();
  737. let exp = BigUint::from(width - 1);
  738. let mut exp_data = exp.to_bytes_le();
  739. let width_rounded = (width / 8usize).next_power_of_two();
  740. base_data.resize(width_rounded, 0);
  741. exp_data.resize(width_rounded, 0);
  742. contract.function(
  743. "pow",
  744. base_data.clone().into_iter().chain(exp_data).collect(),
  745. );
  746. let res = BigUint::from(2_usize).pow((width - 1).try_into().unwrap());
  747. let mut res_data = res.to_bytes_le();
  748. res_data.resize(width / 8, 0);
  749. assert_eq!(contract.output()[..width / 8], res_data);
  750. let exp = exp.add(1_usize);
  751. let mut exp_data = exp.to_bytes_le();
  752. exp_data.resize(width_rounded, 0);
  753. contract.function_expect_failure("pow", base_data.into_iter().chain(exp_data).collect());
  754. }
  755. }
  756. #[test]
  757. fn multiply() {
  758. let mut rng = rand::thread_rng();
  759. let size = 32;
  760. let mut runtime = build_solidity(
  761. "
  762. contract c {
  763. function multiply(uint a, uint b) public returns (uint) {
  764. unchecked {
  765. return a * b;
  766. }
  767. }
  768. function multiply_with_cast() public returns (uint64) {
  769. return uint64(255 * 255);
  770. }
  771. }",
  772. );
  773. runtime.function("multiply_with_cast", Vec::new());
  774. assert_eq!(runtime.output(), 65025u64.encode());
  775. let mut rand = || -> (BigInt, Vec<u8>) {
  776. let length = rng.gen::<usize>() % size;
  777. let mut data = Vec::new();
  778. data.resize_with(length + 1, || rng.gen());
  779. data.resize(size, 0);
  780. (BigInt::from_bytes_le(Sign::Plus, &data), data)
  781. };
  782. for _ in 0..1000 {
  783. let (a, a_data) = rand();
  784. let (b, b_data) = rand();
  785. println!("in: a:{a_data:?} b:{b_data:?}");
  786. runtime.function("multiply", a_data.into_iter().chain(b_data).collect());
  787. println!("out: res:{:?}", runtime.output());
  788. let res = BigInt::from_bytes_le(Sign::Plus, &runtime.output());
  789. println!("{res} = {a} * {b}");
  790. // the result is truncated to $size bytes. We do this here by converting to Vec<u8> and truncating
  791. // it. A truncating bigint multiply would be nicer.
  792. let (_, mut res) = (a * b).to_bytes_le();
  793. res.resize(size, 0);
  794. assert_eq!(res, runtime.output());
  795. }
  796. }
  797. #[test]
  798. fn test_mul_within_range_signed() {
  799. // We generate a random value that fits N bits. Then, we multiply that value by 1, -1 or 0.
  800. let mut rng = rand::thread_rng();
  801. for width in (8..=256).step_by(8) {
  802. let src = r#"
  803. contract test {
  804. function mul(intN a, intN b) public returns (intN) {
  805. return a * b;
  806. }
  807. }"#
  808. .replace("intN", &format!("int{width}"));
  809. let width_rounded = (width / 8_usize).next_power_of_two();
  810. let mut runtime = build_solidity(&src);
  811. let upper_bound = BigInt::from(2).pow(width as u32 - 1); // Upper bound is exclusive
  812. let lower_bound = upper_bound.clone().mul(-1);
  813. let a = rng.gen_bigint_range(&lower_bound, &upper_bound);
  814. let a_sign = a.sign();
  815. let mut a_data = a.to_signed_bytes_le();
  816. let side = [-1, 0, 1];
  817. let b = BigInt::from(*side.choose(&mut rng).unwrap());
  818. let b_sign = b.sign();
  819. let mut b_data = b.to_signed_bytes_le();
  820. a_data.resize(width_rounded, sign_extend(a_sign));
  821. b_data.resize(width_rounded, sign_extend(b_sign));
  822. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  823. let value = a * b;
  824. let value_sign = value.sign();
  825. let mut value_data = value.to_signed_bytes_le();
  826. value_data.resize(width / 8, sign_extend(value_sign));
  827. assert_eq!(value_data, runtime.output()[..width / 8]);
  828. }
  829. }
  830. #[test]
  831. fn test_mul_within_range() {
  832. let mut rng = rand::thread_rng();
  833. for width in (8..=256).step_by(8) {
  834. let src = r#"
  835. contract test {
  836. function mul(uintN a, uintN b) public returns (uintN) {
  837. return a * b;
  838. }
  839. }"#
  840. .replace("intN", &format!("int{width}"));
  841. let width_rounded = (width / 8usize).next_power_of_two();
  842. let mut runtime = build_solidity(&src);
  843. // 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
  844. let a = rng.gen_biguint((width).try_into().unwrap());
  845. let mut a_data = a.to_bytes_le();
  846. let b = BigUint::from(1_u32);
  847. let mut b_data = b.to_bytes_le();
  848. a_data.resize(width_rounded, 0);
  849. b_data.resize(width_rounded, 0);
  850. runtime.function("mul", a_data.into_iter().chain(b_data).collect());
  851. let value = a * b;
  852. let mut value_data = value.to_bytes_le();
  853. value_data.resize(width / 8, 0);
  854. assert_eq!(value_data, runtime.output()[..width / 8]);
  855. }
  856. }
  857. #[test]
  858. fn test_overflow_boundaries() {
  859. for width in (8..=256).step_by(8) {
  860. let src = r#"
  861. contract test {
  862. function mul(intN a, intN b) public returns (intN) {
  863. return a * b;
  864. }
  865. }"#
  866. .replace("intN", &format!("int{width}"));
  867. let mut contract = build_solidity_with_options(&src, false);
  868. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1]. We generate these boundaries:
  869. let upper_boundary = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  870. let mut up_data = upper_boundary.to_signed_bytes_le();
  871. let lower_boundary = BigInt::from(2_u32).pow(width - 1).mul(-1_i32);
  872. let mut low_data = lower_boundary.to_signed_bytes_le();
  873. let second_op = BigInt::from(1_u32);
  874. let mut sec_data = second_op.to_signed_bytes_le();
  875. let width_rounded = (width as usize / 8).next_power_of_two();
  876. up_data.resize(width_rounded, 0);
  877. low_data.resize(width_rounded, 255);
  878. sec_data.resize(width_rounded, 0);
  879. // Multiply the boundaries by 1.
  880. contract.function(
  881. "mul",
  882. up_data
  883. .clone()
  884. .into_iter()
  885. .chain(sec_data.clone())
  886. .collect(),
  887. );
  888. let res = upper_boundary.clone().mul(1_u32);
  889. let mut res_data = res.to_signed_bytes_le();
  890. res_data.resize((width / 8) as usize, 0);
  891. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  892. contract.function(
  893. "mul",
  894. low_data
  895. .clone()
  896. .into_iter()
  897. .chain(sec_data.clone())
  898. .collect(),
  899. );
  900. let res = lower_boundary.clone().mul(1_u32);
  901. let mut res_data = res.to_signed_bytes_le();
  902. res_data.resize((width / 8) as usize, 0);
  903. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  904. let upper_boundary_plus_one = BigInt::from(2_u32).pow(width - 1);
  905. // We subtract 2 instead of one to make the number even, so that no rounding occurs when we divide by 2 later on.
  906. let lower_boundary_minus_two = BigInt::from(2_u32).pow(width - 1).mul(-1_i32).sub(2_i32);
  907. let upper_second_op = upper_boundary_plus_one.div(2_u32);
  908. let mut upper_second_op_data = upper_second_op.to_signed_bytes_le();
  909. let lower_second_op = lower_boundary_minus_two.div(2_u32);
  910. let mut lower_second_op_data = lower_second_op.to_signed_bytes_le();
  911. let mut two_data = BigInt::from(2_u32).to_signed_bytes_le();
  912. upper_second_op_data.resize(width_rounded, 0);
  913. two_data.resize(width_rounded, 0);
  914. lower_second_op_data.resize(width_rounded, 255);
  915. // This will generate a value more than the upper boundary.
  916. contract.function_expect_failure(
  917. "mul",
  918. upper_second_op_data
  919. .clone()
  920. .into_iter()
  921. .chain(two_data.clone())
  922. .collect(),
  923. );
  924. // Generate a value less than the lower boundary
  925. contract.function_expect_failure(
  926. "mul",
  927. lower_second_op_data
  928. .clone()
  929. .into_iter()
  930. .chain(two_data.clone())
  931. .collect(),
  932. );
  933. // Upper boundary * Upper boundary
  934. contract.function_expect_failure(
  935. "mul",
  936. up_data.clone().into_iter().chain(up_data.clone()).collect(),
  937. );
  938. // Lower boundary * Lower boundary
  939. contract.function_expect_failure(
  940. "mul",
  941. low_data
  942. .clone()
  943. .into_iter()
  944. .chain(low_data.clone())
  945. .collect(),
  946. );
  947. // Lower boundary * Upper boundary
  948. contract.function_expect_failure(
  949. "mul",
  950. low_data
  951. .clone()
  952. .into_iter()
  953. .chain(up_data.clone())
  954. .collect(),
  955. );
  956. }
  957. }
  958. #[test]
  959. fn test_overflow_detect_signed() {
  960. let mut rng = rand::thread_rng();
  961. for width in (8..=256).step_by(8) {
  962. let src = r#"
  963. contract test {
  964. function mul(intN a, intN b) public returns (intN) {
  965. return a * b;
  966. }
  967. }"#
  968. .replace("intN", &format!("int{width}"));
  969. let mut contract = build_solidity_with_options(&src, false);
  970. // 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:
  971. let limit = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  972. // Generate a random number within the the range [(2^N-1)/2, (2^N-1) -1]
  973. let first_operand_rand =
  974. rng.gen_bigint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  975. let first_op_sign = first_operand_rand.sign();
  976. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  977. let width_rounded = (width as usize / 8).next_power_of_two();
  978. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  979. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  980. let second_operand_rand = rng.gen_bigint_range(&BigInt::from(2usize), &limit);
  981. let second_op_sign = second_operand_rand.sign();
  982. let mut second_op_data = second_operand_rand.to_signed_bytes_le();
  983. second_op_data.resize(width_rounded, sign_extend(second_op_sign));
  984. contract.function_expect_failure(
  985. "mul",
  986. first_op_data
  987. .into_iter()
  988. .chain(second_op_data.clone())
  989. .collect(),
  990. );
  991. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1] .
  992. let lower_limit = BigInt::from(2_u32).pow(width - 1).sub(1usize).mul(-1_i32);
  993. // Generate a random number within the the range [-(2^N-1), -(2^N-1)/2]
  994. let first_operand_rand =
  995. rng.gen_bigint_range(&lower_limit, &(lower_limit.clone().div(2usize)).add(1usize));
  996. let first_op_sign = first_operand_rand.sign();
  997. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  998. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  999. contract.function_expect_failure(
  1000. "mul",
  1001. first_op_data.into_iter().chain(second_op_data).collect(),
  1002. );
  1003. }
  1004. }
  1005. #[test]
  1006. fn test_overflow_detect_unsigned() {
  1007. let mut rng = rand::thread_rng();
  1008. for width in (8..=256).step_by(8) {
  1009. let src = r#"
  1010. contract test {
  1011. function mul(uintN a, uintN b) public returns (uintN) {
  1012. return a * b;
  1013. }
  1014. }"#
  1015. .replace("intN", &format!("int{width}"));
  1016. let mut contract = build_solidity_with_options(&src, false);
  1017. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1].
  1018. let limit = BigUint::from(2_u32).pow(width).sub(1_u32);
  1019. // Generate a random number within the the range [(2^N-1)/2, 2^N -1]
  1020. let first_operand_rand =
  1021. rng.gen_biguint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  1022. let mut first_op_data = first_operand_rand.to_bytes_le();
  1023. let width_rounded = (width as usize / 8).next_power_of_two();
  1024. first_op_data.resize(width_rounded, 0);
  1025. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  1026. let second_operand_rand = rng.gen_biguint_range(&BigUint::from(2usize), &limit);
  1027. let mut second_op_data = second_operand_rand.to_bytes_le();
  1028. second_op_data.resize(width_rounded, 0);
  1029. contract.function_expect_failure(
  1030. "mul",
  1031. first_op_data.into_iter().chain(second_op_data).collect(),
  1032. );
  1033. }
  1034. }
  1035. #[test]
  1036. fn bytes_bitwise() {
  1037. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1038. struct Bytes3([u8; 3]);
  1039. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1040. struct Bytes5([u8; 5]);
  1041. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1042. struct BytesArray([u8; 7], u32);
  1043. // parse
  1044. let mut runtime = build_solidity(
  1045. "
  1046. contract c {
  1047. function or(bytes5 x) public returns (bytes5 y) {
  1048. y = x | hex\"80808080\";
  1049. }
  1050. function and(bytes5 x) public returns (bytes5) {
  1051. return x & hex\"FFFF\";
  1052. }
  1053. function xor(bytes5 x) public returns (bytes5) {
  1054. x ^= 0xFF00000000;
  1055. return x;
  1056. }
  1057. function shift_left(bytes3 a) public returns (bytes5 b) {
  1058. b = bytes5(a) << 8;
  1059. }
  1060. function shift_right(bytes3 a) public returns (bytes5 b) {
  1061. b = bytes5(a) >> 8;
  1062. }
  1063. function shift_left2(bytes3 a) public returns (bytes5 b) {
  1064. b = bytes5(a);
  1065. b <<= 8;
  1066. }
  1067. function shift_right2(bytes3 a) public returns (bytes5 b) {
  1068. b = bytes5(a);
  1069. b >>= 8;
  1070. }
  1071. function bytes_length() public {
  1072. bytes4 b4;
  1073. assert(b4.length == 4);
  1074. }
  1075. function complement(bytes3 a) public returns (bytes3) {
  1076. return ~a;
  1077. }
  1078. function bytes_array(bytes7 foo, uint32 index) public returns (bytes1) {
  1079. return foo[index];
  1080. }
  1081. }",
  1082. );
  1083. runtime.function("or", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1084. assert_eq!(
  1085. runtime.output(),
  1086. Bytes5([0x81, 0x81, 0x81, 0x81, 0x01]).encode()
  1087. );
  1088. runtime.function("and", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1089. assert_eq!(runtime.output(), Bytes5([0x01, 0x01, 0, 0, 0]).encode());
  1090. runtime.function("xor", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1091. assert_eq!(
  1092. runtime.output(),
  1093. Bytes5([0xfe, 0x01, 0x01, 0x01, 0x01]).encode()
  1094. );
  1095. // shifty-shift
  1096. runtime.function("shift_left", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1097. assert_eq!(
  1098. runtime.output(),
  1099. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1100. );
  1101. runtime.function("shift_right", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1102. assert_eq!(
  1103. runtime.output(),
  1104. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1105. );
  1106. // assignment versions
  1107. runtime.function("shift_left2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1108. assert_eq!(
  1109. runtime.output(),
  1110. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1111. );
  1112. runtime.function("shift_right2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1113. assert_eq!(
  1114. runtime.output(),
  1115. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1116. );
  1117. // check length
  1118. runtime.function("bytes_length", Vec::new());
  1119. // complement
  1120. runtime.function("complement", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1121. assert_eq!(runtime.output(), Bytes3([0x0c, 0x82, 0xfc]).encode());
  1122. // array access
  1123. let bytes7 = *b"NAWABRA";
  1124. for i in 0..6 {
  1125. runtime.function("bytes_array", BytesArray(bytes7, i).encode());
  1126. assert_eq!(runtime.output(), [bytes7[i as usize]]);
  1127. }
  1128. }
  1129. #[test]
  1130. fn bytesn_underflow_index_acccess() {
  1131. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1132. struct BytesArray([u8; 7], i32);
  1133. // parse
  1134. let mut runtime = build_solidity(
  1135. "
  1136. contract test {
  1137. function bytes_array(bytes7 foo, int32 index) public returns (bytes1) {
  1138. return foo[uint(index)];
  1139. }
  1140. }",
  1141. );
  1142. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", -1).encode());
  1143. }
  1144. #[test]
  1145. fn bytesn_overflow_index_acccess() {
  1146. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1147. struct BytesArray([u8; 7], i32);
  1148. // parse
  1149. let mut runtime = build_solidity(
  1150. "
  1151. contract test {
  1152. function bytes_array(bytes7 foo, int32 index) public returns (byte) {
  1153. return foo[uint(index)];
  1154. }
  1155. }",
  1156. );
  1157. runtime.function_expect_failure("bytes_array", BytesArray(*b"nawabra", 7).encode());
  1158. }
  1159. #[test]
  1160. fn negation_and_subtract() {
  1161. // The minus sign can be a unary negative or subtract.
  1162. let mut runtime = build_solidity(
  1163. r#"
  1164. contract c {
  1165. function test() public {
  1166. uint32 x = 10-10;
  1167. assert(x == 0);
  1168. int32 y = -10-10;
  1169. assert(y == -20);
  1170. }
  1171. }"#,
  1172. );
  1173. runtime.function("test", Vec::new());
  1174. }
  1175. #[test]
  1176. fn div() {
  1177. // The minus sign can be a unary negative or subtract.
  1178. let mut runtime = build_solidity(
  1179. r#"
  1180. contract c {
  1181. function test1() public {
  1182. // see https://solidity.readthedocs.io/en/latest/types.html#modulo
  1183. assert(int256(5) % int256(2) == int256(1));
  1184. assert(int256(5) % int256(-2) == int256(1));
  1185. assert(int256(-5) % int256(2) == int256(-1));
  1186. assert(int256(-5) % int256(-2) == int256(-1));
  1187. assert(int64(5) % int64(2) == int64(1));
  1188. assert(int64(5) % int64(-2) == int64(1));
  1189. assert(int64(-5) % int64(2) == int64(-1));
  1190. assert(int64(-5) % int64(-2) == int64(-1));
  1191. }
  1192. function test2() public {
  1193. // see https://github.com/hyperledger-solang/burrow/pull/1367#issue-399914366
  1194. assert(int256(7) / int256(3) == int256(2));
  1195. assert(int256(7) / int256(-3) == int256(-2));
  1196. assert(int256(-7) / int256(3) == int256(-2));
  1197. assert(int256(-7) / int256(-3) == int256(2));
  1198. assert(int256(7) % int256(3) == int256(1));
  1199. assert(int256(7) % int256(-3) == int256(1));
  1200. assert(int256(-7) % int256(3) == int256(-1));
  1201. assert(int256(-7) % int256(-3) == int256(-1));
  1202. assert(int64(7) / int64(3) == int64(2));
  1203. assert(int64(7) / int64(-3) == int64(-2));
  1204. assert(int64(-7) / int64(3) == int64(-2));
  1205. assert(int64(-7) / int64(-3) == int64(2));
  1206. assert(int64(7) % int64(3) == int64(1));
  1207. assert(int64(7) % int64(-3) == int64(1));
  1208. assert(int64(-7) % int64(3) == int64(-1));
  1209. assert(int64(-7) % int64(-3) == int64(-1));
  1210. }
  1211. }"#,
  1212. );
  1213. runtime.function("test1", Vec::new());
  1214. runtime.function("test2", Vec::new());
  1215. }
  1216. #[test]
  1217. fn destructure() {
  1218. // The minus sign can be a unary negative or subtract.
  1219. let mut runtime = build_solidity(
  1220. r#"
  1221. contract c {
  1222. function test() public {
  1223. int a;
  1224. int b;
  1225. // test one
  1226. (a, b) = (102, 3);
  1227. assert(b == 3 && a == 102);
  1228. // test missing one
  1229. (a, , b) = (1, 2, 3);
  1230. assert(a == 1 && b == 3);
  1231. // test single one
  1232. (a) = 5;
  1233. assert(a == 5);
  1234. // or like so
  1235. (a) = (105);
  1236. assert(a == 105);
  1237. }
  1238. function swap() public {
  1239. int32 a;
  1240. int32 b;
  1241. // test one
  1242. (a, b) = (102, 3);
  1243. // test swap
  1244. (b, a) = (a, b);
  1245. assert(a == 3 && b == 102);
  1246. }
  1247. }"#,
  1248. );
  1249. runtime.function("test", Vec::new());
  1250. runtime.function("swap", Vec::new());
  1251. // The minus sign can be a unary negative or subtract.
  1252. let mut runtime = build_solidity(
  1253. r#"
  1254. contract c {
  1255. function test() public {
  1256. // test one
  1257. (int32 a, int32 b) = (102, 3);
  1258. assert(b == 3 && a == 102);
  1259. // test missing one
  1260. (a, , b) = (1, 2, 3);
  1261. assert(a == 1 && b == 3);
  1262. // test single one
  1263. (a) = 5;
  1264. assert(a == 5);
  1265. // or like so
  1266. (a) = (105);
  1267. assert(a == 105);
  1268. }
  1269. }"#,
  1270. );
  1271. runtime.function("test", Vec::new());
  1272. }
  1273. #[test]
  1274. fn addition_overflow() {
  1275. let mut runtime = build_solidity_with_options(
  1276. r#"
  1277. contract overflow {
  1278. function foo(uint8 x) internal returns (uint8) {
  1279. uint8 y = x + 1;
  1280. return y;
  1281. }
  1282. function bar() public {
  1283. foo(255);
  1284. }
  1285. }
  1286. "#,
  1287. false,
  1288. );
  1289. runtime.function_expect_failure("bar", Vec::new());
  1290. }
  1291. #[test]
  1292. fn unchecked_addition_overflow() {
  1293. let mut runtime = build_solidity_with_options(
  1294. r#"
  1295. contract overflow {
  1296. function foo(uint8 x) internal returns (uint8) {
  1297. unchecked {
  1298. uint8 y = x + 1;
  1299. return y;
  1300. }
  1301. }
  1302. function bar() public {
  1303. foo(255);
  1304. }
  1305. }
  1306. "#,
  1307. false,
  1308. );
  1309. runtime.function("bar", Vec::new());
  1310. }
  1311. #[test]
  1312. fn subtraction_underflow() {
  1313. let mut runtime = build_solidity_with_options(
  1314. r#"
  1315. contract underflow {
  1316. function foo(uint64 x) internal returns (uint64) {
  1317. uint64 y = x - 1;
  1318. return y;
  1319. }
  1320. function bar() public {
  1321. foo(0);
  1322. }
  1323. }
  1324. "#,
  1325. false,
  1326. );
  1327. runtime.function_expect_failure("bar", Vec::new());
  1328. }
  1329. #[test]
  1330. fn unchecked_subtraction_underflow() {
  1331. let mut runtime = build_solidity_with_options(
  1332. r#"
  1333. contract underflow {
  1334. function foo(uint64 x) internal returns (uint64) {
  1335. unchecked {
  1336. uint64 y = x - 1;
  1337. return y;
  1338. }
  1339. }
  1340. function bar() public {
  1341. foo(0);
  1342. }
  1343. }
  1344. "#,
  1345. false,
  1346. );
  1347. runtime.function("bar", Vec::new());
  1348. }
  1349. #[test]
  1350. fn multiplication_overflow() {
  1351. let mut runtime = build_solidity_with_options(
  1352. r#"
  1353. contract overflow {
  1354. function foo(int8 x) internal returns (int8) {
  1355. int8 y = x * int8(64);
  1356. return y;
  1357. }
  1358. function bar() public {
  1359. foo(8);
  1360. }
  1361. }
  1362. "#,
  1363. false,
  1364. );
  1365. runtime.function_expect_failure("bar", Vec::new());
  1366. }
  1367. #[test]
  1368. fn unchecked_multiplication_overflow() {
  1369. let mut runtime = build_solidity_with_options(
  1370. r#"
  1371. contract overflow {
  1372. function foo(int8 x) internal returns (int8) {
  1373. unchecked {
  1374. int8 y = x * int8(64);
  1375. return y;
  1376. }
  1377. }
  1378. function bar() public {
  1379. foo(8);
  1380. }
  1381. }
  1382. "#,
  1383. false,
  1384. );
  1385. runtime.function("bar", Vec::new());
  1386. }
  1387. #[test]
  1388. fn address_compare() {
  1389. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1390. struct Args([u8; 32], [u8; 32]);
  1391. let mut runtime = build_solidity(
  1392. r#"
  1393. contract addr {
  1394. function bar() public {
  1395. address left = address(1);
  1396. address right = address(2);
  1397. assert(left < right);
  1398. assert(left <= right);
  1399. assert(right > left);
  1400. assert(right >= left);
  1401. }
  1402. function order(address tokenA, address tokenB) external returns (address token0, address token1) {
  1403. require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
  1404. (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
  1405. }
  1406. }"#,
  1407. );
  1408. runtime.function("bar", Vec::new());
  1409. let address0: [u8; 32] = [
  1410. 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,
  1411. 0, 1,
  1412. ];
  1413. let address1: [u8; 32] = [
  1414. 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,
  1415. 0, 2,
  1416. ];
  1417. runtime.function("order", Args(address0, address1).encode());
  1418. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1419. runtime.function("order", Args(address1, address0).encode());
  1420. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1421. }
  1422. #[test]
  1423. fn address_pass_by_value() {
  1424. let mut runtime = build_solidity(
  1425. r#"
  1426. contract addr {
  1427. function bar() public {
  1428. address left = address(1);
  1429. foo(left);
  1430. assert(left == address(1));
  1431. }
  1432. function foo(address a) internal {
  1433. a = address(2);
  1434. }
  1435. }"#,
  1436. );
  1437. runtime.function("bar", Vec::new());
  1438. }
  1439. fn sign_extend(sign: Sign) -> u8 {
  1440. if sign == Sign::Minus {
  1441. 255
  1442. } else {
  1443. 0
  1444. }
  1445. }
  1446. /// Given a chain of assignments, with the leftmost hand being a return parameter.
  1447. /// It should compile fine and all values in the chain should be assigned the right most value.
  1448. #[test]
  1449. fn assign_chained() {
  1450. let mut runtime = build_solidity(
  1451. r#"
  1452. contract C {
  1453. uint64 public foo;
  1454. uint64 public bar;
  1455. function f(uint64 x) public returns (uint64) {
  1456. return foo = bar = x;
  1457. }
  1458. }
  1459. "#,
  1460. );
  1461. let expected_output = 42u64.encode();
  1462. runtime.function("f", expected_output.clone());
  1463. assert_eq!(runtime.output(), &expected_output[..]);
  1464. runtime.function("foo", Vec::new());
  1465. assert_eq!(runtime.output(), &expected_output[..]);
  1466. runtime.function("bar", Vec::new());
  1467. assert_eq!(runtime.output(), &expected_output[..]);
  1468. }