Files
openzeppelin-contracts/certora/specs/GovernorInvariants.spec
2023-03-13 17:26:38 +01:00

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