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

chore: weth gateway registration script #71

Merged
merged 14 commits into from
Feb 5, 2024
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ cache
coverage
build
_deployments
dist
dist
lib
out
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ build
coverage
deployments
dist
slither.db.json
slither.db.json
lib
out
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
"prettier": "^2.3.2",
"prettier-plugin-solidity": "^1.0.0-beta.17",
"prompts": "^2.4.1",
"sol2uml": "^2.5.4",
"solhint": "^3.2.0",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "v0.7.17",
Expand Down
89 changes: 87 additions & 2 deletions scripts/atomicTokenBridgeDeployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
IBridge__factory,
Multicall2__factory,
IInboxProxyAdmin__factory,
UpgradeExecutor__factory,
} from '../build/types'
import {
abi as UpgradeExecutorABI,
Expand All @@ -41,6 +42,9 @@ 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 { L1ToL2MessageGasParams } from '@arbitrum/sdk/dist/lib/message/L1ToL2MessageCreator'
import { L1ContractCallTransactionReceipt } from '@arbitrum/sdk/dist/lib/message/L1Transaction'

/**
* Dummy non-zero address which is provided to logic contracts initializers
Expand Down Expand Up @@ -203,7 +207,7 @@ export const deployL1TokenBridgeCreator = async (
l1Deployer: Signer,
l1WethAddress: string,
gasLimitForL2FactoryDeployment: BigNumber,
verifyContracts: boolean = false
verifyContracts = false
) => {
/// deploy creator behind proxy
const l2MulticallAddressOnL1Fac = await new ArbMulticall2__factory(
Expand Down Expand Up @@ -555,6 +559,85 @@ export const deployL1TokenBridgeCreator = async (
return { l1TokenBridgeCreator, retryableSender }
}

export const registerGateway = async (
l1Executor: Signer,
l2Provider: ethers.providers.Provider,
upgradeExecutor: string,
gatewayRouter: string,
tokens: string[],
gateways: string[]
) => {
const l2GatewayRouter = await L1GatewayRouter__factory.connect(
gatewayRouter,
l1Executor
).counterpartGateway()
if ((await l2Provider.getCode(l2GatewayRouter)) === '0x') {
throw new Error('L2GatewayRouter not yet deployed')
}
const l1GatewayRouter = await L2GatewayRouter__factory.connect(
l2GatewayRouter,
l2Provider
).counterpartGateway()
if (l1GatewayRouter != gatewayRouter) {
throw new Error('L2GatewayRouter not properly initialized')
}

const executorAddress = await l1Executor.getAddress()

const buildCall = (params: OmitTyped<L1ToL2MessageGasParams, 'deposit'>) => {
const routerCalldata =
L1GatewayRouter__factory.createInterface().encodeFunctionData(
'setGateways',
[
tokens,
gateways,
params.gasLimit,
params.maxFeePerGas,
params.maxSubmissionCost,
]
)
return {
data: UpgradeExecutor__factory.createInterface().encodeFunctionData(
'executeCall',
[gatewayRouter, routerCalldata]
),
from: executorAddress,
value: params.gasLimit
.mul(params.maxFeePerGas)
.add(params.maxSubmissionCost),
to: upgradeExecutor,
}
}

const estimator = new L1ToL2MessageGasEstimator(l2Provider)
const txRequest = await estimator.populateFunctionParams(
buildCall,
l1Executor.provider!
)

const receipt = new L1ContractCallTransactionReceipt(
await (
await l1Executor.sendTransaction({
to: txRequest.to,
data: txRequest.data,
value: txRequest.value,
})
).wait()
)

// wait for execution of ticket
const message = (await receipt.getL1ToL2Messages(l2Provider))[0]
const messageResult = await message.waitForStatus()
if (messageResult.status !== L1ToL2MessageStatus.REDEEMED) {
console.log(
`Retryable ticket (ID ${message.retryableCreationId}) status: ${
L1ToL2MessageStatus[messageResult.status]
}`
)
exit()
}
}

export const getEstimateForDeployingFactory = async (
l1Deployer: Signer,
l2Provider: ethers.providers.Provider
Expand Down Expand Up @@ -612,7 +695,9 @@ const _getFeeToken = async (
bridge,
l1Provider
).nativeToken()
} catch {}
} catch {
// ignore
}

return feeToken
}
Expand Down
48 changes: 39 additions & 9 deletions scripts/local-deployment/deployCreatorAndCreateTokenBridge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ethers } from 'ethers'
import { Wallet, ethers } from 'ethers'
import { JsonRpcProvider } from '@ethersproject/providers'
import { L1Network, L2Network, addCustomNetwork } from '@arbitrum/sdk'
import { Bridge__factory } from '@arbitrum/sdk/dist/lib/abi/factories/Bridge__factory'
Expand All @@ -9,12 +9,15 @@ import {
createTokenBridge,
deployL1TokenBridgeCreator,
getEstimateForDeployingFactory,
registerGateway,
} from '../atomicTokenBridgeDeployer'
import { l2Networks } from '@arbitrum/sdk/dist/lib/dataEntities/networks'
import { IOwnable__factory, TestWETH9__factory } from '../../build/types'

const LOCALHOST_L2_RPC = 'http://localhost:8547'
const LOCALHOST_L3_RPC = 'http://localhost:3347'
const LOCALHOST_L3_OWNER = '0x863c904166E801527125D8672442D736194A3362'
const LOCALHOST_L3_OWNER_KEY =
'0xecdf21cb41c65afb51f91df408b7656e2c8739a5877f2814add0afd780cc210e'

/**
* Steps:
Expand Down Expand Up @@ -51,10 +54,11 @@ export const setupTokenBridgeInLocalEnv = async () => {
}

// set rollup owner either from env vars or use defaults
let rollupOwner = process.env['ROLLUP_OWNER'] as string
if (rollupOwner === undefined) {
rollupOwner = LOCALHOST_L3_OWNER
let rollupOwnerKey = process.env['ROLLUP_OWNER_KEY'] as string
if (rollupOwnerKey === undefined) {
rollupOwnerKey = LOCALHOST_L3_OWNER_KEY
}
const rollupOwnerAddress = ethers.utils.computeAddress(rollupOwnerKey)

// if no ROLLUP_ADDRESS is defined, it will be pulled from local container
const rollupAddress = process.env['ROLLUP_ADDRESS'] as string
Expand Down Expand Up @@ -105,8 +109,17 @@ export const setupTokenBridgeInLocalEnv = async () => {

// prerequisite - deploy L1 creator and set templates
console.log('Deploying L1TokenBridgeCreator')
// a random address for l1Weth
const l1Weth = '0x05EcEffc7CBA4e43a410340E849052AD43815aCA'

let l1Weth = process.env['PARENT_WETH_OVERRIDE']
if (l1Weth === undefined || l1Weth === '') {
const l1WethContract = await new TestWETH9__factory(parentDeployer).deploy(
'WETH',
'WETH'
)
await l1WethContract.deployed()

l1Weth = l1WethContract.address
}

//// run retryable estimate for deploying L2 factory
const deployFactoryGasParams = await getEstimateForDeployingFactory(
Expand Down Expand Up @@ -135,8 +148,25 @@ export const setupTokenBridgeInLocalEnv = async () => {
childDeployer.provider!,
l1TokenBridgeCreator,
coreL2Network.ethBridge.rollup,
rollupOwner
rollupOwnerAddress
)

// register weth gateway if it exists
if (l1Deployment.wethGateway !== ethers.constants.AddressZero) {
const upExecAddress = await IOwnable__factory.connect(
coreL2Network.ethBridge.rollup,
parentDeployer
).owner()

await registerGateway(
new Wallet(rollupOwnerKey, parentDeployer.provider!),
childDeployer.provider!,
upExecAddress,
l1Deployment.router,
[l1Weth],
[l1Deployment.wethGateway]
)
}

const l2Network: L2Network = {
...coreL2Network,
Expand Down Expand Up @@ -190,7 +220,7 @@ export const getLocalNetworks = async (
}

if (rollupAddress === undefined) {
let sequencerContainer = execSync(
const sequencerContainer = execSync(
'docker ps --filter "name=l3node" --format "{{.Names}}"'
)
.toString()
Expand Down
Loading
Loading