AccessManaged.sol 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.0.0-rc.0) (access/manager/AccessManaged.sol)
  3. pragma solidity ^0.8.20;
  4. import {IAuthority} from "./IAuthority.sol";
  5. import {AuthorityUtils} from "./AuthorityUtils.sol";
  6. import {IAccessManager} from "./IAccessManager.sol";
  7. import {IAccessManaged} from "./IAccessManaged.sol";
  8. import {Context} from "../../utils/Context.sol";
  9. /**
  10. * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
  11. * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
  12. * implementing a policy that allows certain callers to access certain functions.
  13. *
  14. * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
  15. * functions, and ideally only used in `external` functions. See {restricted}.
  16. */
  17. abstract contract AccessManaged is Context, IAccessManaged {
  18. address private _authority;
  19. bool private _consumingSchedule;
  20. /**
  21. * @dev Initializes the contract connected to an initial authority.
  22. */
  23. constructor(address initialAuthority) {
  24. _setAuthority(initialAuthority);
  25. }
  26. /**
  27. * @dev Restricts access to a function as defined by the connected Authority for this contract and the
  28. * caller and selector of the function that entered the contract.
  29. *
  30. * [IMPORTANT]
  31. * ====
  32. * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`
  33. * functions that are used as external entry points and are not called internally. Unless you know what you're
  34. * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security
  35. * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
  36. * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
  37. * ====
  38. *
  39. * [NOTE]
  40. * ====
  41. * Selector collisions are mitigated by scoping permissions per contract, but some edge cases must be considered:
  42. *
  43. * * If the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`] function
  44. * is restricted, any other function with a `0x00000000` selector will share permissions with `receive()`.
  45. * * Similarly, if there's no `receive()` function but a `fallback()` instead, the fallback might be called with
  46. * empty `calldata`, sharing the `0x00000000` selector permissions as well.
  47. * * For any other selector, if the restricted function is set on an upgradeable contract, an upgrade may remove
  48. * the restricted function and replace it with a new method whose selector replaces the last one, keeping the
  49. * previous permissions.
  50. * ====
  51. */
  52. modifier restricted() {
  53. _checkCanCall(_msgSender(), _msgData());
  54. _;
  55. }
  56. /**
  57. * @dev Returns the current authority.
  58. */
  59. function authority() public view virtual returns (address) {
  60. return _authority;
  61. }
  62. /**
  63. * @dev Transfers control to a new authority. The caller must be the current authority.
  64. */
  65. function setAuthority(address newAuthority) public virtual {
  66. address caller = _msgSender();
  67. if (caller != authority()) {
  68. revert AccessManagedUnauthorized(caller);
  69. }
  70. if (newAuthority.code.length == 0) {
  71. revert AccessManagedInvalidAuthority(newAuthority);
  72. }
  73. _setAuthority(newAuthority);
  74. }
  75. /**
  76. * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is
  77. * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs
  78. * attacker controlled calls.
  79. */
  80. function isConsumingScheduledOp() public view returns (bytes4) {
  81. return _consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);
  82. }
  83. /**
  84. * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the
  85. * permissions set by the current authority.
  86. */
  87. function _setAuthority(address newAuthority) internal virtual {
  88. _authority = newAuthority;
  89. emit AuthorityUpdated(newAuthority);
  90. }
  91. /**
  92. * @dev Reverts if the caller is not allowed to call the function identified by a selector.
  93. */
  94. function _checkCanCall(address caller, bytes calldata data) internal virtual {
  95. (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(
  96. authority(),
  97. caller,
  98. address(this),
  99. bytes4(data)
  100. );
  101. if (!immediate) {
  102. if (delay > 0) {
  103. _consumingSchedule = true;
  104. IAccessManager(authority()).consumeScheduledOp(caller, data);
  105. _consumingSchedule = false;
  106. } else {
  107. revert AccessManagedUnauthorized(caller);
  108. }
  109. }
  110. }
  111. }