RulesInProgress.spec 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //////////////////////////////////////////////////////////////////////////////
  2. ////////////// THIS SPEC IS A RESERVE FOR NOT IN PROGRESS //////////////
  3. //////////////////////////////////////////////////////////////////////////////
  4. import "GovernorBase.spec"
  5. using ERC20VotesHarness as erc20votes
  6. methods {
  7. ghost_sum_vote_power_by_id(uint256) returns uint256 envfree
  8. quorum(uint256) returns uint256
  9. proposalVotes(uint256) returns (uint256, uint256, uint256) envfree
  10. quorumNumerator() returns uint256
  11. _executor() returns address
  12. erc20votes._getPastVotes(address, uint256) returns uint256
  13. getExecutor() returns address
  14. timelock() returns address
  15. }
  16. //////////////////////////////////////////////////////////////////////////////
  17. ///////////////////////////////// GHOSTS /////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////// ghosts to keep track of votes counting ////////////
  20. /*
  21. * the sum of voting power of those who voted
  22. */
  23. ghost sum_all_votes_power() returns uint256 {
  24. init_state axiom sum_all_votes_power() == 0;
  25. }
  26. hook Sstore ghost_sum_vote_power_by_id [KEY uint256 pId] uint256 current_power(uint256 old_power) STORAGE {
  27. havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power;
  28. }
  29. /*
  30. * sum of all votes casted per proposal
  31. */
  32. ghost tracked_weight(uint256) returns uint256 {
  33. init_state axiom forall uint256 p. tracked_weight(p) == 0;
  34. }
  35. /*
  36. * sum of all votes casted
  37. */
  38. ghost sum_tracked_weight() returns uint256 {
  39. init_state axiom sum_tracked_weight() == 0;
  40. }
  41. /*
  42. * getter for _proposalVotes.againstVotes
  43. */
  44. ghost votesAgainst() returns uint256 {
  45. init_state axiom votesAgainst() == 0;
  46. }
  47. /*
  48. * getter for _proposalVotes.forVotes
  49. */
  50. ghost votesFor() returns uint256 {
  51. init_state axiom votesFor() == 0;
  52. }
  53. /*
  54. * getter for _proposalVotes.abstainVotes
  55. */
  56. ghost votesAbstain() returns uint256 {
  57. init_state axiom votesAbstain() == 0;
  58. }
  59. hook Sstore _proposalVotes [KEY uint256 pId].againstVotes uint256 votes(uint256 old_votes) STORAGE {
  60. havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) &&
  61. (p != pId => tracked_weight@new(p) == tracked_weight@old(p));
  62. havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes;
  63. havoc votesAgainst assuming votesAgainst@new() == votesAgainst@old() - old_votes + votes;
  64. }
  65. hook Sstore _proposalVotes [KEY uint256 pId].forVotes uint256 votes(uint256 old_votes) STORAGE {
  66. havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) &&
  67. (p != pId => tracked_weight@new(p) == tracked_weight@old(p));
  68. havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes;
  69. havoc votesFor assuming votesFor@new() == votesFor@old() - old_votes + votes;
  70. }
  71. hook Sstore _proposalVotes [KEY uint256 pId].abstainVotes uint256 votes(uint256 old_votes) STORAGE {
  72. havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) &&
  73. (p != pId => tracked_weight@new(p) == tracked_weight@old(p));
  74. havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes;
  75. havoc votesAbstain assuming votesAbstain@new() == votesAbstain@old() - old_votes + votes;
  76. }
  77. //////////////////////////////////////////////////////////////////////////////
  78. ////////////////////////////// INVARIANTS ////////////////////////////////////
  79. //////////////////////////////////////////////////////////////////////////////
  80. //////////////////////////////////////////////////////////////////////////////
  81. ///////////////////////////////// RULES //////////////////////////////////////
  82. //////////////////////////////////////////////////////////////////////////////
  83. //NOT FINISHED
  84. /*
  85. * the sum of voting power of those who voted is less or equal to the maximum possible votes, per each proposal
  86. */
  87. rule possibleTotalVotes(uint256 pId, uint8 sup, env e, method f) {
  88. // add requireinvariant for all i, j. i = i - 1 && i < j => checkpointlookup[i] < checkpointlookup[j];
  89. require tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId));
  90. uint256 againstB;
  91. uint256 forB;
  92. uint256 absatinB;
  93. againstB, forB, absatinB = proposalVotes(pId);
  94. calldataarg args;
  95. //f(e, args);
  96. castVote(e, pId, sup);
  97. uint256 against;
  98. uint256 for;
  99. uint256 absatin;
  100. against, for, absatin = proposalVotes(pId);
  101. uint256 ps = proposalSnapshot(pId);
  102. assert tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId)), "bla bla bla";
  103. }