Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream Certora Specifications #130

Open
wants to merge 76 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
b8b4e4a
initial setup
dominik-velan Aug 6, 2024
297f80d
update linking
dominik-velan Aug 7, 2024
0a19b58
fix path in configs, set higher timeout for big contracts
dominik-velan Aug 7, 2024
d1ee6c4
Delete a few empty unused spec files
andrew-certora Aug 19, 2024
9946904
run script. adding back generic spec, delete unused imports
andrew-certora Aug 19, 2024
a180ae0
initial setup
dominik-velan Aug 6, 2024
55da68d
update linking
dominik-velan Aug 7, 2024
33786fe
fix path in configs, set higher timeout for big contracts
dominik-velan Aug 7, 2024
2760d8a
Delete a few empty unused spec files
andrew-certora Aug 19, 2024
6d062ee
run script. adding back generic spec, delete unused imports
andrew-certora Aug 19, 2024
61c70e9
Fix run all script
andrew-certora Aug 21, 2024
04dabc1
a little start, trying to figure out how to interact with _proposals
christiane-certora Aug 21, 2024
3af2f71
EPT_KP_1 verifies using the accessor from EPT
christiane-certora Aug 21, 2024
b765d9b
Added W1_4 and EPT_10, plus comments and better rule names
christiane-certora Aug 22, 2024
720c7d3
EPT_3
christiane-certora Aug 23, 2024
4a1ef3f
adjustments after rebase
christiane-certora Aug 23, 2024
2e76f3a
EPT_1 and EPT_5
christiane-certora Aug 23, 2024
79d40e8
setup for escrow
nd-certora Aug 26, 2024
c2453d2
EPT_9 and improvement to EPT_10
christiane-certora Aug 26, 2024
52dff79
fix steth and withdrawlqueue mocks
nd-certora Aug 26, 2024
44e7ba5
Merge remote-tracking branch 'origin/certora' into nurit/escrow
nd-certora Aug 26, 2024
d0d9e79
EPT_11
christiane-certora Aug 28, 2024
67c7789
mutants for EPT
christiane-certora Aug 28, 2024
8b7dc65
one more mutant
christiane-certora Aug 29, 2024
1ca74ae
all rules but solvency
nd-certora Aug 29, 2024
3851081
Delete extra stuff
andrew-certora Aug 29, 2024
ebce035
Initial draft of w2_1a_indexes_match
andrew-certora Aug 22, 2024
8556e1d
Fix some havocs in DG spec
andrew-certora Aug 22, 2024
283645d
WIP, can't declare DualGovernanceStateMachine.State
andrew-certora Aug 23, 2024
bfd8850
Workaround for type name issue. kp 1, 2
andrew-certora Aug 23, 2024
3c7104c
dg_kp_3
andrew-certora Aug 23, 2024
e6f1b31
Working on kp3 kp4
andrew-certora Aug 23, 2024
609576b
kp 3,4 done. better escrow setup
andrew-certora Aug 26, 2024
397272d
Check in WIP on PP_KP_1
andrew-certora Aug 26, 2024
72e5a93
Mainly add escrows linked spec and conf for pp1_v2
andrew-certora Aug 27, 2024
4af0731
WIP on pp2, pp1
andrew-certora Aug 27, 2024
9b53ac3
PP_4
christiane-certora Aug 27, 2024
52ef497
pp_kp_2 passing
andrew-certora Aug 27, 2024
12897ef
PP-3
christiane-certora Aug 27, 2024
28f4d5e
dg_states_1 and dg_states_2
christiane-certora Aug 27, 2024
a2108fe
dg_transitions_1
christiane-certora Aug 28, 2024
6a2127a
Update ERC20 dummys
andrew-certora Aug 28, 2024
3b2e72d
improve pp_kp_2
andrew-certora Aug 28, 2024
2536050
Initial mutation testing commit
andrew-certora Aug 29, 2024
b48bad6
remove todo comments
christiane-certora Aug 29, 2024
ff00321
Mainly save NONDET that fixes timeout
andrew-certora Aug 30, 2024
e33314e
Fixes for mutation testing
andrew-certora Aug 30, 2024
8fcf5b7
Merge pull request #2 from Certora/andrew@cleanup
andrew-certora Aug 30, 2024
a0ecdba
uncomment finding rule
andrew-certora Aug 30, 2024
d3db6b4
some first mutants for escrow
christiane-certora Aug 30, 2024
de64e5b
Cleanup before PR
andrew-certora Sep 2, 2024
69df5ad
Delete monday update script
andrew-certora Sep 2, 2024
076cc61
mutant for E_KP_1
christiane-certora Sep 2, 2024
d5d33a2
address simple review comments
christiane-certora Sep 2, 2024
17a13e6
add comment for EPT_10
christiane-certora Sep 2, 2024
95b540b
add an unchanged copy of ExecutableProposals to mutants to preserve t…
christiane-certora Sep 2, 2024
d8b5222
PR fixups
andrew-certora Sep 3, 2024
60135c9
try putting space instead of tabs
andrew-certora Sep 3, 2024
edc8239
methods block whitespace
andrew-certora Sep 3, 2024
1a7f141
delete extraneous comment
andrew-certora Sep 3, 2024
0fdb20d
comments on EPT_5 and helper functions
christiane-certora Sep 3, 2024
f16df84
Merge pull request #4 from Certora/andrew@dual-governance
andrew-certora Sep 4, 2024
793f451
Merge pull request #3 from Certora/christiane/emergency-protected-tim…
andrew-certora Sep 4, 2024
182d0d0
Merge branch 'main' into andrew@merge-contract-updates
andrew-certora Sep 4, 2024
856442e
AssetsAccounting mutants
christiane-certora Sep 5, 2024
56c5c86
new version of w2_1
christiane-certora Sep 6, 2024
077e469
Merge pull request #8 from Certora/christiane/w2_1
andrew-certora Sep 6, 2024
df8f29f
W2_2 with frontrunning formulation plus mutant preserving the buggy s…
christiane-certora Sep 9, 2024
e282bc9
escrow valid state and solvency rules
nd-certora Sep 9, 2024
7e34bb2
Merge branch 'certora' into nurit/escrow
andrew-certora Sep 9, 2024
6e2e658
revert check instead of filter
christiane-certora Sep 10, 2024
6a7f4c7
review fixes and 2 more solvency rules
nd-certora Sep 10, 2024
47f1b25
Merge pull request #10 from Certora/nurit/escrow
nd-certora Sep 10, 2024
f7e5f0f
Merge branch 'certora' into christiane/escrow-mutations
nd-certora Sep 11, 2024
5776db0
Merge pull request #9 from Certora/christiane/escrow-mutations
nd-certora Sep 11, 2024
5b88def
Merge pull request #7 from Certora/andrew@merge-contract-updates
nd-certora Sep 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ out/
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

