123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- //////////////////////////////////////////////////////////////////////////////
- ///////////////////// Governor.sol base definitions //////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- using ERC721VotesHarness as erc721votes
- using ERC20VotesHarness as erc20votes
- methods {
- proposalSnapshot(uint256) returns uint256 envfree // matches proposalVoteStart
- proposalDeadline(uint256) returns uint256 envfree // matches proposalVoteEnd
- hashProposal(address[],uint256[],bytes[],bytes32) returns uint256 envfree
- isExecuted(uint256) returns bool envfree
- isCanceled(uint256) returns bool envfree
- execute(address[], uint256[], bytes[], bytes32) returns uint256
- hasVoted(uint256, address) returns bool
- castVote(uint256, uint8) returns uint256
- updateQuorumNumerator(uint256)
- queue(address[], uint256[], bytes[], bytes32) returns uint256
- quorumNumerator() returns uint256 envfree
- quorumDenominator() returns uint256 envfree
- votingPeriod() returns uint256 envfree
- lateQuorumVoteExtension() returns uint64 envfree
- propose(address[], uint256[], bytes[], string)
- // harness
- getExtendedDeadlineIsUnset(uint256) returns bool envfree
- getExtendedDeadline(uint256) returns uint64 envfree
- quorumReached(uint256) returns bool envfree
- voteSucceeded(uint256) returns bool envfree
- quorum(uint256) returns uint256
- latestCastVoteCall() returns uint256 envfree // more robust check than f.selector == _castVote(...).selector
- // function summarization
- proposalThreshold() returns uint256 envfree
- // erc20votes dispatch
- getVotes(address, uint256) returns uint256 => DISPATCHER(true)
- // erc721votes/Votes dispatch
- getPastTotalSupply(uint256) returns uint256 => DISPATCHER(true)
- getPastVotes(address, uint256) returns uint256 => DISPATCHER(true)
- // timelock dispatch
- getMinDelay() returns uint256 => DISPATCHER(true)
-
- hashOperationBatch(address[], uint256[], bytes[], bytes32, bytes32) => DISPATCHER(true)
- executeBatch(address[], uint256[], bytes[], bytes32, bytes32) => CONSTANT
- scheduleBatch(address[], uint256[], bytes[], bytes32, bytes32, uint256) => CONSTANT
- }
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////// Definitions /////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // where can invariants help?
- // can I replace definitions with invariants?
- // create definition for extended
- definition deadlineCanBeExtended(uint256 pId) returns bool =
- getExtendedDeadlineIsUnset(pId) &&
- !quorumReached(pId);
- definition deadlineHasBeenExtended(uint256 pId) returns bool =
- !getExtendedDeadlineIsUnset(pId) &&
- quorumReached(pId);
- definition proposalCreated(uint256 pId) returns bool = proposalSnapshot(pId) > 0;
- //////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////// Rules /////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // RULE deadline can only be extended only once PASSING but vacuous
- // 1. if deadline changes then we have state transition to deadlineHasBeenExtended RULE PASSING; ADV SANITY PASSING
- rule deadlineChangeEffects(method f)
- filtered {
- f -> !f.isView
- } {
- env e; calldataarg args; uint256 pId;
- require (proposalCreated(pId));
-
- uint256 deadlineBefore = proposalDeadline(pId);
- f(e, args);
- uint256 deadlineAfter = proposalDeadline(pId);
-
- assert(deadlineAfter > deadlineBefore => latestCastVoteCall() == e.block.number && deadlineHasBeenExtended(pId));
- }
- // 2. cant unextend RULE PASSING*; ADV SANITY PASSING
- rule deadlineCantBeUnextended(method f)
- filtered {
- f -> !f.isView
- && f.selector != updateQuorumNumerator(uint256).selector // * fails for this function
- } {
- env e; calldataarg args; uint256 pId;
- require(deadlineHasBeenExtended(pId));
- require(proposalCreated(pId));
-
- f(e, args);
-
- assert(deadlineHasBeenExtended(pId));
- }
- // 3. extended => can't change deadline RULE PASSING; ADV SANITY PASSING
- //@note if deadline changed, then it wasnt extended and castvote was called
- rule canExtendDeadlineOnce(method f)
- filtered {
- f -> !f.isView
- } {
- env e; calldataarg args; uint256 pId;
- require(deadlineHasBeenExtended(pId));
- require(proposalCreated(pId));
-
- uint256 deadlineBefore = proposalDeadline(pId);
- f(e, args);
- uint256 deadlineAfter = proposalDeadline(pId);
-
- assert(deadlineBefore == deadlineAfter, "deadline can not be extended twice");
- }
|