ERC1155Pausable.spec 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //// ## Verification of `ERC1155Pausable`
  2. ////
  3. //// `ERC1155Pausable` extends existing `Pausable` functionality by requiring that a
  4. //// contract not be in a `paused` state prior to a token transfer.
  5. ////
  6. //// ### Assumptions and Simplifications
  7. //// - Internal methods `_pause` and `_unpause` wrapped by functions callable from CVL
  8. //// - Dummy functions created to verify `whenPaused` and `whenNotPaused` modifiers
  9. ////
  10. ////
  11. //// ### Properties
  12. methods {
  13. balanceOf(address, uint256) returns uint256 envfree
  14. paused() returns bool envfree
  15. }
  16. /// When a contract is in a paused state, the token balance for a given user and
  17. /// token must not change.
  18. rule balancesUnchangedWhenPaused() {
  19. address user; uint256 token;
  20. uint256 balanceBefore = balanceOf(user, token);
  21. require paused();
  22. method f; calldataarg arg; env e;
  23. f(e, arg);
  24. uint256 balanceAfter = balanceOf(user, token);
  25. assert balanceBefore == balanceAfter,
  26. "Token balance for a user must not change in a paused contract";
  27. }
  28. /// When a contract is in a paused state, transfer methods must revert.
  29. rule transferMethodsRevertWhenPaused (method f)
  30. filtered {
  31. f -> f.selector == safeTransferFrom(address,address,uint256,uint256,bytes).selector
  32. || f.selector == safeBatchTransferFrom(address,address,uint256[],uint256[],bytes).selector
  33. }
  34. {
  35. require paused();
  36. env e; calldataarg args;
  37. f@withrevert(e, args);
  38. assert lastReverted,
  39. "Transfer methods must revert in a paused contract";
  40. }
  41. /// When a contract is in an unpaused state, calling `pause()` must pause.
  42. rule pauseMethodPausesContract {
  43. require !paused();
  44. env e;
  45. pause(e);
  46. assert paused(),
  47. "Calling pause must pause an unpaused contract";
  48. }
  49. /// When a contract is in a paused state, calling unpause() must unpause.
  50. rule unpauseMethodUnpausesContract {
  51. require paused();
  52. env e;
  53. unpause(e);
  54. assert !paused(),
  55. "Calling unpause must unpause a paused contract";
  56. }
  57. /// When a contract is in a paused state, calling pause() must revert.
  58. rule cannotPauseWhilePaused {
  59. require paused();
  60. env e;
  61. pause@withrevert(e);
  62. assert lastReverted,
  63. "A call to pause when already paused must revert";
  64. }
  65. /// When a contract is in an unpaused state, calling unpause() must revert.
  66. rule cannotUnpauseWhileUnpaused {
  67. require !paused();
  68. env e;
  69. unpause@withrevert(e);
  70. assert lastReverted,
  71. "A call to unpause when already unpaused must revert";
  72. }
  73. /// When a contract is in a paused state, functions with the `whenNotPaused`
  74. /// modifier must revert.
  75. /// @title `whenNotPaused` modifier causes revert if paused
  76. rule whenNotPausedModifierCausesRevertIfPaused {
  77. require paused();
  78. env e; calldataarg args;
  79. onlyWhenNotPausedMethod@withrevert(e, args);
  80. assert lastReverted,
  81. "Functions with the whenNotPaused modifier must revert if the contract is paused";
  82. }
  83. /// When a contract is in an unpaused state, functions with the `whenPaused`
  84. /// modifier must revert.
  85. /// @title `whenPaused` modifier causes revert if unpaused
  86. rule whenPausedModifierCausesRevertIfUnpaused {
  87. require !paused();
  88. env e; calldataarg args;
  89. onlyWhenPausedMethod@withrevert(e, args);
  90. assert lastReverted,
  91. "Functions with the whenPaused modifier must revert if the contract is not paused";
  92. }
  93. /*
  94. /// This rule should always fail.
  95. rule sanity {
  96. method f; env e; calldataarg args;
  97. f(e, args);
  98. assert false,
  99. "This rule should always fail";
  100. }
  101. */