#Certora
.certora_internal/
.vscode/
50 changes: 50 additions & 0 deletions certora/confs/DualGovernance.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"files": [
"contracts/libraries/DualGovernanceStateMachine.sol",
"contracts/Executor.sol",
"contracts/EmergencyProtectedTimelock.sol",
"contracts/ResealManager.sol",
"certora/helpers/EscrowA.sol",
"certora/helpers/EscrowB.sol",
"contracts/DualGovernanceConfigProvider.sol:ImmutableDualGovernanceConfigProvider",
"certora/harnesses/ERC20Like/DummyStETH.sol",
"certora/harnesses/ERC20Like/DummyWstETH.sol",
"certora/harnesses/DualGovernanceHarness.sol",
],
"link": [
"DualGovernanceHarness:TIMELOCK=EmergencyProtectedTimelock",
"DualGovernanceHarness:_configProvider=ImmutableDualGovernanceConfigProvider",
"ResealManager:EMERGENCY_PROTECTED_TIMELOCK=EmergencyProtectedTimelock",
"DualGovernanceHarness:RESEAL_MANAGER=ResealManager",
"EscrowA:ST_ETH=DummyStETH",
"EscrowA:WST_ETH=DummyWstETH",
"EscrowA:DUAL_GOVERNANCE=DualGovernanceHarness",
"EscrowB:ST_ETH=DummyStETH",
"EscrowB:WST_ETH=DummyWstETH",
"EscrowB:DUAL_GOVERNANCE=DualGovernanceHarness"
],
"struct_link": [
"DualGovernanceHarness:resealManager=ResealManager",
"EmergencyProtectedTimelock:executor=Executor",
],
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
],
"parametric_contracts": [
"DualGovernanceHarness",
// "EmergencyProtectedTimelock",
// "ResealManager",
// "Escrow",
// // Not sure these are needed
// "DummyStETH",
// "DummyWstETH",
],
"rule_sanity": "basic",
"process": "emv",
"solc": "solc8.26",
"optimistic_loop": true,
"loop_iter": "5",
"smt_timeout": "3600",
"build_cache": true,
"verify": "DualGovernanceHarness:certora/specs/DualGovernance.spec"
}
24 changes: 24 additions & 0 deletions certora/confs/EmergencyProtectedTimelock.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"files": [
"contracts/EmergencyProtectedTimelock.sol",
"contracts/Executor.sol",
"contracts/libraries/ExecutableProposals.sol",
"contracts/libraries/EmergencyProtection.sol",
"contracts/types/Timestamp.sol:Timestamps",
"contracts/types/Duration.sol:Durations"
],
"struct_link": [
"EmergencyProtectedTimelock:executor=Executor",
],
"msg": "Emergency Protected Timelock",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
],
"process": "emv",
"solc": "solc8.26",
"optimistic_loop": true,
"solc_via_ir": false,
"verify": "EmergencyProtectedTimelock:certora/specs/Timelock.spec",
"rule_sanity": "basic",
"server": "production"
}
32 changes: 32 additions & 0 deletions certora/confs/Escrow.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"files": [
"contracts/Escrow.sol",
"contracts/DualGovernance.sol",
"contracts/DualGovernanceConfigProvider.sol:ImmutableDualGovernanceConfigProvider",
"certora/helpers/DummyWithdrawalQueue.sol",
"certora/harnesses/ERC20Like/DummyStETH.sol",
"certora/harnesses/ERC20Like/DummyWstETH.sol",
],
"link": [
"Escrow:DUAL_GOVERNANCE=DualGovernance",
"Escrow:WITHDRAWAL_QUEUE=DummyWithdrawalQueue",
"Escrow:ST_ETH=DummyStETH",
"Escrow:WST_ETH=DummyWstETH",
"DummyWstETH:stETH=DummyStETH",
"DummyWithdrawalQueue:stETH=DummyStETH",
"DualGovernance:_configProvider=ImmutableDualGovernanceConfigProvider",
],

