value.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. // SPDX-License-Identifier: Apache-2.0
  2. use parity_scale_codec::{Decode, Encode};
  3. use crate::build_solidity;
  4. #[test]
  5. fn external_call_value() {
  6. let mut runtime = build_solidity(
  7. r##"
  8. contract b {
  9. a f;
  10. function step1() public {
  11. f = new a();
  12. }
  13. function step2() public {
  14. f.test{value: 1023}(501);
  15. }
  16. }
  17. contract a {
  18. function test(int32 l) public payable {
  19. }
  20. }"##,
  21. );
  22. runtime.constructor(0, Vec::new());
  23. runtime.function("step1", Vec::new());
  24. runtime.function("step2", Vec::new());
  25. // Minimum balance + transferred value = 500 + 1023
  26. assert_eq!(runtime.balance(2), 1523);
  27. let mut runtime = build_solidity(
  28. r##"
  29. contract b {
  30. function step1() public {
  31. a f = new a();
  32. try f.test{value: 1023}(501) {
  33. //
  34. }
  35. catch (bytes) {
  36. //
  37. }
  38. }
  39. }
  40. contract a {
  41. function test(int32 l) public payable {
  42. }
  43. }"##,
  44. );
  45. runtime.constructor(0, Vec::new());
  46. runtime.function("step1", Vec::new());
  47. // Minimum balance + transferred value = 500 + 1023
  48. assert_eq!(runtime.balance(2), 1523);
  49. }
  50. #[test]
  51. fn constructor_value() {
  52. let mut runtime = build_solidity(
  53. r##"
  54. contract b {
  55. function step1() public {
  56. a f = new a();
  57. }
  58. }
  59. contract a {
  60. function test(int32 l) public payable {
  61. }
  62. }"##,
  63. );
  64. runtime.constructor(0, Vec::new());
  65. runtime.function("step1", Vec::new());
  66. assert_eq!(runtime.balance(2), 500);
  67. let mut runtime = build_solidity(
  68. r##"
  69. contract b {
  70. function step1() public {
  71. a f = (new a){value: 0}();
  72. }
  73. }
  74. contract a {
  75. function test(int32 l) public payable {
  76. }
  77. }"##,
  78. );
  79. runtime.constructor(0, Vec::new());
  80. runtime.function("step1", Vec::new());
  81. assert_eq!(runtime.balance(2), 0);
  82. let mut runtime = build_solidity(
  83. r##"
  84. contract b {
  85. function step1() public {
  86. a f = new a{value: 499}();
  87. }
  88. }
  89. contract a {
  90. function test(int32 l) public payable {
  91. }
  92. }"##,
  93. );
  94. runtime.constructor(0, Vec::new());
  95. runtime.function("step1", Vec::new());
  96. assert_eq!(runtime.balance(2), 499);
  97. let mut runtime = build_solidity(
  98. r##"
  99. contract b {
  100. function step1() public {
  101. try (new a{value: 511})() {
  102. //
  103. }
  104. catch (bytes) {
  105. //
  106. }
  107. }
  108. }
  109. contract a {
  110. function test(int32 l) public payable {
  111. }
  112. }"##,
  113. );
  114. runtime.constructor(0, Vec::new());
  115. runtime.function("step1", Vec::new());
  116. assert_eq!(runtime.balance(2), 511);
  117. let mut runtime = build_solidity(
  118. r##"
  119. contract b {
  120. function step1() public {
  121. try (new a){value: 511}() returns (a) {
  122. //
  123. }
  124. catch (bytes) {
  125. //
  126. }
  127. }
  128. }
  129. contract a {
  130. function test(int32 l) public payable {
  131. }
  132. }"##,
  133. );
  134. runtime.constructor(0, Vec::new());
  135. runtime.function("step1", Vec::new());
  136. assert_eq!(runtime.balance(2), 511)
  137. }
  138. #[test]
  139. fn constructor_salt() {
  140. let mut runtime = build_solidity(
  141. r##"
  142. contract b {
  143. function step1() public {
  144. a f = new a{salt: 0}();
  145. }
  146. }
  147. contract a {
  148. function test(int32 l) public payable {
  149. }
  150. }"##,
  151. );
  152. runtime.constructor(0, Vec::new());
  153. runtime.function("step1", Vec::new());
  154. let mut runtime = build_solidity(
  155. r##"
  156. contract b {
  157. function step1() public {
  158. a f = new a{salt: hex"01"}();
  159. }
  160. }
  161. contract a {
  162. function test(int32 l) public payable {
  163. }
  164. }"##,
  165. );
  166. runtime.constructor(0, Vec::new());
  167. runtime.function("step1", Vec::new());
  168. // we can instantiate the same contract if we provide a different contract
  169. let mut runtime = build_solidity(
  170. r##"
  171. contract b {
  172. function step1() public {
  173. a f = new a{salt: hex"01"}();
  174. f = new a{salt: hex"02"}();
  175. }
  176. }
  177. contract a {
  178. function test(int32 l) public payable {
  179. }
  180. }"##,
  181. );
  182. runtime.constructor(0, Vec::new());
  183. runtime.function("step1", Vec::new());
  184. }
  185. #[test]
  186. fn this_address() {
  187. let mut runtime = build_solidity(
  188. r##"
  189. contract b {
  190. function step1() public returns (address) {
  191. return address(this);
  192. }
  193. }"##,
  194. );
  195. runtime.constructor(0, Vec::new());
  196. runtime.function("step1", Vec::new());
  197. assert_eq!(runtime.output(), runtime.caller());
  198. let mut runtime = build_solidity(
  199. r##"
  200. contract b {
  201. function step1() public returns (b) {
  202. return this;
  203. }
  204. }"##,
  205. );
  206. runtime.constructor(0, Vec::new());
  207. runtime.function("step1", Vec::new());
  208. assert_eq!(runtime.output(), runtime.caller());
  209. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  210. struct Ret(u32);
  211. let mut runtime = build_solidity(
  212. r##"
  213. contract b {
  214. int32 s;
  215. function step1() public returns (int32) {
  216. this.other{flags: 8}(102);
  217. return s;
  218. }
  219. function other(int32 n) public {
  220. s = n;
  221. }
  222. }"##,
  223. );
  224. runtime.constructor(0, Vec::new());
  225. runtime.function("step1", Vec::new());
  226. assert_eq!(runtime.output(), Ret(102).encode());
  227. let mut runtime = build_solidity(
  228. r##"
  229. contract b {
  230. function step1() public returns (b) {
  231. return this;
  232. }
  233. }"##,
  234. );
  235. runtime.constructor(0, Vec::new());
  236. runtime.function("step1", Vec::new());
  237. assert_eq!(runtime.output(), runtime.caller());
  238. }
  239. #[test]
  240. fn balance() {
  241. let mut runtime = build_solidity(
  242. r##"
  243. contract b {
  244. other o;
  245. constructor() public {
  246. o = new other();
  247. }
  248. function step1() public returns (uint128) {
  249. return address(this).balance;
  250. }
  251. function step2() public returns (uint128) {
  252. return o.balance();
  253. }
  254. }
  255. contract other {
  256. function balance() public returns (uint128) {
  257. return address(this).balance;
  258. }
  259. }"##,
  260. );
  261. runtime.constructor(0, Vec::new());
  262. runtime.function("step1", Vec::new());
  263. // Constructor received 20000 by default, however 500 were sent to "o"
  264. assert_eq!(runtime.output(), 19500u128.to_le_bytes());
  265. runtime.function("step2", Vec::new());
  266. assert_eq!(runtime.output(), 500u128.to_le_bytes());
  267. }
  268. #[test]
  269. fn selfdestruct() {
  270. let mut runtime = build_solidity(
  271. r##"
  272. contract c {
  273. other o;
  274. function step1() public {
  275. o = new other{value: 511}();
  276. }
  277. function step2() public {
  278. o.goaway(payable(address(this)));
  279. }
  280. }
  281. contract other {
  282. function goaway(address payable recipient) public returns (bool) {
  283. selfdestruct(recipient);
  284. }
  285. }"##,
  286. );
  287. runtime.constructor(0, Vec::new());
  288. runtime.function("step1", Vec::new());
  289. assert_eq!(runtime.balance(0), 20000 - 511);
  290. runtime.function("step2", Vec::new());
  291. assert_eq!(runtime.balance(0), 20000);
  292. }
  293. #[test]
  294. fn send_and_transfer() {
  295. let mut runtime = build_solidity(
  296. r##"
  297. contract c {
  298. other o;
  299. constructor() public {
  300. o = new other();
  301. }
  302. function step1() public returns (bool) {
  303. return payable(o).send(511);
  304. }
  305. }
  306. contract other {
  307. function giveme() public payable {
  308. }
  309. }"##,
  310. );
  311. runtime.constructor(0, Vec::new());
  312. runtime.function("step1", Vec::new());
  313. // no receive() required for send/transfer
  314. assert_eq!(runtime.output(), true.encode());
  315. assert_eq!(runtime.balance(2), 1011);
  316. let mut runtime = build_solidity(
  317. r##"
  318. contract c {
  319. other o;
  320. constructor() public {
  321. o = new other();
  322. }
  323. function step1() public returns (bool) {
  324. return payable(o).send(511);
  325. }
  326. }
  327. contract other {
  328. receive() external payable {
  329. }
  330. }"##,
  331. );
  332. runtime.constructor(0, Vec::new());
  333. runtime.function("step1", Vec::new());
  334. assert_eq!(runtime.output(), true.encode());
  335. assert_eq!(runtime.balance(2), 1011);
  336. let mut runtime = build_solidity(
  337. r##"
  338. contract c {
  339. other o;
  340. constructor() public {
  341. o = new other();
  342. }
  343. function step1() public {
  344. payable(o).transfer(511);
  345. }
  346. }
  347. contract other {
  348. function giveme() public {
  349. }
  350. }"##,
  351. );
  352. runtime.constructor(0, Vec::new());
  353. runtime.function("step1", Vec::new());
  354. assert_eq!(runtime.balance(2), 1011);
  355. let mut runtime = build_solidity(
  356. r##"
  357. contract c {
  358. other o;
  359. constructor() public {
  360. o = new other();
  361. }
  362. function step1() public {
  363. payable(o).transfer(511);
  364. }
  365. }
  366. contract other {
  367. receive() external payable {
  368. }
  369. }"##,
  370. );
  371. runtime.constructor(0, Vec::new());
  372. runtime.function("step1", Vec::new());
  373. assert_eq!(runtime.balance(2), 1011);
  374. }