value.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. for (address, account) in runtime.accounts {
  26. if address == runtime.vm.account {
  27. continue;
  28. }
  29. assert_eq!(account.1, 1523);
  30. }
  31. let mut runtime = build_solidity(
  32. r##"
  33. contract b {
  34. function step1() public {
  35. a f = new a();
  36. try f.test{value: 1023}(501) {
  37. //
  38. }
  39. catch (bytes) {
  40. //
  41. }
  42. }
  43. }
  44. contract a {
  45. function test(int32 l) public payable {
  46. }
  47. }"##,
  48. );
  49. runtime.constructor(0, Vec::new());
  50. runtime.function("step1", Vec::new());
  51. for (address, account) in runtime.accounts {
  52. if address == runtime.vm.account {
  53. continue;
  54. }
  55. assert_eq!(account.1, 1523);
  56. }
  57. }
  58. #[test]
  59. fn constructor_value() {
  60. let mut runtime = build_solidity(
  61. r##"
  62. contract b {
  63. function step1() public {
  64. a f = new a();
  65. }
  66. }
  67. contract a {
  68. function test(int32 l) public payable {
  69. }
  70. }"##,
  71. );
  72. runtime.constructor(0, Vec::new());
  73. runtime.function("step1", Vec::new());
  74. for (address, account) in runtime.accounts {
  75. if address == runtime.vm.account {
  76. continue;
  77. }
  78. assert_eq!(account.1, 500);
  79. }
  80. let mut runtime = build_solidity(
  81. r##"
  82. contract b {
  83. function step1() public {
  84. a f = (new a){value: 0}();
  85. }
  86. }
  87. contract a {
  88. function test(int32 l) public payable {
  89. }
  90. }"##,
  91. );
  92. runtime.constructor(0, Vec::new());
  93. runtime.function("step1", Vec::new());
  94. for (address, account) in runtime.accounts {
  95. if address == runtime.vm.account {
  96. continue;
  97. }
  98. assert_eq!(account.1, 0);
  99. }
  100. let mut runtime = build_solidity(
  101. r##"
  102. contract b {
  103. function step1() public {
  104. a f = new a{value: 499}();
  105. }
  106. }
  107. contract a {
  108. function test(int32 l) public payable {
  109. }
  110. }"##,
  111. );
  112. runtime.constructor(0, Vec::new());
  113. runtime.function("step1", Vec::new());
  114. for (address, account) in runtime.accounts {
  115. if address == runtime.vm.account {
  116. continue;
  117. }
  118. assert_eq!(account.1, 499);
  119. }
  120. let mut runtime = build_solidity(
  121. r##"
  122. contract b {
  123. function step1() public {
  124. try (new a{value: 511})() {
  125. //
  126. }
  127. catch (bytes) {
  128. //
  129. }
  130. }
  131. }
  132. contract a {
  133. function test(int32 l) public payable {
  134. }
  135. }"##,
  136. );
  137. runtime.constructor(0, Vec::new());
  138. runtime.function("step1", Vec::new());
  139. for (address, account) in runtime.accounts {
  140. if address == runtime.vm.account {
  141. continue;
  142. }
  143. assert_eq!(account.1, 511);
  144. }
  145. let mut runtime = build_solidity(
  146. r##"
  147. contract b {
  148. function step1() public {
  149. try (new a){value: 511}() returns (a) {
  150. //
  151. }
  152. catch (bytes) {
  153. //
  154. }
  155. }
  156. }
  157. contract a {
  158. function test(int32 l) public payable {
  159. }
  160. }"##,
  161. );
  162. runtime.constructor(0, Vec::new());
  163. runtime.function("step1", Vec::new());
  164. for (address, account) in runtime.accounts {
  165. if address == runtime.vm.account {
  166. continue;
  167. }
  168. assert_eq!(account.1, 511);
  169. }
  170. }
  171. #[test]
  172. fn constructor_salt() {
  173. let mut runtime = build_solidity(
  174. r##"
  175. contract b {
  176. function step1() public {
  177. a f = new a{salt: 0}();
  178. }
  179. }
  180. contract a {
  181. function test(int32 l) public payable {
  182. }
  183. }"##,
  184. );
  185. runtime.constructor(0, Vec::new());
  186. runtime.function("step1", Vec::new());
  187. let mut runtime = build_solidity(
  188. r##"
  189. contract b {
  190. function step1() public {
  191. a f = new a{salt: 1}();
  192. }
  193. }
  194. contract a {
  195. function test(int32 l) public payable {
  196. }
  197. }"##,
  198. );
  199. runtime.constructor(0, Vec::new());
  200. runtime.function("step1", Vec::new());
  201. // we can instantiate the same contract if we provide a different contract
  202. let mut runtime = build_solidity(
  203. r##"
  204. contract b {
  205. function step1() public {
  206. a f = new a{salt: 1}();
  207. f = new a{salt: 2}();
  208. }
  209. }
  210. contract a {
  211. function test(int32 l) public payable {
  212. }
  213. }"##,
  214. );
  215. runtime.constructor(0, Vec::new());
  216. runtime.function("step1", Vec::new());
  217. }
  218. #[test]
  219. fn this_address() {
  220. let mut runtime = build_solidity(
  221. r##"
  222. contract b {
  223. function step1() public returns (address) {
  224. return address(this);
  225. }
  226. }"##,
  227. );
  228. runtime.constructor(0, Vec::new());
  229. runtime.function("step1", Vec::new());
  230. assert_eq!(runtime.vm.output, runtime.vm.account);
  231. let mut runtime = build_solidity(
  232. r##"
  233. contract b {
  234. function step1() public returns (b) {
  235. return this;
  236. }
  237. }"##,
  238. );
  239. runtime.constructor(0, Vec::new());
  240. runtime.function("step1", Vec::new());
  241. assert_eq!(runtime.vm.output, runtime.vm.account);
  242. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  243. struct Ret(u32);
  244. let mut runtime = build_solidity(
  245. r##"
  246. contract b {
  247. int32 s;
  248. function step1() public returns (int32) {
  249. this.other(102);
  250. return s;
  251. }
  252. function other(int32 n) public {
  253. s = n;
  254. }
  255. }"##,
  256. );
  257. runtime.constructor(0, Vec::new());
  258. runtime.function("step1", Vec::new());
  259. assert_eq!(runtime.vm.output, Ret(102).encode());
  260. let mut runtime = build_solidity(
  261. r##"
  262. contract b {
  263. function step1() public returns (b) {
  264. return this;
  265. }
  266. }"##,
  267. );
  268. runtime.constructor(0, Vec::new());
  269. runtime.function("step1", Vec::new());
  270. assert_eq!(runtime.vm.output, runtime.vm.account);
  271. }
  272. #[test]
  273. fn balance() {
  274. let mut runtime = build_solidity(
  275. r##"
  276. contract b {
  277. other o;
  278. constructor() public {
  279. o = new other();
  280. }
  281. function step1() public returns (uint128) {
  282. return address(this).balance;
  283. }
  284. function step2() public returns (uint128) {
  285. return o.balance();
  286. }
  287. }
  288. contract other {
  289. function balance() public returns (uint128) {
  290. return address(this).balance;
  291. }
  292. }"##,
  293. );
  294. runtime.constructor(0, Vec::new());
  295. runtime.accounts.get_mut(&runtime.vm.account).unwrap().1 = 315;
  296. runtime.function("step1", Vec::new());
  297. assert_eq!(runtime.vm.output, 315u128.to_le_bytes());
  298. runtime.function("step2", Vec::new());
  299. assert_eq!(runtime.vm.output, 500u128.to_le_bytes());
  300. }
  301. #[test]
  302. fn selfdestruct() {
  303. let mut runtime = build_solidity(
  304. r##"
  305. contract c {
  306. other o;
  307. function step1() public {
  308. o = new other{value: 511}();
  309. }
  310. function step2() public {
  311. o.goaway(payable(address(this)));
  312. }
  313. }
  314. contract other {
  315. function goaway(address payable recipient) public returns (bool) {
  316. selfdestruct(recipient);
  317. }
  318. }"##,
  319. );
  320. runtime.constructor(0, Vec::new());
  321. runtime.function("step1", Vec::new());
  322. assert_eq!(runtime.accounts.get_mut(&runtime.vm.account).unwrap().1, 0);
  323. runtime.function_expect_failure("step2", Vec::new());
  324. assert_eq!(
  325. runtime.accounts.get_mut(&runtime.vm.account).unwrap().1,
  326. 511
  327. );
  328. }
  329. #[test]
  330. fn send_and_transfer() {
  331. let mut runtime = build_solidity(
  332. r##"
  333. contract c {
  334. other o;
  335. constructor() public {
  336. o = new other();
  337. }
  338. function step1() public returns (bool) {
  339. return payable(o).send(511);
  340. }
  341. }
  342. contract other {
  343. function giveme() public payable {
  344. }
  345. }"##,
  346. );
  347. runtime.constructor(0, Vec::new());
  348. runtime.function("step1", Vec::new());
  349. // no receive() required for send/transfer
  350. assert_eq!(runtime.vm.output, true.encode());
  351. for (address, account) in runtime.accounts {
  352. if address == runtime.vm.account {
  353. continue;
  354. }
  355. assert_eq!(account.1, 1011);
  356. }
  357. let mut runtime = build_solidity(
  358. r##"
  359. contract c {
  360. other o;
  361. constructor() public {
  362. o = new other();
  363. }
  364. function step1() public returns (bool) {
  365. return payable(o).send(511);
  366. }
  367. }
  368. contract other {
  369. receive() external payable {
  370. }
  371. }"##,
  372. );
  373. runtime.constructor(0, Vec::new());
  374. runtime.function("step1", Vec::new());
  375. assert_eq!(runtime.vm.output, true.encode());
  376. for (address, account) in runtime.accounts {
  377. if address == runtime.vm.account {
  378. continue;
  379. }
  380. assert_eq!(account.1, 1011);
  381. }
  382. let mut runtime = build_solidity(
  383. r##"
  384. contract c {
  385. other o;
  386. constructor() public {
  387. o = new other();
  388. }
  389. function step1() public {
  390. payable(o).transfer(511);
  391. }
  392. }
  393. contract other {
  394. function giveme() public {
  395. }
  396. }"##,
  397. );
  398. runtime.constructor(0, Vec::new());
  399. runtime.function("step1", Vec::new());
  400. for (address, account) in runtime.accounts {
  401. if address == runtime.vm.account {
  402. continue;
  403. }
  404. assert_eq!(account.1, 1011);
  405. }
  406. let mut runtime = build_solidity(
  407. r##"
  408. contract c {
  409. other o;
  410. constructor() public {
  411. o = new other();
  412. }
  413. function step1() public {
  414. payable(o).transfer(511);
  415. }
  416. }
  417. contract other {
  418. receive() external payable {
  419. }
  420. }"##,
  421. );
  422. runtime.constructor(0, Vec::new());
  423. runtime.function("step1", Vec::new());
  424. for (address, account) in runtime.accounts {
  425. if address == runtime.vm.account {
  426. continue;
  427. }
  428. assert_eq!(account.1, 1011);
  429. }
  430. }