@@ -2,14 +2,14 @@ import "helpers/helpers.spec";
2
2
import "ERC20.spec" ;
3
3
4
4
methods {
5
- function underlying () external returns (address ) envfree ;
6
- function underlyingTotalSupply () external returns (uint256 ) envfree ;
7
- function underlyingBalanceOf (address ) external returns (uint256 ) envfree ;
8
- function underlyingAllowanceToThis ( address ) external returns (uint256 ) envfree ;
9
-
10
- function depositFor (address , uint256 ) external returns (bool );
11
- function withdrawTo (address , uint256 ) external returns (bool );
12
- function recover (address ) external returns (uint256 );
5
+ function underlying () external returns (address ) envfree ;
6
+ function underlyingTotalSupply () external returns (uint256 ) envfree ;
7
+ function underlyingBalanceOf (address ) external returns (uint256 ) envfree ;
8
+ function underlyingAllowance ( address , address ) external returns (uint256 ) envfree ;
9
+
10
+ function depositFor (address , uint256 ) external returns (bool );
11
+ function withdrawTo (address , uint256 ) external returns (bool );
12
+ function recover (address ) external returns (uint256 );
13
13
}
14
14
15
15
use invariant totalSupplyIsSumOfBalances ;
@@ -19,12 +19,25 @@ use invariant totalSupplyIsSumOfBalances;
19
19
│ Helper : consequence of `totalSupplyIsSumOfBalances` applied to underlying │
20
20
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
21
21
* /
22
- definition underlyingBalancesLowerThanUnderlyingSupply (address a ) returns bool =
23
- underlyingBalanceOf (a ) <= underlyingTotalSupply ();
24
-
25
22
definition sumOfUnderlyingBalancesLowerThanUnderlyingSupply (address a , address b ) returns bool =
26
23
a != b = > underlyingBalanceOf (a ) + underlyingBalanceOf (b ) <= to_mathint (underlyingTotalSupply ());
27
24
25
+ / *
26
+ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
27
+ │ Invariant : wrapped token should not allow any third party to spend its tokens │
28
+ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
29
+ * /
30
+ invariant noAllowance (address user )
31
+ underlyingAllowance (currentContract , user ) == 0
32
+ {
33
+ preserved ERC20PermitHarness .approve (address spender , uint256 value ) with (env e ) {
34
+ require e .msg .sender != currentContract ;
35
+ }
36
+ preserved ERC20PermitHarness .permit (address owner , address spender , uint256 value , uint256 deadline , uint8 v , bytes32 r , bytes32 s ) with (env e ) {
37
+ require owner != currentContract ;
38
+ }
39
+ }
40
+
28
41
/ *
29
42
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
30
43
│ Invariant : wrapped token can 't be undercollateralized (solvency of the wrapper ) │
@@ -35,13 +48,20 @@ invariant totalSupplyIsSmallerThanUnderlyingBalance()
35
48
underlyingBalanceOf (currentContract ) <= underlyingTotalSupply () & &
36
49
underlyingTotalSupply () <= max_uint256
37
50
{
38
- preserved {
51
+ preserved with ( env e ) {
39
52
requireInvariant totalSupplyIsSumOfBalances ;
40
- require underlyingBalancesLowerThanUnderlyingSupply (currentContract );
41
- }
42
- preserved depositFor (address account , uint256 amount ) with (env e ) {
53
+ require e .msg .sender != currentContract ;
43
54
require sumOfUnderlyingBalancesLowerThanUnderlyingSupply (e .msg .sender , currentContract );
44
55
}
56
+ preserved ERC20PermitHarness .transferFrom (address from , address to , uint256 amount ) with (env e ) {
57
+ requireInvariant noAllowance (e .msg .sender );
58
+ require sumOfUnderlyingBalancesLowerThanUnderlyingSupply (from , to );
59
+ }
60
+ preserved ERC20PermitHarness .burn (address from , uint256 amount ) with (env e ) {
61
+ // If someone can burn from the wrapper , than the invariant obviously doesn 't hold .
62
+ require from != currentContract ;
63
+ require sumOfUnderlyingBalancesLowerThanUnderlyingSupply (from , currentContract );
64
+ }
45
65
}
46
66
47
67
invariant noSelfWrap ()
@@ -69,7 +89,7 @@ rule depositFor(env e) {
69
89
uint256 balanceBefore = balanceOf (receiver );
70
90
uint256 supplyBefore = totalSupply ();
71
91
uint256 senderUnderlyingBalanceBefore = underlyingBalanceOf (sender );
72
- uint256 senderUnderlyingAllowanceBefore = underlyingAllowanceToThis (sender );
92
+ uint256 senderUnderlyingAllowanceBefore = underlyingAllowance (sender , currentContract );
73
93
uint256 wrapperUnderlyingBalanceBefore = underlyingBalanceOf (currentContract );
74
94
uint256 underlyingSupplyBefore = underlyingTotalSupply ();
75
95
0 commit comments