123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.0;
- import "../../utils/Context.sol";
- import "./IAuthority.sol";
- /**
- * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
- * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
- * implementing a policy that allows certain callers access to certain functions.
- *
- * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
- * functions, and ideally only used in `external` functions. See {restricted}.
- */
- contract AccessManaged is Context {
- event AuthorityUpdated(address indexed sender, IAuthority indexed newAuthority);
- IAuthority private _authority;
- /**
- * @dev Restricts access to a function as defined by the connected Authority for this contract and the
- * caller and selector of the function that entered the contract.
- *
- * [IMPORTANT]
- * ====
- * In general, this modifier should only be used on `external` functions. It is okay to use it on `public` functions
- * that are used as external entry points and are not called internally. Unless you know what you're doing, it
- * should never be used on `internal` functions. Failure to follow these rules can have critical security
- * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
- * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
- * ====
- */
- modifier restricted() {
- _checkCanCall(_msgSender(), msg.sig);
- _;
- }
- /**
- * @dev Initializes the contract connected to an initial authority.
- */
- constructor(IAuthority initialAuthority) {
- _setAuthority(initialAuthority);
- }
- /**
- * @dev Returns the current authority.
- */
- function authority() public view virtual returns (IAuthority) {
- return _authority;
- }
- /**
- * @dev Transfers control to a new authority. The caller must be the current authority.
- */
- function setAuthority(IAuthority newAuthority) public virtual {
- require(_msgSender() == address(_authority), "AccessManaged: not current authority");
- _setAuthority(newAuthority);
- }
- /**
- * @dev Transfers control to a new authority. Internal function with no access restriction.
- */
- function _setAuthority(IAuthority newAuthority) internal virtual {
- _authority = newAuthority;
- emit AuthorityUpdated(_msgSender(), newAuthority);
- }
- /**
- * @dev Reverts if the caller is not allowed to call the function identified by a selector.
- */
- function _checkCanCall(address caller, bytes4 selector) internal view virtual {
- require(_authority.canCall(caller, address(this), selector), "AccessManaged: authority rejected");
- }
- }
|