AccessControl.spec 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. methods {
  2. hasRole(bytes32, address) returns(bool) envfree
  3. getRoleAdmin(bytes32) returns(bytes32) envfree
  4. grantRole(bytes32, address)
  5. revokeRole(bytes32, address)
  6. renounceRole(bytes32, address)
  7. }
  8. /*
  9. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  10. │ Rule: only grantRole can grant a role │
  11. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  12. */
  13. rule onlyGrantCanGrant(env e, bytes32 role, address account) {
  14. require !hasRole(role, account);
  15. method f; calldataarg args;
  16. f(e, args);
  17. assert hasRole(role, account) => f.selector == grantRole(bytes32, address).selector;
  18. }
  19. /*
  20. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  21. │ Rule: only revokeRole and renounceRole can grant a role │
  22. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  23. */
  24. rule onlyRevokeAndRenounceCanRevoke(env e, bytes32 role, address account) {
  25. require hasRole(role, account);
  26. method f; calldataarg args;
  27. f(e, args);
  28. assert !hasRole(role, account) => (f.selector == revokeRole(bytes32, address).selector || f.selector == renounceRole(bytes32, address).selector);
  29. }
  30. /*
  31. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  32. │ Rule: only an account with admin role can call grantRole │
  33. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  34. */
  35. rule onlyAdminCanGrant(env e, bytes32 role, address account) {
  36. bool isAdmin = hasRole(getRoleAdmin(role), e.msg.sender);
  37. grantRole@withrevert(e, role, account);
  38. assert !lastReverted => isAdmin;
  39. }
  40. /*
  41. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  42. │ Rule: only an account with admin role can call revokeRole │
  43. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  44. */
  45. rule onlyAdminCanRevoke(env e, bytes32 role, address account) {
  46. bool isAdmin = hasRole(getRoleAdmin(role), e.msg.sender);
  47. revokeRole@withrevert(e, role, account);
  48. assert !lastReverted => isAdmin;
  49. }
  50. /*
  51. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  52. │ Rule: only the affected account can revoke │
  53. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  54. */
  55. rule onlyUserCanRenounce(env e, bytes32 role, address account) {
  56. renounceRole@withrevert(e, role, account);
  57. assert !lastReverted => account == e.msg.sender;
  58. }
  59. /*
  60. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  61. │ Rule: grantRole only affects the specified user/role combo │
  62. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  63. */
  64. rule grantRoleEffect(env e) {
  65. bytes32 role1; bytes32 role2;
  66. address account1; address account2;
  67. bool hasRoleBefore = hasRole(role1, account1);
  68. grantRole(e, role2, account2);
  69. bool hasRoleAfter = hasRole(role1, account1);
  70. assert (
  71. hasRoleBefore != hasRoleAfter
  72. ) => (
  73. hasRoleAfter == true && role1 == role2 && account1 == account2
  74. );
  75. }
  76. /*
  77. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  78. │ Rule: revokeRole only affects the specified user/role combo │
  79. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  80. */
  81. rule revokeRoleEffect(env e) {
  82. bytes32 role1; bytes32 role2;
  83. address account1; address account2;
  84. bool hasRoleBefore = hasRole(role1, account1);
  85. revokeRole(e, role2, account2);
  86. bool hasRoleAfter = hasRole(role1, account1);
  87. assert (
  88. hasRoleBefore != hasRoleAfter
  89. ) => (
  90. hasRoleAfter == false && role1 == role2 && account1 == account2
  91. );
  92. }
  93. /*
  94. ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  95. │ Rule: renounceRole only affects the specified user/role combo │
  96. └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  97. */
  98. rule renounceRoleEffect(env e) {
  99. bytes32 role1; bytes32 role2;
  100. address account1; address account2;
  101. bool hasRoleBefore = hasRole(role1, account1);
  102. renounceRole(e, role2, account2);
  103. bool hasRoleAfter = hasRole(role1, account1);
  104. assert (
  105. hasRoleBefore != hasRoleAfter
  106. ) => (
  107. hasRoleAfter == false && role1 == role2 && account1 == account2
  108. );
  109. }