|
|
|
@ -3,7 +3,7 @@ import "Governor.helpers.spec" |
|
|
|
|
import "GovernorInvariants.spec" |
|
|
|
|
|
|
|
|
|
use invariant proposalStateConsistency |
|
|
|
|
use invariant votesImplySnapshotPassed |
|
|
|
|
// use invariant votesImplySnapshotPassed |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ |
|
|
|
@ -131,27 +131,46 @@ rule stateIsConsistentWithVotes(uint256 pId, env e) { |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ |
|
|
|
|
│ Rule: `updateQuorumNumerator` cannot cause quorumReached to change. │ |
|
|
|
|
│ [NEED WORK] Rule: `updateQuorumNumerator` cannot cause quorumReached to change. │ |
|
|
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ |
|
|
|
|
*/ |
|
|
|
|
rule onlyVoteCanChangeQuorumReached(uint256 pId, env e, method f, calldataarg args) |
|
|
|
|
filtered { f -> !skip(f) } |
|
|
|
|
{ |
|
|
|
|
require clockSanity(e); |
|
|
|
|
requireInvariant votesImplySnapshotPassed(e, pId); |
|
|
|
|
|
|
|
|
|
bool quorumReachedBefore = quorumReached(pId); |
|
|
|
|
|
|
|
|
|
uint256 snapshot = proposalSnapshot(pId); |
|
|
|
|
uint256 totalSupply = token_getPastTotalSupply(snapshot); |
|
|
|
|
|
|
|
|
|
f(e, args); |
|
|
|
|
|
|
|
|
|
// Needed because the prover doesn't understand the checkpoint properties of the voting token. |
|
|
|
|
require clock(e) > snapshot => token_getPastTotalSupply(snapshot) == totalSupply; |
|
|
|
|
|
|
|
|
|
assert quorumReached(pId) != quorumReachedBefore => ( |
|
|
|
|
!quorumReachedBefore && |
|
|
|
|
votingAll(f) |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
//// This would be nice, but its way to slow to run because "quorumReached" is a FV nightmare |
|
|
|
|
//// Also, for it to work we need to prove that the checkpoints have (strictly) increase values ... what a nightmare |
|
|
|
|
// rule onlyVoteCanChangeQuorumReached(uint256 pId, env e, method f, calldataarg args) |
|
|
|
|
// filtered { f -> !skip(f) } |
|
|
|
|
// { |
|
|
|
|
// require clockSanity(e); |
|
|
|
|
// require clock(e) > proposalSnapshot(pId); // vote has started |
|
|
|
|
// require quorumNumeratorLength() < max_uint256; // sanity |
|
|
|
|
// |
|
|
|
|
// bool quorumReachedBefore = quorumReached(pId); |
|
|
|
|
// |
|
|
|
|
// uint256 snapshot = proposalSnapshot(pId); |
|
|
|
|
// uint256 totalSupply = token_getPastTotalSupply(snapshot); |
|
|
|
|
// |
|
|
|
|
// f(e, args); |
|
|
|
|
// |
|
|
|
|
// // Needed because the prover doesn't understand the checkpoint properties of the voting token. |
|
|
|
|
// require clock(e) > snapshot => token_getPastTotalSupply(snapshot) == totalSupply; |
|
|
|
|
// |
|
|
|
|
// assert quorumReached(pId) != quorumReachedBefore => ( |
|
|
|
|
// !quorumReachedBefore && |
|
|
|
|
// votingAll(f) |
|
|
|
|
// ); |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
//// To prove that, we need to prove that the checkpoints have (strictly) increase values ... what a nightmare |
|
|
|
|
//// otherwise it gives us counter example where the checkpoint history has keys: |
|
|
|
|
//// [ 12,12,13,13,12] and the lookup obviously fail to get the correct value |
|
|
|
|
// rule quorumUpdateDoesntAffectPastProposals(uint256 pId, env e) { |
|
|
|
|
// require clockSanity(e); |
|
|
|
|
// require clock(e) > proposalSnapshot(pId); // vote has started |
|
|
|
|
// require quorumNumeratorLength() < max_uint256; // sanity |
|
|
|
|
// |
|
|
|
|
// bool quorumReachedBefore = quorumReached(pId); |
|
|
|
|
// |
|
|
|
|
// uint256 newQuorumNumerator; |
|
|
|
|
// updateQuorumNumerator(e, newQuorumNumerator); |
|
|
|
|
// |
|
|
|
|
// assert quorumReached(pId) == quorumReachedBefore; |
|
|
|
|
// } |
|
|
|
|