inheritance.rs 16 KB

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