inheritance.rs 16 KB

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