GovernorInvariants.spec 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import "helpers.spec"
  2. import "methods/IGovernor.spec"
  3. import "Governor.helpers.spec"
  4. /*
  5. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  6. │ Invariant: clock is consistent between the goernor and the token │
  7. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  8. */
  9. rule clockMode(env e) {
  10. require clockSanity(e);
  11. assert clock(e) == e.block.number || clock(e) == e.block.timestamp;
  12. assert clock(e) == token_clock(e);
  13. /// This causes a failure in the prover
  14. // assert CLOCK_MODE(e) == token_CLOCK_MODE(e);
  15. }
  16. /*
  17. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  18. │ Invariant: Votes start and end are either initialized (non zero) or uninitialized (zero) simultaneously │
  19. │ │
  20. │ This invariant assumes that the block number cannot be 0 at any stage of the contract cycle │
  21. │ This is very safe assumption as usually the 0 block is genesis block which is uploaded with data │
  22. │ by the developers and will not be valid to raise proposals (at the current way that block chain is functioning) │
  23. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  24. */
  25. invariant proposalStateConsistency(uint256 pId)
  26. (proposalProposer(pId) == 0 <=> proposalSnapshot(pId) == 0) &&
  27. (proposalProposer(pId) == 0 <=> proposalDeadline(pId) == 0)
  28. {
  29. preserved with (env e) {
  30. require clockSanity(e);
  31. }
  32. }
  33. /*
  34. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  35. │ Invariant: cancel => created │
  36. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  37. */
  38. invariant canceledImplyCreated(uint pId)
  39. isCanceled(pId) => proposalCreated(pId)
  40. {
  41. preserved with (env e) {
  42. require clockSanity(e);
  43. requireInvariant proposalStateConsistency(pId);
  44. }
  45. }
  46. /*
  47. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  48. │ Invariant: executed => created │
  49. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  50. */
  51. invariant executedImplyCreated(uint pId)
  52. isExecuted(pId) => proposalCreated(pId)
  53. {
  54. preserved with (env e) {
  55. require clockSanity(e);
  56. requireInvariant proposalStateConsistency(pId);
  57. }
  58. }
  59. /*
  60. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  61. │ Invariant: queued => created │
  62. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  63. */
  64. invariant queuedImplyCreated(uint pId)
  65. isQueued(pId) => proposalCreated(pId)
  66. {
  67. preserved with (env e) {
  68. require clockSanity(e);
  69. requireInvariant proposalStateConsistency(pId);
  70. }
  71. }
  72. /*
  73. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  74. │ Invariant: Votes start before it ends │
  75. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  76. */
  77. invariant voteStartBeforeVoteEnd(uint256 pId)
  78. proposalSnapshot(pId) <= proposalDeadline(pId)
  79. {
  80. preserved {
  81. requireInvariant proposalStateConsistency(pId);
  82. }
  83. }
  84. /*
  85. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  86. │ Invariant: A proposal cannot be both executed and canceled simultaneously │
  87. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  88. */
  89. invariant noBothExecutedAndCanceled(uint256 pId)
  90. !isExecuted(pId) || !isCanceled(pId)
  91. /*
  92. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  93. │ Invariant: the "governance call" dequeue is empty │
  94. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  95. */
  96. invariant governanceCallLength()
  97. governanceCallLength() == 0