expressions.rs 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904
  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]
  198. fn divisions_by_zero() {
  199. // parse
  200. let mut runtime = build_solidity(
  201. "
  202. contract test {
  203. function do_test() public returns (uint){
  204. uint256 val = 100;
  205. return (val / 0);
  206. }
  207. }",
  208. );
  209. runtime.function("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)
  649. .encode()
  650. .into_iter()
  651. .chain(Val(5).encode().into_iter())
  652. .collect();
  653. runtime.function("power", args);
  654. assert_eq!(runtime.output(), Val(1024).encode());
  655. // n ** 1 = n
  656. let args = Val(2345)
  657. .encode()
  658. .into_iter()
  659. .chain(Val(1).encode().into_iter())
  660. .collect();
  661. runtime.function("power", args);
  662. assert_eq!(runtime.output(), Val(2345).encode());
  663. // n ** 0 = 0
  664. let args = Val(0xdead_beef)
  665. .encode()
  666. .into_iter()
  667. .chain(Val(0).encode().into_iter())
  668. .collect();
  669. runtime.function("power", args);
  670. assert_eq!(runtime.output(), Val(1).encode());
  671. // 0 ** n = 0
  672. let args = Val(0)
  673. .encode()
  674. .into_iter()
  675. .chain(Val(0xdead_beef).encode().into_iter())
  676. .collect();
  677. runtime.function("power", args);
  678. assert_eq!(runtime.output(), Val(0).encode());
  679. runtime.function("power_with_cast", Vec::new());
  680. assert_eq!(runtime.output(), Val(0x1_0000_0000).encode());
  681. }
  682. #[test]
  683. fn large_power() {
  684. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  685. struct Val(u128);
  686. // parse
  687. let mut runtime = build_solidity(
  688. "
  689. contract c {
  690. function power(uint128 base, uint128 exp) public returns (uint128) {
  691. return base ** exp;
  692. }
  693. }",
  694. );
  695. // 4**5 = 1024
  696. let args = Val(4)
  697. .encode()
  698. .into_iter()
  699. .chain(Val(5).encode().into_iter())
  700. .collect();
  701. runtime.function("power", args);
  702. assert_eq!(runtime.output(), Val(1024).encode());
  703. // n ** 1 = n
  704. let args = Val(2345)
  705. .encode()
  706. .into_iter()
  707. .chain(Val(1).encode().into_iter())
  708. .collect();
  709. runtime.function("power", args);
  710. assert_eq!(runtime.output(), Val(2345).encode());
  711. // n ** 0 = 0
  712. let args = Val(0xdeadbeef)
  713. .encode()
  714. .into_iter()
  715. .chain(Val(0).encode().into_iter())
  716. .collect();
  717. runtime.function("power", args);
  718. assert_eq!(runtime.output(), Val(1).encode());
  719. // 0 ** n = 0
  720. let args = Val(0)
  721. .encode()
  722. .into_iter()
  723. .chain(Val(0xdeadbeef).encode().into_iter())
  724. .collect();
  725. runtime.function("power", args);
  726. assert_eq!(runtime.output(), Val(0).encode());
  727. // 10 ** 36 = 1000000000000000000000000000000000000
  728. let args = Val(10)
  729. .encode()
  730. .into_iter()
  731. .chain(Val(36).encode().into_iter())
  732. .collect();
  733. runtime.function("power", args);
  734. assert_eq!(
  735. runtime.output(),
  736. Val(1000000000000000000000000000000000000).encode()
  737. );
  738. }
  739. #[test]
  740. fn test_power_overflow_boundaries() {
  741. for width in (8..=256).step_by(8) {
  742. let src = r#"
  743. contract test {
  744. function pow(uintN a, uintN b) public returns (uintN) {
  745. return a ** b;
  746. }
  747. }"#
  748. .replace("intN", &format!("int{width}"));
  749. let mut contract = build_solidity_with_options(&src, false, false);
  750. let base = BigUint::from(2_u32);
  751. let mut base_data = base.to_bytes_le();
  752. let exp = BigUint::from(width - 1);
  753. let mut exp_data = exp.to_bytes_le();
  754. let width_rounded = (width / 8usize).next_power_of_two();
  755. base_data.resize(width_rounded, 0);
  756. exp_data.resize(width_rounded, 0);
  757. contract.function(
  758. "pow",
  759. base_data
  760. .clone()
  761. .into_iter()
  762. .chain(exp_data.into_iter())
  763. .collect(),
  764. );
  765. let res = BigUint::from(2_usize).pow((width - 1).try_into().unwrap());
  766. let mut res_data = res.to_bytes_le();
  767. res_data.resize(width / 8, 0);
  768. assert_eq!(contract.output()[..width / 8], res_data);
  769. let exp = exp.add(1_usize);
  770. let mut exp_data = exp.to_bytes_le();
  771. exp_data.resize(width_rounded, 0);
  772. contract.function_expect_failure(
  773. "pow",
  774. base_data.into_iter().chain(exp_data.into_iter()).collect(),
  775. );
  776. }
  777. }
  778. #[test]
  779. fn multiply() {
  780. let mut rng = rand::thread_rng();
  781. let size = 32;
  782. let mut runtime = build_solidity(
  783. "
  784. contract c {
  785. function multiply(uint a, uint b) public returns (uint) {
  786. unchecked {
  787. return a * b;
  788. }
  789. }
  790. function multiply_with_cast() public returns (uint64) {
  791. return uint64(255 * 255);
  792. }
  793. }",
  794. );
  795. runtime.function("multiply_with_cast", Vec::new());
  796. assert_eq!(runtime.output(), 65025u64.encode());
  797. let mut rand = || -> (BigInt, Vec<u8>) {
  798. let length = rng.gen::<usize>() % size;
  799. let mut data = Vec::new();
  800. data.resize_with(length + 1, || rng.gen());
  801. data.resize(size, 0);
  802. (BigInt::from_bytes_le(Sign::Plus, &data), data)
  803. };
  804. for _ in 0..1000 {
  805. let (a, a_data) = rand();
  806. let (b, b_data) = rand();
  807. println!("in: a:{a_data:?} b:{b_data:?}");
  808. runtime.function(
  809. "multiply",
  810. a_data.into_iter().chain(b_data.into_iter()).collect(),
  811. );
  812. println!("out: res:{:?}", runtime.output());
  813. let res = BigInt::from_bytes_le(Sign::Plus, &runtime.output());
  814. println!("{res} = {a} * {b}");
  815. // the result is truncated to $size bytes. We do this here by converting to Vec<u8> and truncating
  816. // it. A truncating bigint multiply would be nicer.
  817. let (_, mut res) = (a * b).to_bytes_le();
  818. res.resize(size, 0);
  819. assert_eq!(res, runtime.output());
  820. }
  821. }
  822. #[test]
  823. fn test_mul_within_range_signed() {
  824. // We generate a random value that fits N bits. Then, we multiply that value by 1, -1 or 0.
  825. let mut rng = rand::thread_rng();
  826. for width in (8..=256).step_by(8) {
  827. let src = r#"
  828. contract test {
  829. function mul(intN a, intN b) public returns (intN) {
  830. return a * b;
  831. }
  832. }"#
  833. .replace("intN", &format!("int{width}"));
  834. let width_rounded = (width / 8_usize).next_power_of_two();
  835. let mut runtime = build_solidity(&src);
  836. let a = rng.gen_bigint((width - 1).try_into().unwrap()).sub(1_u32);
  837. let a_sign = a.sign();
  838. let mut a_data = a.to_signed_bytes_le();
  839. let side = vec![-1, 0, 1];
  840. let b = BigInt::from(*side.choose(&mut rng).unwrap());
  841. let b_sign = b.sign();
  842. let mut b_data = b.to_signed_bytes_le();
  843. a_data.resize(width_rounded, sign_extend(a_sign));
  844. b_data.resize(width_rounded, sign_extend(b_sign));
  845. runtime.function(
  846. "mul",
  847. a_data.into_iter().chain(b_data.into_iter()).collect(),
  848. );
  849. let value = a * b;
  850. let value_sign = value.sign();
  851. let mut value_data = value.to_signed_bytes_le();
  852. value_data.resize(width / 8, sign_extend(value_sign));
  853. assert_eq!(value_data, runtime.output()[..width / 8]);
  854. }
  855. }
  856. #[test]
  857. fn test_mul_within_range() {
  858. let mut rng = rand::thread_rng();
  859. for width in (8..=256).step_by(8) {
  860. let src = r#"
  861. contract test {
  862. function mul(uintN a, uintN b) public returns (uintN) {
  863. return a * b;
  864. }
  865. }"#
  866. .replace("intN", &format!("int{width}"));
  867. let width_rounded = (width / 8usize).next_power_of_two();
  868. let mut runtime = build_solidity(&src);
  869. // The range of values that can be held in unsigned N bits is [0, 2^N-1]. Here we generate a random number within this range and multiply it by 1
  870. let a = rng.gen_biguint((width).try_into().unwrap());
  871. let mut a_data = a.to_bytes_le();
  872. let b = BigUint::from(1_u32);
  873. let mut b_data = b.to_bytes_le();
  874. a_data.resize(width_rounded, 0);
  875. b_data.resize(width_rounded, 0);
  876. runtime.function(
  877. "mul",
  878. a_data.into_iter().chain(b_data.into_iter()).collect(),
  879. );
  880. let value = a * b;
  881. let mut value_data = value.to_bytes_le();
  882. value_data.resize(width / 8, 0);
  883. assert_eq!(value_data, runtime.output()[..width / 8]);
  884. }
  885. }
  886. #[test]
  887. fn test_overflow_boundaries() {
  888. for width in (8..=256).step_by(8) {
  889. let src = r#"
  890. contract test {
  891. function mul(intN a, intN b) public returns (intN) {
  892. return a * b;
  893. }
  894. }"#
  895. .replace("intN", &format!("int{width}"));
  896. let mut contract = build_solidity_with_options(&src, false, false);
  897. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1]. We generate these boundaries:
  898. let upper_boundary = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  899. let mut up_data = upper_boundary.to_signed_bytes_le();
  900. let lower_boundary = BigInt::from(2_u32).pow(width - 1).mul(-1_i32);
  901. let mut low_data = lower_boundary.to_signed_bytes_le();
  902. let second_op = BigInt::from(1_u32);
  903. let mut sec_data = second_op.to_signed_bytes_le();
  904. let width_rounded = (width as usize / 8).next_power_of_two();
  905. up_data.resize(width_rounded, 0);
  906. low_data.resize(width_rounded, 255);
  907. sec_data.resize(width_rounded, 0);
  908. // Multiply the boundaries by 1.
  909. contract.function(
  910. "mul",
  911. up_data
  912. .clone()
  913. .into_iter()
  914. .chain(sec_data.clone().into_iter())
  915. .collect(),
  916. );
  917. let res = upper_boundary.clone().mul(1_u32);
  918. let mut res_data = res.to_signed_bytes_le();
  919. res_data.resize((width / 8) as usize, 0);
  920. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  921. contract.function(
  922. "mul",
  923. low_data
  924. .clone()
  925. .into_iter()
  926. .chain(sec_data.clone().into_iter())
  927. .collect(),
  928. );
  929. let res = lower_boundary.clone().mul(1_u32);
  930. let mut res_data = res.to_signed_bytes_le();
  931. res_data.resize((width / 8) as usize, 0);
  932. assert_eq!(res_data, contract.output()[..(width / 8) as usize]);
  933. let upper_boundary_plus_one = BigInt::from(2_u32).pow(width - 1);
  934. // We subtract 2 instead of one to make the number even, so that no rounding occurs when we divide by 2 later on.
  935. let lower_boundary_minus_two = BigInt::from(2_u32).pow(width - 1).mul(-1_i32).sub(2_i32);
  936. let upper_second_op = upper_boundary_plus_one.div(2_u32);
  937. let mut upper_second_op_data = upper_second_op.to_signed_bytes_le();
  938. let lower_second_op = lower_boundary_minus_two.div(2_u32);
  939. let mut lower_second_op_data = lower_second_op.to_signed_bytes_le();
  940. let mut two_data = BigInt::from(2_u32).to_signed_bytes_le();
  941. upper_second_op_data.resize(width_rounded, 0);
  942. two_data.resize(width_rounded, 0);
  943. lower_second_op_data.resize(width_rounded, 255);
  944. // This will generate a value more than the upper boundary.
  945. contract.function_expect_failure(
  946. "mul",
  947. upper_second_op_data
  948. .clone()
  949. .into_iter()
  950. .chain(two_data.clone().into_iter())
  951. .collect(),
  952. );
  953. // Generate a value less than the lower boundary
  954. contract.function_expect_failure(
  955. "mul",
  956. lower_second_op_data
  957. .clone()
  958. .into_iter()
  959. .chain(two_data.clone().into_iter())
  960. .collect(),
  961. );
  962. // Upper boundary * Upper boundary
  963. contract.function_expect_failure(
  964. "mul",
  965. up_data
  966. .clone()
  967. .into_iter()
  968. .chain(up_data.clone().into_iter())
  969. .collect(),
  970. );
  971. // Lower boundary * Lower boundary
  972. contract.function_expect_failure(
  973. "mul",
  974. low_data
  975. .clone()
  976. .into_iter()
  977. .chain(low_data.clone().into_iter())
  978. .collect(),
  979. );
  980. // Lower boundary * Upper boundary
  981. contract.function_expect_failure(
  982. "mul",
  983. low_data
  984. .clone()
  985. .into_iter()
  986. .chain(up_data.clone().into_iter())
  987. .collect(),
  988. );
  989. }
  990. }
  991. #[test]
  992. fn test_overflow_detect_signed() {
  993. let mut rng = rand::thread_rng();
  994. for width in (8..=256).step_by(8) {
  995. let src = r#"
  996. contract test {
  997. function mul(intN a, intN b) public returns (intN) {
  998. return a * b;
  999. }
  1000. }"#
  1001. .replace("intN", &format!("int{width}"));
  1002. let mut contract = build_solidity_with_options(&src, false, false);
  1003. // 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:
  1004. let limit = BigInt::from(2_u32).pow(width - 1).sub(1_u32);
  1005. // Generate a random number within the the range [(2^N-1)/2, (2^N-1) -1]
  1006. let first_operand_rand =
  1007. rng.gen_bigint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  1008. let first_op_sign = first_operand_rand.sign();
  1009. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  1010. let width_rounded = (width as usize / 8).next_power_of_two();
  1011. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  1012. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  1013. let second_operand_rand = rng.gen_bigint_range(&BigInt::from(2usize), &limit);
  1014. let second_op_sign = second_operand_rand.sign();
  1015. let mut second_op_data = second_operand_rand.to_signed_bytes_le();
  1016. second_op_data.resize(width_rounded, sign_extend(second_op_sign));
  1017. contract.function_expect_failure(
  1018. "mul",
  1019. first_op_data
  1020. .into_iter()
  1021. .chain(second_op_data.clone().into_iter())
  1022. .collect(),
  1023. );
  1024. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1] .
  1025. let lower_limit = BigInt::from(2_u32).pow(width - 1).sub(1usize).mul(-1_i32);
  1026. // Generate a random number within the the range [-(2^N-1), -(2^N-1)/2]
  1027. let first_operand_rand =
  1028. rng.gen_bigint_range(&lower_limit, &(lower_limit.clone().div(2usize)).add(1usize));
  1029. let first_op_sign = first_operand_rand.sign();
  1030. let mut first_op_data = first_operand_rand.to_signed_bytes_le();
  1031. first_op_data.resize(width_rounded, sign_extend(first_op_sign));
  1032. contract.function_expect_failure(
  1033. "mul",
  1034. first_op_data
  1035. .into_iter()
  1036. .chain(second_op_data.into_iter())
  1037. .collect(),
  1038. );
  1039. }
  1040. }
  1041. #[test]
  1042. fn test_overflow_detect_unsigned() {
  1043. let mut rng = rand::thread_rng();
  1044. for width in (8..=256).step_by(8) {
  1045. let src = r#"
  1046. contract test {
  1047. function mul(uintN a, uintN b) public returns (uintN) {
  1048. return a * b;
  1049. }
  1050. }"#
  1051. .replace("intN", &format!("int{width}"));
  1052. let mut contract = build_solidity_with_options(&src, false, false);
  1053. // The range of values that can be held in signed N bits is [-2^(N-1), 2^(N-1)-1].
  1054. let limit = BigUint::from(2_u32).pow(width).sub(1_u32);
  1055. // Generate a random number within the the range [(2^N-1)/2, 2^N -1]
  1056. let first_operand_rand =
  1057. rng.gen_biguint_range(&(limit.clone().div(2usize)).add(1usize), &limit);
  1058. let mut first_op_data = first_operand_rand.to_bytes_le();
  1059. let width_rounded = (width as usize / 8).next_power_of_two();
  1060. first_op_data.resize(width_rounded, 0);
  1061. // Calculate a number that when multiplied by first_operand_rand, the result will overflow N bits
  1062. let second_operand_rand = rng.gen_biguint_range(&BigUint::from(2usize), &limit);
  1063. let mut second_op_data = second_operand_rand.to_bytes_le();
  1064. second_op_data.resize(width_rounded, 0);
  1065. contract.function_expect_failure(
  1066. "mul",
  1067. first_op_data
  1068. .into_iter()
  1069. .chain(second_op_data.into_iter())
  1070. .collect(),
  1071. );
  1072. }
  1073. }
  1074. #[test]
  1075. fn bytes_bitwise() {
  1076. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1077. struct Bytes3([u8; 3]);
  1078. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1079. struct Bytes5([u8; 5]);
  1080. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1081. struct BytesArray([u8; 7], u32);
  1082. // parse
  1083. let mut runtime = build_solidity(
  1084. "
  1085. contract c {
  1086. function or(bytes5 x) public returns (bytes5 y) {
  1087. y = x | hex\"80808080\";
  1088. }
  1089. function and(bytes5 x) public returns (bytes5) {
  1090. return x & hex\"FFFF\";
  1091. }
  1092. function xor(bytes5 x) public returns (bytes5) {
  1093. x ^= 0xFF00000000;
  1094. return x;
  1095. }
  1096. function shift_left(bytes3 a) public returns (bytes5 b) {
  1097. b = bytes5(a) << 8;
  1098. }
  1099. function shift_right(bytes3 a) public returns (bytes5 b) {
  1100. b = bytes5(a) >> 8;
  1101. }
  1102. function shift_left2(bytes3 a) public returns (bytes5 b) {
  1103. b = bytes5(a);
  1104. b <<= 8;
  1105. }
  1106. function shift_right2(bytes3 a) public returns (bytes5 b) {
  1107. b = bytes5(a);
  1108. b >>= 8;
  1109. }
  1110. function bytes_length() public {
  1111. bytes4 b4;
  1112. assert(b4.length == 4);
  1113. }
  1114. function complement(bytes3 a) public returns (bytes3) {
  1115. return ~a;
  1116. }
  1117. function bytes_array(bytes7 foo, uint32 index) public returns (bytes1) {
  1118. return foo[index];
  1119. }
  1120. }",
  1121. );
  1122. runtime.function("or", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1123. assert_eq!(
  1124. runtime.output(),
  1125. Bytes5([0x81, 0x81, 0x81, 0x81, 0x01]).encode()
  1126. );
  1127. runtime.function("and", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1128. assert_eq!(runtime.output(), Bytes5([0x01, 0x01, 0, 0, 0]).encode());
  1129. runtime.function("xor", Bytes5([0x01, 0x01, 0x01, 0x01, 0x01]).encode());
  1130. assert_eq!(
  1131. runtime.output(),
  1132. Bytes5([0xfe, 0x01, 0x01, 0x01, 0x01]).encode()
  1133. );
  1134. // shifty-shift
  1135. runtime.function("shift_left", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1136. assert_eq!(
  1137. runtime.output(),
  1138. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1139. );
  1140. runtime.function("shift_right", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1141. assert_eq!(
  1142. runtime.output(),
  1143. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1144. );
  1145. // assignment versions
  1146. runtime.function("shift_left2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1147. assert_eq!(
  1148. runtime.output(),
  1149. Bytes5([0x7d, 0x03, 0x00, 0x00, 0x00]).encode()
  1150. );
  1151. runtime.function("shift_right2", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1152. assert_eq!(
  1153. runtime.output(),
  1154. Bytes5([0x00, 0xf3, 0x7d, 0x03, 0x00]).encode()
  1155. );
  1156. // check length
  1157. runtime.function("bytes_length", Vec::new());
  1158. // complement
  1159. runtime.function("complement", Bytes3([0xf3, 0x7d, 0x03]).encode());
  1160. assert_eq!(runtime.output(), Bytes3([0x0c, 0x82, 0xfc]).encode());
  1161. // array access
  1162. let bytes7 = *b"NAWABRA";
  1163. for i in 0..6 {
  1164. runtime.function("bytes_array", BytesArray(bytes7, i).encode());
  1165. assert_eq!(runtime.output(), [bytes7[i as usize]]);
  1166. }
  1167. }
  1168. #[test]
  1169. #[should_panic]
  1170. fn bytesn_underflow_index_acccess() {
  1171. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1172. struct BytesArray([u8; 7], i32);
  1173. // parse
  1174. let mut runtime = build_solidity(
  1175. "
  1176. contract test {
  1177. function bytes_array(bytes7 foo, int32 index) public returns (bytes1) {
  1178. return foo[index];
  1179. }
  1180. }",
  1181. );
  1182. runtime.function("bytes_array", BytesArray(*b"nawabra", -1).encode());
  1183. }
  1184. #[test]
  1185. #[should_panic]
  1186. fn bytesn_overflow_index_acccess() {
  1187. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1188. struct BytesArray([u8; 7], i32);
  1189. // parse
  1190. let mut runtime = build_solidity(
  1191. "
  1192. contract test {
  1193. function bytes_array(bytes7 foo, int32 index) public returns (byte) {
  1194. return foo[index];
  1195. }
  1196. }",
  1197. );
  1198. runtime.function("bytes_array", BytesArray(*b"nawabra", 7).encode());
  1199. }
  1200. #[test]
  1201. fn negation_and_subtract() {
  1202. // The minus sign can be a unary negative or subtract.
  1203. let mut runtime = build_solidity(
  1204. r#"
  1205. contract c {
  1206. function test() public {
  1207. uint32 x = 10-10;
  1208. assert(x == 0);
  1209. int32 y = -10-10;
  1210. assert(y == -20);
  1211. }
  1212. }"#,
  1213. );
  1214. runtime.function("test", Vec::new());
  1215. }
  1216. #[test]
  1217. fn div() {
  1218. // The minus sign can be a unary negative or subtract.
  1219. let mut runtime = build_solidity(
  1220. r#"
  1221. contract c {
  1222. function test1() public {
  1223. // see https://solidity.readthedocs.io/en/latest/types.html#modulo
  1224. assert(int256(5) % int256(2) == int256(1));
  1225. assert(int256(5) % int256(-2) == int256(1));
  1226. assert(int256(-5) % int256(2) == int256(-1));
  1227. assert(int256(-5) % int256(-2) == int256(-1));
  1228. assert(int64(5) % int64(2) == int64(1));
  1229. assert(int64(5) % int64(-2) == int64(1));
  1230. assert(int64(-5) % int64(2) == int64(-1));
  1231. assert(int64(-5) % int64(-2) == int64(-1));
  1232. }
  1233. function test2() public {
  1234. // see https://github.com/hyperledger/burrow/pull/1367#issue-399914366
  1235. assert(int256(7) / int256(3) == int256(2));
  1236. assert(int256(7) / int256(-3) == int256(-2));
  1237. assert(int256(-7) / int256(3) == int256(-2));
  1238. assert(int256(-7) / int256(-3) == int256(2));
  1239. assert(int256(7) % int256(3) == int256(1));
  1240. assert(int256(7) % int256(-3) == int256(1));
  1241. assert(int256(-7) % int256(3) == int256(-1));
  1242. assert(int256(-7) % int256(-3) == int256(-1));
  1243. assert(int64(7) / int64(3) == int64(2));
  1244. assert(int64(7) / int64(-3) == int64(-2));
  1245. assert(int64(-7) / int64(3) == int64(-2));
  1246. assert(int64(-7) / int64(-3) == int64(2));
  1247. assert(int64(7) % int64(3) == int64(1));
  1248. assert(int64(7) % int64(-3) == int64(1));
  1249. assert(int64(-7) % int64(3) == int64(-1));
  1250. assert(int64(-7) % int64(-3) == int64(-1));
  1251. }
  1252. }"#,
  1253. );
  1254. runtime.function("test1", Vec::new());
  1255. runtime.function("test2", Vec::new());
  1256. }
  1257. #[test]
  1258. fn destructure() {
  1259. // The minus sign can be a unary negative or subtract.
  1260. let mut runtime = build_solidity(
  1261. r#"
  1262. contract c {
  1263. function test() public {
  1264. int a;
  1265. int b;
  1266. // test one
  1267. (a, b) = (102, 3);
  1268. assert(b == 3 && a == 102);
  1269. // test missing one
  1270. (a, , b) = (1, 2, 3);
  1271. assert(a == 1 && b == 3);
  1272. // test single one
  1273. (a) = 5;
  1274. assert(a == 5);
  1275. // or like so
  1276. (a) = (105);
  1277. assert(a == 105);
  1278. }
  1279. function swap() public {
  1280. int32 a;
  1281. int32 b;
  1282. // test one
  1283. (a, b) = (102, 3);
  1284. // test swap
  1285. (b, a) = (a, b);
  1286. assert(a == 3 && b == 102);
  1287. }
  1288. }"#,
  1289. );
  1290. runtime.function("test", Vec::new());
  1291. runtime.function("swap", Vec::new());
  1292. // The minus sign can be a unary negative or subtract.
  1293. let mut runtime = build_solidity(
  1294. r#"
  1295. contract c {
  1296. function test() public {
  1297. // test one
  1298. (int32 a, int32 b) = (102, 3);
  1299. assert(b == 3 && a == 102);
  1300. // test missing one
  1301. (a, , b) = (1, 2, 3);
  1302. assert(a == 1 && b == 3);
  1303. // test single one
  1304. (a) = 5;
  1305. assert(a == 5);
  1306. // or like so
  1307. (a) = (105);
  1308. assert(a == 105);
  1309. }
  1310. }"#,
  1311. );
  1312. runtime.function("test", Vec::new());
  1313. }
  1314. #[test]
  1315. #[should_panic]
  1316. fn addition_overflow() {
  1317. let mut runtime = build_solidity_with_options(
  1318. r#"
  1319. contract overflow {
  1320. function foo(uint8 x) internal returns (uint8) {
  1321. uint8 y = x + 1;
  1322. return y;
  1323. }
  1324. function bar() public {
  1325. foo(255);
  1326. }
  1327. }
  1328. "#,
  1329. false,
  1330. false,
  1331. );
  1332. runtime.function("bar", Vec::new());
  1333. }
  1334. #[test]
  1335. fn unchecked_addition_overflow() {
  1336. let mut runtime = build_solidity_with_options(
  1337. r#"
  1338. contract overflow {
  1339. function foo(uint8 x) internal returns (uint8) {
  1340. unchecked {
  1341. uint8 y = x + 1;
  1342. return y;
  1343. }
  1344. }
  1345. function bar() public {
  1346. foo(255);
  1347. }
  1348. }
  1349. "#,
  1350. false,
  1351. false,
  1352. );
  1353. runtime.function("bar", Vec::new());
  1354. }
  1355. #[test]
  1356. #[should_panic]
  1357. fn subtraction_underflow() {
  1358. let mut runtime = build_solidity_with_options(
  1359. r#"
  1360. contract underflow {
  1361. function foo(uint64 x) internal returns (uint64) {
  1362. uint64 y = x - 1;
  1363. return y;
  1364. }
  1365. function bar() public {
  1366. foo(0);
  1367. }
  1368. }
  1369. "#,
  1370. false,
  1371. false,
  1372. );
  1373. runtime.function("bar", Vec::new());
  1374. }
  1375. #[test]
  1376. fn unchecked_subtraction_underflow() {
  1377. let mut runtime = build_solidity_with_options(
  1378. r#"
  1379. contract underflow {
  1380. function foo(uint64 x) internal returns (uint64) {
  1381. unchecked {
  1382. uint64 y = x - 1;
  1383. return y;
  1384. }
  1385. }
  1386. function bar() public {
  1387. foo(0);
  1388. }
  1389. }
  1390. "#,
  1391. false,
  1392. false,
  1393. );
  1394. runtime.function("bar", Vec::new());
  1395. }
  1396. #[test]
  1397. #[should_panic]
  1398. fn multiplication_overflow() {
  1399. let mut runtime = build_solidity_with_options(
  1400. r#"
  1401. contract overflow {
  1402. function foo(int8 x) internal returns (int8) {
  1403. int8 y = x * int8(64);
  1404. return y;
  1405. }
  1406. function bar() public {
  1407. foo(8);
  1408. }
  1409. }
  1410. "#,
  1411. false,
  1412. false,
  1413. );
  1414. runtime.function("bar", Vec::new());
  1415. }
  1416. #[test]
  1417. fn unchecked_multiplication_overflow() {
  1418. let mut runtime = build_solidity_with_options(
  1419. r#"
  1420. contract overflow {
  1421. function foo(int8 x) internal returns (int8) {
  1422. unchecked {
  1423. int8 y = x * int8(64);
  1424. return y;
  1425. }
  1426. }
  1427. function bar() public {
  1428. foo(8);
  1429. }
  1430. }
  1431. "#,
  1432. false,
  1433. false,
  1434. );
  1435. runtime.function("bar", Vec::new());
  1436. }
  1437. #[test]
  1438. fn address_compare() {
  1439. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  1440. struct Args([u8; 32], [u8; 32]);
  1441. let mut runtime = build_solidity(
  1442. r#"
  1443. contract addr {
  1444. function bar() public {
  1445. address left = address(1);
  1446. address right = address(2);
  1447. assert(left < right);
  1448. assert(left <= right);
  1449. assert(right > left);
  1450. assert(right >= left);
  1451. }
  1452. function order(address tokenA, address tokenB) external returns (address token0, address token1) {
  1453. require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
  1454. (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
  1455. }
  1456. }"#,
  1457. );
  1458. runtime.function("bar", Vec::new());
  1459. let address0: [u8; 32] = [
  1460. 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,
  1461. 0, 1,
  1462. ];
  1463. let address1: [u8; 32] = [
  1464. 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,
  1465. 0, 2,
  1466. ];
  1467. runtime.function("order", Args(address0, address1).encode());
  1468. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1469. runtime.function("order", Args(address1, address0).encode());
  1470. assert_eq!(runtime.output(), Args(address0, address1).encode());
  1471. }
  1472. #[test]
  1473. fn address_pass_by_value() {
  1474. let mut runtime = build_solidity(
  1475. r#"
  1476. contract addr {
  1477. function bar() public {
  1478. address left = address(1);
  1479. foo(left);
  1480. assert(left == address(1));
  1481. }
  1482. function foo(address a) internal {
  1483. a = address(2);
  1484. }
  1485. }"#,
  1486. );
  1487. runtime.function("bar", Vec::new());
  1488. }
  1489. fn sign_extend(sign: Sign) -> u8 {
  1490. if sign == Sign::Minus {
  1491. 255
  1492. } else {
  1493. 0
  1494. }
  1495. }