AccessManaged.sol 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "../../utils/Context.sol";
  4. import "./IAuthority.sol";
  5. /**
  6. * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
  7. * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
  8. * implementing a policy that allows certain callers access to certain functions.
  9. *
  10. * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
  11. * functions, and ideally only used in `external` functions. See {restricted}.
  12. */
  13. contract AccessManaged is Context {
  14. event AuthorityUpdated(address indexed sender, IAuthority indexed newAuthority);
  15. IAuthority private _authority;
  16. /**
  17. * @dev Restricts access to a function as defined by the connected Authority for this contract and the
  18. * caller and selector of the function that entered the contract.
  19. *
  20. * [IMPORTANT]
  21. * ====
  22. * In general, this modifier should only be used on `external` functions. It is okay to use it on `public` functions
  23. * that are used as external entry points and are not called internally. Unless you know what you're doing, it
  24. * should never be used on `internal` functions. Failure to follow these rules can have critical security
  25. * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
  26. * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
  27. * ====
  28. */
  29. modifier restricted() {
  30. _checkCanCall(_msgSender(), msg.sig);
  31. _;
  32. }
  33. /**
  34. * @dev Initializes the contract connected to an initial authority.
  35. */
  36. constructor(IAuthority initialAuthority) {
  37. _setAuthority(initialAuthority);
  38. }
  39. /**
  40. * @dev Returns the current authority.
  41. */
  42. function authority() public view virtual returns (IAuthority) {
  43. return _authority;
  44. }
  45. /**
  46. * @dev Transfers control to a new authority. The caller must be the current authority.
  47. */
  48. function setAuthority(IAuthority newAuthority) public virtual {
  49. require(_msgSender() == address(_authority), "AccessManaged: not current authority");
  50. _setAuthority(newAuthority);
  51. }
  52. /**
  53. * @dev Transfers control to a new authority. Internal function with no access restriction.
  54. */
  55. function _setAuthority(IAuthority newAuthority) internal virtual {
  56. _authority = newAuthority;
  57. emit AuthorityUpdated(_msgSender(), newAuthority);
  58. }
  59. /**
  60. * @dev Reverts if the caller is not allowed to call the function identified by a selector.
  61. */
  62. function _checkCanCall(address caller, bytes4 selector) internal view virtual {
  63. require(_authority.canCall(caller, address(this), selector), "AccessManaged: authority rejected");
  64. }
  65. }