// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.25; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import "./IAccessControlManagerV8.sol"; /** * @title AccessControlledV8 * @author Venus * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.8.13) * to integrate access controlled mechanism. It provides initialise methods and verifying access methods. */ abstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable { /// @notice Access control manager contract IAccessControlManagerV8 internal _accessControlManager; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; /// @notice Emitted when access control manager contract address is changed event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager); /// @notice Thrown when the action is prohibited by AccessControlManager error Unauthorized(address sender, address calledContract, string methodSignature); function __AccessControlled_init(address accessControlManager_) internal onlyInitializing { __Ownable2Step_init(); __AccessControlled_init_unchained(accessControlManager_); } function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing { _setAccessControlManager(accessControlManager_); } /** * @notice Sets the address of AccessControlManager * @dev Admin function to set address of AccessControlManager * @param accessControlManager_ The new address of the AccessControlManager * @custom:event Emits NewAccessControlManager event * @custom:access Only Governance */ function setAccessControlManager(address accessControlManager_) external onlyOwner { _setAccessControlManager(accessControlManager_); } /** * @notice Returns the address of the access control manager contract */ function accessControlManager() external view returns (IAccessControlManagerV8) { return _accessControlManager; } /** * @dev Internal function to set address of AccessControlManager * @param accessControlManager_ The new address of the AccessControlManager */ function _setAccessControlManager(address accessControlManager_) internal { require(address(accessControlManager_) != address(0), "invalid acess control manager address"); address oldAccessControlManager = address(_accessControlManager); _accessControlManager = IAccessControlManagerV8(accessControlManager_); emit NewAccessControlManager(oldAccessControlManager, accessControlManager_); } /** * @notice Reverts if the call is not allowed by AccessControlManager * @param signature Method signature */ function _checkAccessAllowed(string memory signature) internal view { bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature); if (!isAllowedToCall) { revert Unauthorized(msg.sender, address(this), signature); } } }