// SPDX-License-Identifier: UNLICENSED pragma solidity =0.8.18; import "../../SomaAccessControl/utils/AccessibleUpgradeable.sol"; import "../ISomaGuard.sol"; import "./GuardHelper.sol"; import "./IGuardable.sol"; /** * @notice Implementation of the {IGuardable} interface. */ abstract contract GuardableUpgradeable is IGuardable, AccessibleUpgradeable { /** * @notice Initializer for extended contracts. */ function __Guardable__init() internal { __Context_init_unchained(); __ERC165_init_unchained(); __Guardable__init_unchained(); __SomaContract_init_unchained(); __Accessible_init_unchained(); __Multicall_init_unchained(); __Pausable_init_unchained(); } /** * @notice Unchained initializer for extended contracts. */ function __Guardable__init_unchained() internal onlyInitializing { LOCAL_UPDATE_PRIVILEGES_ROLE = keccak256(abi.encodePacked(address(this), GLOBAL_UPDATE_PRIVILEGES_ROLE)); _updateRequiredPrivileges(bytes32(type(uint256).max)); } bytes32 public immutable DEFAULT_PRIVILEGES = GuardHelper.DEFAULT_PRIVILEGES; bytes32 public constant GLOBAL_UPDATE_PRIVILEGES_ROLE = keccak256("Guardable.GLOBAL_UPDATE_PRIVILEGES_ROLE"); bytes32 public LOCAL_UPDATE_PRIVILEGES_ROLE; bytes32 private _requiredPrivileges; /** * @notice Modifier restricting a function call to accounts that have the required privileges. */ modifier onlyApprovedPrivileges(address sender) { require(hasPrivileges(sender), "required privileges not met"); _; } /** * @inheritdoc IGuardable */ function hasPrivileges(address account) public view virtual override returns (bool) { return ISomaGuard(SOMA.guard()).check(account, requiredPrivileges()); } /** * @inheritdoc IGuardable */ function requiredPrivileges() public view virtual override returns (bytes32) { return _requiredPrivileges; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IGuardable).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IGuardable */ function updateRequiredPrivileges(bytes32 newRequiredPrivileges) external virtual override returns (bool) { require( hasRole(LOCAL_UPDATE_PRIVILEGES_ROLE, _msgSender()) || hasRole(GLOBAL_UPDATE_PRIVILEGES_ROLE, _msgSender()), "Guardable: you do not have the required roles to do this" ); _updateRequiredPrivileges(newRequiredPrivileges); return true; } function _updateRequiredPrivileges(bytes32 newRequiredPrivileges) internal { emit RequiredPrivilegesUpdated(_requiredPrivileges, newRequiredPrivileges, _msgSender()); _requiredPrivileges = newRequiredPrivileges; } uint256[50] private __gap; }