"msg": "sanity",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
],

"solc": "solc8.26",
"optimistic_loop": true,
"optimistic_fallback": true,
"loop_iter": "3",
"build_cache" : true,
"rule_sanity" : "basic",
"verify": "Escrow:certora/specs/Escrow.spec"
}
32 changes: 32 additions & 0 deletions certora/confs/Escrow_solvency.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"files": [
"contracts/Escrow.sol",
"contracts/DualGovernance.sol",
"contracts/DualGovernanceConfigProvider.sol:ImmutableDualGovernanceConfigProvider",
"certora/helpers/DummyWithdrawalQueue.sol",
"certora/harnesses/ERC20Like/DummyStETH.sol",
"certora/harnesses/ERC20Like/DummyWstETH.sol",
],
"link": [
"Escrow:DUAL_GOVERNANCE=DualGovernance",
"Escrow:WITHDRAWAL_QUEUE=DummyWithdrawalQueue",
"Escrow:ST_ETH=DummyStETH",
"Escrow:WST_ETH=DummyWstETH",
"DummyWstETH:stETH=DummyStETH",
"DummyWithdrawalQueue:stETH=DummyStETH",
"DualGovernance:_configProvider=ImmutableDualGovernanceConfigProvider",
],

"msg": "sanity",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
],

