Skip to content

Commit 23e46d2

Browse files
authored
Add internal helpers and typed interface calls (#1949)
* Add internal helpers and typed interface calls * Handle multi-argument typed interface calls * Reject interface type name collisions
1 parent 84ea2d2 commit 23e46d2

10 files changed

Lines changed: 660 additions & 50 deletions

File tree

Contracts/Smoke.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Compiler.Modules.Create2SSTORE2
1616
import Compiler.Modules.ERC20
1717
import Compiler.Modules.Oracle
1818
import Compiler.Modules.Precompiles
19+
import Contracts.Smoke.InternalInterfaceSmoke
1920

2021
namespace Contracts.Smoke
2122

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import Contracts.Common
2+
3+
set_option linter.unusedVariables false
4+
5+
namespace Contracts.Smoke
6+
7+
open Verity hiding pure bind
8+
open Verity.EVM.Uint256
9+
10+
verity_contract InternalHelperSmoke where
11+
storage
12+
13+
function internal bump (x : Uint256) : Uint256 := do
14+
return (add x 1)
15+
16+
example :
17+
(InternalHelperSmoke.spec.functions).any (fun fn =>
18+
fn.name == "bump" && !fn.isInternal) = false := by
19+
decide
20+
21+
example :
22+
(InternalHelperSmoke.spec.functions).any (fun fn =>
23+
fn.name == "internal_bump" && fn.isInternal) = true := by
24+
decide
25+
26+
verity_contract TypedInterfaceCallSmoke where
27+
storage
28+
29+
interfaces
30+
interface IERC20 where
31+
function balanceOf(Address) view returns (Uint256)
32+
function transfer(Address, Uint256) returns (Bool)
33+
end
34+
35+
function readBalance (token : IERC20, owner : Address) : Uint256 := do
36+
let bal ← token.balanceOf owner
37+
return bal
38+
39+
function readBalanceViaAlias (token : IERC20, owner : Address) : Uint256 := do
40+
let t := token
41+
let bal ← t.balanceOf owner
42+
return bal
43+
44+
function transferToken (token : IERC20, recipient : Address, amount : Uint256) : Bool := do
45+
let ok ← token.transfer recipient amount
46+
return ok
47+
48+
example :
49+
(TypedInterfaceCallSmoke.spec.externals).any (fun ext =>
50+
ext.name == "IERC20.balanceOf") = true := by
51+
decide
52+
53+
example :
54+
(TypedInterfaceCallSmoke.spec.functions).any (fun fn =>
55+
fn.name == "readBalance" &&
56+
fn.body.any (fun stmt =>
57+
match stmt with
58+
| Compiler.CompilationModel.Stmt.ecm mod args =>
59+
mod.name == "externalCallWithReturn" &&
60+
mod.numArgs == 2 &&
61+
mod.resultVars == ["bal"] &&
62+
mod.readsState &&
63+
!mod.writesState &&
64+
args.length == 2
65+
| _ => false)) = true := by
66+
decide
67+
68+
example :
69+
(TypedInterfaceCallSmoke.spec.functions).any (fun fn =>
70+
fn.name == "readBalanceViaAlias" &&
71+
fn.body.any (fun stmt =>
72+
match stmt with
73+
| Compiler.CompilationModel.Stmt.ecm mod args =>
74+
mod.name == "externalCallWithReturn" &&
75+
mod.numArgs == 2 &&
76+
mod.resultVars == ["bal"] &&
77+
mod.readsState &&
78+
!mod.writesState &&
79+
args.length == 2
80+
| _ => false)) = true := by
81+
decide
82+
83+
example :
84+
(TypedInterfaceCallSmoke.spec.functions).any (fun fn =>
85+
fn.name == "transferToken" &&
86+
fn.body.any (fun stmt =>
87+
match stmt with
88+
| Compiler.CompilationModel.Stmt.ecm mod args =>
89+
mod.name == "externalCallWithReturn" &&
90+
mod.numArgs == 3 &&
91+
mod.resultVars == ["ok"] &&
92+
mod.readsState &&
93+
mod.writesState &&
94+
args.length == 3
95+
| _ => false)) = true := by
96+
decide
97+
98+
/--
99+
error: interface name 'Clash' conflicts with an existing type name
100+
-/
101+
#guard_msgs in
102+
verity_contract InterfaceTypeNameClashRejected where
103+
types
104+
Clash : Uint256
105+
106+
storage
107+
108+
interfaces
109+
interface Clash where
110+
function read() view returns (Uint256)
111+
end
112+
113+
function noop (_item : Clash) : Unit := do
114+
pure ()
115+
116+
end Contracts.Smoke

Verity/Macro/Syntax.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ declare_syntax_cat verityConstant
1616
declare_syntax_cat verityImmutable
1717
declare_syntax_cat verityExternal
1818
declare_syntax_cat verityExternalLinkMode
19+
declare_syntax_cat verityInterface
20+
declare_syntax_cat verityInterfaceFunction
21+
declare_syntax_cat verityInterfaceParam
1922
declare_syntax_cat verityLocalObligation
2023
declare_syntax_cat verityLocalObligations
2124
declare_syntax_cat verityConstructor
@@ -67,10 +70,17 @@ syntax "external " ident "(" sepBy(term, ",") ")" : verityExternal
6770
syntax "external " ident "(" sepBy(term, ",") ")" " -> " "(" sepBy(term, ",") ")" : verityExternal
6871
syntax "external " ident "(" sepBy(term, ",") ")" ppSpace "linked_as" " := " verityExternalLinkMode : verityExternal
6972
syntax "external " ident "(" sepBy(term, ",") ")" " -> " "(" sepBy(term, ",") ")" ppSpace "linked_as" " := " verityExternalLinkMode : verityExternal
73+
syntax ident " : " term : verityInterfaceParam
74+
syntax "function " ident "(" sepBy(term, ",") ")" verityMutability* ident "(" sepBy(term, ",") ")" : verityInterfaceFunction
75+
syntax "function " ident " (" sepBy(term, ",") ")" verityMutability* ident "(" sepBy(term, ",") ")" : verityInterfaceFunction
76+
syntax "function " ident "(" sepBy(verityInterfaceParam, ",") ")" verityMutability* ident "(" sepBy(term, ",") ")" : verityInterfaceFunction
77+
syntax "function " ident " (" sepBy(verityInterfaceParam, ",") ")" verityMutability* ident "(" sepBy(term, ",") ")" : verityInterfaceFunction
78+
syntax "interface " ident " where " verityInterfaceFunction* "end" : verityInterface
7079
syntax ident " := " ident ppSpace str : verityLocalObligation
7180
syntax "local_obligations " "[" sepBy(verityLocalObligation, ",") "]" : verityLocalObligations
7281
syntax "payable" : verityMutability
7382
syntax "view" : verityMutability
83+
syntax "internal" : verityMutability
7484
syntax pureMutabilityMarker := &"pure"
7585
syntax "no_external_calls" : verityMutability
7686
syntax "allow_post_interaction_writes" : verityMutability
@@ -158,6 +168,7 @@ syntax (name := verityContractCmd)
158168
("event_defs " verityEvent+)?
159169
("constants " verityConstant+)?
160170
("immutables " verityImmutable+)?
171+
("interfaces " verityInterface+)?
161172
("linked_externals " verityExternal+)?
162173
(verityConstructor)?
163174
(veritySpecialEntrypoint)*

0 commit comments

Comments
 (0)