expressions.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. use crate::build_solidity;
  2. use ethabi::{ethereum_types::U256, Token};
  3. use rand::Rng;
  4. #[test]
  5. fn interfaceid() {
  6. let mut vm = build_solidity(
  7. r#"
  8. contract foo {
  9. function get() public returns (bytes4) {
  10. return type(I).interfaceId;
  11. }
  12. }
  13. interface I {
  14. function bar(int) external;
  15. function baz(bytes) external returns (int);
  16. }"#,
  17. );
  18. vm.constructor("foo", &[]);
  19. let returns = vm.function("get", &[], &[], None);
  20. assert_eq!(
  21. returns,
  22. vec![Token::FixedBytes(0xc78d9f3au32.to_be_bytes().to_vec())]
  23. );
  24. }
  25. #[test]
  26. fn write_buffer() {
  27. let mut vm = build_solidity(
  28. r#"
  29. contract foo {
  30. function test1() public returns (bytes) {
  31. bytes bs = new bytes(12);
  32. bs.writeInt32LE(-0x41424344, 0);
  33. bs.writeUint64LE(0x0102030405060708, 4);
  34. return bs;
  35. }
  36. function test2() public returns (bytes) {
  37. bytes bs = new bytes(34);
  38. bs.writeUint16LE(0x4142, 0);
  39. bs.writeAddress(msg.sender, 2);
  40. return bs;
  41. }
  42. function test3() public returns (bytes) {
  43. bytes bs = new bytes(9);
  44. bs.writeUint64LE(1, 2);
  45. return bs;
  46. }
  47. }"#,
  48. );
  49. vm.constructor("foo", &[]);
  50. let returns = vm.function("test1", &[], &[], None);
  51. assert_eq!(
  52. returns,
  53. vec![Token::Bytes(
  54. [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec()
  55. )]
  56. );
  57. let returns = vm.function("test2", &[], &[], None);
  58. let mut buf = vec![0x42u8, 0x41u8];
  59. buf.extend_from_slice(&vm.origin);
  60. assert_eq!(returns, vec![Token::Bytes(buf)]);
  61. let res = vm.function_must_fail("test3", &[], &[], None);
  62. assert_eq!(res, Ok(4294967296));
  63. }
  64. #[test]
  65. fn read_buffer() {
  66. let mut vm = build_solidity(
  67. r#"
  68. contract foo {
  69. function test1(bytes bs) public returns (int32, uint64) {
  70. return (bs.readInt32LE(0), bs.readUint64LE(4));
  71. }
  72. function test2(bytes bs) public returns (uint16, address) {
  73. return (bs.readUint16LE(0), bs.readAddress(2));
  74. }
  75. }"#,
  76. );
  77. vm.constructor("foo", &[]);
  78. let returns = vm.function(
  79. "test1",
  80. &[Token::Bytes(
  81. [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec(),
  82. )],
  83. &[],
  84. None,
  85. );
  86. assert_eq!(
  87. returns,
  88. vec![
  89. Token::Int(U256::from(
  90. "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffbebdbcbc"
  91. )),
  92. Token::Uint(U256::from(0x0102030405060708u64))
  93. ]
  94. );
  95. let res = vm.function_must_fail(
  96. "test1",
  97. &[Token::Bytes(
  98. [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2].to_vec(),
  99. )],
  100. &[],
  101. None,
  102. );
  103. assert_eq!(res, Ok(4294967296));
  104. let mut buf = vec![0x42u8, 0x41u8];
  105. buf.extend_from_slice(&vm.origin);
  106. let returns = vm.function("test2", &[Token::Bytes(buf.clone())], &[], None);
  107. assert_eq!(
  108. returns,
  109. vec![
  110. Token::Uint(U256::from(0x4142)),
  111. Token::FixedBytes(vm.origin.to_vec())
  112. ]
  113. );
  114. buf.pop();
  115. let res = vm.function_must_fail("test2", &[Token::Bytes(buf)], &[], None);
  116. assert_eq!(res, Ok(4294967296));
  117. }
  118. #[test]
  119. fn bytes_compare() {
  120. let mut vm = build_solidity(
  121. r#"
  122. contract foo {
  123. function test1(bytes4 bs) public returns (bool) {
  124. return bs != 0;
  125. }
  126. function test2(bytes4 bs) public returns (bool) {
  127. return bs == 0;
  128. }
  129. }"#,
  130. );
  131. vm.constructor("foo", &[]);
  132. let returns = vm.function(
  133. "test1",
  134. &[Token::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
  135. &[],
  136. None,
  137. );
  138. assert_eq!(returns, vec![Token::Bool(true)]);
  139. let returns = vm.function(
  140. "test2",
  141. &[Token::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
  142. &[],
  143. None,
  144. );
  145. assert_eq!(returns, vec![Token::Bool(false)]);
  146. }
  147. #[test]
  148. fn assignment_in_ternary() {
  149. let mut rng = rand::thread_rng();
  150. let mut vm = build_solidity(
  151. r#"
  152. contract foo {
  153. function minimum(uint64 x, uint64 y) public pure returns (uint64 z) {
  154. x >= y ? z = y : z = x;
  155. }
  156. }"#,
  157. );
  158. vm.constructor("foo", &[]);
  159. for _ in 0..10 {
  160. let left = rng.gen::<u64>();
  161. let right = rng.gen::<u64>();
  162. let returns = vm.function(
  163. "minimum",
  164. &[
  165. Token::Uint(U256::from(left)),
  166. Token::Uint(U256::from(right)),
  167. ],
  168. &[],
  169. None,
  170. );
  171. assert_eq!(
  172. returns,
  173. vec![Token::Uint(U256::from(std::cmp::min(left, right)))]
  174. );
  175. }
  176. }
  177. #[test]
  178. fn power() {
  179. let mut vm = build_solidity(
  180. r#"
  181. contract foo {
  182. function power() public returns (uint) {
  183. return 2 ** 3 ** 4;
  184. }
  185. }"#,
  186. );
  187. vm.constructor("foo", &[]);
  188. let returns = vm.function("power", &[], &[], None);
  189. assert_eq!(
  190. returns,
  191. vec![Token::Uint(U256::from(2417851639229258349412352u128))]
  192. );
  193. }