parent
07d637980c
commit
96df9799c3
@ -0,0 +1,8 @@ |
||||
certoraRun certora/harnesses/GovernorBasicHarness.sol \ |
||||
--verify GovernorBasicHarness:certora/specs/GovernorCountingSimple.spec \ |
||||
--solc solc8.2 \ |
||||
--staging \ |
||||
--optimistic_loop \ |
||||
--settings -copyLoopUnroll=4 \ |
||||
--rule SumOfVotesCastEqualSumOfPowerOfVoted \ |
||||
--msg "$1" |
@ -0,0 +1,87 @@ |
||||
////////////////////////////////////////////////////////////////////////////// |
||||
///////////////////// Governor.sol base definitions ////////////////////////// |
||||
////////////////////////////////////////////////////////////////////////////// |
||||
methods { |
||||
proposalSnapshot(uint256) returns uint256 envfree // matches proposalVoteStart |
||||
proposalDeadline(uint256) returns uint256 envfree |
||||
hashProposal(address[],uint256[],bytes[],bytes32) returns uint256 envfree |
||||
isExecuted(uint256) returns bool envfree |
||||
isCanceled(uint256) returns bool envfree |
||||
// initialized(uint256) returns bool envfree |
||||
|
||||
hasVoted(uint256, address) returns bool |
||||
|
||||
castVote(uint256, uint8) returns uint256 |
||||
|
||||
// internal functions made public in harness: |
||||
_quorumReached(uint256) returns bool envfre |
||||
_voteSucceeded(uint256) returns bool envfree |
||||
|
||||
// getter for checking the sums |
||||
ghost_sum_vote_power_by_id(uint256) returns uint256 envfree |
||||
} |
||||
|
||||
////////////////////////////////////////////////////////////////////////////// |
||||
///////////////////////////////// GHOSTS ///////////////////////////////////// |
||||
////////////////////////////////////////////////////////////////////////////// |
||||
|
||||
ghost sum_all_votes_power() returns uint256 { |
||||
init_state axiom sum_all_votes_power() == 0; |
||||
} |
||||
|
||||
hook Sstore ghost_sum_vote_power_by_id[KEY uint256 pId] uint256 current_power (uint256 old_power) STORAGE{ |
||||
havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power; |
||||
} |
||||
|
||||
ghost tracked_weight(uint256) returns uint256 { |
||||
init_state axiom forall uint256 p. tracked_weight(p) == 0; |
||||
} |
||||
ghost sum_tracked_weight() returns uint256 { |
||||
init_state axiom sum_tracked_weight() == 0; |
||||
} |
||||
|
||||
/* |
||||
function update_tracked_weights(uint256 pId, uint256 votes, uint256 old_votes) { |
||||
havoc tracked_weight assuming forall uint256 p. (p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && |
||||
(p != pId => tracked_weight@new(p) == tracked_weight@old(p)); |
||||
havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; |
||||
}*/ |
||||
|
||||
hook Sstore _proposalVotes[KEY uint256 pId].againstVotes uint256 votes (uint256 old_votes) STORAGE { |
||||
//update_tracked_weights(pId, votes, old_votes); |
||||
havoc tracked_weight assuming forall uint256 p. (p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && |
||||
(p != pId => tracked_weight@new(p) == tracked_weight@old(p)); |
||||
havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; |
||||
} |
||||
|
||||
hook Sstore _proposalVotes[KEY uint256 pId].forVotes uint256 votes (uint256 old_votes) STORAGE { |
||||
//update_tracked_weights(pId, votes, old_votes); |
||||
havoc tracked_weight assuming forall uint256 p. (p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && |
||||
(p != pId => tracked_weight@new(p) == tracked_weight@old(p)); |
||||
havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; |
||||
} |
||||
|
||||
hook Sstore _proposalVotes[KEY uint256 pId].abstainVotes uint256 votes (uint256 old_votes) STORAGE { |
||||
//update_tracked_weights(pId, votes, old_votes); |
||||
havoc tracked_weight assuming forall uint256 p. (p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && |
||||
(p != pId => tracked_weight@new(p) == tracked_weight@old(p)); |
||||
havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; |
||||
} |
||||
|
||||
////////////////////////////////////////////////////////////////////////////// |
||||
////////////////////////////// INVARIANTS //////////////////////////////////// |
||||
////////////////////////////////////////////////////////////////////////////// |
||||
|
||||
|
||||
/* |
||||
* sum of all votes casted is equal to the sum of voting power of those who voted, per each proposal |
||||
*/ |
||||
invariant SumOfVotesCastEqualSumOfPowerOfVotedPerProposal(uint256 pId) |
||||
tracked_weight(pId) == ghost_sum_vote_power_by_id(pId) |
||||
|
||||
/* |
||||
* sum of all votes casted is equal to the sum of voting power of those who voted |
||||
*/ |
||||
invariant SumOfVotesCastEqualSumOfPowerOfVoted() |
||||
sum_tracked_weight() == sum_all_votes_power() |
||||
|
Loading…
Reference in new issue