inheritance.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::build_solidity;
  3. use parity_scale_codec::{Decode, Encode};
  4. use solang::file_resolver::FileResolver;
  5. use solang::Target;
  6. use std::ffi::OsStr;
  7. #[test]
  8. fn test_abstract() {
  9. let mut cache = FileResolver::new();
  10. cache.set_file_contents(
  11. "a.sol",
  12. r#"
  13. abstract contract foo {
  14. constructor(int arg1) public {
  15. }
  16. function f1() public {
  17. }
  18. }
  19. contract bar {
  20. function test() public returns (uint32) {
  21. return 102;
  22. }
  23. }
  24. "#
  25. .to_string(),
  26. );
  27. let (contracts, ns) = solang::compile(
  28. OsStr::new("a.sol"),
  29. &mut cache,
  30. inkwell::OptimizationLevel::Default,
  31. Target::default_substrate(),
  32. false,
  33. false,
  34. true,
  35. #[cfg(feature = "wasm_opt")]
  36. Some(contract_build::OptimizationPasses::Z),
  37. );
  38. assert!(!ns.diagnostics.any_errors());
  39. assert_eq!(contracts.len(), 1);
  40. let mut cache = FileResolver::new();
  41. cache.set_file_contents(
  42. "a.sol",
  43. r#"
  44. contract foo {
  45. function f1() public {
  46. }
  47. }"#
  48. .to_string(),
  49. );
  50. cache.set_file_contents(
  51. "b.sol",
  52. r#"
  53. import "a.sol";
  54. contract bar is foo {
  55. function test() public returns (uint32) {
  56. return 102;
  57. }
  58. }
  59. "#
  60. .to_string(),
  61. );
  62. let (contracts, ns) = solang::compile(
  63. OsStr::new("a.sol"),
  64. &mut cache,
  65. inkwell::OptimizationLevel::Default,
  66. Target::default_substrate(),
  67. false,
  68. false,
  69. true,
  70. #[cfg(feature = "wasm_opt")]
  71. Some(contract_build::OptimizationPasses::Z),
  72. );
  73. assert!(!ns.diagnostics.any_errors());
  74. assert_eq!(contracts.len(), 1);
  75. }
  76. #[test]
  77. fn inherit_variables() {
  78. let mut runtime = build_solidity(
  79. r##"
  80. contract b is a {
  81. uint16 public foo = 65535;
  82. }
  83. abstract contract a {
  84. uint16 private foo = 102;
  85. }"##,
  86. );
  87. runtime.constructor(0, Vec::new());
  88. let mut slot = [0u8; 32];
  89. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(102, 0));
  90. slot[0] = 1;
  91. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(0xff, 0xff));
  92. let mut runtime = build_solidity(
  93. r##"
  94. contract b is a {
  95. uint16 public var_b;
  96. function test() public {
  97. var_a = 102;
  98. var_b = 65535;
  99. }
  100. }
  101. contract a {
  102. uint16 public var_a;
  103. }"##,
  104. );
  105. runtime.constructor(0, Vec::new());
  106. runtime.function("test", Vec::new());
  107. let mut slot = [0u8; 32];
  108. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(102, 0));
  109. slot[0] = 1;
  110. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(0xff, 0xff));
  111. }
  112. #[test]
  113. fn call_inherited_function() {
  114. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  115. struct Val(u64);
  116. let mut runtime = build_solidity(
  117. r##"
  118. contract apex is base {
  119. function bar() public returns (uint64) {
  120. return foo() + 3;
  121. }
  122. }
  123. contract base {
  124. function foo() public returns (uint64) {
  125. return 102;
  126. }
  127. }"##,
  128. );
  129. runtime.constructor(0, Vec::new());
  130. runtime.function("bar", Vec::new());
  131. assert_eq!(runtime.output(), Val(105).encode());
  132. let mut runtime = build_solidity(
  133. r##"
  134. contract apex is base {
  135. uint64 private x = 7;
  136. function bar() public returns (uint64) {
  137. return foo() + x + 13;
  138. }
  139. }
  140. contract base {
  141. uint64 private x = 5;
  142. function foo() public returns (uint64) {
  143. return x + 11;
  144. }
  145. }"##,
  146. );
  147. runtime.constructor(0, Vec::new());
  148. runtime.function("bar", Vec::new());
  149. assert_eq!(runtime.output(), Val(36).encode());
  150. let mut runtime = build_solidity(
  151. r##"
  152. contract apex is base, base2 {
  153. uint64 private x = 7;
  154. function bar() public returns (uint64) {
  155. return foo() + foo2() + x + 13;
  156. }
  157. }
  158. contract base {
  159. uint64 private x = 50000;
  160. function foo() public returns (uint64) {
  161. return x + 110000;
  162. }
  163. }
  164. contract base2 {
  165. uint64 private x = 600;
  166. function foo2() public returns (uint64) {
  167. return x + 1100;
  168. }
  169. }"##,
  170. );
  171. runtime.constructor(0, Vec::new());
  172. runtime.function("bar", Vec::new());
  173. assert_eq!(runtime.output(), Val(161720).encode());
  174. let mut runtime = build_solidity(
  175. r##"
  176. contract apex is base, base2 {
  177. function foo(int64 x) public returns (uint64) {
  178. return 3;
  179. }
  180. }
  181. contract base {
  182. function foo() public returns (uint64) {
  183. return 1;
  184. }
  185. }
  186. contract base2 {
  187. function foo(bool) public returns (uint64) {
  188. return 2;
  189. }
  190. }"##,
  191. );
  192. runtime.constructor(0, Vec::new());
  193. runtime.set_transferred_value(0);
  194. runtime.raw_function([0xC2, 0x98, 0x55, 0x78].to_vec());
  195. assert_eq!(runtime.output(), Val(1).encode());
  196. runtime.raw_function([0x45, 0x55, 0x75, 0x78, 1].to_vec());
  197. assert_eq!(runtime.output(), Val(2).encode());
  198. runtime.raw_function([0x36, 0x8E, 0x4A, 0x7F, 1, 2, 3, 4, 5, 6, 7, 8].to_vec());
  199. assert_eq!(runtime.output(), Val(3).encode());
  200. }
  201. #[test]
  202. fn test_override() {
  203. let mut runtime = build_solidity(
  204. r##"
  205. contract b is a {
  206. receive() override payable external {
  207. x = 2;
  208. }
  209. }
  210. contract a {
  211. int8 public x = 3;
  212. receive() virtual payable external {
  213. x = 1;
  214. }
  215. }
  216. contract c is b {
  217. function test() public returns (int8) {
  218. return x;
  219. }
  220. }"##,
  221. );
  222. runtime.constructor(0, Vec::new());
  223. let slot = [0u8; 32];
  224. assert_eq!(runtime.storage()[&slot], vec!(3));
  225. runtime.set_transferred_value(1);
  226. runtime.raw_function([0xC2, 0x98, 0x55, 0x78].to_vec());
  227. let slot = [0u8; 32];
  228. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(2));
  229. let mut runtime = build_solidity(
  230. r##"
  231. contract b is a {
  232. fallback() override external {
  233. x = 2;
  234. }
  235. }
  236. contract a {
  237. int8 public x = 3;
  238. fallback() virtual external {
  239. x = 1;
  240. }
  241. }"##,
  242. );
  243. runtime.constructor(0, Vec::new());
  244. let slot = [0u8; 32];
  245. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(3));
  246. runtime.set_transferred_value(0);
  247. runtime.raw_function([0xC2, 0x98, 0x55, 0x78].to_vec());
  248. let slot = [0u8; 32];
  249. assert_eq!(runtime.contracts()[0].storage[&slot], vec!(2));
  250. }
  251. #[test]
  252. fn base_contract() {
  253. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  254. struct Val(u32);
  255. let mut runtime = build_solidity(
  256. r##"
  257. contract b is a(foo) {
  258. int32 constant foo = 102;
  259. function f() public returns (int32) {
  260. return bar;
  261. }
  262. }
  263. contract a {
  264. int32 public bar;
  265. constructor(int32 x) public {
  266. bar = x;
  267. }
  268. }"##,
  269. );
  270. runtime.constructor(0, Vec::new());
  271. runtime.function("f", Vec::new());
  272. assert_eq!(runtime.output(), Val(102).encode());
  273. }
  274. #[test]
  275. fn base_contract_on_constructor() {
  276. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  277. struct Val(i32);
  278. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  279. struct Val64(u64);
  280. let mut runtime = build_solidity(
  281. r##"
  282. contract b is a {
  283. int32 constant BAR = 102;
  284. int64 public foo;
  285. constructor(int64 i) a(BAR) { foo = i; }
  286. function get_x() public returns (int32) {
  287. return x;
  288. }
  289. }
  290. contract a {
  291. int32 public x;
  292. constructor(int32 i) { x = i; }
  293. }"##,
  294. );
  295. runtime.constructor(0, Val64(0xbffe).encode());
  296. runtime.function("get_x", Vec::new());
  297. assert_eq!(runtime.output(), Val(102).encode());
  298. let mut runtime = build_solidity(
  299. r##"
  300. contract c is b(2) {
  301. constructor() {
  302. }
  303. }
  304. contract a {
  305. int32 public x;
  306. constructor(int32 i) { x = i; }
  307. }
  308. contract b is a {
  309. int32 constant BAR = 102;
  310. int64 public foo;
  311. constructor(int64 i) a(BAR + int32(i)) { foo = i; }
  312. function get_x() public view returns (int32) {
  313. return x;
  314. }
  315. function get_foo() public view returns (int64) {
  316. return foo;
  317. }
  318. }"##,
  319. );
  320. runtime.constructor(0, Vec::new());
  321. runtime.function("get_x", Vec::new());
  322. assert_eq!(runtime.output(), Val(104).encode());
  323. let mut runtime = build_solidity(
  324. r##"
  325. contract c is b {
  326. constructor(int64 x) b(x+3) {}
  327. }
  328. contract b is a {
  329. constructor(int64 y) a(y+2) {}
  330. }
  331. contract a {
  332. int64 foo;
  333. function get_foo() public returns (int64) { return foo; }
  334. constructor(int64 z) { foo = z; }
  335. }"##,
  336. );
  337. runtime.constructor(0, Val64(7).encode());
  338. runtime.function("get_foo", Vec::new());
  339. assert_eq!(runtime.output(), Val64(12).encode());
  340. let mut runtime = build_solidity(
  341. r##"
  342. contract c is b {
  343. constructor(int64 x) b(x+3) a(x+5){}
  344. }
  345. abstract contract b is a {
  346. constructor(int64 y) {}
  347. }
  348. contract a {
  349. int64 foo;
  350. function get_foo() public returns (int64) { return foo; }
  351. constructor(int64 z) { foo = z; }
  352. }"##,
  353. );
  354. runtime.constructor(0, Val64(7).encode());
  355. runtime.function("get_foo", Vec::new());
  356. assert_eq!(runtime.output(), Val64(12).encode());
  357. }
  358. #[test]
  359. fn call_base_function_via_basename() {
  360. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  361. struct Val(i32);
  362. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  363. struct Val64(u64);
  364. let mut runtime = build_solidity(
  365. r##"
  366. contract c is b {
  367. function bar() public returns (uint64) {
  368. return a.foo();
  369. }
  370. }
  371. abstract contract b is a {
  372. function foo() internal override returns (uint64) {
  373. return 2;
  374. }
  375. }
  376. abstract contract a {
  377. function foo() internal virtual returns (uint64) {
  378. return 1;
  379. }
  380. }"##,
  381. );
  382. runtime.constructor(0, Vec::new());
  383. runtime.function("bar", Vec::new());
  384. assert_eq!(runtime.output(), Val64(1).encode());
  385. let mut runtime = build_solidity(
  386. r##"
  387. contract c is b {
  388. uint64 constant private C = 100;
  389. function bar() public returns (uint64) {
  390. return a.foo({ x: C });
  391. }
  392. }
  393. abstract contract b is a {
  394. uint64 constant private C = 300;
  395. function foo(uint64 x) internal override returns (uint64) {
  396. return 2;
  397. }
  398. }
  399. abstract contract a {
  400. uint64 constant private C = 200;
  401. function foo(uint64 x) internal virtual returns (uint64) {
  402. return 1 + x;
  403. }
  404. }"##,
  405. );
  406. runtime.constructor(0, Vec::new());
  407. runtime.function("bar", Vec::new());
  408. assert_eq!(runtime.output(), Val64(101).encode());
  409. }
  410. #[test]
  411. fn simple_interface() {
  412. let mut runtime = build_solidity(
  413. r##"
  414. contract foo is IFoo {
  415. function bar(uint32 a) public pure override returns (uint32) {
  416. return a * 2;
  417. }
  418. }
  419. interface IFoo {
  420. function bar(uint32) external pure returns (uint32);
  421. }"##,
  422. );
  423. runtime.constructor(0, Vec::new());
  424. runtime.function("bar", 100u32.encode());
  425. assert_eq!(runtime.output(), 200u32.encode());
  426. }
  427. #[test]
  428. fn test_super() {
  429. let mut runtime = build_solidity(
  430. r##"
  431. contract b is a {
  432. function bar() public returns (uint64) {
  433. super.foo();
  434. return var;
  435. }
  436. function foo() internal override {
  437. var = 103;
  438. }
  439. }
  440. abstract contract a {
  441. uint64 var;
  442. function foo() internal virtual {
  443. var = 102;
  444. }
  445. }"##,
  446. );
  447. runtime.constructor(0, Vec::new());
  448. runtime.function("bar", Vec::new());
  449. assert_eq!(runtime.output(), 102u64.encode());
  450. let mut runtime = build_solidity(
  451. r##"
  452. contract b is a {
  453. function bar() public returns (uint64) {
  454. super.foo({x: 10});
  455. return var;
  456. }
  457. function foo2(uint64 x) internal {
  458. var = 103 + x;
  459. }
  460. }
  461. abstract contract a {
  462. uint64 var;
  463. function foo(uint64 x) internal virtual {
  464. var = 102 + x;
  465. }
  466. }"##,
  467. );
  468. runtime.constructor(0, Vec::new());
  469. runtime.function("bar", Vec::new());
  470. assert_eq!(runtime.output(), 112u64.encode());
  471. let mut runtime = build_solidity(
  472. r##"
  473. contract b is a, aa {
  474. function bar() public returns (uint64) {
  475. return super.foo({x: 10});
  476. }
  477. function foo(uint64 x) public override(a, aa) returns (uint64) {
  478. return 103 + x;
  479. }
  480. }
  481. contract a {
  482. function foo(uint64 x) public virtual returns (uint64) {
  483. return 102 + x;
  484. }
  485. }
  486. contract aa {
  487. function foo(uint64 x) public virtual returns (uint64) {
  488. return 202 + x;
  489. }
  490. }"##,
  491. );
  492. runtime.constructor(0, Vec::new());
  493. runtime.function("bar", Vec::new());
  494. assert_eq!(runtime.output(), 112u64.encode());
  495. // super should not consider interfaces
  496. let mut runtime = build_solidity(
  497. r##"
  498. contract b is a, aa {
  499. function bar() public returns (uint64) {
  500. return super.foo({x: 10});
  501. }
  502. function foo(uint64 x) public override(a, aa) returns (uint64) {
  503. return 103 + x;
  504. }
  505. }
  506. interface a {
  507. function foo(uint64 x) external returns (uint64);
  508. }
  509. contract aa {
  510. function foo(uint64 x) public virtual returns (uint64) {
  511. return 202 + x;
  512. }
  513. }"##,
  514. );
  515. runtime.constructor(0, Vec::new());
  516. runtime.function("bar", Vec::new());
  517. assert_eq!(runtime.output(), 212u64.encode());
  518. }
  519. #[test]
  520. fn var_or_function() {
  521. let mut runtime = build_solidity(
  522. r##"
  523. contract x is c {
  524. function f1() public returns (int64) {
  525. return selector;
  526. }
  527. function f2() public returns (int64) {
  528. function() external returns (int64) a = this.selector;
  529. return a{flags: 8}();
  530. }
  531. }
  532. contract c {
  533. int64 public selector = 102;
  534. }"##,
  535. );
  536. runtime.constructor(0, Vec::new());
  537. runtime.function("f1", Vec::new());
  538. assert_eq!(runtime.output(), 102u64.encode());
  539. runtime.function("f2", Vec::new());
  540. assert_eq!(runtime.output(), 102u64.encode());
  541. }