108 lines
8.7 KiB
Ruby
108 lines
8.7 KiB
Ruby
import "helpers.spec"
|
|
import "methods/IGovernor.spec"
|
|
import "Governor.helpers.spec"
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: clock is consistent between the goernor and the token │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
rule clockMode(env e) {
|
|
require clockSanity(e);
|
|
|
|
assert clock(e) == e.block.number || clock(e) == e.block.timestamp;
|
|
assert clock(e) == token_clock(e);
|
|
|
|
/// This causes a failure in the prover
|
|
// assert CLOCK_MODE(e) == token_CLOCK_MODE(e);
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: Votes start and end are either initialized (non zero) or uninitialized (zero) simultaneously │
|
|
│ │
|
|
│ This invariant assumes that the block number cannot be 0 at any stage of the contract cycle │
|
|
│ This is very safe assumption as usually the 0 block is genesis block which is uploaded with data │
|
|
│ by the developers and will not be valid to raise proposals (at the current way that block chain is functioning) │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant proposalStateConsistency(uint256 pId)
|
|
(proposalProposer(pId) == 0 <=> proposalSnapshot(pId) == 0) &&
|
|
(proposalProposer(pId) == 0 <=> proposalDeadline(pId) == 0)
|
|
{
|
|
preserved with (env e) {
|
|
require clockSanity(e);
|
|
}
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: cancel => created │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant canceledImplyCreated(uint pId)
|
|
isCanceled(pId) => proposalCreated(pId)
|
|
{
|
|
preserved with (env e) {
|
|
require clockSanity(e);
|
|
requireInvariant proposalStateConsistency(pId);
|
|
}
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: executed => created │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant executedImplyCreated(uint pId)
|
|
isExecuted(pId) => proposalCreated(pId)
|
|
{
|
|
preserved with (env e) {
|
|
require clockSanity(e);
|
|
requireInvariant proposalStateConsistency(pId);
|
|
}
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: queued => created │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant queuedImplyCreated(uint pId)
|
|
isQueued(pId) => proposalCreated(pId)
|
|
{
|
|
preserved with (env e) {
|
|
require clockSanity(e);
|
|
requireInvariant proposalStateConsistency(pId);
|
|
}
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: Votes start before it ends │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant voteStartBeforeVoteEnd(uint256 pId)
|
|
proposalSnapshot(pId) <= proposalDeadline(pId)
|
|
{
|
|
preserved {
|
|
requireInvariant proposalStateConsistency(pId);
|
|
}
|
|
}
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: A proposal cannot be both executed and canceled simultaneously │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant noBothExecutedAndCanceled(uint256 pId)
|
|
!isExecuted(pId) || !isCanceled(pId)
|
|
|
|
/*
|
|
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ Invariant: the "governance call" dequeue is empty │
|
|
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
*/
|
|
invariant governanceCallLength()
|
|
governanceCallLength() == 0
|
|
|