"solc": "solc8.26",
"optimistic_loop": true,
"optimistic_fallback": true,
"loop_iter": "3",
"build_cache" : true,
"rule_sanity" : "basic",
"verify": "Escrow:certora/specs/Escrow_solvency.spec"
}
32 changes: 32 additions & 0 deletions certora/confs/Escrow_validState.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"files": [
"contracts/Escrow.sol",
"contracts/DualGovernance.sol",
"contracts/DualGovernanceConfigProvider.sol:ImmutableDualGovernanceConfigProvider",
"certora/helpers/DummyWithdrawalQueue.sol",
"certora/harnesses/ERC20Like/DummyStETH.sol",
"certora/harnesses/ERC20Like/DummyWstETH.sol",
],
"link": [
"Escrow:DUAL_GOVERNANCE=DualGovernance",
"Escrow:WITHDRAWAL_QUEUE=DummyWithdrawalQueue",
"Escrow:ST_ETH=DummyStETH",
"Escrow:WST_ETH=DummyWstETH",
"DummyWstETH:stETH=DummyStETH",
"DummyWithdrawalQueue:stETH=DummyStETH",
"DualGovernance:_configProvider=ImmutableDualGovernanceConfigProvider",
],

"msg": "Escrow_validState",
"packages": [
"@openzeppelin=lib/openzeppelin-contracts"
],

"solc": "solc8.26",
"optimistic_loop": true,
"optimistic_fallback": true,
"loop_iter": "3",
"build_cache" : true,
"rule_sanity" : "basic",
"verify": "Escrow:certora/specs/Escrow_validState.spec"
}
145 changes: 145 additions & 0 deletions certora/harnesses/DualGovernanceHarness.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import "../../contracts/libraries/Proposers.sol";
import "../../contracts/DualGovernance.sol";
import {Status as ProposalStatus} from "../../contracts/libraries/ExecutableProposals.sol";
import {Proposal} from "../../contracts/libraries/EnumerableProposals.sol";
// This is to make a type available for a NONDET summary
import {IExternalExecutor} from "../../contracts/interfaces/IExternalExecutor.sol";
import {State, DualGovernanceStateMachine} from "../../contracts/libraries/DualGovernanceStateMachine.sol";

// The following are for methods about checking if max durations have passed
import {DualGovernanceConfig} from "../../contracts/libraries/DualGovernanceConfig.sol";
import {PercentD16} from "../../contracts/types/PercentD16.sol";
import {Timestamp, Timestamps} from "../../contracts/types/Timestamp.sol";

