diff --git a/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol b/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol index 3a5ba91d1..fa7aba5fe 100644 --- a/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol +++ b/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol @@ -85,6 +85,14 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { MasterVaultFactory masterVaultFactory; } + struct CreateTokenBridgeArgs { + address inbox; + address rollupOwner; + uint256 maxGasForContracts; + uint256 gasPriceBid; + bool isYieldBearingBridge; + } + // use separate mapping to allow appending to the struct in the future // and workaround some stack too deep issues mapping(address => L1DeploymentAddresses) public inboxToL1Deployment; @@ -193,11 +201,7 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { * fully deployed and initialized before sending tokens to the bridge. Otherwise tokens might be permanently lost. */ function createTokenBridge( - address inbox, - address rollupOwner, - uint256 maxGasForContracts, - uint256 gasPriceBid, - bool isYieldBearingBridge + CreateTokenBridgeArgs calldata args ) external payable { // templates have to be in place if (address(l1Templates.routerTemplate) == address(0)) { @@ -206,10 +210,10 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { // Check that the rollupOwner account has EXECUTOR role // on the upgrade executor which is the owner of the rollup - address upgradeExecutor = IInbox(inbox).bridge().rollup().owner(); + address upgradeExecutor = IInbox(args.inbox).bridge().rollup().owner(); if ( !IAccessControlUpgradeable(upgradeExecutor).hasRole( - UpgradeExecutor(upgradeExecutor).EXECUTOR_ROLE(), rollupOwner + UpgradeExecutor(upgradeExecutor).EXECUTOR_ROLE(), args.rollupOwner ) ) { revert L1AtomicTokenBridgeCreator_RollupOwnershipMisconfig(); @@ -219,9 +223,9 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { // this is useful to recover from expired or out-of-order retryables // in case of resend, we assume L1 contracts already exist and we just need to deploy L2 contracts // deployment mappings should not be updated in case of resend - bool isResend = (inboxToL1Deployment[inbox].router != address(0)); + bool isResend = (inboxToL1Deployment[args.inbox].router != address(0)); - address feeToken = _getFeeToken(inbox); + address feeToken = _getFeeToken(args.inbox); // store L2 addresses before deployments L1DeploymentAddresses memory l1Deployment; @@ -229,12 +233,12 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { // if resend, we use the existing l1 deployment if (isResend) { - l1Deployment = inboxToL1Deployment[inbox]; + l1Deployment = inboxToL1Deployment[args.inbox]; } { // store L2 addresses which are proxies - uint256 chainId = IRollupCore(address(IInbox(inbox).bridge().rollup())).chainId(); + uint256 chainId = IRollupCore(address(IInbox(args.inbox).bridge().rollup())).chainId(); l2Deployment.router = _getProxyAddress(OrbitSalts.L2_ROUTER, chainId); l2Deployment.standardGateway = _getProxyAddress(OrbitSalts.L2_STANDARD_GATEWAY, chainId); l2Deployment.customGateway = _getProxyAddress(OrbitSalts.L2_CUSTOM_GATEWAY, chainId); @@ -252,17 +256,17 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { // deploy L1 side of token bridge // get existing proxy admin and upgrade executor - address proxyAdmin = IInboxProxyAdmin(inbox).getProxyAdmin(); + address proxyAdmin = IInboxProxyAdmin(args.inbox).getProxyAdmin(); if (proxyAdmin == address(0)) { revert L1AtomicTokenBridgeCreator_ProxyAdminNotFound(); } // if resend, we assume L1 contracts already exist if (!isResend) { - if (isYieldBearingBridge) { + if (args.isYieldBearingBridge) { // deploy master vault factory l1Deployment.masterVaultFactory = _deployProxyWithSalt( - _getL1Salt(OrbitSalts.MASTER_VAULT_FACTORY, inbox), + _getL1Salt(OrbitSalts.MASTER_VAULT_FACTORY, args.inbox), address(l1Templates.masterVaultFactory), proxyAdmin ); @@ -274,7 +278,7 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { ? address(l1Templates.feeTokenBasedRouterTemplate) : address(l1Templates.routerTemplate); l1Deployment.router = _deployProxyWithSalt( - _getL1Salt(OrbitSalts.L1_ROUTER, inbox), routerTemplate, proxyAdmin + _getL1Salt(OrbitSalts.L1_ROUTER, args.inbox), routerTemplate, proxyAdmin ); } @@ -286,14 +290,14 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { L1ERC20Gateway standardGateway = L1ERC20Gateway( _deployProxyWithSalt( - _getL1Salt(OrbitSalts.L1_STANDARD_GATEWAY, inbox), template, proxyAdmin + _getL1Salt(OrbitSalts.L1_STANDARD_GATEWAY, args.inbox), template, proxyAdmin ) ); standardGateway.initialize( l2Deployment.standardGateway, l1Deployment.router, - inbox, + args.inbox, keccak256(type(ClonableBeaconProxy).creationCode), l2Deployment.beaconProxyFactory, l1Deployment.masterVaultFactory @@ -310,12 +314,12 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { L1CustomGateway customGateway = L1CustomGateway( _deployProxyWithSalt( - _getL1Salt(OrbitSalts.L1_CUSTOM_GATEWAY, inbox), template, proxyAdmin + _getL1Salt(OrbitSalts.L1_CUSTOM_GATEWAY, args.inbox), template, proxyAdmin ) ); customGateway.initialize( - l2Deployment.customGateway, l1Deployment.router, inbox, upgradeExecutor, l1Deployment.masterVaultFactory + l2Deployment.customGateway, l1Deployment.router, args.inbox, upgradeExecutor, l1Deployment.masterVaultFactory ); l1Deployment.customGateway = address(customGateway); @@ -326,7 +330,7 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { L1WethGateway wethGateway = L1WethGateway( payable( _deployProxyWithSalt( - _getL1Salt(OrbitSalts.L1_WETH_GATEWAY, inbox), + _getL1Salt(OrbitSalts.L1_WETH_GATEWAY, args.inbox), address(l1Templates.wethGatewayTemplate), proxyAdmin ) @@ -334,7 +338,7 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { ); wethGateway.initialize( - l2Deployment.wethGateway, l1Deployment.router, inbox, l1Weth, l2Deployment.weth + l2Deployment.wethGateway, l1Deployment.router, args.inbox, l1Weth, l2Deployment.weth ); l1Deployment.wethGateway = address(wethGateway); @@ -347,30 +351,30 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { l1Deployment.standardGateway, address(0), l2Deployment.router, - inbox + args.inbox ); } // deploy factory and then L2 contracts through L2 factory, using 2 retryables calls // we do not care if it is a resend or not, if the L2 deployment already exists it will simply fail on L2 - _deployL2Factory(inbox, gasPriceBid, feeToken); + _deployL2Factory(args.inbox, args.gasPriceBid, feeToken); RetryableParams memory retryableParams = RetryableParams( - inbox, + args.inbox, canonicalL2FactoryAddress, msg.sender, msg.sender, - maxGasForContracts, - gasPriceBid, + args.maxGasForContracts, + args.gasPriceBid, 0 ); if (feeToken != address(0)) { // transfer fee tokens to inbox to pay for 2nd retryable retryableParams.feeTokenTotalFeeAmount = - _getScaledAmount(feeToken, maxGasForContracts * gasPriceBid); + _getScaledAmount(feeToken, args.maxGasForContracts * args.gasPriceBid); IERC20(feeToken).safeTransferFrom( - msg.sender, inbox, retryableParams.feeTokenTotalFeeAmount + msg.sender, args.inbox, retryableParams.feeTokenTotalFeeAmount ); } @@ -385,9 +389,9 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { ); // alias rollup owner if it is a contract - address l2RollupOwner = rollupOwner.code.length == 0 - ? rollupOwner - : AddressAliasHelper.applyL1ToL2Alias(rollupOwner); + address l2RollupOwner = args.rollupOwner.code.length == 0 + ? args.rollupOwner + : AddressAliasHelper.applyL1ToL2Alias(args.rollupOwner); // sweep the balance to send the retryable and refund the difference // it is known that any eth previously in this contract can be extracted @@ -404,10 +408,10 @@ contract L1AtomicTokenBridgeCreator is Initializable, OwnableUpgradeable { // deployment mappings should not be updated in case of resend if (!isResend) { emit OrbitTokenBridgeCreated( - inbox, rollupOwner, l1Deployment, l2Deployment, proxyAdmin, upgradeExecutor + args.inbox, args.rollupOwner, l1Deployment, l2Deployment, proxyAdmin, upgradeExecutor ); - inboxToL1Deployment[inbox] = l1Deployment; - inboxToL2Deployment[inbox] = l2Deployment; + inboxToL1Deployment[args.inbox] = l1Deployment; + inboxToL2Deployment[args.inbox] = l2Deployment; } }