expressions.rs 41 KB

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