using.rs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::borsh_encoding::BorshToken;
  3. use crate::build_solidity;
  4. use num_bigint::BigInt;
  5. #[test]
  6. fn user_defined_oper() {
  7. let mut runtime = build_solidity(
  8. r#"
  9. type Bitmap is int256;
  10. function eq(Bitmap a, Bitmap b) pure returns (bool) {
  11. return Bitmap.unwrap(a) == Bitmap.unwrap(b);
  12. }
  13. function ne(Bitmap a, Bitmap b) pure returns (bool) {
  14. return Bitmap.unwrap(a) != Bitmap.unwrap(b);
  15. }
  16. function gt(Bitmap a, Bitmap b) pure returns (bool) {
  17. return Bitmap.unwrap(a) > Bitmap.unwrap(b);
  18. }
  19. function gte(Bitmap a, Bitmap b) pure returns (bool) {
  20. return Bitmap.unwrap(a) >= Bitmap.unwrap(b);
  21. }
  22. function lt(Bitmap a, Bitmap b) pure returns (bool) {
  23. return Bitmap.unwrap(a) < Bitmap.unwrap(b);
  24. }
  25. function lte(Bitmap a, Bitmap b) pure returns (bool) {
  26. return Bitmap.unwrap(a) <= Bitmap.unwrap(b);
  27. }
  28. using {eq as ==, ne as !=, lt as <, lte as <=, gt as >, gte as >=} for Bitmap global;
  29. // arithmetic
  30. function neg(Bitmap a) pure returns (Bitmap) {
  31. return Bitmap.wrap(-Bitmap.unwrap(a));
  32. }
  33. function sub(Bitmap a, Bitmap b) pure returns (Bitmap) {
  34. return Bitmap.wrap(Bitmap.unwrap(a) - Bitmap.unwrap(b));
  35. }
  36. function add(Bitmap a, Bitmap b) pure returns (Bitmap) {
  37. return Bitmap.wrap(Bitmap.unwrap(a) + Bitmap.unwrap(b));
  38. }
  39. function mul(Bitmap a, Bitmap b) pure returns (Bitmap) {
  40. return Bitmap.wrap(Bitmap.unwrap(a) * Bitmap.unwrap(b));
  41. }
  42. function div(Bitmap a, Bitmap b) pure returns (Bitmap) {
  43. return Bitmap.wrap(Bitmap.unwrap(a) / Bitmap.unwrap(b));
  44. }
  45. function mod(Bitmap a, Bitmap b) pure returns (Bitmap) {
  46. return Bitmap.wrap(Bitmap.unwrap(a) % Bitmap.unwrap(b));
  47. }
  48. using {neg as -, sub as -, add as +, mul as *, div as /, mod as %} for Bitmap global;
  49. function and(Bitmap a, Bitmap b) pure returns (Bitmap) {
  50. return Bitmap.wrap(Bitmap.unwrap(a) & Bitmap.unwrap(b));
  51. }
  52. function or(Bitmap a, Bitmap b) pure returns (Bitmap) {
  53. return Bitmap.wrap(Bitmap.unwrap(a) | Bitmap.unwrap(b));
  54. }
  55. function xor(Bitmap a, Bitmap b) pure returns (Bitmap) {
  56. return Bitmap.wrap(Bitmap.unwrap(a) ^ Bitmap.unwrap(b));
  57. }
  58. function cpl(Bitmap a) pure returns (Bitmap) {
  59. return Bitmap.wrap(~Bitmap.unwrap(a));
  60. }
  61. using {and as &, or as |, xor as ^, cpl as ~} for Bitmap global;
  62. contract C {
  63. Bitmap a;
  64. function test_cmp() public view {
  65. Bitmap zero = Bitmap.wrap(0);
  66. Bitmap one = Bitmap.wrap(1);
  67. Bitmap one2 = Bitmap.wrap(1);
  68. assert(zero != one);
  69. assert(zero < one);
  70. assert(zero <= one);
  71. assert(one == one2);
  72. assert(one <= one2);
  73. assert(one >= zero);
  74. assert(one >= one2);
  75. assert(one > zero);
  76. }
  77. function test_arith() public view {
  78. Bitmap two = Bitmap.wrap(2);
  79. Bitmap three = Bitmap.wrap(3);
  80. Bitmap seven = Bitmap.wrap(7);
  81. assert(Bitmap.unwrap(two + three) == 5);
  82. assert(Bitmap.unwrap(two - three) == -1);
  83. assert(Bitmap.unwrap(two * three) == 6);
  84. assert(Bitmap.unwrap(seven / two) == 3);
  85. assert(Bitmap.unwrap(seven / two) == 3);
  86. assert(Bitmap.unwrap(-seven) == -7);
  87. }
  88. function test_bit() public view {
  89. Bitmap two = Bitmap.wrap(2);
  90. Bitmap three = Bitmap.wrap(3);
  91. Bitmap seven = Bitmap.wrap(7);
  92. Bitmap eight = Bitmap.wrap(8);
  93. assert(Bitmap.unwrap(two | three) == 3);
  94. assert(Bitmap.unwrap(eight | three) == 11);
  95. assert(Bitmap.unwrap(eight & three) == 0);
  96. assert(Bitmap.unwrap(eight & seven) == 0);
  97. assert(Bitmap.unwrap(two ^ three) == 1);
  98. assert((Bitmap.unwrap(~three) & 255) == 252);
  99. }
  100. }"#,
  101. );
  102. let data_account = runtime.initialize_data_account();
  103. runtime
  104. .function("new")
  105. .accounts(vec![("dataAccount", data_account)])
  106. .call();
  107. runtime.function("test_cmp").call();
  108. runtime.function("test_arith").call();
  109. runtime.function("test_bit").call();
  110. }
  111. #[test]
  112. fn using_for_struct() {
  113. let mut vm = build_solidity(
  114. r#"
  115. struct Pet {
  116. string name;
  117. uint8 age;
  118. }
  119. library Info {
  120. function isCat(Pet memory myPet) public pure returns (bool) {
  121. return myPet.name == "cat";
  122. }
  123. function setAge(Pet memory myPet, uint8 age) pure public {
  124. myPet.age = age;
  125. }
  126. }
  127. contract C {
  128. using Info for Pet;
  129. function testPet(string memory name, uint8 age) pure public returns (bool) {
  130. Pet memory my_pet = Pet(name, age);
  131. return my_pet.isCat();
  132. }
  133. function changeAge(Pet memory myPet) public pure returns (Pet memory) {
  134. myPet.setAge(5);
  135. return myPet;
  136. }
  137. }
  138. "#,
  139. );
  140. let data_account = vm.initialize_data_account();
  141. vm.function("new")
  142. .accounts(vec![("dataAccount", data_account)])
  143. .call();
  144. let res = vm
  145. .function("testPet")
  146. .arguments(&[
  147. BorshToken::String("cat".to_string()),
  148. BorshToken::Uint {
  149. width: 8,
  150. value: BigInt::from(2u8),
  151. },
  152. ])
  153. .call()
  154. .unwrap();
  155. assert_eq!(res, BorshToken::Bool(true));
  156. let res = vm
  157. .function("changeAge")
  158. .arguments(&[BorshToken::Tuple(vec![
  159. BorshToken::String("cat".to_string()),
  160. BorshToken::Uint {
  161. width: 8,
  162. value: BigInt::from(2u8),
  163. },
  164. ])])
  165. .call()
  166. .unwrap();
  167. assert_eq!(
  168. res,
  169. BorshToken::Tuple(vec![
  170. BorshToken::String("cat".to_string()),
  171. BorshToken::Uint {
  172. width: 8,
  173. value: BigInt::from(5u8),
  174. }
  175. ])
  176. );
  177. }
  178. #[test]
  179. fn using_overload() {
  180. let mut vm = build_solidity(
  181. r#"
  182. library MyBytes {
  183. function push(bytes memory b, uint8[] memory a) pure public returns (bool) {
  184. return b[0] == bytes1(a[0]) && b[1] == bytes1(a[1]);
  185. }
  186. }
  187. contract C {
  188. using MyBytes for bytes;
  189. function check() public pure returns (bool) {
  190. bytes memory b;
  191. b.push(1);
  192. b.push(2);
  193. uint8[] memory vec = new uint8[](2);
  194. vec[0] = 1;
  195. vec[1] = 2;
  196. return b.push(vec);
  197. }
  198. }
  199. "#,
  200. );
  201. let data_account = vm.initialize_data_account();
  202. vm.function("new")
  203. .accounts(vec![("dataAccount", data_account)])
  204. .call();
  205. let res = vm.function("check").call().unwrap();
  206. assert_eq!(res, BorshToken::Bool(true));
  207. }
  208. #[test]
  209. fn using_function_for_struct() {
  210. let mut vm = build_solidity(
  211. r#"
  212. struct Pet {
  213. string name;
  214. uint8 age;
  215. }
  216. library Info {
  217. function isCat(Pet memory myPet) public pure returns (bool) {
  218. return myPet.name == "cat";
  219. }
  220. function setAge(Pet memory myPet, uint8 age) pure public {
  221. myPet.age = age;
  222. }
  223. }
  224. contract C {
  225. using {Info.isCat, Info.setAge} for Pet;
  226. function testPet(string memory name, uint8 age) pure public returns (bool) {
  227. Pet memory my_pet = Pet(name, age);
  228. return my_pet.isCat();
  229. }
  230. function changeAge(Pet memory myPet) public pure returns (Pet memory) {
  231. myPet.setAge(5);
  232. return myPet;
  233. }
  234. }
  235. "#,
  236. );
  237. let data_account = vm.initialize_data_account();
  238. vm.function("new")
  239. .accounts(vec![("dataAccount", data_account)])
  240. .call();
  241. let res = vm
  242. .function("testPet")
  243. .arguments(&[
  244. BorshToken::String("cat".to_string()),
  245. BorshToken::Uint {
  246. width: 8,
  247. value: BigInt::from(2u8),
  248. },
  249. ])
  250. .call()
  251. .unwrap();
  252. assert_eq!(res, BorshToken::Bool(true));
  253. let res = vm
  254. .function("changeAge")
  255. .arguments(&[BorshToken::Tuple(vec![
  256. BorshToken::String("cat".to_string()),
  257. BorshToken::Uint {
  258. width: 8,
  259. value: BigInt::from(2u8),
  260. },
  261. ])])
  262. .call()
  263. .unwrap();
  264. assert_eq!(
  265. res,
  266. BorshToken::Tuple(vec![
  267. BorshToken::String("cat".to_string()),
  268. BorshToken::Uint {
  269. width: 8,
  270. value: BigInt::from(5u8),
  271. }
  272. ])
  273. );
  274. }
  275. #[test]
  276. fn using_function_overload() {
  277. let mut vm = build_solidity(
  278. r#"
  279. library LibInLib {
  280. function get0(bytes x) public pure returns (bytes1) {
  281. return x[0];
  282. }
  283. function get1(bytes x) public pure returns (bytes1) {
  284. return x[1];
  285. }
  286. }
  287. library MyBytes {
  288. using {LibInLib.get0, LibInLib.get1} for bytes;
  289. function push(bytes memory b, uint8[] memory a) pure public returns (bool) {
  290. return b.get0() == a[0] && b.get1()== a[1];
  291. }
  292. }
  293. contract C {
  294. using {MyBytes.push} for bytes;
  295. function check() public pure returns (bool) {
  296. bytes memory b;
  297. b.push(1);
  298. b.push(2);
  299. uint8[] memory vec = new uint8[](2);
  300. vec[0] = 1;
  301. vec[1] = 2;
  302. return b.push(vec);
  303. }
  304. }"#,
  305. );
  306. let data_account = vm.initialize_data_account();
  307. vm.function("new")
  308. .accounts(vec![("dataAccount", data_account)])
  309. .call();
  310. let res = vm.function("check").call().unwrap();
  311. assert_eq!(res, BorshToken::Bool(true));
  312. }