inheritance.rs 16 KB

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