Skip to content

Commit

Permalink
certora setup for stakemanager and vault
Browse files Browse the repository at this point in the history
  • Loading branch information
nd-certora committed Jan 24, 2024
1 parent cf7a8b6 commit 766e412
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 5 deletions.
11 changes: 9 additions & 2 deletions certora/certora.conf → certora/confs/StakeManager.conf
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
{
"files": ["contracts/StakeManager.sol"],
"files":
["contracts/StakeManager.sol",
"certora/helpers/ERC20A.sol"
],
"link" : [
"StakeManager:stakedToken=ERC20A"
],
"msg": "Verifying StakeManager.sol",
"rule_sanity": "basic",
"verify": "StakeManager:certora/specs/StakeManager.spec",
"wait_for_results": "all",
"optimistic_loop": true,
"loop_iter": "3",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
]
Expand Down
22 changes: 22 additions & 0 deletions certora/confs/StakeVault.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"files": [
"contracts/StakeManager.sol",
"contracts/StakeVault.sol",
"certora/helpers/ERC20A.sol"
],
"link" : [
"StakeVault:STAKED_TOKEN=ERC20A",
"StakeManager:stakedToken=ERC20A",
"StakeVault:stakeManager=StakeManager"
],
"msg": "Verifying StakeVault.sol",
"rule_sanity": "basic",
"verify": "StakeVault:certora/specs/StakeVault.spec",
"optimistic_loop": true,
"loop_iter": "3",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
]
}


9 changes: 9 additions & 0 deletions certora/helpers/ERC20A.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.18;

Check failure on line 3 in certora/helpers/ERC20A.sol

View workflow job for this annotation

GitHub Actions / lint

Compiler version ^0.8.18 does not satisfy the >=0.8.19 semver requirement

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract ERC20A is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}
}
50 changes: 48 additions & 2 deletions certora/specs/StakeManager.spec
Original file line number Diff line number Diff line change
@@ -1,4 +1,50 @@
using ERC20A as staked;
methods {
function staked.balanceOf(address) external returns (uint256) envfree;
}

function isMigrationfunction(method f) returns bool {
return f.selector == sig:leave().selector ||
f.selector == sig:migrate(address,StakeManager.Account).selector ||
f.selector == sig:migrate().selector;
}

rule shouldPass {
assert true;
/* assume that migration is zero, causing the verification to take into account only
cases where it is zero. specifically no externall call to the migration contract */
function simplification() {
require currentContract.migration == 0;
}


rule reachability(method f)
{
calldataarg args;
env e;
f(e,args);
satisfy true;
}

/**
@title when there is no migration - some functions must revert.
Other function should have non reverting cases
**/
rule revertsWhenNoMigration(method f) {
calldataarg args;
env e;
require currentContract.migration == 0;
f@withrevert(e,args);
bool reverted = lastReverted;
if (!isMigrationfunction(f))
satisfy !reverted;
assert isMigrationfunction(f) => reverted;
}

rule whoChangeERC20Balance( method f ) filtered { f -> f.contract != staked }
{
address user;
uint256 before = staked.balanceOf(user);
calldataarg args;
env e;
f(e,args);
assert before == staked.balanceOf(user);
}
31 changes: 31 additions & 0 deletions certora/specs/StakeVault.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using ERC20A as staked;
using StakeManager as stakeManger;
methods {
function ERC20A.balanceOf(address) external returns (uint256) envfree;
}

/* assume that migration is zero, causing to ignore cases where it is not zero */
function simplification() {
require stakeManger.migration == 0;
}

rule reachability(method f){
calldataarg args;
env e;
simplification();
f(e,args);
satisfy true;
}



rule whoChangeERC20Balance( method f )
{
simplification();
address user;
uint256 before = staked.balanceOf(user);
calldataarg args;
env e;
f(e,args);
assert before == staked.balanceOf(user);
}
2 changes: 1 addition & 1 deletion contracts/StakeVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract StakeVault is Ownable {

StakeManager private stakeManager;

ERC20 private immutable STAKED_TOKEN;
ERC20 public immutable STAKED_TOKEN;

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

Expand Down

0 comments on commit 766e412

Please sign in to comment.