Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smr 1910 rbac #23

Merged
merged 25 commits into from
Nov 13, 2023
Merged

Smr 1910 rbac #23

merged 25 commits into from
Nov 13, 2023

Conversation

Benjimmutable
Copy link
Contributor

This adds roles, but does not add some things that roles will be used for, e.g.:

@Benjimmutable Benjimmutable self-assigned this Nov 7, 2023
@@ -281,7 +300,10 @@ contract ChildERC20Bridge is
}
}

function updateBridgeAdaptor(address newBridgeAdaptor) external override onlyOwner {
function updateBridgeAdaptor(address newBridgeAdaptor) external override /*onlyOwner*/ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing inheritdoc

function updateBridgeAdaptor(address newBridgeAdaptor) external override onlyOwner {
function updateBridgeAdaptor(address newBridgeAdaptor) external override /*onlyOwner*/ {
if (!(hasRole(VARIABLE_MANAGER_ROLE, msg.sender))) {
revert NotVariableManager();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding the caller address in NotVariableManager, i.e. NotVariableManager(msg.sender).

AccessControl default error messages will also return the account being checked for role in the error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

@@ -27,8 +27,16 @@ contract DeployChildContracts is Script {
ChildERC20 childTokenTemplate = new ChildERC20();
childTokenTemplate.initialize(address(123), "TEMPLATE", "TPT", 18);

IChildERC20Bridge.InitializationRoles memory roles = IChildERC20Bridge.InitializationRoles({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a blocker but in general better to avoid the precompile addresses for things

@@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.21;
pragma solidity 0.8.19;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import for Initializable can be removed

_grantRole(UNPAUSER_ROLE, newRoles.unpauser);
_grantRole(VARIABLE_MANAGER_ROLE, newRoles.variableManager);
_grantRole(ADAPTOR_MANAGER_ROLE, newRoles.adaptorManager);

Copy link
Contributor

@rzmahmood rzmahmood Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best practice to call initializer of inherited contracts, i.e.

__AccessControl_init()

In this case its empty, so not critical but its good to get the habit

@@ -55,6 +63,8 @@ interface IChildERC20BridgeEvents {

// TODO add parameters to errors if it makes sense
interface IChildERC20BridgeErrors {
/// @notice Error when the caller is not the variable manager role.
error NotVariableManager();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above about adding the msg.sender

Comment on lines +59 to +60
variableManager: params.childAdminAddress,
adaptorManager: params.childAdminAddress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right. The variable manager and adaptor manager is same as the childAdmin?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script isn't looking good and looks pretty outdated, so worth creating a ticket to update the script in a separate PR.

Comment on lines +69 to +70
variableManager: params.rootAdminAddress,
adaptorManager: params.rootAdminAddress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, is it intended that the variableManager and adaptorManager is the rootAdmin?

@@ -83,6 +91,8 @@ interface IRootERC20BridgeEvents {
}

interface IRootERC20BridgeErrors {
/// @notice Error when the caller is not the variable manager role.
error NotVariableManager();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment about adding caller as argument

@@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.21;
pragma solidity 0.8.19;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializable line is not required


import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address is imported twice

import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IAxelarGateway} from "@axelar-cgp-solidity/contracts/interfaces/IAxelarGateway.sol";
import {IRootERC20Bridge, IERC20Metadata} from "../interfaces/root/IRootERC20Bridge.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two separate imports from the same IRootERC20Bridge.sol?

_grantRole(UNPAUSER_ROLE, newRoles.unpauser);
_grantRole(VARIABLE_MANAGER_ROLE, newRoles.variableManager);
_grantRole(ADAPTOR_MANAGER_ROLE, newRoles.adaptorManager);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better practice to add __AccessControl_init()

@@ -115,7 +131,11 @@ contract RootERC20Bridge is
* @param newRootBridgeAdaptor Address of new root bridge adaptor.
* @dev Can only be called by owner.
Copy link
Contributor

@rzmahmood rzmahmood Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated comment. There is no owner

@@ -131,7 +151,11 @@ contract RootERC20Bridge is
* @dev Can only be called by owner.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated comment. There is no owner

@@ -115,7 +131,11 @@ contract RootERC20Bridge is
* @param newRootBridgeAdaptor Address of new root bridge adaptor.
* @dev Can only be called by owner.
*/
function updateRootBridgeAdaptor(address newRootBridgeAdaptor) external onlyOwner {
function updateRootBridgeAdaptor(address newRootBridgeAdaptor) external {
if (!hasRole(VARIABLE_MANAGER_ROLE, msg.sender)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ADAPTOR_MANAGER, not variable_manager

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right

if (!hasRole(VARIABLE_MANAGER_ROLE, msg.sender)) {
revert NotVariableManager();
}

if (
newImxCumulativeDepositLimit != NO_DEPOSIT_LIMIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid double negatives as it is confusing. Better to change NO_DEPOSIT_LIMIT to DEPOSIT_LIMIT

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constant represents no limit in deposit. How about UNLIMITED_DEPOSIT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unlimited feels better

@@ -19,7 +19,7 @@ contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAx
address constant IMX_TOKEN_ADDRESS = address(0xccc);
address constant NATIVE_ETH = address(0xeee);
address constant WRAPPED_ETH = address(0xddd);
uint256 constant unlimitedDepositLimit = 0;
uint256 constant UNLIMITED_DEPOSIT_LIMIT = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this named differently to imxCumulativeDepositLimit? It makes it seem like UNLIMITED_DEPOSIT_LIMIT is false, when reality the deposit limit is unlimited.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this constant represents no limit in the deposit while any other positive number in imxCumulativeDepositLimit represents a limit in-place.

});

vm.expectRevert(ZeroAddress.selector);
bridge.initialize(roles, address(0), ROOT_BRIDGE_ADAPTOR, address(1), ROOT_CHAIN_NAME, address(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will revert because newBridgeAdaptor is 0, not because defaultAdmin is 0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, fixed

});

vm.expectRevert(ZeroAddress.selector);
bridge.initialize(roles, address(0), ROOT_BRIDGE_ADAPTOR, address(1), ROOT_CHAIN_NAME, address(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will revert because newBridgeAdaptor is 0. Same as above

});

vm.expectRevert(ZeroAddress.selector);
bridge.initialize(roles, address(0), ROOT_BRIDGE_ADAPTOR, address(1), ROOT_CHAIN_NAME, address(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will revert because newBridgeAdaptor is 0. Same as above

});

vm.expectRevert(ZeroAddress.selector);
bridge.initialize(roles, address(0), ROOT_BRIDGE_ADAPTOR, address(1), ROOT_CHAIN_NAME, address(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will revert because newBridgeAdaptor is 0. Same as above

});

vm.expectRevert(ZeroAddress.selector);
bridge.initialize(roles, address(0), ROOT_BRIDGE_ADAPTOR, address(1), ROOT_CHAIN_NAME, address(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will revert because newBridgeAdaptor is 0. Same as above

@@ -220,7 +353,7 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B

function test_RevertIf_updateBridgeAdaptorCalledByNonOwner() public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test name outdated

@@ -220,7 +353,7 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B

function test_RevertIf_updateBridgeAdaptorCalledByNonOwner() public {
vm.prank(address(0xf00f00));
vm.expectRevert("Ownable: caller is not the owner");
vm.expectRevert(NotVariableManager.selector);
Copy link
Contributor

@rzmahmood rzmahmood Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be testing for AdaptorManager

/**
* ROLES
*/
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see these same roles are also defined in RootERC20Bridge.sol. Possibly worth moving to another contract for DRY, consistency, less error-prone and for prosperity reasons when we support bridging of other assets?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, not just this. The root and child bridge share a lot of common constants, errors, etc, so it would be nice to create an issue and do that all in a separate PR.

@@ -56,7 +63,8 @@ contract ChildERC20Bridge is
address public childETHToken;

/**
* @notice Initilization function for RootERC20Bridge.
* @notice Initialization function for RootERC20Bridge.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect comment, should be ChildERC20Bridge?

/**
* ROLES
*/
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment regarding role definitions in contract.

Copy link
Contributor

@rzmahmood rzmahmood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

@wcgcyx wcgcyx merged commit 81697c0 into main Nov 13, 2023
3 checks passed
@ermyas ermyas deleted the smr-1910-rbac branch April 12, 2024 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants