Skip to content

Commit 14248a2

Browse files
nd-certora0x-r4bbit
authored andcommitted
chore: certora setup for stakemanager and vault
1 parent 119b8de commit 14248a2

File tree

7 files changed

+121
-7
lines changed

7 files changed

+121
-7
lines changed

certora/certora.conf renamed to certora/confs/StakeManager.conf

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
{
2-
"files": ["contracts/StakeManager.sol"],
2+
"files":
3+
["contracts/StakeManager.sol",
4+
"certora/helpers/ERC20A.sol"
5+
],
6+
"link" : [
7+
"StakeManager:stakedToken=ERC20A"
8+
],
39
"msg": "Verifying StakeManager.sol",
410
"rule_sanity": "basic",
511
"verify": "StakeManager:certora/specs/StakeManager.spec",
6-
"wait_for_results": "all",
12+
"optimistic_loop": true,
13+
"loop_iter": "3",
714
"packages": [
815
"@openzeppelin=lib/openzeppelin-contracts"
916
]

certora/confs/StakeVault.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"files": [
3+
"contracts/StakeManager.sol",
4+
"contracts/StakeVault.sol",
5+
"certora/helpers/ERC20A.sol"
6+
],
7+
"link" : [
8+
"StakeVault:STAKED_TOKEN=ERC20A",
9+
"StakeManager:stakedToken=ERC20A",
10+
"StakeVault:stakeManager=StakeManager"
11+
],
12+
"msg": "Verifying StakeVault.sol",
13+
"rule_sanity": "basic",
14+
"verify": "StakeVault:certora/specs/StakeVault.spec",
15+
"optimistic_loop": true,
16+
"loop_iter": "3",
17+
"packages": [
18+
"@openzeppelin=lib/openzeppelin-contracts"
19+
]
20+
}
21+
22+

certora/helpers/ERC20A.sol

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.19;
4+
5+
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
6+
7+
contract ERC20A is ERC20 {
8+
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}
9+
}

certora/specs/StakeManager.spec

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,50 @@
1+
using ERC20A as staked;
2+
methods {
3+
function staked.balanceOf(address) external returns (uint256) envfree;
4+
}
5+
6+
function isMigrationfunction(method f) returns bool {
7+
return f.selector == sig:leave().selector ||
8+
f.selector == sig:migrate(address,StakeManager.Account).selector ||
9+
f.selector == sig:migrate().selector;
10+
}
11+
12+
/* assume that migration is zero, causing the verification to take into account only
13+
cases where it is zero. specifically no externall call to the migration contract */
14+
function simplification() {
15+
require currentContract.migration == 0;
16+
}
17+
18+
19+
rule reachability(method f)
20+
{
21+
calldataarg args;
22+
env e;
23+
f(e,args);
24+
satisfy true;
25+
}
26+
27+
/**
28+
@title when there is no migration - some functions must revert.
29+
Other function should have non reverting cases
30+
**/
31+
rule revertsWhenNoMigration(method f) {
32+
calldataarg args;
33+
env e;
34+
require currentContract.migration == 0;
35+
f@withrevert(e,args);
36+
bool reverted = lastReverted;
37+
if (!isMigrationfunction(f))
38+
satisfy !reverted;
39+
assert isMigrationfunction(f) => reverted;
40+
}
141

2-
rule shouldPass {
3-
assert true;
42+
rule whoChangeERC20Balance( method f ) filtered { f -> f.contract != staked }
43+
{
44+
address user;
45+
uint256 before = staked.balanceOf(user);
46+
calldataarg args;
47+
env e;
48+
f(e,args);
49+
assert before == staked.balanceOf(user);
450
}

certora/specs/StakeVault.spec

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using ERC20A as staked;
2+
using StakeManager as stakeManager;
3+
methods {
4+
function ERC20A.balanceOf(address) external returns (uint256) envfree;
5+
}
6+
7+
/* assume that migration is zero, causing to ignore cases where it is not zero */
8+
function simplification() {
9+
require stakeManager.migration == 0;
10+
}
11+
12+
rule reachability(method f){
13+
calldataarg args;
14+
env e;
15+
f(e,args);
16+
satisfy true;
17+
}
18+
19+
rule whoChangeERC20Balance(method f)
20+
{
21+
simplification();
22+
address user;
23+
uint256 before = staked.balanceOf(user);
24+
calldataarg args;
25+
env e;
26+
f(e,args);
27+
assert before == staked.balanceOf(user);
28+
}

contracts/StakeVault.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ contract StakeVault is Ownable {
2020

2121
StakeManager private stakeManager;
2222

23-
ERC20 private immutable STAKED_TOKEN;
23+
ERC20 public immutable STAKED_TOKEN;
2424

2525
event Staked(address from, address to, uint256 _amount, uint256 time);
2626

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
"scripts": {
2121
"clean": "rm -rf cache out",
2222
"lint": "pnpm lint:sol && pnpm prettier:check",
23-
"verify": "certoraRun certora/certora.conf",
23+
"verify": "pnpm verify:stake_vault && pnpm verify:stake_manager",
2424
"lint:sol": "forge fmt --check && pnpm solhint {script,src,test,certora}/**/*.sol",
2525
"prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore",
26-
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore"
26+
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore",
27+
"verify:stake_vault": "certoraRun certora/confs/StakeVault.conf",
28+
"verify:stake_manager": "certoraRun certora/confs/StakeManager.conf"
2729
}
2830
}

0 commit comments

Comments
 (0)