diff --git a/scripts/atomicTokenBridgeDeployer.ts b/scripts/atomicTokenBridgeDeployer.ts index 47a375ac2..577578200 100644 --- a/scripts/atomicTokenBridgeDeployer.ts +++ b/scripts/atomicTokenBridgeDeployer.ts @@ -1,50 +1,49 @@ +import { + ParentContractCallTransactionReceipt, + ParentToChildMessageGasEstimator, + ParentToChildMessageStatus, + ParentTransactionReceipt, +} from '@arbitrum/sdk' +import { RollupAdminLogic__factory } from '@arbitrum/sdk/dist/lib/abi/factories/RollupAdminLogic__factory' +import { ParentToChildMessageGasParams } from '@arbitrum/sdk/dist/lib/message/ParentToChildMessageCreator' +import { getBaseFee } from '@arbitrum/sdk/dist/lib/utils/lib' +import { OmitTyped } from '@arbitrum/sdk/dist/lib/utils/types' +import { JsonRpcProvider } from '@ethersproject/providers' +import { + abi as UpgradeExecutorABI, + bytecode as UpgradeExecutorBytecode, +} from '@offchainlabs/upgrade-executor/build/contracts/src/UpgradeExecutor.sol/UpgradeExecutor.json' import { BigNumber, Signer, Wallet, ethers } from 'ethers' +import { exit } from 'process' import { + AeWETH__factory, + ArbMulticall2__factory, + IERC20Bridge__factory, + IERC20__factory, + IInboxProxyAdmin__factory, + IInbox__factory, + L1AtomicTokenBridgeCreator, + L1AtomicTokenBridgeCreator__factory, L1CustomGateway__factory, L1ERC20Gateway__factory, L1GatewayRouter__factory, - L1AtomicTokenBridgeCreator__factory, + L1OrbitCustomGateway__factory, + L1OrbitERC20Gateway__factory, + L1OrbitGatewayRouter__factory, + L1TokenBridgeRetryableSender__factory, + L1WethGateway__factory, L2AtomicTokenBridgeFactory__factory, - L2GatewayRouter__factory, - L2ERC20Gateway__factory, L2CustomGateway__factory, - L1AtomicTokenBridgeCreator, + L2ERC20Gateway__factory, + L2GatewayRouter__factory, L2WethGateway__factory, - AeWETH__factory, - L1WethGateway__factory, - TransparentUpgradeableProxy__factory, - ProxyAdmin__factory, - L1TokenBridgeRetryableSender__factory, - L1OrbitERC20Gateway__factory, - L1OrbitCustomGateway__factory, - L1OrbitGatewayRouter__factory, - IInbox__factory, - IERC20Bridge__factory, - IERC20__factory, - ArbMulticall2__factory, Multicall2__factory, - IInboxProxyAdmin__factory, - ERC20__factory, + ProxyAdmin__factory, + TransparentUpgradeableProxy__factory, UpgradeExecutor__factory, } from '../build/types' -import { - abi as UpgradeExecutorABI, - bytecode as UpgradeExecutorBytecode, -} from '@offchainlabs/upgrade-executor/build/contracts/src/UpgradeExecutor.sol/UpgradeExecutor.json' -import { JsonRpcProvider } from '@ethersproject/providers' -import { - ParentToChildMessageGasEstimator, - ParentToChildMessageStatus, - ParentTransactionReceipt, - ParentContractCallTransactionReceipt -} from '@arbitrum/sdk' -import { exit } from 'process' -import { getBaseFee } from '@arbitrum/sdk/dist/lib/utils/lib' -import { RollupAdminLogic__factory } from '@arbitrum/sdk/dist/lib/abi/factories/RollupAdminLogic__factory' import { ContractVerifier } from './contractVerifier' -import { OmitTyped } from '@arbitrum/sdk/dist/lib/utils/types' import { _getScaledAmount } from './local-deployment/localDeploymentLib' -import { ParentToChildMessageGasParams } from '@arbitrum/sdk/dist/lib/message/ParentToChildMessageCreator' /** * Dummy non-zero address which is provided to logic contracts initializers @@ -113,10 +112,10 @@ export const createTokenBridge = async ( const maxSubmissionCostForContracts = deployFactoryGasParams.maxSubmissionCost.mul(2) - let retryableFeeForFactory = maxSubmissionCostForFactory.add( + const retryableFeeForFactory = maxSubmissionCostForFactory.add( maxGasForFactory.mul(gasPrice) ) - let retryableFeeForContracts = maxSubmissionCostForContracts.add( + const retryableFeeForContracts = maxSubmissionCostForContracts.add( maxGasForContracts.mul(gasPrice) ) @@ -130,12 +129,12 @@ export const createTokenBridge = async ( const feeToken = await _getFeeToken(inbox, l1Signer.provider!) if (feeToken != ethers.constants.AddressZero) { // scale the retryable fees to the fee token decimals denomination - let scaledRetryableFeeForFactory = await _getScaledAmount( + const scaledRetryableFeeForFactory = await _getScaledAmount( feeToken, retryableFeeForFactory, l1Signer.provider! ) - let scaledRetryableFeeForContracts = await _getScaledAmount( + const scaledRetryableFeeForContracts = await _getScaledAmount( feeToken, retryableFeeForContracts, l1Signer.provider! @@ -214,6 +213,10 @@ export const createTokenBridge = async ( return { l1Deployment, l2Deployment, l1MultiCall, l1ProxyAdmin } } +function sleepFor5() { + return new Promise(resolve => setTimeout(resolve, 5000)) +} + /** * Deploy token bridge creator contract to base chain and set all the templates * @param l1Deployer @@ -232,15 +235,33 @@ export const deployL1TokenBridgeCreator = async ( l1Deployer ).deploy() const l2MulticallAddressOnL1 = await l2MulticallAddressOnL1Fac.deployed() + console.log( + 'L2MulticallAddressOnL1 deployed at:', + l2MulticallAddressOnL1.address + ) + + await sleepFor5() const l1TokenBridgeCreatorProxyAdmin = await new ProxyAdmin__factory( l1Deployer ).deploy() await l1TokenBridgeCreatorProxyAdmin.deployed() + console.log( + 'L1TokenBridgeCreatorProxyAdmin deployed at:', + l1TokenBridgeCreatorProxyAdmin.address + ) + + await sleepFor5() const l1TokenBridgeCreatorLogic = await new L1AtomicTokenBridgeCreator__factory(l1Deployer).deploy() await l1TokenBridgeCreatorLogic.deployed() + console.log( + 'L1TokenBridgeCreatorLogic deployed at:', + l1TokenBridgeCreatorLogic.address + ) + + await sleepFor5() const l1TokenBridgeCreatorProxy = await new TransparentUpgradeableProxy__factory(l1Deployer).deploy( @@ -249,6 +270,11 @@ export const deployL1TokenBridgeCreator = async ( '0x' ) await l1TokenBridgeCreatorProxy.deployed() + console.log( + 'L1TokenBridgeCreatorProxy deployed at:', + l1TokenBridgeCreatorProxy.address + ) + await sleepFor5() const l1TokenBridgeCreator = L1AtomicTokenBridgeCreator__factory.connect( l1TokenBridgeCreatorProxy.address, @@ -260,6 +286,9 @@ export const deployL1TokenBridgeCreator = async ( l1Deployer ).deploy() await retryableSenderLogic.deployed() + console.log('RetryableSenderLogic deployed at:', retryableSenderLogic.address) + + await sleepFor5() const retryableSenderProxy = await new TransparentUpgradeableProxy__factory( l1Deployer @@ -269,6 +298,9 @@ export const deployL1TokenBridgeCreator = async ( '0x' ) await retryableSenderProxy.deployed() + console.log('RetryableSenderProxy deployed at:', retryableSenderProxy.address) + + await sleepFor5() const retryableSender = L1TokenBridgeRetryableSender__factory.connect( retryableSenderProxy.address, @@ -278,26 +310,59 @@ export const deployL1TokenBridgeCreator = async ( // initialize retryable sender logic contract await (await retryableSenderLogic.initialize()).wait() + await sleepFor5() + /// init creator await (await l1TokenBridgeCreator.initialize(retryableSender.address)).wait() + await sleepFor5() + /// deploy L1 logic contracts. Initialize them with dummy data const routerTemplate = await new L1GatewayRouter__factory(l1Deployer).deploy() await routerTemplate.deployed() - await ( - await routerTemplate.initialize( + console.log('RouterTemplate deployed at:', routerTemplate.address) + + await sleepFor5() + + // Verify router template has code + const routerCode = await l1Deployer.provider!.getCode(routerTemplate.address) + console.log('Router template code length:', routerCode.length) + if (routerCode === '0x' || routerCode.length < 10) { + throw new Error(`RouterTemplate at ${routerTemplate.address} has no code`) + } + + try { + const initTx = await routerTemplate.initialize( ADDRESS_DEAD, ADDRESS_DEAD, ADDRESS_DEAD, ADDRESS_DEAD, ADDRESS_DEAD ) - ).wait() + console.log('Router initialize TX hash:', initTx.hash) + const initReceipt = await initTx.wait() + console.log( + 'RouterTemplate initialized, gas used:', + initReceipt.gasUsed.toString() + ) + await sleepFor5() + } catch (error: any) { + console.error('RouterTemplate initialization failed:', error.message) + console.error('Error details:', JSON.stringify(error, null, 2)) + throw error + } const standardGatewayTemplate = await new L1ERC20Gateway__factory( l1Deployer ).deploy() await standardGatewayTemplate.deployed() + console.log( + 'StandardGatewayTemplate deployed at:', + standardGatewayTemplate.address + ) + + await sleepFor5() + await ( await standardGatewayTemplate.initialize( ADDRESS_DEAD, @@ -307,11 +372,21 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('StandardGatewayTemplate initialized') + + await sleepFor5() const customGatewayTemplate = await new L1CustomGateway__factory( l1Deployer ).deploy() await customGatewayTemplate.deployed() + console.log( + 'CustomGatewayTemplate deployed at:', + customGatewayTemplate.address + ) + + await sleepFor5() + await ( await customGatewayTemplate.initialize( ADDRESS_DEAD, @@ -320,11 +395,16 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('CustomGatewayTemplate initialized') const wethGatewayTemplate = await new L1WethGateway__factory( l1Deployer ).deploy() await wethGatewayTemplate.deployed() + console.log('WethGatewayTemplate deployed at:', wethGatewayTemplate.address) + + await sleepFor5() + await ( await wethGatewayTemplate.initialize( ADDRESS_DEAD, @@ -334,11 +414,21 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('WethGatewayTemplate initialized') + + await sleepFor5() const feeTokenBasedRouterTemplate = await new L1OrbitGatewayRouter__factory( l1Deployer ).deploy() await feeTokenBasedRouterTemplate.deployed() + console.log( + 'FeeTokenBasedRouterTemplate deployed at:', + feeTokenBasedRouterTemplate.address + ) + + await sleepFor5() + await ( await feeTokenBasedRouterTemplate.initialize( ADDRESS_DEAD, @@ -348,10 +438,20 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('FeeTokenBasedRouterTemplate initialized') + + await sleepFor5() const feeTokenBasedStandardGatewayTemplate = await new L1OrbitERC20Gateway__factory(l1Deployer).deploy() await feeTokenBasedStandardGatewayTemplate.deployed() + console.log( + 'FeeTokenBasedStandardGatewayTemplate deployed at:', + feeTokenBasedStandardGatewayTemplate.address + ) + + await sleepFor5() + await ( await feeTokenBasedStandardGatewayTemplate.initialize( ADDRESS_DEAD, @@ -361,10 +461,20 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('FeeTokenBasedStandardGatewayTemplate initialized') + + await sleepFor5() const feeTokenBasedCustomGatewayTemplate = await new L1OrbitCustomGateway__factory(l1Deployer).deploy() await feeTokenBasedCustomGatewayTemplate.deployed() + console.log( + 'FeeTokenBasedCustomGatewayTemplate deployed at:', + feeTokenBasedCustomGatewayTemplate.address + ) + + await sleepFor5() + await ( await feeTokenBasedCustomGatewayTemplate.initialize( ADDRESS_DEAD, @@ -373,6 +483,9 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('FeeTokenBasedCustomGatewayTemplate initialized') + + await sleepFor5() const upgradeExecutorFactory = new ethers.ContractFactory( UpgradeExecutorABI, @@ -381,6 +494,9 @@ export const deployL1TokenBridgeCreator = async ( ) const upgradeExecutor = await upgradeExecutorFactory.deploy() await upgradeExecutor.deployed() + console.log('UpgradeExecutor deployed at:', upgradeExecutor.address) + + await sleepFor5() const l1Templates = { routerTemplate: routerTemplate.address, @@ -394,24 +510,45 @@ export const deployL1TokenBridgeCreator = async ( feeTokenBasedCustomGatewayTemplate.address, upgradeExecutor: upgradeExecutor.address, } + console.log('L1Templates:', l1Templates) /// deploy L2 contracts as placeholders on L1. Initialize them with dummy data const l2TokenBridgeFactoryOnL1 = await new L2AtomicTokenBridgeFactory__factory(l1Deployer).deploy() await l2TokenBridgeFactoryOnL1.deployed() + console.log( + 'L2TokenBridgeFactoryOnL1 deployed at:', + l2TokenBridgeFactoryOnL1.address + ) + + await sleepFor5() const l2GatewayRouterOnL1 = await new L2GatewayRouter__factory( l1Deployer ).deploy() await l2GatewayRouterOnL1.deployed() + console.log('L2GatewayRouterOnL1 deployed at:', l2GatewayRouterOnL1.address) + + await sleepFor5() + await ( await l2GatewayRouterOnL1.initialize(ADDRESS_DEAD, ADDRESS_DEAD) ).wait() + console.log('L2GatewayRouterOnL1 initialized') + + await sleepFor5() const l2StandardGatewayAddressOnL1 = await new L2ERC20Gateway__factory( l1Deployer ).deploy() await l2StandardGatewayAddressOnL1.deployed() + console.log( + 'L2StandardGatewayAddressOnL1 deployed at:', + l2StandardGatewayAddressOnL1.address + ) + + await sleepFor5() + await ( await l2StandardGatewayAddressOnL1.initialize( ADDRESS_DEAD, @@ -419,19 +556,39 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('L2StandardGatewayAddressOnL1 initialized') + + await sleepFor5() const l2CustomGatewayAddressOnL1 = await new L2CustomGateway__factory( l1Deployer ).deploy() await l2CustomGatewayAddressOnL1.deployed() + console.log( + 'L2CustomGatewayAddressOnL1 deployed at:', + l2CustomGatewayAddressOnL1.address + ) + + await sleepFor5() + await ( await l2CustomGatewayAddressOnL1.initialize(ADDRESS_DEAD, ADDRESS_DEAD) ).wait() + console.log('L2CustomGatewayAddressOnL1 initialized') + + await sleepFor5() const l2WethGatewayAddressOnL1 = await new L2WethGateway__factory( l1Deployer ).deploy() await l2WethGatewayAddressOnL1.deployed() + console.log( + 'L2WethGatewayAddressOnL1 deployed at:', + l2WethGatewayAddressOnL1.address + ) + + await sleepFor5() + await ( await l2WethGatewayAddressOnL1.initialize( ADDRESS_DEAD, @@ -440,12 +597,21 @@ export const deployL1TokenBridgeCreator = async ( ADDRESS_DEAD ) ).wait() + console.log('L2WethGatewayAddressOnL1 initialized') + + await sleepFor5() const l2WethAddressOnL1 = await new AeWETH__factory(l1Deployer).deploy() await l2WethAddressOnL1.deployed() + console.log('L2WethAddressOnL1 deployed at:', l2WethAddressOnL1.address) + + await sleepFor5() const l1Multicall = await new Multicall2__factory(l1Deployer).deploy() await l1Multicall.deployed() + console.log('L1Multicall deployed at:', l1Multicall.address) + + await sleepFor5() await ( await l1TokenBridgeCreator.setTemplates( @@ -462,6 +628,9 @@ export const deployL1TokenBridgeCreator = async ( gasLimitForL2FactoryDeployment ) ).wait() + console.log('L1TokenBridgeCreator setTemplates') + + await sleepFor5() ///// verify contracts if (verifyContracts) { @@ -603,7 +772,9 @@ export const registerGateway = async ( const executorAddress = await l1Executor.getAddress() - const buildCall = (params: OmitTyped) => { + const buildCall = ( + params: OmitTyped + ) => { const routerCalldata = L1GatewayRouter__factory.createInterface().encodeFunctionData( 'setGateways',