inheritance.rs 16 KB

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