GovernorPreventLateQuorum.spec 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import "helpers/helpers.spec"
  2. import "helpers/Governor.helpers.spec"
  3. import "GovernorInvariants.spec"
  4. methods {
  5. lateQuorumVoteExtension() returns uint64 envfree
  6. getExtendedDeadline(uint256) returns uint64 envfree
  7. }
  8. use invariant proposalStateConsistency
  9. use invariant votesImplySnapshotPassed
  10. /*
  11. โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  12. โ”‚ This is not (easily) provable as an invariant because the prover think `_totalSupplyCheckpoints` can arbitrarily โ”‚
  13. โ”‚ change, which causes the quorum() to change. Not sure how to fix that. โ”‚
  14. โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  15. */
  16. // invariant deadlineExtendedEquivQuorumReached(uint256 pId)
  17. // getExtendedDeadline(pId) > 0 <=> (quorumReached(pId) && !isCanceled(pId))
  18. /*
  19. โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  20. โ”‚ Rule: โ”‚
  21. โ”‚ * Deadline can never be reduced โ”‚
  22. โ”‚ * If deadline increases then we are in `deadlineExtended` state and `castVote` was called. โ”‚
  23. โ”‚ * A proposal's deadline can't change in `deadlineExtended` state. โ”‚
  24. โ”‚ * A proposal's deadline can't be unextended. โ”‚
  25. โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  26. */
  27. rule deadlineChangeToPreventLateQuorum(uint256 pId, env e, method f, calldataarg args)
  28. filtered { f -> !assumedSafe(f) }
  29. {
  30. require clockSanity(e);
  31. requireInvariant proposalStateConsistency(pId);
  32. requireInvariant votesImplySnapshotPassed(e, pId);
  33. uint256 deadlineBefore = proposalDeadline(pId);
  34. bool deadlineExtendedBefore = getExtendedDeadline(pId) > 0;
  35. f(e, args);
  36. uint256 deadlineAfter = proposalDeadline(pId);
  37. bool deadlineExtendedAfter = getExtendedDeadline(pId) > 0;
  38. // deadline can never be reduced
  39. assert deadlineBefore <= deadlineAfter;
  40. // deadline can only be extended in proposal or on cast vote
  41. assert deadlineAfter != deadlineBefore => (
  42. (
  43. !deadlineExtendedBefore &&
  44. !deadlineExtendedAfter &&
  45. f.selector == propose(address[], uint256[], bytes[], string).selector
  46. ) || (
  47. !deadlineExtendedBefore &&
  48. deadlineExtendedAfter &&
  49. deadlineAfter == clock(e) + lateQuorumVoteExtension() &&
  50. votingAll(f)
  51. )
  52. );
  53. // a deadline can only be extended once
  54. assert deadlineExtendedBefore => deadlineBefore == deadlineAfter;
  55. // a deadline cannot be un-extended
  56. assert deadlineExtendedBefore => deadlineExtendedAfter;
  57. }