primitives.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::build_solidity;
  3. use parity_scale_codec::{Decode, Encode};
  4. #[test]
  5. fn various_constants() {
  6. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  7. struct FooReturn(u32);
  8. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  9. struct Foo64Return(i64);
  10. // parse
  11. let mut runtime = build_solidity(
  12. "
  13. contract test {
  14. function foo() public returns (uint32) {
  15. return 2;
  16. }
  17. }",
  18. );
  19. runtime.function("foo", Vec::new());
  20. assert_eq!(runtime.output(), FooReturn(2).encode());
  21. // parse
  22. let mut runtime = build_solidity(
  23. "
  24. contract test {
  25. function foo() public returns (uint32) {
  26. return 0xdeadcafe;
  27. }
  28. }",
  29. );
  30. runtime.function("foo", Vec::new());
  31. assert_eq!(runtime.output(), FooReturn(0xdead_cafe).encode());
  32. // parse
  33. let mut runtime = build_solidity(
  34. "
  35. contract test {
  36. function foo() public returns (uint32) {
  37. return 1e3;
  38. }
  39. }",
  40. );
  41. runtime.function("foo", Vec::new());
  42. assert_eq!(runtime.output(), FooReturn(1000).encode());
  43. // parse
  44. let mut runtime = build_solidity(
  45. "
  46. contract test {
  47. function foo() public returns (int64) {
  48. return -7e3;
  49. }
  50. }",
  51. );
  52. runtime.function("foo", Vec::new());
  53. assert_eq!(runtime.output(), Foo64Return(-7000).encode());
  54. // parse
  55. let mut runtime = build_solidity(
  56. "
  57. contract test {
  58. function foo() public returns (int64) {
  59. return -0x7afedeaddeedcafe;
  60. }
  61. }",
  62. );
  63. runtime.function("foo", Vec::new());
  64. assert_eq!(
  65. runtime.output(),
  66. Foo64Return(-0x7afe_dead_deed_cafe).encode()
  67. );
  68. }
  69. #[test]
  70. fn bytes() {
  71. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  72. struct Bytes3([u8; 3]);
  73. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  74. struct Bytes4([u8; 4]);
  75. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  76. struct Bytes7([u8; 7]);
  77. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  78. struct Bytes32([u8; 32]);
  79. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  80. struct Test4args(u32, [u8; 4]);
  81. // parse
  82. let mut runtime = build_solidity(
  83. r#"
  84. contract test {
  85. function const3() public returns (bytes3) {
  86. return hex"112233";
  87. }
  88. function const4() public returns (bytes4) {
  89. return "ABCD";
  90. }
  91. function const32() public returns (bytes32) {
  92. return "The quick brown fox jumped over ";
  93. }
  94. function test4(uint32 x, bytes4 foo) public {
  95. if (x == 1)
  96. assert(foo == "abcd");
  97. else if (x == 2)
  98. assert(foo == "ABCD");
  99. else
  100. assert(false);
  101. }
  102. function test7(bytes7 foo) public returns (bytes32) {
  103. return bytes32(foo);
  104. }
  105. function test3(bytes3 foo) public returns (bytes7) {
  106. return bytes7(foo);
  107. }
  108. function test7trunc(bytes7 foo) public returns (bytes3) {
  109. return bytes3(foo);
  110. }
  111. function hex_lit_leading_zero() public pure {
  112. assert(bytes4(0x00) == hex"00000000");
  113. assert(
  114. bytes32(0x00d4f4fc2f5752f06faf7ece82edbdcd093e8ee1144d482ea5820899b3520315)
  115. ==
  116. hex"00d4f4fc2f5752f06faf7ece82edbdcd093e8ee1144d482ea5820899b3520315"
  117. );
  118. }
  119. }"#,
  120. );
  121. runtime.function("const3", Vec::new());
  122. assert_eq!(runtime.output(), Bytes3([0x11, 0x22, 0x33]).encode());
  123. runtime.function("const4", Vec::new());
  124. assert_eq!(runtime.output(), Bytes4(*b"ABCD").encode());
  125. runtime.function("const32", Vec::new());
  126. assert_eq!(
  127. runtime.output(),
  128. Bytes32(*b"The quick brown fox jumped over ").encode()
  129. );
  130. runtime.function("test4", Test4args(1, *b"abcd").encode());
  131. runtime.function("test4", Test4args(2, *b"ABCD").encode());
  132. // Casting to larger bytesN should insert stuff on the right
  133. runtime.function("test7", Bytes7(*b"1234567").encode());
  134. assert_eq!(
  135. runtime.output(),
  136. Bytes32(*b"1234567\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").encode()
  137. );
  138. runtime.function("test3", Bytes3(*b"XYZ").encode());
  139. assert_eq!(runtime.output(), Bytes7(*b"XYZ\0\0\0\0").encode());
  140. // truncating should drop values on the right
  141. runtime.function("test7trunc", Bytes7(*b"XYWOLEH").encode());
  142. assert_eq!(runtime.output(), Bytes3(*b"XYW").encode());
  143. runtime.function("hex_lit_leading_zero", vec![]);
  144. }
  145. #[test]
  146. fn address() {
  147. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  148. struct Address([u8; 32]);
  149. // parse
  150. let mut runtime = build_solidity(
  151. "
  152. contract test {
  153. function check_return() public returns (address) {
  154. return address(0x7d5839e24ACaDa338c257643a7d2e025453F77D058b8335C1c3791Bc6742b320);
  155. }
  156. function check_param(address a) public {
  157. assert(a == address(0x8D166E028f3148854F2427d29B8755F617EED0651Bc6C8809b189200A4E3aaa9));
  158. }
  159. }",
  160. );
  161. runtime.function("check_return", Vec::new());
  162. assert_eq!(
  163. runtime.output(),
  164. Address([
  165. 0x7d, 0x58, 0x39, 0xe2, 0x4a, 0xca, 0xda, 0x33, 0x8c, 0x25, 0x76, 0x43, 0xa7, 0xd2,
  166. 0xe0, 0x25, 0x45, 0x3f, 0x77, 0xd0, 0x58, 0xb8, 0x33, 0x5c, 0x1c, 0x37, 0x91, 0xbc,
  167. 0x67, 0x42, 0xb3, 0x20,
  168. ])
  169. .encode()
  170. );
  171. let val = Address([
  172. 0x8d, 0x16, 0x6e, 0x2, 0x8f, 0x31, 0x48, 0x85, 0x4f, 0x24, 0x27, 0xd2, 0x9b, 0x87, 0x55,
  173. 0xf6, 0x17, 0xee, 0xd0, 0x65, 0x1b, 0xc6, 0xc8, 0x80, 0x9b, 0x18, 0x92, 0x0, 0xa4, 0xe3,
  174. 0xaa, 0xa9,
  175. ])
  176. .encode();
  177. runtime.function("check_param", val);
  178. }
  179. #[test]
  180. fn type_name() {
  181. // parse
  182. let mut runtime = build_solidity(
  183. r#"
  184. contract test {
  185. function foo() public returns (uint32) {
  186. assert(type(foobar).name == "foobar");
  187. assert(type(uint8).min == 0);
  188. assert(type(uint128).min == 0);
  189. assert(type(uint256).min == 0);
  190. assert(type(uint48).min == 0);
  191. return 2;
  192. }
  193. }
  194. abstract contract foobar {
  195. int32 a;
  196. }"#,
  197. );
  198. runtime.function("foo", Vec::new());
  199. let mut runtime = build_solidity(
  200. r##"
  201. contract test {
  202. function min() public returns (uint32) {
  203. assert(type(int8).min == -128);
  204. assert(type(int16).min == -32768);
  205. assert(type(int64).min == -9223372036854775808);
  206. assert(type(int48).min == -140737488355328);
  207. return 2;
  208. }
  209. function max_int() public returns (uint32) {
  210. assert(type(int8).max == 127);
  211. assert(type(int16).max == 32767);
  212. assert(type(int64).max == 9223372036854775807);
  213. assert(type(int48).max == 140737488355327);
  214. return 2;
  215. }
  216. function max_uint() public returns (uint32) {
  217. assert(type(uint8).max == 255);
  218. assert(type(uint16).max == 65535);
  219. assert(type(uint64).max == 18446744073709551615);
  220. assert(type(uint48).max == 281474976710655);
  221. return 2;
  222. }
  223. }"##,
  224. );
  225. runtime.function("min", Vec::new());
  226. runtime.function("max_int", Vec::new());
  227. runtime.function("max_uint", Vec::new());
  228. }
  229. #[test]
  230. fn units() {
  231. // parse
  232. let mut runtime = build_solidity(
  233. r##"
  234. contract test {
  235. function foo() public {
  236. assert(10 seconds == 10);
  237. assert(1 minutes == 60);
  238. assert(60 minutes == 1 hours);
  239. assert(48 hours == 2 days);
  240. assert(14 days == 2 weeks);
  241. }
  242. }"##,
  243. );
  244. runtime.function("foo", Vec::new());
  245. // parse
  246. let mut runtime = build_solidity(
  247. r##"
  248. contract test {
  249. function foo() public {
  250. assert(10 wei == 10);
  251. assert(1 gwei == 1000_000_000);
  252. assert(1 ether == 1000_000_000_000_000_000);
  253. }
  254. }"##,
  255. );
  256. runtime.function("foo", Vec::new());
  257. }
  258. #[test]
  259. fn literal_bytes_cast() {
  260. // parse
  261. let mut runtime = build_solidity(
  262. r#"
  263. contract test {
  264. function foo() public {
  265. bytes4 x = bytes4(hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  266. assert(x == hex'acaf_3289');
  267. bytes32 y = hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f";
  268. assert(bytes4(x) == hex"acaf_3289");
  269. }
  270. }"#,
  271. );
  272. runtime.function("foo", Vec::new());
  273. }
  274. #[test]
  275. fn implicit_bytes_cast() {
  276. let mut runtime = build_solidity(
  277. r#"
  278. contract c {
  279. function test() public {
  280. bytes4 b1 = hex"01020304";
  281. bytes b2 = b1;
  282. assert(b2 == hex"01020304");
  283. }
  284. }"#,
  285. );
  286. runtime.function("test", Vec::new());
  287. let mut runtime = build_solidity(
  288. r#"
  289. contract c {
  290. function test() public {
  291. bytes b1 = hex"01020304";
  292. bytes4 b2 = b1;
  293. assert(b2 == hex"01020304");
  294. }
  295. }
  296. "#,
  297. );
  298. runtime.function("test", Vec::new());
  299. }
  300. #[test]
  301. fn implicit_bytes_cast_incompatible_size() {
  302. let mut runtime = build_solidity(
  303. r#"
  304. contract c {
  305. function test() public returns (bytes3) {
  306. bytes b1 = hex"01020304";
  307. bytes3 b2 = b1;
  308. return b2;
  309. }
  310. }
  311. "#,
  312. );
  313. runtime.function_expect_failure("test", Vec::new());
  314. }
  315. #[test]
  316. fn signed_literal_unsigned_cast() {
  317. let mut runtime = build_solidity(
  318. r##"
  319. contract test {
  320. function foo() public {
  321. assert(uint16(-1) == 0xffff);
  322. assert(uint8(-2) == 0xfe);
  323. assert(uint32(-3) == 0xffff_fffd);
  324. assert(uint8(-4000) == 96);
  325. }
  326. }"##,
  327. );
  328. runtime.function("foo", Vec::new());
  329. }
  330. #[test]
  331. fn mul() {
  332. // https://github.com/hyperledger-solang/solang/issues/1507
  333. let mut runtime = build_solidity(
  334. r#"
  335. contract Test {
  336. function test()
  337. external view
  338. returns (uint256 result)
  339. {
  340. return f(10_000_000_000);
  341. }
  342. function f(uint256 x)
  343. internal pure
  344. returns (uint256)
  345. {
  346. return x * x / 10_000_000_000;
  347. }
  348. }"#,
  349. );
  350. runtime.function("test", Vec::new());
  351. assert_eq!(
  352. runtime.output(),
  353. (10000000000u64, 0u64, 0u64, 0u64).encode()
  354. );
  355. }