From 6654bd051f3eb8cb39306f95476ef177bec593a6 Mon Sep 17 00:00:00 2001 From: Christophe Deveaux Date: Thu, 26 Sep 2024 10:31:12 +0200 Subject: [PATCH 1/5] chore: update audit-ci.jsonc (#188) --- audit-ci.jsonc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/audit-ci.jsonc b/audit-ci.jsonc index 6925ec78..68a5b08a 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -65,6 +65,21 @@ // from: @arbitrum/token-bridge-contracts>@openzeppelin/contracts-upgradeable // from: @arbitrum/nitro-contracts>@openzeppelin/contracts // from: @arbitrum/token-bridge-contracts>@openzeppelin/contracts - "GHSA-9vx6-7xxf-x967" + "GHSA-9vx6-7xxf-x967", + // https://github.com/advisories/GHSA-64vr-g452-qvp3 + // Vite DOM Clobbering gadget found in vite bundled scripts that leads to XSS + // vite is not used in production + // from: vitest > vite + "GHSA-64vr-g452-qvp3", + // https://github.com/advisories/GHSA-9cwx-2883-4wfx + // server.fs.deny bypassed when using ?import&raw + // vite is not used in production + // from: vitest > vite + "GHSA-9cwx-2883-4wfx", + // https://github.com/advisories/GHSA-gcx4-mw62-g8wm + // DOM Clobbering Gadget found in rollup bundled scripts that leads to XSS + // vite is not used in production + // from: vitest > vite + "GHSA-gcx4-mw62-g8wm" ] } From 9c9aaa92b2c80e3c89740f02f9c4d569197a473c Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 26 Sep 2024 10:50:22 +0200 Subject: [PATCH 2/5] test: update expected ArbOS version to 32 (#192) --- src/utils/getArbOSVersion.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/getArbOSVersion.unit.test.ts b/src/utils/getArbOSVersion.unit.test.ts index a90aacee..9ccbd324 100644 --- a/src/utils/getArbOSVersion.unit.test.ts +++ b/src/utils/getArbOSVersion.unit.test.ts @@ -10,7 +10,7 @@ it('returns the ArbOS version of Arbitrum One', async () => { transport: http(), }); - expect(await getArbOSVersion(arbitrumOneClient)).toBe(31); + expect(await getArbOSVersion(arbitrumOneClient)).toBe(32); }); it('throws if the chain is not an Arbitrum chain', async () => { From 8cd7791ce2eb3e03ddab387dd7979c841163f0cf Mon Sep 17 00:00:00 2001 From: Christophe Deveaux Date: Thu, 26 Sep 2024 16:33:52 +0200 Subject: [PATCH 3/5] fix: check if token bridge is already deployed (#186) --- src/createTokenBridge.integration.test.ts | 48 +++++++++++++++++ src/createTokenBridge.ts | 63 +++++++++++++++++++++++ src/index.ts | 2 + 3 files changed, 113 insertions(+) diff --git a/src/createTokenBridge.integration.test.ts b/src/createTokenBridge.integration.test.ts index 99e68507..83d870dc 100644 --- a/src/createTokenBridge.integration.test.ts +++ b/src/createTokenBridge.integration.test.ts @@ -436,4 +436,52 @@ describe('createTokenBridge', () => { checkTokenBridgeContracts(tokenBridgeContracts); checkWethGateways(tokenBridgeContracts, { customFeeToken: true }); }); + + it('should throw when createTokenBridge is called multiple times', async () => { + const testnodeInformation = getInformationFromTestnode(); + + const tokenBridgeCreator = await deployTokenBridgeCreator({ + publicClient: nitroTestnodeL1Client, + }); + + const cfg = { + rollupOwner: l2RollupOwner.address, + rollupAddress: testnodeInformation.rollup, + account: l2RollupOwner, + parentChainPublicClient: nitroTestnodeL1Client, + orbitChainPublicClient: nitroTestnodeL2Client, + tokenBridgeCreatorAddressOverride: tokenBridgeCreator, + gasOverrides: { + gasLimit: { + base: 6_000_000n, + }, + }, + retryableGasOverrides: { + maxGasForFactory: { + base: 20_000_000n, + }, + maxGasForContracts: { + base: 20_000_000n, + }, + maxSubmissionCostForFactory: { + base: 4_000_000_000_000n, + }, + maxSubmissionCostForContracts: { + base: 4_000_000_000_000n, + }, + }, + setWethGatewayGasOverrides: { + gasLimit: { + base: 100_000n, + }, + }, + }; + const { tokenBridgeContracts } = await createTokenBridge(cfg); + await expect(createTokenBridge(cfg)).rejects.toThrowError( + `Token bridge contracts for Rollup ${testnodeInformation.rollup} are already deployed`, + ); + + checkTokenBridgeContracts(tokenBridgeContracts); + checkWethGateways(tokenBridgeContracts, { customFeeToken: false }); + }); }); diff --git a/src/createTokenBridge.ts b/src/createTokenBridge.ts index 25cea9ed..0d53e4b0 100644 --- a/src/createTokenBridge.ts +++ b/src/createTokenBridge.ts @@ -34,6 +34,58 @@ import { isCustomFeeTokenAddress } from './utils/isCustomFeeTokenAddress'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; import { TransactionRequestGasOverrides } from './utils/gasOverrides'; import { getBlockExplorerUrl } from './utils/getBlockExplorerUrl'; +import { tokenBridgeCreatorABI } from './contracts/TokenBridgeCreator'; +import { getTokenBridgeCreatorAddress } from './utils'; +import { rollupABI } from './contracts/Rollup'; + +/** + * If token bridge was already deployed, `createTokenBridge` will fail when waiting for retryables. + * This function returns true if token bridge was deployed previously. + * + * @param {String} assertTokenBridgeDoesntExistParams.parentChainPublicClient - The parent chain Viem Public Client + * @param {String} assertTokenBridgeDoesntExistParams.orbitChainPublicClient - The orbit chain Viem Public Client + * @param {String=} assertTokenBridgeDoesntExistParams.tokenBridgeCreatorAddress - The TokenBridgeCreator address. + * Default to getTokenBridgeCreatorAddress(parentChainPublicClient) if not provided + * @param {String} assertTokenBridgeDoesntExistParams.rollupAddress - The address of the rollup on the parent chain + * + * @returns true if token bridge was already deployed + */ +export async function isTokenBridgeDeployed< + TParentChain extends Chain | undefined, + TOrbitChain extends Chain | undefined, +>({ + parentChainPublicClient, + orbitChainPublicClient, + tokenBridgeCreatorAddress, + rollupAddress, +}: { + parentChainPublicClient: PublicClient; + orbitChainPublicClient: PublicClient; + tokenBridgeCreatorAddress?: Address; + rollupAddress: Address; +}) { + const inbox = await parentChainPublicClient.readContract({ + address: rollupAddress, + abi: rollupABI, + functionName: 'inbox', + }); + + const [router] = await parentChainPublicClient.readContract({ + address: tokenBridgeCreatorAddress ?? getTokenBridgeCreatorAddress(parentChainPublicClient), + abi: tokenBridgeCreatorABI, + functionName: 'inboxToL2Deployment', + args: [inbox], + }); + + if (router) { + const code = await orbitChainPublicClient.getBytecode({ address: router }); + if (code) { + return true; + } + } + + return false; +} export type CreateTokenBridgeParams< TParentChain extends Chain | undefined, @@ -171,6 +223,17 @@ export async function createTokenBridge< }: CreateTokenBridgeParams): Promise< CreateTokenBridgeResults > { + const isTokenBridgeAlreadyDeployed = await isTokenBridgeDeployed({ + parentChainPublicClient, + orbitChainPublicClient, + tokenBridgeCreatorAddress: tokenBridgeCreatorAddressOverride, + rollupAddress, + }); + + if (isTokenBridgeAlreadyDeployed) { + throw new Error(`Token bridge contracts for Rollup ${rollupAddress} are already deployed`); + } + const isCustomFeeTokenBridge = isCustomFeeTokenAddress(nativeTokenAddress); if (isCustomFeeTokenBridge) { // set the custom fee token diff --git a/src/index.ts b/src/index.ts index 5cbd3c94..521dd755 100644 --- a/src/index.ts +++ b/src/index.ts @@ -80,6 +80,7 @@ import { CreateTokenBridgeParams, CreateTokenBridgeResults, createTokenBridge, + isTokenBridgeDeployed, } from './createTokenBridge'; import { createTokenBridgeEnoughCustomFeeTokenAllowance, @@ -210,6 +211,7 @@ export { prepareKeyset, utils, // + isTokenBridgeDeployed, CreateTokenBridgeParams, CreateTokenBridgeResults, createTokenBridge, From ac848fa56cb72422fb55243e19827245136e4485 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 27 Sep 2024 10:03:11 +0200 Subject: [PATCH 4/5] feat: allow create rollup callvalue override (#194) --- src/createRollupPrepareTransactionRequest.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/createRollupPrepareTransactionRequest.ts b/src/createRollupPrepareTransactionRequest.ts index fa790d05..8dc3adc2 100644 --- a/src/createRollupPrepareTransactionRequest.ts +++ b/src/createRollupPrepareTransactionRequest.ts @@ -32,6 +32,7 @@ export type CreateRollupPrepareTransactionRequestParams; gasOverrides?: TransactionRequestGasOverrides; }> @@ -40,6 +41,7 @@ export type CreateRollupPrepareTransactionRequestParams({ params, account, + value, publicClient, gasOverrides, rollupCreatorAddressOverride, @@ -81,7 +83,7 @@ export async function createRollupPrepareTransactionRequest Date: Fri, 27 Sep 2024 10:11:05 +0200 Subject: [PATCH 5/5] chore: bump version --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 014cd073..f8b7b611 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "name": "@arbitrum/orbit-sdk", "description": "TypeScript SDK for building Arbitrum Orbit chains", - "version": "0.19.0", + "version": "0.20.0-beta.1", "main": "./dist/index.js", "files": [ "./dist"