-
Notifications
You must be signed in to change notification settings - Fork 345
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement restriction to allow limiting chain admin in power (#699)
Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Co-authored-by: Yberjon <106954795+Yberjon@users.noreply.github.com>
- Loading branch information
1 parent
3d6e02f
commit 8b5b296
Showing
40 changed files
with
1,106 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
l1-contracts/contracts/governance/AccessControlRestriction.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.24; | ||
|
||
import {AccessToFallbackDenied, AccessToFunctionDenied} from "../common/L1ContractErrors.sol"; | ||
import {IAccessControlRestriction} from "./IAccessControlRestriction.sol"; | ||
import {AccessControlDefaultAdminRules} from "@openzeppelin/contracts-v4/access/AccessControlDefaultAdminRules.sol"; | ||
import {IRestriction} from "./IRestriction.sol"; | ||
import {Call} from "./Common.sol"; | ||
|
||
/// @author Matter Labs | ||
/// @custom:security-contact security@matterlabs.dev | ||
/// @notice The Restriction that is designed to provide the access control logic for the `ChainAdmin` contract. | ||
/// @dev It inherits from `AccessControlDefaultAdminRules` without overriding `_setRoleAdmin` functionaity. In other | ||
/// words, the `DEFAULT_ADMIN_ROLE` is the only role that can manage roles. This is done for simplicity. | ||
/// @dev An instance of this restriction should be deployed separately for each `ChainAdmin` contract. | ||
/// @dev IMPORTANT: this function does not validate the ability of the invoker to use `msg.value`. Thus, | ||
/// either all callers with access to functions should be trusted to not steal ETH from the `ChainAdmin` account | ||
/// or not ETH should be passively stored in `ChainAdmin` account. | ||
contract AccessControlRestriction is IRestriction, IAccessControlRestriction, AccessControlDefaultAdminRules { | ||
/// @notice Required roles to call a specific functions. | ||
/// @dev Note, that the role 0 means the `DEFAULT_ADMIN_ROLE` from the `AccessControlDefaultAdminRules` contract. | ||
mapping(address target => mapping(bytes4 selector => bytes32 requiredRole)) public requiredRoles; | ||
|
||
/// @notice Required roles to call a fallback function. | ||
mapping(address target => bytes32 requiredRole) public requiredRolesForFallback; | ||
|
||
constructor( | ||
uint48 initialDelay, | ||
address initialDefaultAdmin | ||
) AccessControlDefaultAdminRules(initialDelay, initialDefaultAdmin) {} | ||
|
||
/// @notice Sets the required role for a specific function call. | ||
/// @param _target The address of the contract. | ||
/// @param _selector The selector of the function. | ||
/// @param _requiredRole The required role. | ||
function setRequiredRoleForCall( | ||
address _target, | ||
bytes4 _selector, | ||
bytes32 _requiredRole | ||
) external onlyRole(DEFAULT_ADMIN_ROLE) { | ||
requiredRoles[_target][_selector] = _requiredRole; | ||
|
||
emit RoleSet(_target, _selector, _requiredRole); | ||
} | ||
|
||
/// @notice Sets the required role for a fallback function call. | ||
/// @param _target The address of the contract. | ||
/// @param _requiredRole The required role. | ||
function setRequiredRoleForFallback(address _target, bytes32 _requiredRole) external onlyRole(DEFAULT_ADMIN_ROLE) { | ||
requiredRolesForFallback[_target] = _requiredRole; | ||
|
||
emit FallbackRoleSet(_target, _requiredRole); | ||
} | ||
|
||
/// @inheritdoc IRestriction | ||
function validateCall(Call calldata _call, address _invoker) external view { | ||
// Note, that since `DEFAULT_ADMIN_ROLE` is 0 and the default storage value for the | ||
// `requiredRoles` and `requiredRolesForFallback` is 0, the default admin is by default a required | ||
// role for all the functions. | ||
if (_call.data.length < 4) { | ||
if (!hasRole(requiredRolesForFallback[_call.target], _invoker)) { | ||
revert AccessToFallbackDenied(_call.target, _invoker); | ||
} | ||
} else { | ||
bytes4 selector = bytes4(_call.data[:4]); | ||
if (!hasRole(requiredRoles[_call.target][selector], _invoker)) { | ||
revert AccessToFunctionDenied(_call.target, selector, _invoker); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.24; | ||
|
||
/// @dev Represents a call to be made during multicall. | ||
/// @param target The address to which the call will be made. | ||
/// @param value The amount of Ether (in wei) to be sent along with the call. | ||
/// @param data The calldata to be executed on the `target` address. | ||
struct Call { | ||
address target; | ||
uint256 value; | ||
bytes data; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
l1-contracts/contracts/governance/IAccessControlRestriction.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.24; | ||
|
||
/// @title AccessControlRestriction contract interface | ||
/// @author Matter Labs | ||
/// @custom:security-contact security@matterlabs.dev | ||
interface IAccessControlRestriction { | ||
/// @notice Emitted when the required role for a specific function is set. | ||
event RoleSet(address indexed target, bytes4 indexed selector, bytes32 requiredRole); | ||
|
||
/// @notice Emitted when the required role for a fallback function is set. | ||
event FallbackRoleSet(address indexed target, bytes32 requiredRole); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.