errors.rs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::build_solidity_with_options;
  3. use parity_scale_codec::Encode;
  4. #[test]
  5. fn errors() {
  6. let mut runtime = build_solidity_with_options(
  7. r#"contract RuntimeErrors {
  8. bytes b = hex"0000_00fa";
  9. uint256[] arr;
  10. child public c;
  11. child public c2;
  12. callee public cal;
  13. constructor() public payable {}
  14. function print_test(int8 num) public returns (int8) {
  15. print("Hello world!");
  16. return num;
  17. }
  18. function math_overflow(int8 num) public returns (int8) {
  19. int8 ovf = num + 120;
  20. return ovf;
  21. }
  22. function require_test(int8 num) public returns (int8) {
  23. require(num > 10, "sesa");
  24. return 0;
  25. }
  26. // assert failure
  27. function assert_test(int8 num) public returns (int8) {
  28. assert(num > 10);
  29. return 0;
  30. }
  31. // storage index out of bounds
  32. function set_storage_bytes() public returns (bytes) {
  33. bytes sesa = new bytes(1);
  34. b[5] = sesa[0];
  35. return sesa;
  36. }
  37. // storage array index out of bounds
  38. function get_storage_bytes() public returns (bytes) {
  39. bytes sesa = new bytes(1);
  40. sesa[0] = b[5];
  41. return sesa;
  42. }
  43. // value transfer failure
  44. function transfer_abort() public {
  45. address a = address(0);
  46. payable(a).transfer(10);
  47. }
  48. // pop from empty storage array
  49. function pop_empty_storage() public {
  50. arr.pop();
  51. }
  52. // external call failed
  53. function call_ext() public {
  54. //cal = new callee();
  55. cal.callee_func{gas: 1e15}();
  56. }
  57. // contract creation failed (contract was deplyed with no value)
  58. function create_child() public {
  59. c = new child{value: 900e15, salt:2}();
  60. c2 = new child{value: 900e15, salt:2}();
  61. uint128 x = address(this).balance;
  62. //print("sesa");
  63. print("x = {}".format(x));
  64. }
  65. // non payable function dont_pay_me received value
  66. function dont_pay_me() public {}
  67. function pay_me() public payable {
  68. print("PAYED");
  69. uint128 x = address(this).balance;
  70. //print("sesa");
  71. print("x = {}".format(x));
  72. }
  73. function i_will_revert() public {
  74. revert();
  75. }
  76. function write_integer_failure(uint8 buf_size) public {
  77. bytes smol_buf = new bytes(buf_size);
  78. smol_buf.writeUint32LE(350, 20);
  79. }
  80. function write_bytes_failure(uint8 buf_size) public {
  81. bytes data = new bytes(10);
  82. bytes smol_buf = new bytes(buf_size);
  83. smol_buf.writeBytes(data, 0);
  84. }
  85. function read_integer_failure(uint32 offset) public {
  86. bytes smol_buf = new bytes(1);
  87. smol_buf.readUint16LE(offset);
  88. }
  89. // truncated type overflows
  90. function trunc_failure(uint128 input) public returns (uint256) {
  91. uint256[] a = new uint256[](input);
  92. return a[0];
  93. }
  94. function out_of_bounds(uint8 input) public returns (uint256) {
  95. uint256[] a = new uint256[](input);
  96. return a[20];
  97. }
  98. function invalid_instruction() public {
  99. assembly {
  100. invalid()
  101. }
  102. }
  103. function byte_cast_failure(uint8 num) public returns (bytes) {
  104. bytes smol_buf = new bytes(num);
  105. //bytes32 b32 = new bytes(num);
  106. bytes32 b32 = bytes32(smol_buf);
  107. return b32;
  108. }
  109. }
  110. contract callee {
  111. constructor() {}
  112. function callee_func() public {
  113. revert();
  114. }
  115. }
  116. contract child {
  117. constructor() {}
  118. function say_my_name() public pure returns (string memory) {
  119. print("say_my_name");
  120. return "child";
  121. }
  122. }
  123. "#,
  124. false,
  125. true,
  126. );
  127. runtime.constructor(0, vec![]);
  128. runtime.function_expect_failure("write_bytes_failure", 9u8.encode());
  129. assert_eq!(
  130. runtime.debug_buffer(),
  131. "runtime_error: data does not fit into buffer in test.sol:95:22-32,\n"
  132. );
  133. runtime.debug_buffer().clear();
  134. runtime.function_expect_failure("math_overflow", 10u8.encode());
  135. assert_eq!(
  136. runtime.debug_buffer(),
  137. "runtime_error: math overflow in test.sol:16:24-33,\n"
  138. );
  139. runtime.debug_buffer().clear();
  140. runtime.function_expect_failure("require_test", 9u8.encode());
  141. assert_eq!(
  142. runtime.debug_buffer(),
  143. "runtime_error: sesa require condition failed in test.sol:21:31-37,\n"
  144. );
  145. runtime.debug_buffer().clear();
  146. runtime.function_expect_failure("assert_test", 9u8.encode());
  147. assert_eq!(
  148. runtime.debug_buffer(),
  149. "runtime_error: assert failure in test.sol:27:20-28,\n"
  150. );
  151. runtime.debug_buffer().clear();
  152. runtime.function_expect_failure("set_storage_bytes", Vec::new());
  153. assert_eq!(
  154. runtime.debug_buffer(),
  155. "runtime_error: storage index out of bounds in test.sol:34:15-16,\n"
  156. );
  157. runtime.debug_buffer().clear();
  158. runtime.function_expect_failure("get_storage_bytes", Vec::new());
  159. assert_eq!(
  160. runtime.debug_buffer(),
  161. "runtime_error: storage array index out of bounds in test.sol:41:23-27,\n"
  162. );
  163. runtime.debug_buffer().clear();
  164. runtime.function_expect_failure("transfer_abort", Vec::new());
  165. assert_eq!(
  166. runtime.debug_buffer(),
  167. "runtime_error: value transfer failure in test.sol:48:33-35,\n"
  168. );
  169. runtime.debug_buffer().clear();
  170. runtime.function_expect_failure("pop_empty_storage", Vec::new());
  171. assert_eq!(
  172. runtime.debug_buffer(),
  173. "runtime_error: pop from empty storage array in test.sol:53:17-20,\n"
  174. );
  175. runtime.set_transferred_value(3500);
  176. runtime.constructor(0, Vec::new());
  177. runtime.debug_buffer().clear();
  178. runtime.set_transferred_value(0);
  179. runtime.function_expect_failure("create_child", Vec::new());
  180. assert_eq!(
  181. runtime.debug_buffer(),
  182. "runtime_error: contract creation failed in test.sol:64:17-51,\n"
  183. );
  184. runtime.debug_buffer().clear();
  185. runtime.function_expect_failure("i_will_revert", Vec::new());
  186. assert_eq!(
  187. runtime.debug_buffer(),
  188. "runtime_error: revert encountered in test.sol:84:13-21,\n"
  189. );
  190. runtime.debug_buffer().clear();
  191. runtime.function_expect_failure("write_integer_failure", 1u8.encode());
  192. assert_eq!(
  193. runtime.debug_buffer(),
  194. "runtime_error: integer too large to write in buffer in test.sol:89:22-35,\n"
  195. );
  196. runtime.debug_buffer().clear();
  197. runtime.function_expect_failure("invalid_instruction", Vec::new());
  198. assert_eq!(
  199. runtime.debug_buffer(),
  200. "runtime_error: reached invalid instruction in test.sol:116:17-26,\n"
  201. );
  202. runtime.debug_buffer().clear();
  203. runtime.function_expect_failure("out_of_bounds", 19u8.encode());
  204. assert_eq!(
  205. runtime.debug_buffer(),
  206. "runtime_error: array index out of bounds in test.sol:111:20-25,\n"
  207. );
  208. runtime.debug_buffer().clear();
  209. runtime.function_expect_failure("trunc_failure", u128::MAX.encode());
  210. assert_eq!(
  211. runtime.debug_buffer(),
  212. "runtime_error: truncated type overflows in test.sol:105:41-46,\n"
  213. );
  214. runtime.debug_buffer().clear();
  215. runtime.function_expect_failure("byte_cast_failure", 33u8.encode());
  216. assert_eq!(
  217. runtime.debug_buffer(),
  218. "runtime_error: bytes cast error in test.sol:124:27-44,\n"
  219. );
  220. runtime.debug_buffer().clear();
  221. runtime.function_expect_failure("read_integer_failure", 2u32.encode());
  222. assert_eq!(
  223. runtime.debug_buffer(),
  224. "runtime_error: read integer out of bounds in test.sol:100:22-34,\n"
  225. );
  226. runtime.debug_buffer().clear();
  227. runtime.function_expect_failure("call_ext", Vec::new());
  228. assert_eq!(
  229. runtime.debug_buffer(),
  230. "runtime_error: external call failed in test.sol:59:13-41,\n"
  231. );
  232. runtime.debug_buffer().clear();
  233. runtime.set_transferred_value(1);
  234. runtime.function_expect_failure("dont_pay_me", Vec::new());
  235. assert_eq!(
  236. runtime.debug_buffer(),
  237. "runtime_error: non payable function dont_pay_me received value,\n"
  238. );
  239. }