contract DualGovernanceHarness is DualGovernance {
using Proposers for Proposers.Context;
using Proposers for Proposers.Proposer;
using Tiebreaker for Tiebreaker.Context;
using DualGovernanceStateMachine for DualGovernanceStateMachine.Context;
using DualGovernanceConfig for DualGovernanceConfig.Context;

// Needed because DualGovernanceStateMachine.State is not
// referrable without redeclaring this here.
enum DGHarnessState {
Unset,
Normal,
VetoSignalling,
VetoSignallingDeactivation,
VetoCooldown,
RageQuit
}

constructor(
ExternalDependencies memory dependencies,
SanityCheckParams memory sanityCheckParams
) DualGovernance(dependencies, sanityCheckParams) {}

// Return is uint32 which is the same as IndexOneBased
function getProposerIndexFromExecutor(address proposer) external view returns (uint32) {
return IndexOneBased.unwrap(_proposers.executors[proposer].proposerIndex);
}

function getProposalInfoHarnessed(uint256 proposalId)
external
view
returns (uint256 id, ProposalStatus status, address executor, Timestamp submittedAt, Timestamp scheduledAt)
{
return TIMELOCK.getProposalInfo(proposalId);
}

function getProposalHarnessed(uint256 proposalId) external view returns (ITimelock.Proposal memory proposal) {
return TIMELOCK.getProposal(proposalId);
}

function getVetoSignallingActivatedAt() external view returns (Timestamp) {
return _stateMachine.vetoSignallingActivatedAt;
}

function asDGHarnessState(State state) public returns (DGHarnessState) {
uint256 state_underlying = uint256(state);
return DGHarnessState(state_underlying);
}

function getState() external returns (DGHarnessState) {
return asDGHarnessState(_stateMachine.state);
}

function getFirstSeal() external view returns (uint256) {
return PercentD16.unwrap(_configProvider.getDualGovernanceConfig().firstSealRageQuitSupport);
}

function getSecondSeal() external view returns (uint256) {
return PercentD16.unwrap(_configProvider.getDualGovernanceConfig().secondSealRageQuitSupport);
}

function getFirstSealRageQuitSupportCrossed() external view returns (bool) {
return _configProvider.getDualGovernanceConfig().isFirstSealRageQuitSupportCrossed(
_stateMachine.signallingEscrow.getRageQuitSupport()
);
}

function getSecondSealRageQuitSupportCrossed() external view returns (bool) {
return _configProvider.getDualGovernanceConfig().isSecondSealRageQuitSupportCrossed(
_stateMachine.signallingEscrow.getRageQuitSupport()
);
}

function getRageQuitSupportHarnessed() external view returns (PercentD16) {
return _stateMachine.signallingEscrow.getRageQuitSupport();
}

function isDynamicTimelockPassed(uint256 rageQuitSupport) public returns (bool) {
return _configProvider.getDualGovernanceConfig().isDynamicTimelockDurationPassed(
_stateMachine.vetoSignallingActivatedAt, PercentD16.wrap(rageQuitSupport)
);
}

function isVetoSignallingReactivationPassed() public returns (bool) {
return _configProvider.getDualGovernanceConfig().isVetoSignallingReactivationDurationPassed(
Timestamps.max(_stateMachine.vetoSignallingReactivationTime, _stateMachine.vetoSignallingActivatedAt)
);
}

function isVetoSignallingDeactivationPassed() public returns (bool) {
return _configProvider.getDualGovernanceConfig().isVetoSignallingDeactivationMaxDurationPassed(
_stateMachine.enteredAt
);
}

function isVetoSignallingDeactivationMaxDurationPassed() public returns (bool) {
return _configProvider.getDualGovernanceConfig().isVetoSignallingDeactivationMaxDurationPassed(
_stateMachine.enteredAt
);
}

function isVetoCooldownDurationPassed() public returns (bool) {
return _configProvider.getDualGovernanceConfig().isVetoCooldownDurationPassed(_stateMachine.enteredAt);
}

function isUnset(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.Unset;
}

function isNormal(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.Normal;
}

function isVetoSignalling(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.VetoSignalling;
}

function isVetoSignallingDeactivation(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.VetoSignallingDeactivation;
}

function isVetoCooldown(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.VetoCooldown;
}

function isRageQuit(DGHarnessState state) public returns (bool) {
return state == DGHarnessState.RageQuit;
}
}
51 changes: 51 additions & 0 deletions certora/harnesses/ERC20Like/DummyERC20A.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Represents a symbolic/dummy ERC20 token

// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.0;

contract DummyERC20A {
uint256 t;
mapping(address => uint256) b;
mapping(address => mapping(address => uint256)) a;

string public name;
string public symbol;
uint256 public decimals;

function myAddress() external view returns (address) {
return address(this);
}

function totalSupply() external view returns (uint256) {
return t;
}

function balanceOf(address account) external view returns (uint256) {
return b[account];
}

function transfer(address recipient, uint256 amount) external returns (bool) {
b[msg.sender] -= amount;
b[recipient] += amount;

return true;
}

function allowance(address owner, address spender) external view returns (uint256) {
return a[owner][spender];
}

function approve(address spender, uint256 amount) external returns (bool) {
a[msg.sender][spender] = amount;

return true;
}

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
b[sender] -= amount;
b[recipient] += amount;
a[sender][msg.sender] -= amount;

return true;
}
}
Loading