primitives.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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.vm.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.vm.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.vm.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.vm.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.vm.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. "
  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. }",
  112. );
  113. runtime.function("const3", Vec::new());
  114. assert_eq!(runtime.vm.output, Bytes3([0x11, 0x22, 0x33]).encode());
  115. runtime.function("const4", Vec::new());
  116. assert_eq!(runtime.vm.output, Bytes4(*b"ABCD").encode());
  117. runtime.function("const32", Vec::new());
  118. assert_eq!(
  119. runtime.vm.output,
  120. Bytes32(*b"The quick brown fox jumped over ").encode()
  121. );
  122. runtime.function("test4", Test4args(1, *b"abcd").encode());
  123. runtime.function("test4", Test4args(2, *b"ABCD").encode());
  124. // Casting to larger bytesN should insert stuff on the right
  125. runtime.function("test7", Bytes7(*b"1234567").encode());
  126. assert_eq!(
  127. runtime.vm.output,
  128. 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()
  129. );
  130. runtime.function("test3", Bytes3(*b"XYZ").encode());
  131. assert_eq!(runtime.vm.output, Bytes7(*b"XYZ\0\0\0\0").encode());
  132. // truncating should drop values on the right
  133. runtime.function("test7trunc", Bytes7(*b"XYWOLEH").encode());
  134. assert_eq!(runtime.vm.output, Bytes3(*b"XYW").encode());
  135. }
  136. #[test]
  137. fn address() {
  138. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  139. struct Address([u8; 32]);
  140. // parse
  141. let mut runtime = build_solidity(
  142. "
  143. contract test {
  144. function check_return() public returns (address) {
  145. return address(0x7d5839e24ACaDa338c257643a7d2e025453F77D058b8335C1c3791Bc6742b320);
  146. }
  147. function check_param(address a) public {
  148. assert(a == address(0x8D166E028f3148854F2427d29B8755F617EED0651Bc6C8809b189200A4E3aaa9));
  149. }
  150. }",
  151. );
  152. runtime.function("check_return", Vec::new());
  153. assert_eq!(
  154. runtime.vm.output,
  155. Address([
  156. 0x7d, 0x58, 0x39, 0xe2, 0x4a, 0xca, 0xda, 0x33, 0x8c, 0x25, 0x76, 0x43, 0xa7, 0xd2,
  157. 0xe0, 0x25, 0x45, 0x3f, 0x77, 0xd0, 0x58, 0xb8, 0x33, 0x5c, 0x1c, 0x37, 0x91, 0xbc,
  158. 0x67, 0x42, 0xb3, 0x20,
  159. ])
  160. .encode()
  161. );
  162. let val = Address([
  163. 0x8d, 0x16, 0x6e, 0x2, 0x8f, 0x31, 0x48, 0x85, 0x4f, 0x24, 0x27, 0xd2, 0x9b, 0x87, 0x55,
  164. 0xf6, 0x17, 0xee, 0xd0, 0x65, 0x1b, 0xc6, 0xc8, 0x80, 0x9b, 0x18, 0x92, 0x0, 0xa4, 0xe3,
  165. 0xaa, 0xa9,
  166. ])
  167. .encode();
  168. runtime.function("check_param", val);
  169. }
  170. #[test]
  171. fn type_name() {
  172. // parse
  173. let mut runtime = build_solidity(
  174. r##"
  175. contract test {
  176. function foo() public returns (uint32) {
  177. assert(type(foobar).name == "foobar");
  178. assert(type(uint8).min == 0);
  179. assert(type(uint128).min == 0);
  180. assert(type(uint256).min == 0);
  181. assert(type(uint48).min == 0);
  182. return 2;
  183. }
  184. }
  185. abstract contract foobar {
  186. int32 a;
  187. }"##,
  188. );
  189. runtime.function("foo", Vec::new());
  190. let mut runtime = build_solidity(
  191. r##"
  192. contract test {
  193. function min() public returns (uint32) {
  194. assert(type(int8).min == -128);
  195. assert(type(int16).min == -32768);
  196. assert(type(int64).min == -9223372036854775808);
  197. assert(type(int48).min == -140737488355328);
  198. return 2;
  199. }
  200. function max_int() public returns (uint32) {
  201. assert(type(int8).max == 127);
  202. assert(type(int16).max == 32767);
  203. assert(type(int64).max == 9223372036854775807);
  204. assert(type(int48).max == 140737488355327);
  205. return 2;
  206. }
  207. function max_uint() public returns (uint32) {
  208. assert(type(uint8).max == 255);
  209. assert(type(uint16).max == 65535);
  210. assert(type(uint64).max == 18446744073709551615);
  211. assert(type(uint48).max == 281474976710655);
  212. return 2;
  213. }
  214. }"##,
  215. );
  216. runtime.function("min", Vec::new());
  217. runtime.function("max_int", Vec::new());
  218. runtime.function("max_uint", Vec::new());
  219. }
  220. #[test]
  221. fn units() {
  222. // parse
  223. let mut runtime = build_solidity(
  224. r##"
  225. contract test {
  226. function foo() public {
  227. assert(10 seconds == 10);
  228. assert(1 minutes == 60);
  229. assert(60 minutes == 1 hours);
  230. assert(48 hours == 2 days);
  231. assert(14 days == 2 weeks);
  232. }
  233. }"##,
  234. );
  235. runtime.function("foo", Vec::new());
  236. // parse
  237. let mut runtime = build_solidity(
  238. r##"
  239. contract test {
  240. function foo() public {
  241. assert(10 wei == 10);
  242. assert(1 gwei == 1000_000_000);
  243. assert(1 ether == 1000_000_000_000_000_000);
  244. }
  245. }"##,
  246. );
  247. runtime.function("foo", Vec::new());
  248. }
  249. #[test]
  250. fn literal_bytes_cast() {
  251. // parse
  252. let mut runtime = build_solidity(
  253. r##"
  254. contract test {
  255. function foo() public {
  256. bytes4 x = bytes4(hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f");
  257. assert(x == hex'acaf_3289');
  258. bytes32 y = hex"acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f";
  259. assert(bytes4(x) == hex"acaf_3289");
  260. }
  261. }"##,
  262. );
  263. runtime.function("foo", Vec::new());
  264. }
  265. #[test]
  266. fn implicit_bytes_cast() {
  267. let mut runtime = build_solidity(
  268. r#"
  269. contract c {
  270. function test() public {
  271. bytes4 b1 = hex"01020304";
  272. bytes b2 = b1;
  273. assert(b2 == hex"01020304");
  274. }
  275. }"#,
  276. );
  277. runtime.function("test", Vec::new());
  278. let mut runtime = build_solidity(
  279. r#"
  280. contract c {
  281. function test() public {
  282. bytes b1 = hex"01020304";
  283. bytes4 b2 = b1;
  284. assert(b2 == hex"01020304");
  285. }
  286. }
  287. "#,
  288. );
  289. runtime.function("test", Vec::new());
  290. }
  291. #[test]
  292. #[should_panic]
  293. fn implicit_bytes_cast_incompatible_size() {
  294. let mut runtime = build_solidity(
  295. r#"
  296. contract c {
  297. function test() public returns (bytes3) {
  298. bytes b1 = hex"01020304";
  299. bytes3 b2 = b1;
  300. return b2;
  301. }
  302. }
  303. "#,
  304. );
  305. runtime.function("test", Vec::new());
  306. }
  307. #[test]
  308. fn signed_literal_unsigned_cast() {
  309. let mut runtime = build_solidity(
  310. r##"
  311. contract test {
  312. function foo() public {
  313. assert(uint16(-1) == 0xffff);
  314. assert(uint8(-2) == 0xfe);
  315. assert(uint32(-3) == 0xffff_fffd);
  316. assert(uint8(-4000) == 96);
  317. }
  318. }"##,
  319. );
  320. runtime.function("foo", Vec::new());
  321. }