AccessManaged.sol 4.9 KB

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