|
@@ -22,7 +22,7 @@ rule stateConsistency(env e, uint256 pId) {
|
|
|
|
|
|
/*
|
|
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-โ Rule: State transition โ
|
|
|
+โ Rule: State transitions caused by function calls โ
|
|
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
*/
|
|
|
rule stateTransitionFn(uint256 pId, env e, method f, calldataarg args)
|
|
@@ -55,6 +55,11 @@ rule stateTransitionFn(uint256 pId, env e, method f, calldataarg args)
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
+โ Rule: State transitions caused by time passing โ
|
|
|
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
+*/
|
|
|
rule stateTransitionWait(uint256 pId, env e1, env e2) {
|
|
|
require clock(e1) > 0; // Sanity
|
|
|
require clock(e2) > clock(e1);
|
|
@@ -63,14 +68,9 @@ rule stateTransitionWait(uint256 pId, env e1, env e2) {
|
|
|
uint8 stateAfter = state(e2, pId);
|
|
|
|
|
|
assert (stateBefore != stateAfter) => (
|
|
|
- stateBefore == PENDING() => (
|
|
|
- stateAfter == ACTIVE()
|
|
|
- ) &&
|
|
|
- stateBefore == ACTIVE() => (
|
|
|
- stateAfter == SUCCEEDED() ||
|
|
|
- stateAfter == DEFEATED()
|
|
|
- ) &&
|
|
|
- stateBefore == UNSET() => false &&
|
|
|
+ stateBefore == PENDING() => stateAfter == ACTIVE() &&
|
|
|
+ stateBefore == ACTIVE() => (stateAfter == SUCCEEDED() || stateAfter == DEFEATED()) &&
|
|
|
+ stateBefore == UNSET() => false &&
|
|
|
stateBefore == SUCCEEDED() => false &&
|
|
|
stateBefore == QUEUED() => false &&
|
|
|
stateBefore == CANCELED() => false &&
|
|
@@ -78,135 +78,3 @@ rule stateTransitionWait(uint256 pId, env e1, env e2) {
|
|
|
stateBefore == EXECUTED() => false
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-โ Rule: Once a proposal is created, voteStart, voteEnd and proposer are immutable โ
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-*/
|
|
|
-rule immutableFieldsAfterProposalCreation(uint256 pId, env e, method f, calldataarg arg)
|
|
|
- filtered { f -> !skip(f) }
|
|
|
-{
|
|
|
- require state(e, pId) != UNSET();
|
|
|
-
|
|
|
- uint256 voteStart = proposalSnapshot(pId);
|
|
|
- uint256 voteEnd = proposalDeadline(pId);
|
|
|
- address proposer = proposalProposer(pId);
|
|
|
-
|
|
|
- f(e, arg);
|
|
|
-
|
|
|
- assert voteStart == proposalSnapshot(pId), "Start date was changed";
|
|
|
- assert voteEnd == proposalDeadline(pId), "End date was changed";
|
|
|
- assert proposer == proposalProposer(pId), "Proposer was changed";
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-โ Rule: propose effect and liveness. Includes "no double proposition" โ
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-*/
|
|
|
-rule propose(uint256 pId, env e) {
|
|
|
- require nonpayable(e);
|
|
|
-
|
|
|
- uint256 otherId;
|
|
|
-
|
|
|
- uint8 stateBefore = state(e, pId);
|
|
|
- uint8 otherStateBefore = state(e, otherId);
|
|
|
- uint256 otherVoteStart = proposalSnapshot(otherId);
|
|
|
- uint256 otherVoteEnd = proposalDeadline(otherId);
|
|
|
- address otherProposer = proposalProposer(otherId);
|
|
|
-
|
|
|
- address[] targets; uint256[] values; bytes[] calldatas; string reason;
|
|
|
- require pId == propose@withrevert(e, targets, values, calldatas, reason);
|
|
|
- bool success = !lastReverted;
|
|
|
-
|
|
|
- // liveness & double proposal
|
|
|
- assert success <=> stateBefore == UNSET();
|
|
|
-
|
|
|
- // effect
|
|
|
- assert success => (
|
|
|
- state(e, pId) == PENDING() &&
|
|
|
- proposalProposer(pId) == e.msg.sender &&
|
|
|
- proposalSnapshot(pId) == clock(e) + votingDelay() &&
|
|
|
- proposalDeadline(pId) == clock(e) + votingDelay() + votingPeriod()
|
|
|
- );
|
|
|
-
|
|
|
- // no side-effect
|
|
|
- assert state(e, otherId) != otherStateBefore => otherId == pId;
|
|
|
- assert proposalSnapshot(otherId) == otherVoteStart;
|
|
|
- assert proposalDeadline(otherId) == otherVoteEnd;
|
|
|
- assert proposalProposer(otherId) == otherProposer;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-โ Rule: votes effect and liveness. Includes "A user cannot vote twice" โ
|
|
|
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
-*/
|
|
|
-rule castVote(uint256 pId, env e, method f)
|
|
|
- filtered { f -> voting(f) }
|
|
|
-{
|
|
|
- require nonpayable(e);
|
|
|
-
|
|
|
- uint8 support;
|
|
|
- address voter;
|
|
|
- address otherVoter;
|
|
|
- uint256 otherId;
|
|
|
-
|
|
|
- uint8 stateBefore = state(e, pId);
|
|
|
- bool hasVotedBefore = hasVoted(pId, voter);
|
|
|
- bool otherVotedBefore = hasVoted(otherId, otherVoter);
|
|
|
- uint256 againstVotesBefore = getAgainstVotes(pId);
|
|
|
- uint256 forVotesBefore = getForVotes(pId);
|
|
|
- uint256 abstainVotesBefore = getAbstainVotes(pId);
|
|
|
- uint256 otherAgainstVotesBefore = getAgainstVotes(otherId);
|
|
|
- uint256 otherForVotesBefore = getForVotes(otherId);
|
|
|
- uint256 otherAbstainVotesBefore = getAbstainVotes(otherId);
|
|
|
-
|
|
|
- // voting weight overflow check
|
|
|
- uint256 voterWeight = token_getPastVotes(voter, proposalSnapshot(pId));
|
|
|
- require againstVotesBefore + voterWeight <= max_uint256;
|
|
|
- require forVotesBefore + voterWeight <= max_uint256;
|
|
|
- require abstainVotesBefore + voterWeight <= max_uint256;
|
|
|
-
|
|
|
- uint256 weight = helperVoteWithRevert(e, f, pId, voter, support);
|
|
|
- bool success = !lastReverted;
|
|
|
-
|
|
|
- assert success <=> (
|
|
|
- stateBefore == ACTIVE() &&
|
|
|
- !hasVotedBefore &&
|
|
|
- (support == 0 || support == 1 || support == 2)
|
|
|
- );
|
|
|
-
|
|
|
- assert success => (
|
|
|
- state(e, pId) == ACTIVE() &&
|
|
|
- voterWeight == weight &&
|
|
|
- getAgainstVotes(pId) == againstVotesBefore + (support == 0 ? weight : 0) &&
|
|
|
- getForVotes(pId) == forVotesBefore + (support == 1 ? weight : 0) &&
|
|
|
- getAbstainVotes(pId) == abstainVotesBefore + (support == 2 ? weight : 0) &&
|
|
|
- hasVoted(pId, voter)
|
|
|
- );
|
|
|
-
|
|
|
- // no side-effect
|
|
|
- assert hasVoted(otherId, otherVoter) != otherVotedBefore => (otherId == pId && otherVoter == voter);
|
|
|
- assert getAgainstVotes(otherId) != otherAgainstVotesBefore => (otherId == pId);
|
|
|
- assert getForVotes(otherId) != otherForVotesBefore => (otherId == pId);
|
|
|
- assert getAbstainVotes(otherId) != otherAbstainVotesBefore => (otherId == pId);
|
|
|
-}
|