Skip to content

Commit db70976

Browse files
authored
Merge pull request #49 from Certora/niv/Immutable-exmple+direct-strorage-access
Immutable example + direct storage access
2 parents 6029499 + 59ffba7 commit db70976

11 files changed

Lines changed: 221 additions & 30 deletions

File tree

CVLByExample/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
| Category | Links |
44
| ----------------- | ----- |
55
| **array** | [In a statement](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L88), [In SStore parameter](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L146), [by function call](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L77),<br> [Function declaration in method block](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L21) |
6-
| **assert** | [assert](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L75) |
6+
| **assert** | [assert](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L72) |
77
| **assert_uint256** | [assert_uint256](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Fixed.spec#L180) |
88
| **at** | [at](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L113) |
99
| **builtin rule** | [builtin rule](https://github.com/Certora/Examples/blob/master/CVLByExample/Reentrancy/certora/spec/ReadOnlyReentrancy.spec#L1) |
@@ -15,24 +15,24 @@
1515
| **filtered** | [`filtered`](https://github.com/Certora/Examples/blob/master/CVLByExample/Reentrancy/certora/spec/Reentrancy.spec#L29) |
1616
| **forall** | [`forall`](https://github.com/Certora/Examples/blob/master/CVLByExample/QuantifierExamples/DoublyLinkedList/certora/spec/dll-linkedcorrectly.spec#L13) |
1717
| **Function call** | [Function call](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Fixed.spec#L123) |
18-
| **ghost** | [simple variable example](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Full.spec#L72), [ghost mapping](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L118), [ghost function](https://github.com/Certora/Examples/blob/master/CVLByExample/QuantifierExamples/DoublyLinkedList/certora/spec/dll-linkedcorrectly.spec#L24),<br> [`init_state`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L219), [`axiom`](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L120), [ghost summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/GhostSummary/GhostMapping/certora/specs/WithGhostSummary.spec#L4) |
18+
| **ghost** | [simple variable example](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Full.spec#L72), [ghost mapping](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L118), [ghost function](https://github.com/Certora/Examples/blob/master/CVLByExample/QuantifierExamples/DoublyLinkedList/certora/spec/dll-linkedcorrectly.spec#L24),<br> [`init_state`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L216), [`axiom`](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L120), [ghost summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/GhostSummary/GhostMapping/certora/specs/WithGhostSummary.spec#L4) |
1919
| **hook** | [`Sstore`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Full.spec#L88), [`Sload`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Full.spec#L84) |
2020
| **import** | [`import`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L1) |
21-
| **invariant** | [Simple Invariant](https://github.com/Certora/Examples/blob/master/CVLByExample/Invariant/certora/specs/BallGame.spec#L7), [strengthening](https://github.com/Certora/Examples/blob/master/CVLByExample/Invariant/certora/specs/BallGameCorrect.spec#L7), [`preserved with (env e)`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Broken.spec#L128),<br> [`requireInvariant`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L190) |
21+
| **invariant** | [Simple Invariant](https://github.com/Certora/Examples/blob/master/CVLByExample/Invariant/certora/specs/BallGame.spec#L7), [strengthening](https://github.com/Certora/Examples/blob/master/CVLByExample/Invariant/certora/specs/BallGameCorrect.spec#L7), [`preserved with (env e)`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Broken.spec#L128),<br> [`requireInvariant`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L187) |
2222
| **lastreverted** | [`lastreverted`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Broken.spec#L49) |
2323
| **laststorage** | [`laststorage`](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L27) |
24-
| **methods block** | [Calls to external contracts](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L29), [envfree](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L19),<br> Summary [`ALWAYS`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/AlwaysSummary.spec#L4), [`CONSTANT`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/ConstantVSNondet.spec#L5), [DISPATCHER](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L36), [`NONDET`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/NondetVsHavoc.spec#L2), [`HAVOC_ALL`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/NondetVsHavoc.spec#L3),<br> Summary Application [ALL](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/MultiContract/certora/specs/InternalExternalSummary.spec#L14), [UNRESOLVED](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L12), [direct summarization](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L9),<br> [wildcard summarization](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L12), [CVL Function Summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/WithEnv/WithEnvCVLFunctionSummary/withEnvSummary.spec#L7), [Ghost Summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/WithEnv/WithEnvGhostSummary/WithEnv.spec#L10),<br> [`optional`](https://github.com/Certora/Examples/blob/master/CVLByExample/Optional/certora/specs/Base.spec#L5), ['expect'](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/MultiContract/certora/specs/FunctionSummary.spec#L11) |
24+
| **methods block** | [Calls to external contracts](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L26), [envfree](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L19),<br> Summary [`ALWAYS`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/AlwaysSummary.spec#L4), [`CONSTANT`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/ConstantVSNondet.spec#L5), [DISPATCHER](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L33), [`NONDET`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/NondetVsHavoc.spec#L2), [`HAVOC_ALL`](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Keywords/certora/specs/NondetVsHavoc.spec#L3),<br> Summary Application [ALL](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/MultiContract/certora/specs/InternalExternalSummary.spec#L14), [UNRESOLVED](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L12), [direct summarization](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L9),<br> [wildcard summarization](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/Library/DirectSummary/certora/specs/AllDirect.spec#L12), [CVL Function Summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/WithEnv/WithEnvCVLFunctionSummary/withEnvSummary.spec#L7), [Ghost Summary](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/WithEnv/WithEnvGhostSummary/WithEnv.spec#L10),<br> [`optional`](https://github.com/Certora/Examples/blob/master/CVLByExample/Optional/certora/specs/Base.spec#L5), ['expect'](https://github.com/Certora/Examples/blob/master/CVLByExample/Summarization/MultiContract/certora/specs/FunctionSummary.spec#L11) |
2525
| **nativeBalances**| [`nativeBalances`](https://github.com/Certora/Examples/blob/master/CVLByExample/NativeBalances/certora/specs/Auction.spec#L24) |
2626
| **override** | [`override`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L1), [`definition`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L8), [`function`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L38) |
27-
| **require** | [`require`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L44) |
27+
| **require** | [`require`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L41) |
2828
| **require_uint256**| [`require_uint256`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Broken.spec#L156) |
2929
| **rule** | [Simple Rule](https://github.com/Certora/Examples/blob/master/DEFI/LiquidityPool/certora/specs/pool_havoc.spec#L27), parameterized [Simple Parameters](https://github.com/Certora/Examples/blob/master/DEFI/LiquidityPool/certora/specs/Full.spec#L78), [Method Parameter](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L95) |
30-
| **satisfy** | [`satisfy`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L255) |
30+
| **satisfy** | [`satisfy`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L252) |
3131
| **selector** | [`selector`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Fixed.spec#L92) |
3232
| **sig** | [`sig`](https://github.com/Certora/Examples/blob/master/DEFI/ERC20/certora/specs/ERC20Fixed.spec#L92) |
3333
| **storage** | [of a contract](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L86), [of a ghost](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L149), [of nativeBalances](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L116),<br> [full storage](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L106), [`laststorage`](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L106), [direct storage access](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L48) |
3434
| **struct** | [struct return type](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L47),<br> `struct` in `methods` block: [struct parameter](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L23), [struct return type](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L19),<br> [returning a struct as a tuple](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L21),<br> `struct` in a `CVL` function: [struct parameter to a CVL function](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L36),<br> [struct return type of a CVL function](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L47), [returning struct as a tuple](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L53),<br> [assignment to struct](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L98), [Assigning struct to a tuple](https://github.com/Certora/Examples/blob/master/CVLByExample/Structs/BankAccounts/certora/specs/structs.spec#L77) |
35-
| **to_mathint** | [`to_mathint`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L45) |
35+
| **to_mathint** | [`to_mathint`](https://github.com/Certora/Examples/blob/master/DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec#L42) |
3636
| **use** | `rule`: [with filters](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L32), [overriding imported filters](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L32),<br> [`invariant`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L10): [overriding imported `preserved`](https://github.com/Certora/Examples/blob/master/CVLByExample/Import/certora/specs/sub.spec#L12), [builtin rule](https://github.com/Certora/Examples/blob/master/CVLByExample/Reentrancy/certora/spec/ReadOnlyReentrancy.spec#L1) |
3737
| **using** | [`using`](https://github.com/Certora/Examples/blob/master/DEFI/LiquidityPool/certora/specs/pool_link.spec#L14) |
3838
| **withrevert** | [`withrevert`](https://github.com/Certora/Examples/blob/master/CVLByExample/Storage/certora/specs/storage.spec#L44) |

DEFI/ConstantProductPool/certora/spec/ConstantProductPool.spec

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ methods{
1919
function token0() external returns (address) envfree;
2020
function token1() external returns (address) envfree;
2121
function allowance(address,address) external returns (uint256) envfree;
22-
function balanceOf(address) external returns (uint256) envfree;
2322
function totalSupply() external returns (uint256) envfree;
24-
function getReserve0() external returns (uint256) envfree;
25-
function getReserve1() external returns (uint256) envfree;
2623
function swap(address tokenIn, address recipient) external returns (uint256) envfree;
2724

2825
//calls to external contracts
@@ -41,8 +38,8 @@ methods{
4138
function setup(env e){
4239
address zero_address = 0;
4340
uint256 MINIMUM_LIQUIDITY = 1000;
44-
require totalSupply() == 0 || balanceOf(zero_address) == MINIMUM_LIQUIDITY;
45-
require balanceOf(zero_address) + balanceOf(e.msg.sender) <= to_mathint(totalSupply());
41+
require totalSupply() == 0 || currentContract._balances[zero_address] == MINIMUM_LIQUIDITY;
42+
require currentContract._balances[zero_address] + currentContract._balances[e.msg.sender] <= to_mathint(totalSupply());
4643
require _token0 == token0();
4744
require _token1 == token1();
4845
}
@@ -96,10 +93,10 @@ rule noDecreaseByOther(method f, address account) {
9693
require account != currentContract;
9794
uint256 allowance = allowance(account, e.msg.sender);
9895

99-
uint256 before = balanceOf(account);
96+
uint256 before = currentContract._balances[account];
10097
calldataarg args;
10198
f(e,args); /* check on all possible arguments */
102-
uint256 after = balanceOf(account);
99+
uint256 after = currentContract._balances[account];
103100
/* logic implication : true when: (a) the left hand side is false or (b) right hand side is true */
104101
assert after < before => (e.msg.sender == account || to_mathint(allowance) >= (before-after)) ;
105102
}
@@ -121,8 +118,8 @@ Formula:
121118
*/
122119

123120
invariant balanceGreaterThanReserve()
124-
(getReserve0() <= _token0.balanceOf(currentContract))&&
125-
(getReserve1() <= _token1.balanceOf(currentContract))
121+
(currentContract.reserve0 <= _token0.balanceOf(currentContract))&&
122+
(currentContract.reserve1 <= _token1.balanceOf(currentContract))
126123
{
127124
preserved with (env e){
128125
setup(e);
@@ -157,8 +154,8 @@ Formula:
157154

158155
invariant integrityOfTotalSupply()
159156

160-
(totalSupply() == 0 <=> getReserve0() == 0) &&
161-
(totalSupply() == 0 <=> getReserve1() == 0)
157+
(totalSupply() == 0 <=> currentContract.reserve0 == 0) &&
158+
(totalSupply() == 0 <=> currentContract.reserve1 == 0)
162159
{
163160
preserved with (env e){
164161
requireInvariant balanceGreaterThanReserve();
@@ -193,11 +190,11 @@ rule monotonicityOfMint(uint256 x, uint256 y, address recipient) {
193190
require x > y ;
194191
_token0.transfer(eT0, currentContract, x);
195192
uint256 amountOut0 = mint(eM,recipient);
196-
uint256 balanceAfter1 = balanceOf(recipient);
193+
uint256 balanceAfter1 = currentContract._balances[recipient];
197194

198195
_token0.transfer(eT0, currentContract, y) at init;
199196
uint256 amountOut2 = mint(eM,recipient);
200-
uint256 balanceAfter2 = balanceOf(recipient);
197+
uint256 balanceAfter2 = currentContract._balances[recipient];
201198
assert balanceAfter1 >= balanceAfter2;
202199
}
203200

@@ -270,7 +267,7 @@ rule zeroWithdrawNoEffect(address to) {
270267
env e;
271268
setup(e);
272269
// The assumption is no skimming
273-
require getReserve0() == _token0.balanceOf(currentContract) && getReserve1() == _token1.balanceOf(currentContract);
270+
require currentContract.reserve1 == _token0.balanceOf(currentContract) && currentContract.reserve1 == _token1.balanceOf(currentContract);
274271
storage before = lastStorage;
275272
burnSingle(e, _token0, 0, to);
276273
storage after = lastStorage;

DEFI/ConstantProductPool/contracts/correct/ConstantProductPoolFixed.sol

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,6 @@ contract ConstantProductPool is ERC20 {
173173
reserve1 = balance1;
174174
}
175175

176-
function getReserve0() public view returns (uint256) {
177-
return reserve0;
178-
}
179-
180-
function getReserve1() public view returns (uint256) {
181-
return reserve1;
182-
}
183-
184176
function _getAmountOut(
185177
uint256 amountIn,
186178
uint256 reserveAmountIn,

DEFI/Immutable/Immutable.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: MIT
2+
import {Owner} from './Owner.sol';
3+
pragma solidity >=0.8.0;
4+
contract Immutable {
5+
// coding convention to uppercase constant variables
6+
Owner public immutable OWNER;
7+
uint public immutable MY_UINT;
8+
9+
constructor() {
10+
OWNER = Owner(msg.sender);
11+
MY_UINT = 2;
12+
}
13+
14+
function getMyUint() public view returns (uint) {
15+
return MY_UINT + 1;
16+
}
17+
}

0 commit comments

Comments
 (0)