-
Notifications
You must be signed in to change notification settings - Fork 7
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
Smr 1910 rbac #23
Conversation
update solc version to 0.8.19
src/child/ChildERC20Bridge.sol
Outdated
@@ -281,7 +300,10 @@ contract ChildERC20Bridge is | |||
} | |||
} | |||
|
|||
function updateBridgeAdaptor(address newBridgeAdaptor) external override onlyOwner { | |||
function updateBridgeAdaptor(address newBridgeAdaptor) external override /*onlyOwner*/ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing inheritdoc
src/child/ChildERC20Bridge.sol
Outdated
function updateBridgeAdaptor(address newBridgeAdaptor) external override onlyOwner { | ||
function updateBridgeAdaptor(address newBridgeAdaptor) external override /*onlyOwner*/ { | ||
if (!(hasRole(VARIABLE_MANAGER_ROLE, msg.sender))) { | ||
revert NotVariableManager(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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({ |
There was a problem hiding this comment.
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
src/child/ChildERC20Bridge.sol
Outdated
@@ -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"; |
There was a problem hiding this comment.
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); | ||
|
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
variableManager: params.childAdminAddress, | ||
adaptorManager: params.childAdminAddress |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
variableManager: params.rootAdminAddress, | ||
adaptorManager: params.rootAdminAddress |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
src/root/RootERC20Bridge.sol
Outdated
@@ -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"; |
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address is imported twice
src/root/RootERC20Bridge.sol
Outdated
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"; |
There was a problem hiding this comment.
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); | ||
|
There was a problem hiding this comment.
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()
src/root/RootERC20Bridge.sol
Outdated
@@ -115,7 +131,11 @@ contract RootERC20Bridge is | |||
* @param newRootBridgeAdaptor Address of new root bridge adaptor. | |||
* @dev Can only be called by owner. |
There was a problem hiding this comment.
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
src/root/RootERC20Bridge.sol
Outdated
@@ -131,7 +151,11 @@ contract RootERC20Bridge is | |||
* @dev Can only be called by owner. |
There was a problem hiding this comment.
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
src/root/RootERC20Bridge.sol
Outdated
@@ -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)) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right
src/root/RootERC20Bridge.sol
Outdated
if (!hasRole(VARIABLE_MANAGER_ROLE, msg.sender)) { | ||
revert NotVariableManager(); | ||
} | ||
|
||
if ( | ||
newImxCumulativeDepositLimit != NO_DEPOSIT_LIMIT |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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"); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
src/child/ChildERC20Bridge.sol
Outdated
@@ -56,7 +63,8 @@ contract ChildERC20Bridge is | |||
address public childETHToken; | |||
|
|||
/** | |||
* @notice Initilization function for RootERC20Bridge. | |||
* @notice Initialization function for RootERC20Bridge. |
There was a problem hiding this comment.
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"); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments
Co-authored-by: Zoraiz Mahmood <[email protected]>
Co-authored-by: Zoraiz Mahmood <[email protected]>
This adds roles, but does not add some things that roles will be used for, e.g.: