// SPDX-License-Identifier: AGPL-3.0-only /* Permissions.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see . */ pragma solidity ^0.8.17; import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol"; import { IPermissions } from "@skalenetwork/skale-manager-interfaces/IPermissions.sol"; import { AccessControlUpgradeableLegacy } from "./thirdparty/openzeppelin/AccessControlUpgradeableLegacy.sol"; /** * @title Permissions * @dev Contract is connected module for Upgradeable approach, knows ContractManager */ contract Permissions is AccessControlUpgradeableLegacy, IPermissions { using AddressUpgradeable for address; IContractManager public contractManager; /** * @dev Modifier to make a function callable only when caller is the Owner. * * Requirements: * * - The caller must be the owner. */ modifier onlyOwner() { require(_isOwner(), "Caller is not the owner"); _; } /** * @dev Modifier to make a function callable only when caller is an Admin. * * Requirements: * * - The caller must be an admin. */ modifier onlyAdmin() { require(_isAdmin(msg.sender), "Caller is not an admin"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName` contract. * * Requirements: * * - The caller must be the owner or `contractName`. */ modifier allow(string memory contractName) { require( contractManager.getContract(contractName) == msg.sender || _isOwner(), "Message sender is invalid"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName1` or `contractName2` contract. * * Requirements: * * - The caller must be the owner, `contractName1`, or `contractName2`. */ modifier allowTwo(string memory contractName1, string memory contractName2) { require( contractManager.getContract(contractName1) == msg.sender || contractManager.getContract(contractName2) == msg.sender || _isOwner(), "Message sender is invalid"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName1`, `contractName2`, or `contractName3` contract. * * Requirements: * * - The caller must be the owner, `contractName1`, `contractName2`, or * `contractName3`. */ modifier allowThree( string memory contractName1, string memory contractName2, string memory contractName3 ) { require( contractManager.getContract(contractName1) == msg.sender || contractManager.getContract(contractName2) == msg.sender || contractManager.getContract(contractName3) == msg.sender || _isOwner(), "Message sender is invalid"); _; } function initialize(address contractManagerAddress) public virtual override initializer { AccessControlUpgradeableLegacy.__AccessControl_init(); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setContractManager(contractManagerAddress); } function _isOwner() internal view returns (bool owner) { return hasRole(DEFAULT_ADMIN_ROLE, msg.sender); } function _isAdmin(address account) internal view returns (bool admin) { address skaleManagerAddress = contractManager.contracts(keccak256(abi.encodePacked("SkaleManager"))); if (skaleManagerAddress != address(0)) { AccessControlUpgradeableLegacy skaleManager = AccessControlUpgradeableLegacy(skaleManagerAddress); return skaleManager.hasRole(keccak256("ADMIN_ROLE"), account) || _isOwner(); } else { return _isOwner(); } } function _setContractManager(address contractManagerAddress) private { require(contractManagerAddress != address(0), "ContractManager address is not set"); require(contractManagerAddress.isContract(), "Address is not contract"); contractManager = IContractManager(contractManagerAddress); } }