GovernorPreventLateQuorum.spec 3.1 KB

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