From 5710ca2970746184a5dda3929c254fdee049ea83 Mon Sep 17 00:00:00 2001 From: Doug Lance Date: Thu, 19 Oct 2023 10:19:27 -0400 Subject: [PATCH 01/74] chore: rename L1 and L2 to parent and child chain in inbox (#339) --- scripts/sendL2SignedMsg.ts | 4 +- src/lib/inbox/inbox.ts | 146 +++++++++++++++------------- tests/integration/sendL2msg.test.ts | 4 +- 3 files changed, 82 insertions(+), 72 deletions(-) diff --git a/scripts/sendL2SignedMsg.ts b/scripts/sendL2SignedMsg.ts index 10ac03e9e7..d117247518 100644 --- a/scripts/sendL2SignedMsg.ts +++ b/scripts/sendL2SignedMsg.ts @@ -29,8 +29,8 @@ const sendSignedMsg = async () => { value: BigNumber.from(0), data: '0x12', } - const signedTx = await inbox.signL2Tx(message, l2Deployer) - await inbox.sendL2SignedTx(signedTx) + const signedTx = await inbox.signChildChainTx(message, l2Deployer) + await inbox.sendChildChainSignedTx(signedTx) } sendSignedMsg() diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index 240bfb61b6..5f2759164c 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -28,7 +28,10 @@ import { SequencerInbox__factory } from '../abi/factories/SequencerInbox__factor import { IInbox__factory } from '../abi/factories/IInbox__factory' import { RequiredPick } from '../utils/types' import { MessageDeliveredEvent } from '../abi/Bridge' -import { l1Networks, L2Network } from '../dataEntities/networks' +import { + l1Networks as parentChains, + L2Network as ChildChain, +} from '../dataEntities/networks' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { FetchedEvent, EventFetcher } from '../utils/eventFetcher' import { MultiCaller, CallInput } from '../utils/multicall' @@ -42,12 +45,12 @@ type ForceInclusionParams = FetchedEvent & { delayedAcc: string } -type GasComponentsWithL2Part = { +type GasComponentsWithChildChainPart = { gasEstimate: BigNumber gasEstimateForL1: BigNumber baseFee: BigNumber l1BaseFeeEstimate: BigNumber - gasEstimateForL2: BigNumber + gasEstimateForChildChain: BigNumber } type RequiredTransactionRequestType = RequiredPick< TransactionRequest, @@ -57,18 +60,20 @@ type RequiredTransactionRequestType = RequiredPick< * Tools for interacting with the inbox and bridge contracts */ export class InboxTools { - private readonly l1Provider - private readonly l1Network + private readonly parentChainProvider + private readonly parentChain constructor( - private readonly l1Signer: Signer, - private readonly l2Network: L2Network + private readonly parentChainSigner: Signer, + private readonly childChain: ChildChain ) { - this.l1Provider = SignerProviderUtils.getProviderOrThrow(this.l1Signer) - this.l1Network = l1Networks[l2Network.partnerChainID] - if (!this.l1Network) + this.parentChainProvider = SignerProviderUtils.getProviderOrThrow( + this.parentChainSigner + ) + this.parentChain = parentChains[childChain.partnerChainID] + if (!this.parentChain) throw new ArbSdkError( - `L1Network not found for chain id: ${l2Network.partnerChainID}.` + `ParentChainNetwork not found for chain id: ${childChain.partnerChainID}.` ) } @@ -84,13 +89,16 @@ export class InboxTools { blockNumber: number, blockTimestamp: number ): Promise { - const block = await this.l1Provider.getBlock(blockNumber) + const block = await this.parentChainProvider.getBlock(blockNumber) const diff = block.timestamp - blockTimestamp if (diff < 0) return block // we take a long average block time of 14s // and always move at least 10 blocks - const diffBlocks = Math.max(Math.ceil(diff / this.l1Network.blockTime), 10) + const diffBlocks = Math.max( + Math.ceil(diff / this.parentChain.blockTime), + 10 + ) return await this.findFirstBlockBelow( blockNumber - diffBlocks, @@ -98,14 +106,14 @@ export class InboxTools { ) } - //Check if this request is contract creation or not. + // Check if this request is contract creation or not. private isContractCreation( - transactionl2Request: TransactionRequest + childChainTransactionRequest: TransactionRequest ): boolean { if ( - transactionl2Request.to === '0x' || - !isDefined(transactionl2Request.to) || - transactionl2Request.to === ethers.constants.AddressZero + childChainTransactionRequest.to === '0x' || + !isDefined(childChainTransactionRequest.to) || + childChainTransactionRequest.to === ethers.constants.AddressZero ) { return true } @@ -114,32 +122,34 @@ export class InboxTools { /** * We should use nodeInterface to get the gas estimate is because we - * are making a delayed inbox message which doesn't need l1 calldata + * are making a delayed inbox message which doesn't need parentChain calldata * gas fee part. */ private async estimateArbitrumGas( - transactionl2Request: RequiredTransactionRequestType, - l2Provider: Provider - ): Promise { + childChainTransactionRequest: RequiredTransactionRequestType, + childChainProvider: Provider + ): Promise { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childChainProvider ) - const contractCreation = this.isContractCreation(transactionl2Request) + const contractCreation = this.isContractCreation( + childChainTransactionRequest + ) const gasComponents = await nodeInterface.callStatic.gasEstimateComponents( - transactionl2Request.to || ethers.constants.AddressZero, + childChainTransactionRequest.to || ethers.constants.AddressZero, contractCreation, - transactionl2Request.data, + childChainTransactionRequest.data, { - from: transactionl2Request.from, - value: transactionl2Request.value, + from: childChainTransactionRequest.from, + value: childChainTransactionRequest.value, } ) - const gasEstimateForL2: BigNumber = gasComponents.gasEstimate.sub( + const gasEstimateForChildChain: BigNumber = gasComponents.gasEstimate.sub( gasComponents.gasEstimateForL1 ) - return { ...gasComponents, gasEstimateForL2 } + return { ...gasComponents, gasEstimateForChildChain } } /** @@ -149,11 +159,11 @@ export class InboxTools { */ private async getForceIncludableBlockRange(blockNumberRangeSize: number) { const sequencerInbox = SequencerInbox__factory.connect( - this.l2Network.ethBridge.sequencerInbox, - this.l1Provider + this.childChain.ethBridge.sequencerInbox, + this.parentChainProvider ) - const multicall = await MultiCaller.fromProvider(this.l1Provider) + const multicall = await MultiCaller.fromProvider(this.parentChainProvider) const multicallInput: [ CallInput>>, ReturnType, @@ -207,7 +217,7 @@ export class InboxTools { maxSearchRangeBlocks: number, rangeMultiplier: number ): Promise[]> { - const eFetcher = new EventFetcher(this.l1Provider) + const eFetcher = new EventFetcher(this.parentChainProvider) // events don't become eligible until they pass a delay // find a block range which will emit eligible events @@ -245,7 +255,7 @@ export class InboxTools { /** * Find the event of the latest message that can be force include * @param maxSearchRangeBlocks The max range of blocks to search in. - * Defaults to 3 * 6545 ( = ~3 days) prior to the first eligble block + * Defaults to 3 * 6545 ( = ~3 days) prior to the first eligible block * @param startSearchRangeBlocks The start range of block to search in. * Moves incrementally up to the maxSearchRangeBlocks. Defaults to 100; * @param rangeMultiplier The multiplier to use when increasing the block range @@ -255,11 +265,11 @@ export class InboxTools { public async getForceIncludableEvent( maxSearchRangeBlocks: number = 3 * 6545, startSearchRangeBlocks = 100, - rangeMultipler = 2 + rangeMultiplier = 2 ): Promise { const bridge = Bridge__factory.connect( - this.l2Network.ethBridge.bridge, - this.l1Provider + this.childChain.ethBridge.bridge, + this.parentChainProvider ) // events dont become eligible until they pass a delay @@ -268,7 +278,7 @@ export class InboxTools { bridge, startSearchRangeBlocks, maxSearchRangeBlocks, - rangeMultipler + rangeMultiplier ) // no events appeared within that time period @@ -277,8 +287,8 @@ export class InboxTools { // take the last event - as including this one will include all previous events const eventInfo = events[events.length - 1] const sequencerInbox = SequencerInbox__factory.connect( - this.l2Network.ethBridge.sequencerInbox, - this.l1Provider + this.childChain.ethBridge.sequencerInbox, + this.parentChainProvider ) // has the sequencer inbox already read this latest message const totalDelayedRead = await sequencerInbox.totalDelayedMessagesRead() @@ -296,7 +306,7 @@ export class InboxTools { /** * Force includes all eligible messages in the delayed inbox. - * The inbox contract doesnt allow a message to be force-included + * The inbox contract doesn't allow a message to be force-included * until after a delay period has been completed. * @param messageDeliveredEvent Provide this to include all messages up to this one. Responsibility is on the caller to check the eligibility of this event. * @returns The force include transaction, or null if no eligible message were found for inclusion @@ -317,14 +327,14 @@ export class InboxTools { overrides?: Overrides ): Promise { const sequencerInbox = SequencerInbox__factory.connect( - this.l2Network.ethBridge.sequencerInbox, - this.l1Signer + this.childChain.ethBridge.sequencerInbox, + this.parentChainSigner ) const eventInfo = messageDeliveredEvent || (await this.getForceIncludableEvent()) if (!eventInfo) return null - const block = await this.l1Provider.getBlock(eventInfo.blockHash) + const block = await this.parentChainProvider.getBlock(eventInfo.blockHash) return await sequencerInbox.functions.forceInclusion( eventInfo.event.messageIndex.add(1), @@ -339,19 +349,19 @@ export class InboxTools { } /** - * Send l2 signed tx using delayed inox, which won't alias the sender's adddress - * It will be automatically included by the sequencer on l2, if it isn't included + * Send Child Chain signed tx using delayed inbox, which won't alias the sender's address + * It will be automatically included by the sequencer on Chain, if it isn't included * within 24 hours, you can force include it - * @param signedTx A signed transaction which can be sent directly to network, - * you can call inboxTools.signL2Message to get. - * @returns The l1 delayed inbox's transaction itself. + * @param signedTx A signed transaction which can be sent directly to chain, + * you can call inboxTools.signChainMessage to get. + * @returns The parentChain delayed inbox's transaction itself. */ - public async sendL2SignedTx( + public async sendChildChainSignedTx( signedTx: string ): Promise { const delayedInbox = IInbox__factory.connect( - this.l2Network.ethBridge.inbox, - this.l1Signer + this.childChain.ethBridge.inbox, + this.parentChainSigner ) const sendData = ethers.utils.solidityPack( @@ -364,43 +374,43 @@ export class InboxTools { /** * Sign a transaction with msg.to, msg.value and msg.data. - * You can use this as a helper to call inboxTools.sendL2SignedMessage + * You can use this as a helper to call inboxTools.sendChainSignedMessage * above. - * @param message A signed transaction which can be sent directly to network, + * @param message A signed transaction which can be sent directly to chain, * tx.to, tx.data, tx.value must be provided when not contract creation, if * contractCreation is true, no need provide tx.to. tx.gasPrice and tx.nonce * can be overrided. (You can also send contract creation transaction by set tx.to * to zero address or null) - * @param l2Signer ethers Signer type, used to sign l2 transaction - * @returns The l1 delayed inbox's transaction signed data. + * @param childChainSigner ethers Signer type, used to sign Chain transaction + * @returns The parentChain delayed inbox's transaction signed data. */ - public async signL2Tx( + public async signChildChainTx( txRequest: RequiredTransactionRequestType, - l2Signer: Signer + childChainSigner: Signer ): Promise { const tx: RequiredTransactionRequestType = { ...txRequest } const contractCreation = this.isContractCreation(tx) if (!isDefined(tx.nonce)) { - tx.nonce = await l2Signer.getTransactionCount() + tx.nonce = await childChainSigner.getTransactionCount() } //check transaction type (if no transaction type or gasPrice provided, use eip1559 type) if (tx.type === 1 || tx.gasPrice) { if (tx.gasPrice) { - tx.gasPrice = await l2Signer.getGasPrice() + tx.gasPrice = await childChainSigner.getGasPrice() } } else { if (!isDefined(tx.maxFeePerGas)) { - const feeData = await l2Signer.getFeeData() + const feeData = await childChainSigner.getFeeData() tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas! tx.maxFeePerGas = feeData.maxFeePerGas! } tx.type = 2 } - tx.from = await l2Signer.getAddress() - tx.chainId = await l2Signer.getChainId() + tx.from = await childChainSigner.getAddress() + tx.chainId = await childChainSigner.getChainId() // if this is contract creation, user might not input the to address, // however, it is needed when we call to estimateArbitrumGas, so @@ -409,17 +419,17 @@ export class InboxTools { tx.to = ethers.constants.AddressZero } - //estimate gas on l2 + //estimate gas on child chain try { tx.gasLimit = ( - await this.estimateArbitrumGas(tx, l2Signer.provider!) - ).gasEstimateForL2 + await this.estimateArbitrumGas(tx, childChainSigner.provider!) + ).gasEstimateForChildChain } catch (error) { throw new ArbSdkError('execution failed (estimate gas failed)') } if (contractCreation) { delete tx.to } - return await l2Signer.signTransaction(tx) + return await childChainSigner.signTransaction(tx) } } diff --git a/tests/integration/sendL2msg.test.ts b/tests/integration/sendL2msg.test.ts index e704ab0faa..e9bcdd97ae 100644 --- a/tests/integration/sendL2msg.test.ts +++ b/tests/integration/sendL2msg.test.ts @@ -33,9 +33,9 @@ const sendSignedTx = async (testState: any, info?: any) => { ...info, value: BigNumber.from(0), } - const signedTx = await inbox.signL2Tx(message, l2Deployer) + const signedTx = await inbox.signChildChainTx(message, l2Deployer) - const l1Tx = await inbox.sendL2SignedTx(signedTx) + const l1Tx = await inbox.sendChildChainSignedTx(signedTx) return { signedMsg: signedTx, l1TransactionReceipt: await l1Tx?.wait(), From 09a6eb0ae4e717212f3b60b85b8292fbcd5c2b8a Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 2 Nov 2023 11:44:00 -0400 Subject: [PATCH 02/74] chore: update l1/2 name for dataEntities (#340) * chore: renames L1/2 to parentChain/chain in inbox * update to use new childChain name with ArbitrumChain type * updates name of methods on inbox to use childChain * Update childChainTransactionRequest * remove `network` * update names with from pr feedback * chore: update l1/2 name for dataEntities * removes network * fix child renaming * fix getChildChain * fix integration test * renames partner to parent/child --- scripts/instantiate_bridge.ts | 6 +- scripts/testSetup.ts | 20 +-- src/index.ts | 12 +- src/lib/assetBridger/assetBridger.ts | 10 +- src/lib/assetBridger/erc20Bridger.ts | 5 +- src/lib/assetBridger/ethBridger.ts | 2 +- src/lib/dataEntities/networks.ts | 123 ++++++++++--------- src/lib/inbox/inbox.ts | 9 +- src/lib/message/L1ToL2Message.ts | 2 +- src/lib/message/L1ToL2MessageCreator.ts | 2 +- src/lib/message/L1ToL2MessageGasEstimator.ts | 2 +- src/lib/message/L1Transaction.ts | 2 +- src/lib/message/L2ToL1Message.ts | 2 +- src/lib/message/L2ToL1MessageClassic.ts | 2 +- src/lib/message/L2ToL1MessageNitro.ts | 2 +- src/lib/utils/lib.ts | 4 +- src/lib/utils/multicall.ts | 14 +-- tests/fork/inbox.test.ts | 5 +- tests/integration/ethBridgeAddresses.test.ts | 2 +- tests/integration/sendL2msg.test.ts | 5 +- tests/integration/testHelpers.ts | 2 +- tests/unit/l2toL1MessageEvents.test.ts | 2 +- tests/unit/multicall.test.ts | 2 +- 23 files changed, 124 insertions(+), 113 deletions(-) diff --git a/scripts/instantiate_bridge.ts b/scripts/instantiate_bridge.ts index 7d5887ef61..1c8b91ecf4 100644 --- a/scripts/instantiate_bridge.ts +++ b/scripts/instantiate_bridge.ts @@ -78,12 +78,10 @@ export const instantiateBridge = ( } const l2Network = l2Networks[l2NetworkID] - const l1Network = l1Networks[l2Network.partnerChainID] + const l1Network = l1Networks[l2Network.parentChainId] if (!l1Network) { - throw new Error( - `Unrecognised partner chain id: ${l2Network.partnerChainID}` - ) + throw new Error(`Unrecognised parent chain id: ${l2Network.parentChainId}`) } const l1Rpc = (() => { diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 5558054297..e53b06d0c4 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -22,10 +22,10 @@ import { Wallet } from '@ethersproject/wallet' import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { - L1Network, - L2Network, - getL1Network, - getL2Network, + ParentChain as L1Network, + ChildChain as L2Network, + getParentChain as getL1Network, + getChildChain as getL2Network, addCustomNetwork, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' @@ -104,7 +104,7 @@ export const getCustomNetworks = async ( explorerUrl: '', isCustom: true, name: 'EthLocal', - partnerChainIDs: [l2NetworkInfo.chainId], + childChainIds: [l2NetworkInfo.chainId], isArbitrum: false, } @@ -122,7 +122,7 @@ export const getCustomNetworks = async ( isArbitrum: true, isCustom: true, name: 'ArbLocal', - partnerChainID: l1NetworkInfo.chainId, + parentChainId: l1NetworkInfo.chainId, retryableLifetimeSeconds: 7 * 24 * 60 * 60, nitroGenesisBlock: 0, nitroGenesisL1Block: 0, @@ -171,8 +171,8 @@ export const setupNetworks = async ( } addCustomNetwork({ - customL1Network: l1Network, - customL2Network: l2Network, + customParentChain: l1Network, + customChildChain: l2Network, }) // also register the weth gateway @@ -244,8 +244,8 @@ export const testSetup = async (): Promise<{ l2Network: L2Network } addCustomNetwork({ - customL1Network: l1Network, - customL2Network: l2Network, + customParentChain: l1Network, + customChildChain: l2Network, }) setL1Network = l1Network setL2Network = l2Network diff --git a/src/index.ts b/src/index.ts index 99056afc27..5b5ec58fad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,12 +43,12 @@ export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimat export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { - L1Networks, - L2Networks, - L1Network, - L2Network, - getL1Network, - getL2Network, + ParentChains as L1Networks, + ChildChains as L2Networks, + ParentChain as L1Network, + ChildChain as L2Network, + getParentChain as getL1Network, + getChildChain as getL2Network, addCustomNetwork, addDefaultLocalNetwork, } from './lib/dataEntities/networks' diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index ea3f72162b..6895b8ecb3 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -20,7 +20,11 @@ import { ArbSdkError } from '../dataEntities/errors' import { L1ContractTransaction } from '../message/L1Transaction' import { L2ContractTransaction } from '../message/L2Transaction' -import { l1Networks, L1Network, L2Network } from '../dataEntities/networks' +import { + parentChains as l1Networks, + ParentChain as L1Network, + ChildChain as L2Network, +} from '../dataEntities/networks' import { SignerOrProvider, SignerProviderUtils, @@ -33,10 +37,10 @@ export abstract class AssetBridger { public readonly l1Network: L1Network public constructor(public readonly l2Network: L2Network) { - this.l1Network = l1Networks[l2Network.partnerChainID] + this.l1Network = l1Networks[l2Network.parentChainId] if (!this.l1Network) { throw new ArbSdkError( - `Unknown l1 network chain id: ${l2Network.partnerChainID}` + `Unknown l1 network chain id: ${l2Network.parentChainId}` ) } } diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index d4883ac22f..1504a03420 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -45,7 +45,10 @@ import { L1ToL2MessageGasEstimator, } from '../message/L1ToL2MessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' -import { L2Network, getL2Network } from '../dataEntities/networks' +import { + ChildChain as L2Network, + getChildChain as getL2Network, +} from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' import { DISABLED_GATEWAY } from '../dataEntities/constants' import { EventFetcher } from '../utils/eventFetcher' diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 4441f3d7f6..204b22fee4 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -45,7 +45,7 @@ import { import { OmitTyped } from '../utils/types' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' export interface EthWithdrawParams { /** diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 8199dae1b8..ce0bb72f41 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -21,16 +21,16 @@ import { ArbSdkError } from '../dataEntities/errors' import { SEVEN_DAYS_IN_SECONDS } from './constants' import { RollupAdminLogic__factory } from '../abi/factories/RollupAdminLogic__factory' -export interface L1Network extends Network { - partnerChainIDs: number[] +export interface ParentChain extends Network { + childChainIds: number[] blockTime: number //seconds isArbitrum: false } -export interface L2Network extends Network { +export interface ChildChain extends Network { tokenBridge: TokenBridge ethBridge: EthBridge - partnerChainID: number + parentChainId: number isArbitrum: true confirmPeriodBlocks: number retryableLifetimeSeconds: number @@ -77,12 +77,12 @@ export interface EthBridge { } } -export interface L1Networks { - [id: string]: L1Network +export interface ParentChains { + [id: string]: ParentChain } -export interface L2Networks { - [id: string]: L2Network +export interface ChildChains { + [id: string]: ChildChain } const mainnetTokenBridge: TokenBridge = { @@ -114,12 +114,12 @@ const mainnetETHBridge: EthBridge = { }, } -export const l1Networks: L1Networks = { +export const parentChains: ParentChains = { 1: { chainID: 1, name: 'Mainnet', explorerUrl: 'https://etherscan.io', - partnerChainIDs: [42161, 42170], + childChainIds: [42161, 42170], blockTime: 14, isCustom: false, isArbitrum: false, @@ -128,7 +128,7 @@ export const l1Networks: L1Networks = { chainID: 1338, name: 'Hardhat_Mainnet_Fork', explorerUrl: 'https://etherscan.io', - partnerChainIDs: [42161], + childChainIds: [42161], blockTime: 1, isCustom: false, isArbitrum: false, @@ -139,26 +139,26 @@ export const l1Networks: L1Networks = { explorerUrl: 'https://goerli.etherscan.io', isCustom: false, name: 'Goerli', - partnerChainIDs: [421613], + childChainIds: [421613], isArbitrum: false, }, 11155111: { chainID: 11155111, name: 'Sepolia', explorerUrl: 'https://sepolia.etherscan.io', - partnerChainIDs: [421614], + childChainIds: [421614], blockTime: 12, isCustom: false, isArbitrum: false, }, } -export const l2Networks: L2Networks = { +export const childChains: ChildChains = { 42161: { chainID: 42161, name: 'Arbitrum One', explorerUrl: 'https://arbiscan.io', - partnerChainID: 1, + parentChainId: 1, isArbitrum: true, tokenBridge: mainnetTokenBridge, ethBridge: mainnetETHBridge, @@ -189,7 +189,7 @@ export const l2Networks: L2Networks = { isArbitrum: true, isCustom: false, name: 'Arbitrum Rollup Goerli Testnet', - partnerChainID: 5, + parentChainId: 5, tokenBridge: { l1CustomGateway: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7', l1ERC20Gateway: '0x715D99480b77A8d9D603638e593a539E21345FdF', @@ -228,7 +228,7 @@ export const l2Networks: L2Networks = { isArbitrum: true, isCustom: false, name: 'Arbitrum Nova', - partnerChainID: 1, + parentChainId: 1, retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', @@ -269,7 +269,7 @@ export const l2Networks: L2Networks = { isArbitrum: true, isCustom: false, name: 'Arbitrum Rollup Sepolia Testnet', - partnerChainID: 11155111, + parentChainId: 11155111, retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', @@ -305,7 +305,7 @@ export const l2Networks: L2Networks = { isArbitrum: true, isCustom: false, name: 'Stylus Testnet', - partnerChainID: 421614, + parentChainId: 421614, retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', @@ -345,7 +345,7 @@ const getNetwork = async ( return chainId })() - const networks = layer === 1 ? l1Networks : l2Networks + const networks = layer === 1 ? parentChains : childChains if (networks[chainID]) { return networks[chainID] } else { @@ -353,15 +353,15 @@ const getNetwork = async ( } } -export const getL1Network = ( +export const getParentChain = ( signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 1) as Promise +): Promise => { + return getNetwork(signerOrProviderOrChainID, 1) as Promise } -export const getL2Network = ( +export const getChildChain = ( signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 2) as Promise +): Promise => { + return getNetwork(signerOrProviderOrChainID, 2) as Promise } /** @@ -396,44 +396,47 @@ export const getEthBridgeInformation = async ( } export const addCustomNetwork = ({ - customL1Network, - customL2Network, + customParentChain, + customChildChain, }: { - customL1Network?: L1Network - customL2Network: L2Network + customParentChain?: ParentChain + customChildChain: ChildChain }): void => { - if (customL1Network) { - if (l1Networks[customL1Network.chainID]) { + console.log({ customChildChain }) + if (customParentChain) { + if (parentChains[customParentChain.chainID]) { throw new ArbSdkError( - `Network ${customL1Network.chainID} already included` + `Network ${customParentChain.chainID} already included` ) - } else if (!customL1Network.isCustom) { + } else if (!customParentChain.isCustom) { throw new ArbSdkError( - `Custom network ${customL1Network.chainID} must have isCustom flag set to true` + `Custom network ${customParentChain.chainID} must have isCustom flag set to true` ) } else { - l1Networks[customL1Network.chainID] = customL1Network + parentChains[customParentChain.chainID] = customParentChain } } - if (l2Networks[customL2Network.chainID]) - throw new ArbSdkError(`Network ${customL2Network.chainID} already included`) - else if (!customL2Network.isCustom) { + if (childChains[customChildChain.chainID]) throw new ArbSdkError( - `Custom network ${customL2Network.chainID} must have isCustom flag set to true` + `Network ${customChildChain.chainID} already included` + ) + else if (!customChildChain.isCustom) { + throw new ArbSdkError( + `Custom network ${customChildChain.chainID} must have isCustom flag set to true` ) } - l2Networks[customL2Network.chainID] = customL2Network + childChains[customChildChain.chainID] = customChildChain - const l1PartnerChain = l1Networks[customL2Network.partnerChainID] - if (!l1PartnerChain) + const parentChainChildChain = parentChains[customChildChain.parentChainId] + if (!parentChainChildChain) throw new ArbSdkError( - `Network ${customL2Network.chainID}'s partner network, ${customL2Network.partnerChainID}, not recognized` + `Network ${customChildChain.chainID}'s parent chain, ${customChildChain.parentChainId}, not recognized` ) - if (!l1PartnerChain.partnerChainIDs.includes(customL2Network.chainID)) { - l1PartnerChain.partnerChainIDs.push(customL2Network.chainID) + if (!parentChainChildChain.childChainIds.includes(customChildChain.chainID)) { + parentChainChildChain.childChainIds.push(customChildChain.chainID) } } @@ -443,20 +446,20 @@ export const addCustomNetwork = ({ * @see {@link https://github.com/OffchainLabs/nitro} */ export const addDefaultLocalNetwork = (): { - l1Network: L1Network - l2Network: L2Network + parentChain: ParentChain + chain: ChildChain } => { - const defaultLocalL1Network: L1Network = { + const defaultLocalParentChain: ParentChain = { blockTime: 10, chainID: 1337, explorerUrl: '', isCustom: true, name: 'EthLocal', - partnerChainIDs: [412346], + childChainIds: [412346], isArbitrum: false, } - const defaultLocalL2Network: L2Network = { + const defaultLocalChain: ChildChain = { chainID: 412346, confirmPeriodBlocks: 20, ethBridge: { @@ -470,7 +473,7 @@ export const addDefaultLocalNetwork = (): { isArbitrum: true, isCustom: true, name: 'ArbLocal', - partnerChainID: 1337, + parentChainId: 1337, retryableLifetimeSeconds: 604800, nitroGenesisBlock: 0, nitroGenesisL1Block: 0, @@ -494,19 +497,19 @@ export const addDefaultLocalNetwork = (): { } addCustomNetwork({ - customL1Network: defaultLocalL1Network, - customL2Network: defaultLocalL2Network, + customParentChain: defaultLocalParentChain, + customChildChain: defaultLocalChain, }) return { - l1Network: defaultLocalL1Network, - l2Network: defaultLocalL2Network, + parentChain: defaultLocalParentChain, + chain: defaultLocalChain, } } -export const isL1Network = ( - network: L1Network | L2Network -): network is L1Network => { - if ((network as L1Network).partnerChainIDs) return true +export const isParentChain = ( + network: ParentChain | ChildChain +): network is ParentChain => { + if ((network as ParentChain).childChainIds) return true else return false } diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index 5f2759164c..3e629b2c21 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -28,10 +28,7 @@ import { SequencerInbox__factory } from '../abi/factories/SequencerInbox__factor import { IInbox__factory } from '../abi/factories/IInbox__factory' import { RequiredPick } from '../utils/types' import { MessageDeliveredEvent } from '../abi/Bridge' -import { - l1Networks as parentChains, - L2Network as ChildChain, -} from '../dataEntities/networks' +import { parentChains, ChildChain } from '../dataEntities/networks' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { FetchedEvent, EventFetcher } from '../utils/eventFetcher' import { MultiCaller, CallInput } from '../utils/multicall' @@ -70,10 +67,10 @@ export class InboxTools { this.parentChainProvider = SignerProviderUtils.getProviderOrThrow( this.parentChainSigner ) - this.parentChain = parentChains[childChain.partnerChainID] + this.parentChain = parentChains[childChain.parentChainId] if (!this.parentChain) throw new ArbSdkError( - `ParentChainNetwork not found for chain id: ${childChain.partnerChainID}.` + `ParentChain not found for chain id: ${childChain.parentChainId}.` ) } diff --git a/src/lib/message/L1ToL2Message.ts b/src/lib/message/L1ToL2Message.ts index 2339c77576..7fcc3adabb 100644 --- a/src/lib/message/L1ToL2Message.ts +++ b/src/lib/message/L1ToL2Message.ts @@ -34,7 +34,7 @@ import { import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' import { L2TransactionReceipt, RedeemTransaction } from './L2Transaction' -import { getL2Network } from '../../lib/dataEntities/networks' +import { getChildChain as getL2Network } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' import { EventFetcher } from '../utils/eventFetcher' diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/L1ToL2MessageCreator.ts index d930e2b22f..7823cc9aae 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/L1ToL2MessageCreator.ts @@ -7,7 +7,7 @@ import { } from './L1ToL2MessageGasEstimator' import { L1ContractTransaction, L1TransactionReceipt } from './L1Transaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' import { PayableOverrides } from '@ethersproject/contracts' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' diff --git a/src/lib/message/L1ToL2MessageGasEstimator.ts b/src/lib/message/L1ToL2MessageGasEstimator.ts index 99c7686fc1..128ecb9e59 100644 --- a/src/lib/message/L1ToL2MessageGasEstimator.ts +++ b/src/lib/message/L1ToL2MessageGasEstimator.ts @@ -5,7 +5,7 @@ import { Inbox__factory } from '../abi/factories/Inbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' import { NODE_INTERFACE_ADDRESS } from '../dataEntities/constants' import { ArbSdkError } from '../dataEntities/errors' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' import { RetryableData, RetryableDataTools, diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/L1Transaction.ts index d2b79b3e4b..d2ab95eb0f 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/L1Transaction.ts @@ -46,7 +46,7 @@ import { MessageDeliveredEvent } from '../abi/Bridge' import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' export interface L1ContractTransaction< TReceipt extends L1TransactionReceipt = L1TransactionReceipt diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index 1b3d1a4bce..fcde6086c6 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -35,7 +35,7 @@ import { import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' import { L2ToL1MessageStatus } from '../dataEntities/message' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' export type L2ToL1TransactionEvent = diff --git a/src/lib/message/L2ToL1MessageClassic.ts b/src/lib/message/L2ToL1MessageClassic.ts index 1edba7fc1d..e04c050a27 100644 --- a/src/lib/message/L2ToL1MessageClassic.ts +++ b/src/lib/message/L2ToL1MessageClassic.ts @@ -40,7 +40,7 @@ import { isDefined, wait } from '../utils/lib' import { ArbSdkError } from '../dataEntities/errors' import { EventArgs } from '../dataEntities/event' import { L2ToL1MessageStatus } from '../dataEntities/message' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' export interface MessageBatchProofInfo { /** diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index a744061ec8..4e8892e5cf 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -40,7 +40,7 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { getBlockRangesForL1Block, isArbitrumChain, wait } from '../utils/lib' -import { getL2Network } from '../dataEntities/networks' +import { getChildChain as getL2Network } from '../dataEntities/networks' import { NodeCreatedEvent, RollupUserLogic } from '../abi/RollupUserLogic' import { ArbitrumProvider } from '../utils/arbProvider' import { ArbBlock } from '../dataEntities/rpc' diff --git a/src/lib/utils/lib.ts b/src/lib/utils/lib.ts index c40341e1e6..40bf2b26cc 100644 --- a/src/lib/utils/lib.ts +++ b/src/lib/utils/lib.ts @@ -2,7 +2,7 @@ import { Provider } from '@ethersproject/abstract-provider' import { TransactionReceipt, JsonRpcProvider } from '@ethersproject/providers' import { ArbSdkError } from '../dataEntities/errors' import { ArbitrumProvider } from './arbProvider' -import { l2Networks } from '../dataEntities/networks' +import { childChains } from '../dataEntities/networks' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ARB_SYS_ADDRESS } from '../dataEntities/constants' @@ -100,7 +100,7 @@ export async function getFirstBlockForL1Block({ const arbProvider = new ArbitrumProvider(provider) const currentArbBlock = await arbProvider.getBlockNumber() const arbitrumChainId = (await arbProvider.getNetwork()).chainId - const { nitroGenesisBlock } = l2Networks[arbitrumChainId] + const { nitroGenesisBlock } = childChains[arbitrumChainId] async function getL1Block(forL2Block: number) { const { l1BlockNumber } = await arbProvider.getBlock(forL2Block) diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index 187b170c1f..b100b74b85 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -24,11 +24,11 @@ import { Multicall2 } from '../abi/Multicall2' import { Multicall2__factory } from '../abi/factories/Multicall2__factory' import { ArbSdkError } from '../dataEntities/errors' import { - isL1Network, - L1Network, - l1Networks, - L2Network, - l2Networks, + isParentChain as isL1Network, + ParentChain as L1Network, + parentChains as l1Networks, + ChildChain as L2Network, + childChains as l2Networks, } from '../dataEntities/networks' /** @@ -143,10 +143,10 @@ export class MultiCaller { let multiCallAddr: string if (isL1Network(network)) { - const firstL2 = l2Networks[network.partnerChainIDs[0]] + const firstL2 = l2Networks[network.childChainIds[0]] if (!firstL2) throw new ArbSdkError( - `No partner chain found l1 network: ${network.chainID} : partner chain ids ${network.partnerChainIDs}` + `No child chain found l1 network: ${network.chainID} : child chain ids ${network.childChainIds}` ) multiCallAddr = firstL2.tokenBridge.l1MultiCall } else { diff --git a/tests/fork/inbox.test.ts b/tests/fork/inbox.test.ts index d91c238ee2..7ed76a4790 100644 --- a/tests/fork/inbox.test.ts +++ b/tests/fork/inbox.test.ts @@ -30,7 +30,10 @@ import { InboxTools } from '../../src' import { ethers, network } from 'hardhat' import { hexZeroPad } from '@ethersproject/bytes' -import { L2Network, getL2Network } from '../../src/lib/dataEntities/networks' +import { + ChildChain as L2Network, + getChildChain as getL2Network, +} from '../../src/lib/dataEntities/networks' import { solidityKeccak256 } from 'ethers/lib/utils' import { ContractTransaction, Signer } from 'ethers' diff --git a/tests/integration/ethBridgeAddresses.test.ts b/tests/integration/ethBridgeAddresses.test.ts index 5d9db19974..57c9eb8b62 100644 --- a/tests/integration/ethBridgeAddresses.test.ts +++ b/tests/integration/ethBridgeAddresses.test.ts @@ -3,7 +3,7 @@ import { expect } from 'chai' import { EthBridge, getEthBridgeInformation, - getL2Network, + getChildChain as getL2Network, } from '../../src/lib/dataEntities/networks' import dotenv from 'dotenv' dotenv.config() diff --git a/tests/integration/sendL2msg.test.ts b/tests/integration/sendL2msg.test.ts index e9bcdd97ae..591d4f994c 100644 --- a/tests/integration/sendL2msg.test.ts +++ b/tests/integration/sendL2msg.test.ts @@ -19,7 +19,10 @@ import { BigNumber, ethers, Signer } from 'ethers' import { InboxTools } from '../../src/lib/inbox/inbox' -import { getL2Network, L2Network } from '../../src/lib/dataEntities/networks' +import { + getChildChain as getL2Network, + ChildChain as L2Network, +} from '../../src/lib/dataEntities/networks' import { testSetup } from '../../scripts/testSetup' import { greeter } from './helper/greeter' import { expect } from 'chai' diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index a258c96daf..dea1b93d19 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -31,7 +31,7 @@ import { L1ToL2MessageStatus, L2ToL1MessageStatus, } from '../../src' -import { L2Network } from '../../src/lib/dataEntities/networks' +import { ChildChain as L2Network } from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' diff --git a/tests/unit/l2toL1MessageEvents.test.ts b/tests/unit/l2toL1MessageEvents.test.ts index 8fff9e597b..d17bc71018 100644 --- a/tests/unit/l2toL1MessageEvents.test.ts +++ b/tests/unit/l2toL1MessageEvents.test.ts @@ -19,7 +19,7 @@ import { Logger, LogLevel } from '@ethersproject/logger' Logger.setLogLevel(LogLevel.ERROR) import { L2ToL1Message } from '../../src' -import { getL2Network } from '../../src/lib/dataEntities/networks' +import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito' diff --git a/tests/unit/multicall.test.ts b/tests/unit/multicall.test.ts index 8db7e1dd6a..94b8cdf22d 100644 --- a/tests/unit/multicall.test.ts +++ b/tests/unit/multicall.test.ts @@ -1,6 +1,6 @@ 'use strict' -import { getL2Network } from '../../src/lib/dataEntities/networks' +import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { mock, when, anything, instance, deepEqual } from 'ts-mockito' import { expect } from 'chai' From 4593ce86ea2856f0c3d9b631f265b8d5562745ce Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:28:53 -0500 Subject: [PATCH 03/74] Updates v4 with the latest on `main` (#376) * fix: typos (#316) Co-authored-by: Fionna Chan <13184582+fionnachan@users.noreply.github.com> * fix: default block to 0 if no NodeCreated events found (#371) * chore: bump version to 3.1.13 (#372) * chore: update advisories allowlist (#373) --------- Co-authored-by: omahs <73983677+omahs@users.noreply.github.com> Co-authored-by: Fionna Chan <13184582+fionnachan@users.noreply.github.com> Co-authored-by: Bartek Co-authored-by: spsjvc --- README.md | 18 +++++++++--------- audit-ci.jsonc | 8 +++++++- package.json | 2 +- src/lib/message/L2ToL1MessageNitro.ts | 16 +++++++++++++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f918650b34..645357b1f0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Arbitrum SDK -Typescript library for client-side interactions with Arbitrum. Arbitrum SDK provides common helper functionaliy as well access to the underlying smart contract interfaces. +TypeScript library for client-side interactions with Arbitrum. Arbitrum SDK provides common helper functionality as well as access to the underlying smart contract interfaces. Below is an overview of the Arbitrum SDK functionality. See the [tutorials](https://github.com/OffchainLabs/arbitrum-tutorials) for further examples of how to use these classes. @@ -71,7 +71,7 @@ const dataIsOnL1 = await l2TxnReceipt.isDataAvailable(l2Provider, l1Provider) ### Bridging assets -Arbitrum SDK can be used to bridge assets to/from the rollup chain.The following asset bridgers are currently available: +Arbitrum SDK can be used to bridge assets to/from the rollup chain. The following asset bridgers are currently available: - EthBridger - Erc20Bridger @@ -81,7 +81,7 @@ All asset bridgers have the following methods: - **deposit** - moves assets from the L1 to the L2 - **depositEstimateGas** - estimates the gas required to do the deposit - **withdraw** - moves assets from the L2 to the L1 -- **withdrawEstimateGas** - estimate the gas required to do the withdrawal +- **withdrawEstimateGas** - estimates the gas required to do the withdrawal Which accept different parameters depending on the asset bridger type ### Cross chain messages @@ -94,7 +94,7 @@ Arbitrum SDK comes pre-configured for Mainnet and Goerli, and their Arbitrum cou ### Inbox tools -As part of normal operation the Arbitrum sequencer will messages into the rollup chain. However, if the sequencer is unavailable and not posting batches, the inbox tools can be used to force the inclusion of transactions into the rollup chain. +As part of normal operation the Arbitrum sequencer will send messages into the rollup chain. However, if the sequencer is unavailable and not posting batches, the inbox tools can be used to force the inclusion of transactions into the rollup chain. ### Utils @@ -106,7 +106,7 @@ As part of normal operation the Arbitrum sequencer will messages into the rollup 1. First, make sure you have a Nitro node running. Check out the nitro repo, and run the following command `./test-node.bash --init --no-blockscout` -2. After the node has started up (that could take upto 20-30 mins), run `yarn gen:network`. +2. After the node has started up (that could take up to 20-30 mins), run `yarn gen:network`. 3. Once done, finally run `yarn test:integration` to run the integration tests. @@ -117,15 +117,15 @@ Defaults to `Arbitrum Goerli`, for custom network use `--network` flag. ### Bridge A Standard Token -Bridging new a token to L2 (i.e., deploying a new token contract) through the standard gateway is done by simply depositing a token that hasn't yet been bridged. This repo includes a script to trigger this initial deposit/deployment: +Bridging a new token to L2 (i.e., deploying a new token contract) through the standard gateway is done by simply depositing a token that hasn't yet been bridged. This repo includes a script to trigger this initial deposit/deployment: -1. clone `arbitrum-sdk` +1. Clone `arbitrum-sdk` 2. `yarn install` (from root) -3. Set `PRIVKEY` environmental variable (you can use .env) to the key of the account from which you'll be deploying (account should have some balance of the token you're bridging). +3. Set `PRIVKEY` environment variable (you can use .env) to the key of the account from which you'll be deploying (account should have some balance of the token you're bridging). -4. Set MAINNET_RPC environmental variable to L1 RPC endpoint (i.e., https://mainnet.infura.io/v3/my-infura-key) +4. Set MAINNET_RPC environment variable to L1 RPC endpoint (i.e., https://mainnet.infura.io/v3/my-infura-key) 5. `yarn bridgeStandardToken` diff --git a/audit-ci.jsonc b/audit-ci.jsonc index b74559e91b..ad906a3d53 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -117,6 +117,12 @@ // Undici's cookie header not cleared on cross-origin redirect in fetch // from: hardhat>undici // hardhat is only used in dev - "GHSA-wqq4-5wpv-mx2g" + "GHSA-wqq4-5wpv-mx2g", + // https://github.com/advisories/GHSA-wf5p-g6vw-rhxx + // axios inadvertently reveals the confidential XSRF-TOKEN stored in cookies + // we don't use cookies with axios in the sdk + // from: @arbitrum/nitro-contracts>sol2uml>axios + // from: axios + "GHSA-wf5p-g6vw-rhxx" ] } diff --git a/package.json b/package.json index f9fffd0da9..2eab86d5fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "3.1.12", + "version": "3.1.13", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index 4e8892e5cf..3fb6a1c92c 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -238,10 +238,16 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { private async getBlockFromNodeLog( l2Provider: JsonRpcProvider, - log: FetchedEvent + log: FetchedEvent | undefined ) { - const parsedLog = this.parseNodeCreatedAssertion(log) const arbitrumProvider = new ArbitrumProvider(l2Provider) + + if (!log) { + console.warn('No NodeCreated events found, defaulting to block 0') + return arbitrumProvider.getBlock(0) + } + + const parsedLog = this.parseNodeCreatedAssertion(log) const l2Block = await arbitrumProvider.getBlock( parsedLog.afterState.blockHash ) @@ -302,7 +308,11 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { } ) - if (logs.length !== 1) throw new ArbSdkError('No NodeCreated events found') + if (logs.length > 1) + throw new ArbSdkError( + `Unexpected number of NodeCreated events. Expected 0 or 1, got ${logs.length}.` + ) + return await this.getBlockFromNodeLog( l2Provider as JsonRpcProvider, logs[0] From 1066dbf46e18aafc10cf3db84986682b0def7bda Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Mon, 4 Dec 2023 10:21:34 -0500 Subject: [PATCH 04/74] chore: renames L1ToL2Message to parentChain/Chain (#344) * chore: renames L1/2 to parentChain/chain in inbox * chore: update l1/2 name for dataEntities * chore: renames L1ToL2Message to parentChain/Chain * fix integration test * fix test * chore: rename to ParentToChildMessage * Fix issues with merge * fix length access --- scripts/testSetup.ts | 32 +- src/index.ts | 10 +- src/lib/assetBridger/assetBridger.ts | 4 +- src/lib/assetBridger/erc20Bridger.ts | 9 +- src/lib/assetBridger/ethBridger.ts | 4 +- src/lib/dataEntities/networks.ts | 16 +- src/lib/message/L1ToL2Message.ts | 362 ++++++++++--------- src/lib/message/L1ToL2MessageCreator.ts | 4 +- src/lib/message/L1ToL2MessageGasEstimator.ts | 4 +- src/lib/message/L1Transaction.ts | 24 +- src/lib/message/L2ToL1Message.ts | 4 +- src/lib/message/L2ToL1MessageClassic.ts | 4 +- src/lib/message/L2ToL1MessageNitro.ts | 10 +- src/lib/utils/multicall.ts | 18 +- tests/integration/eth.test.ts | 10 +- tests/integration/standarderc20.test.ts | 10 +- tests/unit/l1toL2MessageEvents.test.ts | 6 +- 17 files changed, 286 insertions(+), 245 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index e53b06d0c4..94eedcc1d1 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -22,10 +22,10 @@ import { Wallet } from '@ethersproject/wallet' import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { - ParentChain as L1Network, - ChildChain as L2Network, - getParentChain as getL1Network, - getChildChain as getL2Network, + ParentChain, + ChildChain, + getParentChain, + getChildChain, addCustomNetwork, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' @@ -70,8 +70,8 @@ export const getCustomNetworks = async ( l1Url: string, l2Url: string ): Promise<{ - l1Network: L1Network - l2Network: Omit + l1Network: ParentChain + l2Network: Omit }> => { const l1Provider = new JsonRpcProvider(l1Url) const l2Provider = new JsonRpcProvider(l2Url) @@ -98,7 +98,7 @@ export const getCustomNetworks = async ( const l1NetworkInfo = await l1Provider.getNetwork() const l2NetworkInfo = await l2Provider.getNetwork() - const l1Network: L1Network = { + const l1Network: ParentChain = { blockTime: 10, chainID: l1NetworkInfo.chainId, explorerUrl: '', @@ -108,7 +108,7 @@ export const getCustomNetworks = async ( isArbitrum: false, } - const l2Network: Omit = { + const l2Network: Omit = { chainID: l2NetworkInfo.chainId, confirmPeriodBlocks: confirmPeriodBlocks.toNumber(), ethBridge: { @@ -149,7 +149,7 @@ export const setupNetworks = async ( l2Deployer, coreL2Network.ethBridge.inbox ) - const l2Network: L2Network = { + const l2Network: ChildChain = { ...coreL2Network, tokenBridge: { l1CustomGateway: l1Contracts.customGateway.address, @@ -204,8 +204,8 @@ export const getSigner = (provider: JsonRpcProvider, key?: string) => { } export const testSetup = async (): Promise<{ - l1Network: L1Network - l2Network: L2Network + l1Network: ParentChain + l2Network: ChildChain l1Signer: Signer l2Signer: Signer erc20Bridger: Erc20Bridger @@ -225,10 +225,10 @@ export const testSetup = async (): Promise<{ const l1Signer = seed.connect(ethProvider) const l2Signer = seed.connect(arbProvider) - let setL1Network: L1Network, setL2Network: L2Network + let setL1Network: ParentChain, setL2Network: ChildChain try { - const l1Network = await getL1Network(l1Deployer) - const l2Network = await getL2Network(l2Deployer) + const l1Network = await getParentChain(l1Deployer) + const l2Network = await getChildChain(l2Deployer) setL1Network = l1Network setL2Network = l2Network } catch (err) { @@ -240,8 +240,8 @@ export const testSetup = async (): Promise<{ const { l1Network, l2Network } = JSON.parse( fs.readFileSync(localNetworkFile).toString() ) as { - l1Network: L1Network - l2Network: L2Network + l1Network: ParentChain + l2Network: ChildChain } addCustomNetwork({ customParentChain: l1Network, diff --git a/src/index.ts b/src/index.ts index 5b5ec58fad..4c33d9206b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,12 +32,12 @@ export { L1TransactionReceipt, } from './lib/message/L1Transaction' export { - L1ToL2MessageStatus, + ParentToChildMessageStatus as L1ToL2MessageStatus, EthDepositStatus, - L1ToL2Message, - L1ToL2MessageReader, - L1ToL2MessageReaderClassic, - L1ToL2MessageWriter, + ParentToChildMessage as L1ToL2Message, + ParentToChildMessageReader as L1ToL2MessageReader, + ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic, + ParentToChildMessageWriter as L1ToL2MessageWriter, } from './lib/message/L1ToL2Message' export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimator' export { argSerializerConstructor } from './lib/utils/byte_serialize_params' diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 6895b8ecb3..21df2215c9 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -22,8 +22,8 @@ import { L2ContractTransaction } from '../message/L2Transaction' import { parentChains as l1Networks, - ParentChain as L1Network, ChildChain as L2Network, + ParentChain, } from '../dataEntities/networks' import { SignerOrProvider, @@ -34,7 +34,7 @@ import { * Base for bridging assets from l1 to l2 and back */ export abstract class AssetBridger { - public readonly l1Network: L1Network + public readonly l1Network: ParentChain public constructor(public readonly l2Network: L2Network) { this.l1Network = l1Networks[l2Network.parentChainId] diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 1504a03420..7d2715473a 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -45,10 +45,7 @@ import { L1ToL2MessageGasEstimator, } from '../message/L1ToL2MessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' -import { - ChildChain as L2Network, - getChildChain as getL2Network, -} from '../dataEntities/networks' +import { ChildChain, getChildChain } from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' import { DISABLED_GATEWAY } from '../dataEntities/constants' import { EventFetcher } from '../utils/eventFetcher' @@ -181,7 +178,7 @@ export class Erc20Bridger extends AssetBridger< /** * Bridger for moving ERC20 tokens back and forth between L1 to L2 */ - public constructor(l2Network: L2Network) { + public constructor(l2Network: ChildChain) { super(l2Network) } @@ -191,7 +188,7 @@ export class Erc20Bridger extends AssetBridger< * @returns */ public static async fromProvider(l2Provider: Provider) { - return new Erc20Bridger(await getL2Network(l2Provider)) + return new Erc20Bridger(await getChildChain(l2Provider)) } /** diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 204b22fee4..1d2ca25c38 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -45,7 +45,7 @@ import { import { OmitTyped } from '../utils/types' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' export interface EthWithdrawParams { /** @@ -138,7 +138,7 @@ export class EthBridger extends AssetBridger< * @returns */ public static async fromProvider(l2Provider: Provider) { - return new EthBridger(await getL2Network(l2Provider)) + return new EthBridger(await getChildChain(l2Provider)) } /** diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index ce0bb72f41..4bc5db12fe 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -402,7 +402,18 @@ export const addCustomNetwork = ({ customParentChain?: ParentChain customChildChain: ChildChain }): void => { - console.log({ customChildChain }) + //@ts-expect-error - Nitro returns this value with partnerChainID + if (customChildChain.partnerChainID) { + //@ts-expect-error - Nitro returns this value with partnerChainID + customChildChain.parentChainId = customChildChain.partnerChainID + } + + //@ts-expect-error - Nitro returns this value with partnerChainID + if (customParentChain.partnerChainIDs?.length > 0) { + //@ts-expect-error - Nitro returns this value with partnerChainID + customParentChain.childChainIds = customParentChain.partnerChainIDs + } + if (customParentChain) { if (parentChains[customParentChain.chainID]) { throw new ArbSdkError( @@ -429,11 +440,14 @@ export const addCustomNetwork = ({ childChains[customChildChain.chainID] = customChildChain + console.log({ customChildChain }) + const parentChainChildChain = parentChains[customChildChain.parentChainId] if (!parentChainChildChain) throw new ArbSdkError( `Network ${customChildChain.chainID}'s parent chain, ${customChildChain.parentChainId}, not recognized` ) + console.log({ parentChainChildChain }) if (!parentChainChildChain.childChainIds.includes(customChildChain.chainID)) { parentChainChildChain.childChainIds.push(customChildChain.chainID) diff --git a/src/lib/message/L1ToL2Message.ts b/src/lib/message/L1ToL2Message.ts index 7fcc3adabb..5efcdb02f9 100644 --- a/src/lib/message/L1ToL2Message.ts +++ b/src/lib/message/L1ToL2Message.ts @@ -33,33 +33,36 @@ import { } from '../dataEntities/signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' -import { L2TransactionReceipt, RedeemTransaction } from './L2Transaction' -import { getChildChain as getL2Network } from '../../lib/dataEntities/networks' +import { + L2TransactionReceipt as ChainTransactionReceipt, + RedeemTransaction, +} from './L2Transaction' +import { getChildChain } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' import { EventFetcher } from '../utils/eventFetcher' import { ErrorCode, Logger } from '@ethersproject/logger' -export enum L1ToL2MessageStatus { +export enum ParentToChildMessageStatus { /** * The retryable ticket has yet to be created */ NOT_YET_CREATED = 1, /** * An attempt was made to create the retryable ticket, but it failed. - * This could be due to not enough submission cost being paid by the L1 transaction + * This could be due to not enough submission cost being paid by the ParentChain transaction */ CREATION_FAILED = 2, /** * The retryable ticket has been created but has not been redeemed. This could be due to the - * auto redeem failing, or if the params (max l2 gas price) * (max l2 gas) = 0 then no auto + * auto redeem failing, or if the params (max chain gas price) * (max chain gas) = 0 then no auto * redeem tx is ever issued. An auto redeem is also never issued for ETH deposits. * A manual redeem is now required. */ - FUNDS_DEPOSITED_ON_L2 = 3, + FUNDS_DEPOSITED_ON_CHAIN = 3, /** * The retryable ticket has been redeemed (either by auto, or manually) and the - * l2 transaction has been executed + * chain transaction has been executed */ REDEEMED = 4, /** @@ -70,11 +73,11 @@ export enum L1ToL2MessageStatus { export enum EthDepositStatus { /** - * ETH is not deposited on L2 yet + * ETH is not deposited on Chain yet */ PENDING = 1, /** - * ETH is deposited successfully on L2 + * ETH is deposited successfully on Chain */ DEPOSITED = 2, } @@ -87,16 +90,16 @@ interface RetryableExistsError extends Error { /** * Conditional type for Signer or Provider. If T is of type Provider - * then L1ToL2MessageReaderOrWriter will be of type L1ToL2MessageReader. - * If T is of type Signer then L1ToL2MessageReaderOrWriter will be of - * type L1ToL2MessageWriter. + * then ParentToChildMessageReaderOrWriter will be of type ParentToChildMessageReader. + * If T is of type Signer then ParentToChildMessageReaderOrWriter will be of + * type ParentToChildMessageWriter. */ -export type L1ToL2MessageReaderOrWriter = - T extends Provider ? L1ToL2MessageReader : L1ToL2MessageWriter +export type ParentToChildMessageReaderOrWriter = + T extends Provider ? ParentToChildMessageReader : ParentToChildMessageWriter -export abstract class L1ToL2Message { +export abstract class ParentToChildMessage { /** - * When messages are sent from L1 to L2 a retryable ticket is created on L2. + * When messages are sent from ParentChain to Chain a retryable ticket is created on Chain. * The retryableCreationId can be used to retrieve information about the success or failure of the * creation of the retryable ticket. */ @@ -105,29 +108,29 @@ export abstract class L1ToL2Message { /** * The submit retryable transactions use the typed transaction envelope 2718. * The id of these transactions is the hash of the RLP encoded transaction. - * @param l2ChainId - * @param fromAddress the aliased address that called the L1 inbox as emitted in the bridge event. + * @param chainChainId + * @param fromAddress the aliased address that called the ParentChain inbox as emitted in the bridge event. * @param messageNumber - * @param l1BaseFee + * @param parentChainBaseFee * @param destAddress - * @param l2CallValue - * @param l1Value + * @param chainCallValue + * @param parentChainValue * @param maxSubmissionFee - * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the L1 inbox aliases this address if it is a L1 smart contract. The user is expected to provide this value already aliased when needed. - * @param callValueRefundAddress refund address specified in the retryable creation. Note the L1 inbox aliases this address if it is a L1 smart contract. The user is expected to provide this value already aliased when needed. + * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. + * @param callValueRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. * @param gasLimit * @param maxFeePerGas * @param data * @returns */ public static calculateSubmitRetryableId( - l2ChainId: number, + chainChainId: number, fromAddress: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, destAddress: string, - l2CallValue: BigNumber, - l1Value: BigNumber, + chainCallValue: BigNumber, + parentChainValue: BigNumber, maxSubmissionFee: BigNumber, excessFeeRefundAddress: string, callValueRefundAddress: string, @@ -139,21 +142,21 @@ export abstract class L1ToL2Message { return ethers.utils.stripZeros(value.toHexString()) } - const chainId = BigNumber.from(l2ChainId) + const chainId = BigNumber.from(chainChainId) const msgNum = BigNumber.from(messageNumber) const fields: any[] = [ formatNumber(chainId), zeroPad(formatNumber(msgNum), 32), fromAddress, - formatNumber(l1BaseFee), + formatNumber(parentChainBaseFee), - formatNumber(l1Value), + formatNumber(parentChainValue), formatNumber(maxFeePerGas), formatNumber(gasLimit), // when destAddress is 0x0, arbos treat that as nil destAddress === ethers.constants.AddressZero ? '0x' : destAddress, - formatNumber(l2CallValue), + formatNumber(chainCallValue), callValueRefundAddress, formatNumber(maxSubmissionFee), excessFeeRefundAddress, @@ -170,36 +173,36 @@ export abstract class L1ToL2Message { } public static fromEventComponents( - l2SignerOrProvider: T, + chainSignerOrProvider: T, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams - ): L1ToL2MessageReaderOrWriter + ): ParentToChildMessageReaderOrWriter public static fromEventComponents( - l2SignerOrProvider: T, + chainSignerOrProvider: T, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams - ): L1ToL2MessageReader | L1ToL2MessageWriter { - return SignerProviderUtils.isSigner(l2SignerOrProvider) - ? new L1ToL2MessageWriter( - l2SignerOrProvider, + ): ParentToChildMessageReader | ParentToChildMessageWriter { + return SignerProviderUtils.isSigner(chainSignerOrProvider) + ? new ParentToChildMessageWriter( + chainSignerOrProvider, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) - : new L1ToL2MessageReader( - l2SignerOrProvider, + : new ParentToChildMessageReader( + chainSignerOrProvider, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) } @@ -208,14 +211,14 @@ export abstract class L1ToL2Message { public readonly chainId: number, public readonly sender: string, public readonly messageNumber: BigNumber, - public readonly l1BaseFee: BigNumber, + public readonly parentChainBaseFee: BigNumber, public readonly messageData: RetryableMessageParams ) { - this.retryableCreationId = L1ToL2Message.calculateSubmitRetryableId( + this.retryableCreationId = ParentToChildMessage.calculateSubmitRetryableId( chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData.destAddress, messageData.l2CallValue, messageData.l1Value, @@ -230,33 +233,41 @@ export abstract class L1ToL2Message { } /** - * If the status is redeemed an l2TxReceipt is populated. - * For all other statuses l2TxReceipt is not populated + * If the status is redeemed an chainTxReceipt is populated. + * For all other statuses chainTxReceipt is not populated */ -export type L1ToL2MessageWaitResult = - | { status: L1ToL2MessageStatus.REDEEMED; l2TxReceipt: TransactionReceipt } - | { status: Exclude } +export type ParentToChildMessageWaitResult = + | { + status: ParentToChildMessageStatus.REDEEMED + chainTxReceipt: TransactionReceipt + } + | { + status: Exclude< + ParentToChildMessageStatus, + ParentToChildMessageStatus.REDEEMED + > + } export type EthDepositMessageWaitResult = { - l2TxReceipt: TransactionReceipt | null + chainTxReceipt: TransactionReceipt | null } -export class L1ToL2MessageReader extends L1ToL2Message { +export class ParentToChildMessageReader extends ParentToChildMessage { private retryableCreationReceipt: TransactionReceipt | undefined | null public constructor( - public readonly l2Provider: Provider, + public readonly chainProvider: Provider, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams ) { - super(chainId, sender, messageNumber, l1BaseFee, messageData) + super(chainId, sender, messageNumber, parentChainBaseFee, messageData) } /** * Try to get the receipt for the retryable ticket creation. - * This is the L2 transaction that creates the retryable ticket. + * This is the Chain transaction that creates the retryable ticket. * If confirmations or timeout is provided, this will wait for the ticket to be created * @returns Null if retryable has not been created */ @@ -266,7 +277,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.l2Provider, + this.chainProvider, this.retryableCreationId, confirmations, timeout @@ -285,11 +296,11 @@ export class L1ToL2MessageReader extends L1ToL2Message { const creationReceipt = await this.getRetryableCreationReceipt() if (creationReceipt) { - const l2Receipt = new L2TransactionReceipt(creationReceipt) - const redeemEvents = l2Receipt.getRedeemScheduledEvents() + const chainReceipt = new ChainTransactionReceipt(creationReceipt) + const redeemEvents = chainReceipt.getRedeemScheduledEvents() if (redeemEvents.length === 1) { - return await this.l2Provider.getTransactionReceipt( + return await this.chainProvider.getTransactionReceipt( redeemEvents[0].retryTxHash ) } else if (redeemEvents.length > 1) { @@ -303,34 +314,39 @@ export class L1ToL2MessageReader extends L1ToL2Message { } /** - * Receipt for the successful l2 transaction created by this message. + * Receipt for the successful chain transaction created by this message. * @returns TransactionReceipt of the first successful redeem if exists, otherwise the current status of the message. */ - public async getSuccessfulRedeem(): Promise { - const l2Network = await getL2Network(this.l2Provider) - const eventFetcher = new EventFetcher(this.l2Provider) + public async getSuccessfulRedeem(): Promise { + const chainNetwork = await getChildChain(this.chainProvider) + const eventFetcher = new EventFetcher(this.chainProvider) const creationReceipt = await this.getRetryableCreationReceipt() if (!isDefined(creationReceipt)) { // retryable was never created, or not created yet // therefore it cant have been redeemed or be expired - return { status: L1ToL2MessageStatus.NOT_YET_CREATED } + return { status: ParentToChildMessageStatus.NOT_YET_CREATED } } if (creationReceipt.status === 0) { - return { status: L1ToL2MessageStatus.CREATION_FAILED } + return { status: ParentToChildMessageStatus.CREATION_FAILED } } // check the auto redeem first to avoid doing costly log queries in the happy case const autoRedeem = await this.getAutoRedeemAttempt() if (autoRedeem && autoRedeem.status === 1) { - return { l2TxReceipt: autoRedeem, status: L1ToL2MessageStatus.REDEEMED } + return { + chainTxReceipt: autoRedeem, + status: ParentToChildMessageStatus.REDEEMED, + } } if (await this.retryableExists()) { // the retryable was created and still exists // therefore it cant have been redeemed or be expired - return { status: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 } + return { + status: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + } } // from this point on we know that the retryable was created but does not exist, @@ -340,10 +356,12 @@ export class L1ToL2MessageReader extends L1ToL2Message { // to do this we need to filter through the whole lifetime of the ticket looking // for relevant redeem scheduled events let increment = 1000 - let fromBlock = await this.l2Provider.getBlock(creationReceipt.blockNumber) - let timeout = fromBlock.timestamp + l2Network.retryableLifetimeSeconds + let fromBlock = await this.chainProvider.getBlock( + creationReceipt.blockNumber + ) + let timeout = fromBlock.timestamp + chainNetwork.retryableLifetimeSeconds const queriedRange: { from: number; to: number }[] = [] - const maxBlock = await this.l2Provider.getBlockNumber() + const maxBlock = await this.chainProvider.getBlockNumber() while (fromBlock.number < maxBlock) { const toBlockNumber = Math.min(fromBlock.number + increment, maxBlock) @@ -363,7 +381,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { const successfulRedeem = ( await Promise.all( redeemEvents.map(e => - this.l2Provider.getTransactionReceipt(e.event.retryTxHash) + this.chainProvider.getTransactionReceipt(e.event.retryTxHash) ) ) ).filter(r => isDefined(r) && r.status === 1) @@ -374,11 +392,11 @@ export class L1ToL2MessageReader extends L1ToL2Message { ) if (successfulRedeem.length == 1) return { - l2TxReceipt: successfulRedeem[0], - status: L1ToL2MessageStatus.REDEEMED, + chainTxReceipt: successfulRedeem[0], + status: ParentToChildMessageStatus.REDEEMED, } - const toBlock = await this.l2Provider.getBlock(toBlockNumber) + const toBlock = await this.chainProvider.getBlock(toBlockNumber) if (toBlock.timestamp > timeout) { // Check for LifetimeExtended event while (queriedRange.length > 0) { @@ -418,7 +436,7 @@ export class L1ToL2MessageReader extends L1ToL2Message { // we know from earlier that the retryable no longer exists, so if we havent found the redemption // we know that it must have expired - return { status: L1ToL2MessageStatus.EXPIRED } + return { status: ParentToChildMessageStatus.EXPIRED } } /** @@ -432,12 +450,12 @@ export class L1ToL2MessageReader extends L1ToL2Message { private async retryableExists(): Promise { const currentTimestamp = BigNumber.from( - (await this.l2Provider.getBlock('latest')).timestamp + (await this.chainProvider.getBlock('latest')).timestamp ) try { const timeoutTimestamp = await this.getTimeout() // timeoutTimestamp returns the timestamp at which the retryable ticket expires - // it can also return revert if the ticket l2Tx does not exist + // it can also return revert if the ticket chainTx does not exist return currentTimestamp.lte(timeoutTimestamp) } catch (err) { if ( @@ -452,31 +470,31 @@ export class L1ToL2MessageReader extends L1ToL2Message { } } - public async status(): Promise { + public async status(): Promise { return (await this.getSuccessfulRedeem()).status } /** - * Wait for the retryable ticket to be created, for it to be redeemed, and for the l2Tx to be executed. - * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_L2 as - * no L2 transaction needs to be executed, however the terminal state of any other transaction is REDEEMED - * which represents that the retryable ticket has been redeemed and the L2 tx has been executed. + * Wait for the retryable ticket to be created, for it to be redeemed, and for the chainTx to be executed. + * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_CHAIN as + * no Chain transaction needs to be executed, however the terminal state of any other transaction is REDEEMED + * which represents that the retryable ticket has been redeemed and the Chain tx has been executed. * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created - * Defaults to 15 minutes, as by this time all transactions are expected to be included on L2. Throws on timeout. - * @returns The wait result contains a status, and optionally the l2TxReceipt. - * If the status is "REDEEMED" then a l2TxReceipt is also available on the result. - * If the status has any other value then l2TxReceipt is not populated. + * Defaults to 15 minutes, as by this time all transactions are expected to be included on Chain. Throws on timeout. + * @returns The wait result contains a status, and optionally the chainTxReceipt. + * If the status is "REDEEMED" then a chainTxReceipt is also available on the result. + * If the status has any other value then chainTxReceipt is not populated. */ public async waitForStatus( confirmations?: number, timeout?: number - ): Promise { - const l2Network = await getL2Network(this.chainId) + ): Promise { + const chainNetwork = await getChildChain(this.chainId) const chosenTimeout = isDefined(timeout) ? timeout - : l2Network.depositTimeout + : chainNetwork.depositTimeout // try to wait for the retryable ticket to be created const _retryableCreationReceipt = await this.getRetryableCreationReceipt( @@ -501,10 +519,10 @@ export class L1ToL2MessageReader extends L1ToL2Message { * The minimium lifetime of a retryable tx * @returns */ - public static async getLifetime(l2Provider: Provider): Promise { + public static async getLifetime(chainProvider: Provider): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - l2Provider + chainProvider ) return await arbRetryableTx.getLifetime() } @@ -516,37 +534,41 @@ export class L1ToL2MessageReader extends L1ToL2Message { public async getTimeout(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Provider + this.chainProvider ) return await arbRetryableTx.getTimeout(this.retryableCreationId) } /** - * Address to which CallValue will be credited to on L2 if the retryable ticket times out or is cancelled. + * Address to which CallValue will be credited to on Chain if the retryable ticket times out or is cancelled. * The Beneficiary is also the address with the right to cancel a Retryable Ticket (if the ticket hasn’t been redeemed yet). * @returns */ public getBeneficiary(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Provider + this.chainProvider ) return arbRetryableTx.getBeneficiary(this.retryableCreationId) } } -export class L1ToL2MessageReaderClassic { +export class ParentToChildMessageReaderClassic { private retryableCreationReceipt: TransactionReceipt | undefined | null public readonly messageNumber: BigNumber public readonly retryableCreationId: string public readonly autoRedeemId: string - public readonly l2TxHash: string - public readonly l2Provider: Provider + public readonly chainTxHash: string + public readonly chainProvider: Provider - constructor(l2Provider: Provider, chainId: number, messageNumber: BigNumber) { + constructor( + chainProvider: Provider, + chainId: number, + messageNumber: BigNumber + ) { const bitFlip = (num: BigNumber) => num.or(BigNumber.from(1).shl(255)) this.messageNumber = messageNumber - this.l2Provider = l2Provider + this.chainProvider = chainProvider this.retryableCreationId = keccak256( concat([ @@ -562,7 +584,7 @@ export class L1ToL2MessageReaderClassic { ]) ) - this.l2TxHash = keccak256( + this.chainTxHash = keccak256( concat([ zeroPad(this.retryableCreationId, 32), zeroPad(BigNumber.from(0).toHexString(), 32), @@ -570,11 +592,11 @@ export class L1ToL2MessageReaderClassic { ) } - private calculateL2DerivedHash(retryableCreationId: string): string { + private calculateChainDerivedHash(retryableCreationId: string): string { return keccak256( concat([ zeroPad(retryableCreationId, 32), - // BN 0 meaning L2 TX + // BN 0 meaning Chain TX zeroPad(BigNumber.from(0).toHexString(), 32), ]) ) @@ -582,7 +604,7 @@ export class L1ToL2MessageReaderClassic { /** * Try to get the receipt for the retryable ticket creation. - * This is the L2 transaction that creates the retryable ticket. + * This is the Chain transaction that creates the retryable ticket. * If confirmations or timeout is provided, this will wait for the ticket to be created * @returns Null if retryable has not been created */ @@ -592,7 +614,7 @@ export class L1ToL2MessageReaderClassic { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.l2Provider, + this.chainProvider, this.retryableCreationId, confirmations, timeout @@ -602,77 +624,81 @@ export class L1ToL2MessageReaderClassic { return this.retryableCreationReceipt || null } - public async status(): Promise { + public async status(): Promise { const creationReceipt = await this.getRetryableCreationReceipt() if (!isDefined(creationReceipt)) { - return L1ToL2MessageStatus.NOT_YET_CREATED + return ParentToChildMessageStatus.NOT_YET_CREATED } if (creationReceipt.status === 0) { - return L1ToL2MessageStatus.CREATION_FAILED + return ParentToChildMessageStatus.CREATION_FAILED } - const l2DerivedHash = this.calculateL2DerivedHash(this.retryableCreationId) - const l2TxReceipt = await this.l2Provider.getTransactionReceipt( - l2DerivedHash + const chainDerivedHash = this.calculateChainDerivedHash( + this.retryableCreationId + ) + const chainTxReceipt = await this.chainProvider.getTransactionReceipt( + chainDerivedHash ) - if (l2TxReceipt && l2TxReceipt.status === 1) { - return L1ToL2MessageStatus.REDEEMED + if (chainTxReceipt && chainTxReceipt.status === 1) { + return ParentToChildMessageStatus.REDEEMED } - return L1ToL2MessageStatus.EXPIRED + return ParentToChildMessageStatus.EXPIRED } } -export class L1ToL2MessageWriter extends L1ToL2MessageReader { +export class ParentToChildMessageWriter extends ParentToChildMessageReader { public constructor( - public readonly l2Signer: Signer, + public readonly chainSigner: Signer, chainId: number, sender: string, messageNumber: BigNumber, - l1BaseFee: BigNumber, + parentChainBaseFee: BigNumber, messageData: RetryableMessageParams ) { super( - l2Signer.provider!, + chainSigner.provider!, chainId, sender, messageNumber, - l1BaseFee, + parentChainBaseFee, messageData ) - if (!l2Signer.provider) + if (!chainSigner.provider) throw new ArbSdkError('Signer not connected to provider.') } /** * Manually redeem the retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async redeem(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) const redeemTx = await arbRetryableTx.redeem(this.retryableCreationId, { ...overrides, }) - return L2TransactionReceipt.toRedeemTransaction( - L2TransactionReceipt.monkeyPatchWait(redeemTx), - this.l2Provider + return ChainTransactionReceipt.toRedeemTransaction( + ChainTransactionReceipt.monkeyPatchWait(redeemTx), + this.chainProvider ) } else { throw new ArbSdkError( `Cannot redeem as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentToChildMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentToChildMessageStatus[ + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -680,22 +706,24 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { /** * Cancel the retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async cancel(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) return await arbRetryableTx.cancel(this.retryableCreationId, overrides) } else { throw new ArbSdkError( `Cannot cancel as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentToChildMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentToChildMessageStatus[ + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -703,22 +731,24 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { /** * Increase the timeout of a retryable ticket. - * Throws if message status is not L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN */ public async keepAlive(overrides?: Overrides): Promise { const status = await this.status() - if (status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.l2Signer + this.chainSigner ) return await arbRetryableTx.keepalive(this.retryableCreationId, overrides) } else { throw new ArbSdkError( `Cannot keep alive as retryable does not exist. Message status: ${ - L1ToL2MessageStatus[status] + ParentToChildMessageStatus[status] } must be: ${ - L1ToL2MessageStatus[L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2] + ParentToChildMessageStatus[ + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ] }.` ) } @@ -726,14 +756,14 @@ export class L1ToL2MessageWriter extends L1ToL2MessageReader { } /** - * A message for Eth deposits from L1 to L2 + * A message for Eth deposits from ParentChain to Chain */ export class EthDepositMessage { - public readonly l2DepositTxHash: string - private l2DepositTxReceipt: TransactionReceipt | undefined | null + public readonly chainDepositTxHash: string + private chainDepositTxReceipt: TransactionReceipt | undefined | null public static calculateDepositTxId( - l2ChainId: number, + chainChainId: number, messageNumber: BigNumber, fromAddress: string, toAddress: string, @@ -743,7 +773,7 @@ export class EthDepositMessage { return ethers.utils.stripZeros(numberVal.toHexString()) } - const chainId = BigNumber.from(l2ChainId) + const chainId = BigNumber.from(chainChainId) const msgNum = BigNumber.from(messageNumber) // https://github.com/OffchainLabs/go-ethereum/blob/07e017aa73e32be92aadb52fa327c552e1b7b118/core/types/arb_types.go#L302-L308 @@ -774,7 +804,7 @@ export class EthDepositMessage { to: string value: BigNumber } { - // https://github.com/OffchainLabs/nitro/blob/aa84e899cbc902bf6da753b1d66668a1def2c106/contracts/src/bridge/Inbox.sol#L242 + // https://github.com/OffchainLabs/nitro/blob/aa84e899cbc902bf6da753b1d66668a1def2c106/contracts/src/bridge/Inbox.sol#Chain42 // ethers.defaultAbiCoder doesnt decode packed args, so we do a hardcoded parsing const addressEnd = 2 + 20 * 2 const to = getAddress('0x' + eventData.substring(2, addressEnd)) @@ -785,25 +815,25 @@ export class EthDepositMessage { /** * Create an EthDepositMessage from data emitted in event when calling ethDeposit on Inbox.sol - * @param l2Provider + * @param chainProvider * @param messageNumber The message number in the Inbox.InboxMessageDelivered event * @param senderAddr The sender address from Bridge.MessageDelivered event * @param inboxMessageEventData The data field from the Inbox.InboxMessageDelivered event * @returns */ public static async fromEventComponents( - l2Provider: Provider, + chainProvider: Provider, messageNumber: BigNumber, senderAddr: string, inboxMessageEventData: string ) { - const chainId = (await l2Provider.getNetwork()).chainId + const chainId = (await chainProvider.getNetwork()).chainId const { to, value } = EthDepositMessage.parseEthDepositData( inboxMessageEventData ) return new EthDepositMessage( - l2Provider, + chainProvider, chainId, messageNumber, senderAddr, @@ -814,22 +844,22 @@ export class EthDepositMessage { /** * - * @param l2Provider - * @param l2ChainId + * @param chainProvider + * @param chainChainId * @param messageNumber - * @param to Recipient address of the ETH on L2 + * @param to Recipient address of the ETH on Chain * @param value */ constructor( - private readonly l2Provider: Provider, - public readonly l2ChainId: number, + private readonly chainProvider: Provider, + public readonly chainChainId: number, public readonly messageNumber: BigNumber, public readonly from: string, public readonly to: string, public readonly value: BigNumber ) { - this.l2DepositTxHash = EthDepositMessage.calculateDepositTxId( - l2ChainId, + this.chainDepositTxHash = EthDepositMessage.calculateDepositTxId( + chainChainId, messageNumber, from, to, @@ -838,29 +868,29 @@ export class EthDepositMessage { } public async status(): Promise { - const receipt = await this.l2Provider.getTransactionReceipt( - this.l2DepositTxHash + const receipt = await this.chainProvider.getTransactionReceipt( + this.chainDepositTxHash ) if (receipt === null) return EthDepositStatus.PENDING else return EthDepositStatus.DEPOSITED } public async wait(confirmations?: number, timeout?: number) { - const l2Network = await getL2Network(this.l2ChainId) + const chainNetwork = await getChildChain(this.chainChainId) const chosenTimeout = isDefined(timeout) ? timeout - : l2Network.depositTimeout + : chainNetwork.depositTimeout - if (!this.l2DepositTxReceipt) { - this.l2DepositTxReceipt = await getTransactionReceipt( - this.l2Provider, - this.l2DepositTxHash, + if (!this.chainDepositTxReceipt) { + this.chainDepositTxReceipt = await getTransactionReceipt( + this.chainProvider, + this.chainDepositTxHash, confirmations, chosenTimeout ) } - return this.l2DepositTxReceipt || null + return this.chainDepositTxReceipt || null } } diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/L1ToL2MessageCreator.ts index 7823cc9aae..c40f845a78 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/L1ToL2MessageCreator.ts @@ -7,7 +7,7 @@ import { } from './L1ToL2MessageGasEstimator' import { L1ContractTransaction, L1TransactionReceipt } from './L1Transaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' import { PayableOverrides } from '@ethersproject/contracts' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' @@ -96,7 +96,7 @@ export class L1ToL2MessageCreator { options ) - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const inboxInterface = Inbox__factory.createInterface() const functionData = inboxInterface.encodeFunctionData( 'createRetryableTicket', diff --git a/src/lib/message/L1ToL2MessageGasEstimator.ts b/src/lib/message/L1ToL2MessageGasEstimator.ts index 128ecb9e59..822afda7fe 100644 --- a/src/lib/message/L1ToL2MessageGasEstimator.ts +++ b/src/lib/message/L1ToL2MessageGasEstimator.ts @@ -5,7 +5,7 @@ import { Inbox__factory } from '../abi/factories/Inbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' import { NODE_INTERFACE_ADDRESS } from '../dataEntities/constants' import { ArbSdkError } from '../dataEntities/errors' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' import { RetryableData, RetryableDataTools, @@ -125,7 +125,7 @@ export class L1ToL2MessageGasEstimator { ): Promise { const defaultedOptions = this.applySubmissionPriceDefaults(options) - const network = await getL2Network(this.l2Provider) + const network = await getChildChain(this.l2Provider) const inbox = Inbox__factory.connect(network.ethBridge.inbox, l1Provider) return this.percentIncrease( diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/L1Transaction.ts index d2ab95eb0f..0cc8e150fb 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/L1Transaction.ts @@ -21,13 +21,13 @@ import { Log, Provider } from '@ethersproject/abstract-provider' import { ContractTransaction } from '@ethersproject/contracts' import { BigNumber } from '@ethersproject/bignumber' import { - L1ToL2Message, - L1ToL2MessageReaderOrWriter, - L1ToL2MessageReader, - L1ToL2MessageReaderClassic, - L1ToL2MessageWriter, - L1ToL2MessageStatus, - L1ToL2MessageWaitResult, + ParentToChildMessage as L1ToL2Message, + ParentToChildMessageReaderOrWriter as L1ToL2MessageReaderOrWriter, + ParentToChildMessageReader as L1ToL2MessageReader, + ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic, + ParentToChildMessageWriter as L1ToL2MessageWriter, + ParentToChildMessageStatus as L1ToL2MessageStatus, + ParentToChildMessageWaitResult as L1ToL2MessageWaitResult, EthDepositMessage, EthDepositMessageWaitResult, } from './L1ToL2Message' @@ -46,7 +46,7 @@ import { MessageDeliveredEvent } from '../abi/Bridge' import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' export interface L1ContractTransaction< TReceipt extends L1TransactionReceipt = L1TransactionReceipt @@ -106,7 +106,7 @@ export class L1TransactionReceipt implements TransactionReceipt { l2SignerOrProvider: T ): Promise { const provider = SignerProviderUtils.getProviderOrThrow(l2SignerOrProvider) - const network = await getL2Network(provider) + const network = await getChildChain(provider) return this.blockNumber < network.nitroGenesisL1Block } @@ -207,7 +207,7 @@ export class L1TransactionReceipt implements TransactionReceipt { public async getL1ToL2MessagesClassic( l2Provider: Provider ): Promise { - const network = await getL2Network(l2Provider) + const network = await getChildChain(l2Provider) const chainID = network.chainID.toString() const isClassic = await this.isClassic(l2Provider) @@ -243,7 +243,7 @@ export class L1TransactionReceipt implements TransactionReceipt { l2SignerOrProvider: T ): Promise { const provider = SignerProviderUtils.getProviderOrThrow(l2SignerOrProvider) - const network = await getL2Network(provider) + const network = await getChildChain(provider) const chainID = network.chainID.toString() const isClassic = await this.isClassic(provider) @@ -372,7 +372,7 @@ export class L1EthDepositTransactionReceipt extends L1TransactionReceipt { return { complete: isDefined(res), - l2TxReceipt: res, + chainTxReceipt: res, message, } } diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index fcde6086c6..3c62d35671 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -35,7 +35,7 @@ import { import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' import { L2ToL1MessageStatus } from '../dataEntities/message' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' export type L2ToL1TransactionEvent = @@ -107,7 +107,7 @@ export class L2ToL1Message { hash?: BigNumber, indexInBatch?: BigNumber ): Promise<(L2ToL1TransactionEvent & { transactionHash: string })[]> { - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const inClassicRange = (blockTag: BlockTag, nitroGenBlock: number) => { if (typeof blockTag === 'string') { diff --git a/src/lib/message/L2ToL1MessageClassic.ts b/src/lib/message/L2ToL1MessageClassic.ts index e04c050a27..160e15c1c3 100644 --- a/src/lib/message/L2ToL1MessageClassic.ts +++ b/src/lib/message/L2ToL1MessageClassic.ts @@ -40,7 +40,7 @@ import { isDefined, wait } from '../utils/lib' import { ArbSdkError } from '../dataEntities/errors' import { EventArgs } from '../dataEntities/event' import { L2ToL1MessageStatus } from '../dataEntities/message' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' export interface MessageBatchProofInfo { /** @@ -205,7 +205,7 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { */ protected async getOutboxAddress(l2Provider: Provider, batchNumber: number) { if (!isDefined(this.outboxAddress)) { - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) // find the outbox where the activation batch number of the next outbox // is greater than the supplied batch diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index 3fb6a1c92c..e1651e284a 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -40,7 +40,7 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { getBlockRangesForL1Block, isArbitrumChain, wait } from '../utils/lib' -import { getChildChain as getL2Network } from '../dataEntities/networks' +import { getChildChain } from '../dataEntities/networks' import { NodeCreatedEvent, RollupUserLogic } from '../abi/RollupUserLogic' import { ArbitrumProvider } from '../utils/arbProvider' import { ArbBlock } from '../dataEntities/rpc' @@ -205,7 +205,7 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { * Check if this message has already been executed in the Outbox */ protected async hasExecuted(l2Provider: Provider): Promise { - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const outbox = Outbox__factory.connect( l2Network.ethBridge.outbox, this.l1Provider @@ -341,7 +341,7 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { protected async getSendProps(l2Provider: Provider) { if (!this.sendRootConfirmed) { - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const rollup = RollupUserLogic__factory.connect( l2Network.ethBridge.rollup, @@ -419,7 +419,7 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { public async getFirstExecutableBlock( l2Provider: Provider ): Promise { - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const rollup = RollupUserLogic__factory.connect( l2Network.ethBridge.rollup, @@ -536,7 +536,7 @@ export class L2ToL1MessageWriterNitro extends L2ToL1MessageReaderNitro { ) } const proof = await this.getOutboxProof(l2Provider) - const l2Network = await getL2Network(l2Provider) + const l2Network = await getChildChain(l2Provider) const outbox = Outbox__factory.connect( l2Network.ethBridge.outbox, this.l1Signer diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index b100b74b85..9f6b1255ea 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -24,11 +24,11 @@ import { Multicall2 } from '../abi/Multicall2' import { Multicall2__factory } from '../abi/factories/Multicall2__factory' import { ArbSdkError } from '../dataEntities/errors' import { - isParentChain as isL1Network, - ParentChain as L1Network, - parentChains as l1Networks, - ChildChain as L2Network, - childChains as l2Networks, + isParentChain, + ParentChain, + parentChains, + ChildChain, + childChains, } from '../dataEntities/networks' /** @@ -131,8 +131,8 @@ export class MultiCaller { */ public static async fromProvider(provider: Provider): Promise { const chainId = (await provider.getNetwork()).chainId - const l2Network = l2Networks[chainId] as L2Network | undefined - const l1Network = l1Networks[chainId] as L1Network | undefined + const l2Network = childChains[chainId] as ChildChain | undefined + const l1Network = parentChains[chainId] as ParentChain | undefined const network = l2Network || l1Network if (!network) { @@ -142,8 +142,8 @@ export class MultiCaller { } let multiCallAddr: string - if (isL1Network(network)) { - const firstL2 = l2Networks[network.childChainIds[0]] + if (isParentChain(network)) { + const firstL2 = childChains[network.childChainIds[0]] if (!firstL2) throw new ArbSdkError( `No child chain found l1 network: ${network.chainID} : child chain ids ${network.childChainIds}` diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index af8ca1c7a6..8cb4d8e09f 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -32,7 +32,7 @@ import { import { L2ToL1Message } from '../../src/lib/message/L2ToL1Message' import { L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' import { L2TransactionReceipt } from '../../src/lib/message/L2Transaction' -import { L1ToL2MessageStatus } from '../../src/lib/message/L1ToL2Message' +import { ParentToChildMessageStatus as L1ToL2MessageStatus } from '../../src/lib/message/L1ToL2Message' import { testSetup } from '../../scripts/testSetup' dotenv.config() @@ -113,11 +113,11 @@ describe('Ether', async () => { ethToDeposit.toString() ) - prettyLog('l2TxHash: ' + waitResult.message.l2DepositTxHash) - prettyLog('l2 transaction found!') + prettyLog('chainTxHash: ' + waitResult.message.chainDepositTxHash) + prettyLog('chain transaction found!') expect(waitResult.complete).to.eq(true, 'eth deposit not complete') - expect(waitResult.l2TxReceipt).to.exist - expect(waitResult.l2TxReceipt).to.not.be.null + expect(waitResult.chainTxReceipt).to.exist + expect(waitResult.chainTxReceipt).to.not.be.null const testWalletL2EthBalance = await l2Signer.getBalance() expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index e79838b6ef..409d9108a8 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -105,7 +105,7 @@ describe('standard ERC20', () => { expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( expectedStatus === 0 - ? L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + ? L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN : L1ToL2MessageStatus.REDEEMED ) } @@ -117,7 +117,7 @@ describe('standard ERC20', () => { testState.erc20Bridger, testState.l1Signer, testState.l2Signer, - L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2, + L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, GatewayType.STANDARD, { gasLimit: { base: BigNumber.from(0) }, @@ -135,7 +135,7 @@ describe('standard ERC20', () => { testState.erc20Bridger, testState.l1Signer, testState.l2Signer, - L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2, + L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, GatewayType.STANDARD, { gasLimit: { base: BigNumber.from(5) }, @@ -155,7 +155,7 @@ describe('standard ERC20', () => { testState.erc20Bridger, testState.l1Signer, testState.l2Signer, - L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2, + L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, GatewayType.STANDARD, { gasLimit: { base: BigNumber.from(21000) }, @@ -187,7 +187,7 @@ describe('standard ERC20', () => { testState.erc20Bridger, testState.l1Signer, testState.l2Signer, - L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2, + L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, GatewayType.STANDARD, { gasLimit: { base: BigNumber.from(5) }, diff --git a/tests/unit/l1toL2MessageEvents.test.ts b/tests/unit/l1toL2MessageEvents.test.ts index a4b5e2f330..8e01e4c2b9 100644 --- a/tests/unit/l1toL2MessageEvents.test.ts +++ b/tests/unit/l1toL2MessageEvents.test.ts @@ -3,7 +3,7 @@ import { BigNumber, constants, providers } from 'ethers' import { JsonRpcProvider } from '@ethersproject/providers' import { expect } from 'chai' -describe('L1toL2Message events', () => { +describe('ParentToChildMessage events', () => { it('does call for nitro events', async () => { // Receipt from mainnet tx: 0x00000a61331187be51ab9ae792d74f601a5a21fb112f5b9ac5bccb23d4d5aaba const receipt: providers.TransactionReceipt = { @@ -184,7 +184,7 @@ describe('L1toL2Message events', () => { 'incorrect message number' ).to.be.true expect( - msg.l1BaseFee.eq(BigNumber.from('0x05e0fc4c58')), + msg.parentChainBaseFee.eq(BigNumber.from('0x05e0fc4c58')), 'incorrect l1 base fee' ).to.be.true expect( @@ -322,7 +322,7 @@ describe('L1toL2Message events', () => { expect(msg.autoRedeemId, 'incorrect auto redeem id').to.be.eq( '0x38c5c31151344c7a1433a849bbc80472786ebe911630255a6e25d6a2efd39526' ) - expect(msg.l2TxHash, 'incorrect l2 tx hash').to.be.eq( + expect(msg.chainTxHash, 'incorrect l2 tx hash').to.be.eq( '0xf91e7d2e7526927e915a2357360a3f1108dce0f9c7fa88a7492669adf5c1e53b' ) }) From 92def11e8b32439fdbd2de15d4eb3761ba0e218c Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:16:33 -0500 Subject: [PATCH 05/74] chore: renames L2ToL1Message to Child/ParentChain (#345) * chore: renames L1/2 to parentChain/chain in inbox * chore: update l1/2 name for dataEntities * chore: renames L1ToL2Message to parentChain/Chain * chore: renames L2ToL1Message to chain/parentChain * chore: renames L1ToL2Message to parentChain/Chain * fix integration test * fix unit tests * fix test * chore: renames to ChildToParentChain * chore: rename to ParentToChildMessage * chore: rename to ParentToChild * fix capitalization * fix test * respond to pr feedback * remove `as` in test --- src/index.ts | 6 +- src/lib/message/L2ToL1Message.ts | 182 +++++++++++++------------ src/lib/message/L2Transaction.ts | 10 +- tests/integration/eth.test.ts | 8 +- tests/unit/l2toL1MessageEvents.test.ts | 20 +-- 5 files changed, 120 insertions(+), 106 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4c33d9206b..316fc790c5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,9 +23,9 @@ export { L2ContractTransaction, } from './lib/message/L2Transaction' export { - L2ToL1Message, - L2ToL1MessageWriter, - L2ToL1MessageReader, + ChildToParentMessage as L2ToL1Message, + ChildToParentMessageWriter as L2ToL1MessageWriter, + ChildToParentMessageReader as L2ToL1MessageReader, } from './lib/message/L2ToL1Message' export { L1ContractTransaction, diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index 3c62d35671..d9a1651bdc 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -29,85 +29,89 @@ import { import * as classic from './L2ToL1MessageClassic' import * as nitro from './L2ToL1MessageNitro' import { - L2ToL1TransactionEvent as ClassicL2ToL1TransactionEvent, - L2ToL1TxEvent as NitroL2ToL1TransactionEvent, + L2ToL1TransactionEvent as ClassicChildToParentTransactionEvent, + L2ToL1TxEvent as NitroChildToParentTransactionEvent, } from '../abi/ArbSys' import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' -import { L2ToL1MessageStatus } from '../dataEntities/message' +import { L2ToL1MessageStatus as ChildToParentChainMessageStatus } from '../dataEntities/message' import { getChildChain } from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' -export type L2ToL1TransactionEvent = - | EventArgs - | EventArgs +export type ChildToParentTransactionEvent = + | EventArgs + | EventArgs /** * Conditional type for Signer or Provider. If T is of type Provider - * then L2ToL1MessageReaderOrWriter will be of type L2ToL1MessageReader. - * If T is of type Signer then L2ToL1MessageReaderOrWriter will be of - * type L2ToL1MessageWriter. + * then ChildToParentMessageReaderOrWriter will be of type ChildToParentMessageReader. + * If T is of type Signer then ChildToParentMessageReaderOrWriter will be of + * type ChildToParentMessageWriter. */ -export type L2ToL1MessageReaderOrWriter = - T extends Provider ? L2ToL1MessageReader : L2ToL1MessageWriter +export type ChildToParentMessageReaderOrWriter = + T extends Provider ? ChildToParentMessageReader : ChildToParentMessageWriter /** - * Base functionality for L2->L1 messages + * Base functionality for Chain->ParentChain messages */ -export class L2ToL1Message { +export class ChildToParentMessage { protected isClassic( - e: L2ToL1TransactionEvent - ): e is EventArgs { + e: ChildToParentTransactionEvent + ): e is EventArgs { return isDefined( - (e as EventArgs).indexInBatch + (e as EventArgs).indexInBatch ) } /** - * Instantiates a new `L2ToL1MessageWriter` or `L2ToL1MessageReader` object. + * Instantiates a new `ChildToParentMessageWriter` or `ChildToParentMessageReader` object. * - * @param {SignerOrProvider} l1SignerOrProvider Signer or provider to be used for executing or reading the L2-to-L1 message. - * @param {L2ToL1TransactionEvent} event The event containing the data of the L2-to-L1 message. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1SignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. + * @param {SignerOrProvider} ParentChainSignerOrProvider Signer or provider to be used for executing or reading the Chain-to-ParentChain message. + * @param {ChildToParentTransactionEvent} event The event containing the data of the Chain-to-ParentChain message. + * @param {Provider} [ParentChainProvider] Optional. Used to override the Provider which is attached to `ParentChainSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromEvent( - l1SignerOrProvider: T, - event: L2ToL1TransactionEvent, - l1Provider?: Provider - ): L2ToL1MessageReaderOrWriter + parentChainSignerOrProvider: T, + event: ChildToParentTransactionEvent, + parentChainProvider?: Provider + ): ChildToParentMessageReaderOrWriter static fromEvent( - l1SignerOrProvider: T, - event: L2ToL1TransactionEvent, - l1Provider?: Provider - ): L2ToL1MessageReader | L2ToL1MessageWriter { - return SignerProviderUtils.isSigner(l1SignerOrProvider) - ? new L2ToL1MessageWriter(l1SignerOrProvider, event, l1Provider) - : new L2ToL1MessageReader(l1SignerOrProvider, event) + parentChainSignerOrProvider: T, + event: ChildToParentTransactionEvent, + parentChainProvider?: Provider + ): ChildToParentMessageReader | ChildToParentMessageWriter { + return SignerProviderUtils.isSigner(parentChainSignerOrProvider) + ? new ChildToParentMessageWriter( + parentChainSignerOrProvider, + event, + parentChainProvider + ) + : new ChildToParentMessageReader(parentChainSignerOrProvider, event) } /** - * Get event logs for L2ToL1 transactions. - * @param l2Provider + * Get event logs for ChildToParent transactions. + * @param childChainProvider * @param filter Block range filter * @param position The batchnumber indexed field was removed in nitro and a position indexed field was added. * For pre-nitro events the value passed in here will be used to find events with the same batchnumber. * For post nitro events it will be used to find events with the same position. - * @param destination The L1 destination of the L2ToL1 message + * @param destination The ParentChain destination of the ChildToParent message * @param hash The uniqueId indexed field was removed in nitro and a hash indexed field was added. * For pre-nitro events the value passed in here will be used to find events with the same uniqueId. * For post nitro events it will be used to find events with the same hash. * @param indexInBatch The index in the batch, only valid for pre-nitro events. This parameter is ignored post-nitro * @returns Any classic and nitro events that match the provided filters. */ - public static async getL2ToL1Events( - l2Provider: Provider, + public static async getChildToParentEvents( + childChainProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, position?: BigNumber, destination?: string, hash?: BigNumber, indexInBatch?: BigNumber - ): Promise<(L2ToL1TransactionEvent & { transactionHash: string })[]> { - const l2Network = await getChildChain(l2Provider) + ): Promise<(ChildToParentTransactionEvent & { transactionHash: string })[]> { + const childChain = await getChildChain(childChainProvider) const inClassicRange = (blockTag: BlockTag, nitroGenBlock: number) => { if (typeof blockTag === 'string') { @@ -150,14 +154,14 @@ export class L2ToL1Message { // only fetch nitro events after the genesis block const classicFilter = { - fromBlock: inClassicRange(filter.fromBlock, l2Network.nitroGenesisBlock), - toBlock: inClassicRange(filter.toBlock, l2Network.nitroGenesisBlock), + fromBlock: inClassicRange(filter.fromBlock, childChain.nitroGenesisBlock), + toBlock: inClassicRange(filter.toBlock, childChain.nitroGenesisBlock), } const logQueries = [] if (classicFilter.fromBlock !== classicFilter.toBlock) { logQueries.push( classic.L2ToL1MessageClassic.getL2ToL1Events( - l2Provider, + childChainProvider, classicFilter, position, destination, @@ -168,13 +172,13 @@ export class L2ToL1Message { } const nitroFilter = { - fromBlock: inNitroRange(filter.fromBlock, l2Network.nitroGenesisBlock), - toBlock: inNitroRange(filter.toBlock, l2Network.nitroGenesisBlock), + fromBlock: inNitroRange(filter.fromBlock, childChain.nitroGenesisBlock), + toBlock: inNitroRange(filter.toBlock, childChain.nitroGenesisBlock), } if (nitroFilter.fromBlock !== nitroFilter.toBlock) { logQueries.push( nitro.L2ToL1MessageNitro.getL2ToL1Events( - l2Provider, + childChainProvider, nitroFilter, position, destination, @@ -188,34 +192,37 @@ export class L2ToL1Message { } /** - * Provides read-only access for l2-to-l1-messages + * Provides read-only access for Chain-to-ParentChain-messages */ -export class L2ToL1MessageReader extends L2ToL1Message { +export class ChildToParentMessageReader extends ChildToParentMessage { private readonly classicReader?: classic.L2ToL1MessageReaderClassic private readonly nitroReader?: nitro.L2ToL1MessageReaderNitro constructor( - protected readonly l1Provider: Provider, - event: L2ToL1TransactionEvent + protected readonly parentChainProvider: Provider, + event: ChildToParentTransactionEvent ) { super() if (this.isClassic(event)) { this.classicReader = new classic.L2ToL1MessageReaderClassic( - l1Provider, + parentChainProvider, event.batchNumber, event.indexInBatch ) } else { - this.nitroReader = new nitro.L2ToL1MessageReaderNitro(l1Provider, event) + this.nitroReader = new nitro.L2ToL1MessageReaderNitro( + parentChainProvider, + event + ) } } public async getOutboxProof( - l2Provider: Provider + childChainProvider: Provider ): Promise { if (this.nitroReader) { - return await this.nitroReader.getOutboxProof(l2Provider) - } else return await this.classicReader!.tryGetProof(l2Provider) + return await this.nitroReader.getOutboxProof(childChainProvider) + } else return await this.classicReader!.tryGetProof(childChainProvider) } /** @@ -223,10 +230,13 @@ export class L2ToL1MessageReader extends L2ToL1Message { * In order to check if the message has been executed proof info must be provided. * @returns */ - public async status(l2Provider: Provider): Promise { - // can we create an l2tol1message here, we need to - the constructor is what we need - if (this.nitroReader) return await this.nitroReader.status(l2Provider) - else return await this.classicReader!.status(l2Provider) + public async status( + childChainProvider: Provider + ): Promise { + // can we create an ChildToParentmessage here, we need to - the constructor is what we need + if (this.nitroReader) + return await this.nitroReader.status(childChainProvider) + else return await this.classicReader!.status(childChainProvider) } /** @@ -237,81 +247,85 @@ export class L2ToL1MessageReader extends L2ToL1Message { * @returns */ public async waitUntilReadyToExecute( - l2Provider: Provider, + childChainProvider: Provider, retryDelay = 500 ): Promise { if (this.nitroReader) - return this.nitroReader.waitUntilReadyToExecute(l2Provider, retryDelay) + return this.nitroReader.waitUntilReadyToExecute( + childChainProvider, + retryDelay + ) else return this.classicReader!.waitUntilOutboxEntryCreated( - l2Provider, + childChainProvider, retryDelay ) } /** - * Estimates the L1 block number in which this L2 to L1 tx will be available for execution. + * Estimates the ParentChain block number in which this Chain to ParentChain tx will be available for execution. * If the message can or already has been executed, this returns null - * @param l2Provider - * @returns expected L1 block number where the L2 to L1 message will be executable. Returns null if the message can or already has been executed + * @param childChainProvider + * @returns expected ParentChain block number where the Chain to ParentChain message will be executable. Returns null if the message can or already has been executed */ public async getFirstExecutableBlock( - l2Provider: Provider + childChainProvider: Provider ): Promise { if (this.nitroReader) - return this.nitroReader.getFirstExecutableBlock(l2Provider) - else return this.classicReader!.getFirstExecutableBlock(l2Provider) + return this.nitroReader.getFirstExecutableBlock(childChainProvider) + else return this.classicReader!.getFirstExecutableBlock(childChainProvider) } } /** - * Provides read and write access for l2-to-l1-messages + * Provides read and write access for Chain-to-ParentChain-messages */ -export class L2ToL1MessageWriter extends L2ToL1MessageReader { +export class ChildToParentMessageWriter extends ChildToParentMessageReader { private readonly classicWriter?: classic.L2ToL1MessageWriterClassic private readonly nitroWriter?: nitro.L2ToL1MessageWriterNitro /** - * Instantiates a new `L2ToL1MessageWriter` object. + * Instantiates a new `ChildToParentMessageWriter` object. * - * @param {Signer} l1Signer The signer to be used for executing the L2-to-L1 message. - * @param {L2ToL1TransactionEvent} event The event containing the data of the L2-to-L1 message. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1Signer` in case you need more control. This will be a required parameter in a future major version update. + * @param {Signer} ParentChainSigner The signer to be used for executing the Chain-to-ParentChain message. + * @param {ChildToParentTransactionEvent} event The event containing the data of the Chain-to-ParentChain message. + * @param {Provider} [ParentChainProvider] Optional. Used to override the Provider which is attached to `ParentChainSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( - l1Signer: Signer, - event: L2ToL1TransactionEvent, - l1Provider?: Provider + parentChainSigner: Signer, + event: ChildToParentTransactionEvent, + parentChainProvider?: Provider ) { - super(l1Provider ?? l1Signer.provider!, event) + super(parentChainProvider ?? parentChainSigner.provider!, event) if (this.isClassic(event)) { this.classicWriter = new classic.L2ToL1MessageWriterClassic( - l1Signer, + parentChainSigner, event.batchNumber, event.indexInBatch, - l1Provider + parentChainProvider ) } else { this.nitroWriter = new nitro.L2ToL1MessageWriterNitro( - l1Signer, + parentChainSigner, event, - l1Provider + parentChainProvider ) } } /** - * Executes the L2ToL1Message on L1. + * Executes the ChildToParentMessage on ParentChain. * Will throw an error if the outbox entry has not been created, which happens when the * corresponding assertion is confirmed. * @returns */ public async execute( - l2Provider: Provider, + childChainProvider: Provider, overrides?: Overrides ): Promise { - if (this.nitroWriter) return this.nitroWriter.execute(l2Provider, overrides) - else return await this.classicWriter!.execute(l2Provider, overrides) + if (this.nitroWriter) + return this.nitroWriter.execute(childChainProvider, overrides) + else return await this.classicWriter!.execute(childChainProvider, overrides) } } diff --git a/src/lib/message/L2Transaction.ts b/src/lib/message/L2Transaction.ts index 51ac0fa7b2..30804921bb 100644 --- a/src/lib/message/L2Transaction.ts +++ b/src/lib/message/L2Transaction.ts @@ -25,11 +25,11 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { - L2ToL1MessageReader, - L2ToL1MessageReaderOrWriter, - L2ToL1Message, - L2ToL1MessageWriter, - L2ToL1TransactionEvent, + ChildToParentMessageReader as L2ToL1MessageReader, + ChildToParentMessageReaderOrWriter as L2ToL1MessageReaderOrWriter, + ChildToParentMessage as L2ToL1Message, + ChildToParentMessageWriter as L2ToL1MessageWriter, + ChildToParentTransactionEvent as L2ToL1TransactionEvent, } from './L2ToL1Message' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ArbRetryableTx__factory } from '../abi/factories/ArbRetryableTx__factory' diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 8cb4d8e09f..3cdde2f1d2 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -29,10 +29,10 @@ import { prettyLog, skipIfMainnet, } from './testHelpers' -import { L2ToL1Message } from '../../src/lib/message/L2ToL1Message' +import { ChildToParentMessage } from '../../src/lib/message/L2ToL1Message' import { L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' import { L2TransactionReceipt } from '../../src/lib/message/L2Transaction' -import { ParentToChildMessageStatus as L1ToL2MessageStatus } from '../../src/lib/message/L1ToL2Message' +import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' import { testSetup } from '../../scripts/testSetup' dotenv.config() @@ -166,7 +166,7 @@ describe('Ether', async () => { const retryableTicketResult = await l1ToL2Message.waitForStatus() expect(retryableTicketResult.status).to.eq( - L1ToL2MessageStatus.REDEEMED, + ParentToChildMessageStatus.REDEEMED, 'Retryable ticket not redeemed' ) @@ -231,7 +231,7 @@ describe('Ether', async () => { 'eth withdraw getWithdrawalsInL2Transaction query came back empty' ).to.exist - const withdrawEvents = await L2ToL1Message.getL2ToL1Events( + const withdrawEvents = await ChildToParentMessage.getChildToParentEvents( l2Signer.provider!, { fromBlock: withdrawEthRec.blockNumber, toBlock: 'latest' }, undefined, diff --git a/tests/unit/l2toL1MessageEvents.test.ts b/tests/unit/l2toL1MessageEvents.test.ts index d17bc71018..eea95ca9b7 100644 --- a/tests/unit/l2toL1MessageEvents.test.ts +++ b/tests/unit/l2toL1MessageEvents.test.ts @@ -18,16 +18,16 @@ import { Logger, LogLevel } from '@ethersproject/logger' Logger.setLogLevel(LogLevel.ERROR) -import { L2ToL1Message } from '../../src' +import { ChildToParentMessage } from '../../src/lib/message/L2ToL1Message' import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito' -describe('L2ToL1Message events', () => { - // L2ToL1Transaction +describe('ChildToParentMessage events', () => { + // ChildToParentTransaction const classicTopic = '0x5baaa87db386365b5c161be377bc3d8e317e8d98d71a3ca7ed7d555340c8f767' - // L2ToL1Tx + // ChildToParentTx const nitroTopic = '0x3e7aafa77dbf186b7fd488006beff893744caa3c4f6f299e8a709fa2087374fc' @@ -59,7 +59,7 @@ describe('L2ToL1Message events', () => { const fromBlock = 0 const toBlock = 1000 - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) @@ -82,7 +82,7 @@ describe('L2ToL1Message events', () => { const fromBlock = l2Network.nitroGenesisBlock const toBlock = l2Network.nitroGenesisBlock + 500 - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) @@ -105,7 +105,7 @@ describe('L2ToL1Message events', () => { const fromBlock = 0 const toBlock = l2Network.nitroGenesisBlock + 500 - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) @@ -138,7 +138,7 @@ describe('L2ToL1Message events', () => { const fromBlock = 'earliest' const toBlock = 'latest' - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) @@ -171,7 +171,7 @@ describe('L2ToL1Message events', () => { const fromBlock = l2Network.nitroGenesisBlock + 2 const toBlock = 'latest' - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) @@ -194,7 +194,7 @@ describe('L2ToL1Message events', () => { const fromBlock = 'earliest' const toBlock = 'latest' - await L2ToL1Message.getL2ToL1Events(l2Provider, { + await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, toBlock: toBlock, }) From de8a7b835815c07c1d2424d325b76f41103953c3 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 16 Jan 2024 09:25:27 -0500 Subject: [PATCH 06/74] chore renames: L2ToL1MessageNitro to ChildToParentChain (#351) * chore: renames L1/2 to parentChain/chain in inbox * chore: update l1/2 name for dataEntities * chore: renames L1ToL2Message to parentChain/Chain * chore: renames L2ToL1Message to chain/parentChain * chore: renames L1ToL2Message to parentChain/Chain * fix integration test * fix unit tests * fix test * chore renames: L2ToL1MessageNitro to ChainToParentChain * chore: renames to ChildToParentChain * chore: renames to ChildToParentChild for Nitro * chore: rename to ParentToChildMessage * chore: rename to ParentToChild * rename more function internals --- src/lib/message/L2ToL1Message.ts | 10 +- src/lib/message/L2ToL1MessageNitro.ts | 331 ++++++++++++++------------ 2 files changed, 181 insertions(+), 160 deletions(-) diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index d9a1651bdc..882ed0dfa1 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -177,7 +177,7 @@ export class ChildToParentMessage { } if (nitroFilter.fromBlock !== nitroFilter.toBlock) { logQueries.push( - nitro.L2ToL1MessageNitro.getL2ToL1Events( + nitro.ChildToParentChainMessageNitro.getChildToParentChainEvents( childChainProvider, nitroFilter, position, @@ -196,7 +196,7 @@ export class ChildToParentMessage { */ export class ChildToParentMessageReader extends ChildToParentMessage { private readonly classicReader?: classic.L2ToL1MessageReaderClassic - private readonly nitroReader?: nitro.L2ToL1MessageReaderNitro + private readonly nitroReader?: nitro.ChildToParentChainMessageReaderNitro constructor( protected readonly parentChainProvider: Provider, @@ -210,7 +210,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { event.indexInBatch ) } else { - this.nitroReader = new nitro.L2ToL1MessageReaderNitro( + this.nitroReader = new nitro.ChildToParentChainMessageReaderNitro( parentChainProvider, event ) @@ -282,7 +282,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { */ export class ChildToParentMessageWriter extends ChildToParentMessageReader { private readonly classicWriter?: classic.L2ToL1MessageWriterClassic - private readonly nitroWriter?: nitro.L2ToL1MessageWriterNitro + private readonly nitroWriter?: nitro.ChildToParentChainMessageWriterNitro /** * Instantiates a new `ChildToParentMessageWriter` object. @@ -306,7 +306,7 @@ export class ChildToParentMessageWriter extends ChildToParentMessageReader { parentChainProvider ) } else { - this.nitroWriter = new nitro.L2ToL1MessageWriterNitro( + this.nitroWriter = new nitro.ChildToParentChainMessageWriterNitro( parentChainSigner, event, parentChainProvider diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index e1651e284a..d6e082ea1f 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -30,7 +30,7 @@ import { RollupUserLogic__factory } from '../abi/factories/RollupUserLogic__fact import { Outbox__factory } from '../abi/factories/Outbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' -import { L2ToL1TxEvent } from '../abi/ArbSys' +import { L2ToL1TxEvent as ChildToParentChainTxEvent } from '../abi/ArbSys' import { ContractTransaction, Overrides } from 'ethers' import { Mutex } from 'async-mutex' import { EventFetcher, FetchedEvent } from '../utils/eventFetcher' @@ -46,116 +46,133 @@ import { ArbitrumProvider } from '../utils/arbProvider' import { ArbBlock } from '../dataEntities/rpc' import { JsonRpcProvider } from '@ethersproject/providers' import { EventArgs } from '../dataEntities/event' -import { L2ToL1MessageStatus } from '../dataEntities/message' +import { L2ToL1MessageStatus as ChildToParentChainMessageStatus } from '../dataEntities/message' /** * Conditional type for Signer or Provider. If T is of type Provider - * then L2ToL1MessageReaderOrWriter will be of type L2ToL1MessageReader. - * If T is of type Signer then L2ToL1MessageReaderOrWriter will be of - * type L2ToL1MessageWriter. + * then ChildToParentChainMessageReaderOrWriter will be of type ChildToParentChainMessageReader. + * If T is of type Signer then ChildToParentChainMessageReaderOrWriter will be of + * type ChildToParentChainMessageWriter. */ -export type L2ToL1MessageReaderOrWriterNitro = - T extends Provider ? L2ToL1MessageReaderNitro : L2ToL1MessageWriterNitro +export type ChildToParentChainMessageReaderOrWriterNitro< + T extends SignerOrProvider +> = T extends Provider + ? ChildToParentChainMessageReaderNitro + : ChildToParentChainMessageWriterNitro -// expected number of L1 blocks that it takes for an L2 tx to be included in a L1 assertion +// expected number of parent chain blocks that it takes for a Child chain tx to be included in a parent chain assertion const ASSERTION_CREATED_PADDING = 50 -// expected number of L1 blocks that it takes for a validator to confirm an L1 block after the node deadline is passed +// expected number of parent chain blocks that it takes for a validator to confirm an parent chain block after the node deadline is passed const ASSERTION_CONFIRMED_PADDING = 20 -const l2BlockRangeCache: { [key in string]: (number | undefined)[] } = {} +const childChainBlockRangeCache: { [key in string]: (number | undefined)[] } = + {} const mutex = new Mutex() -function getL2BlockRangeCacheKey({ - l2ChainId, - l1BlockNumber, +function getChildChainBlockRangeCacheKey({ + childChainId, + parentChainBlockNumber, }: { - l2ChainId: number - l1BlockNumber: number + childChainId: number + parentChainBlockNumber: number }) { - return `${l2ChainId}-${l1BlockNumber}` + return `${childChainId}-${parentChainBlockNumber}` } -function setL2BlockRangeCache(key: string, value: (number | undefined)[]) { - l2BlockRangeCache[key] = value +function setChildChainBlockRangeCache( + key: string, + value: (number | undefined)[] +) { + childChainBlockRangeCache[key] = value } async function getBlockRangesForL1BlockWithCache({ - l1Provider, - l2Provider, - forL1Block, + parentProvider, + childProvider, + forParentChainBlock, }: { - l1Provider: JsonRpcProvider - l2Provider: JsonRpcProvider - forL1Block: number + parentProvider: JsonRpcProvider + childProvider: JsonRpcProvider + forParentChainBlock: number }) { - const l2ChainId = (await l2Provider.getNetwork()).chainId - const key = getL2BlockRangeCacheKey({ - l2ChainId, - l1BlockNumber: forL1Block, + const childChainId = (await childProvider.getNetwork()).chainId + const key = getChildChainBlockRangeCacheKey({ + childChainId, + parentChainBlockNumber: forParentChainBlock, }) - if (l2BlockRangeCache[key]) { - return l2BlockRangeCache[key] + if (childChainBlockRangeCache[key]) { + return childChainBlockRangeCache[key] } // implements a lock that only fetches cache once const release = await mutex.acquire() // if cache has been acquired while awaiting the lock - if (l2BlockRangeCache[key]) { + if (childChainBlockRangeCache[key]) { release() - return l2BlockRangeCache[key] + return childChainBlockRangeCache[key] } try { - const l2BlockRange = await getBlockRangesForL1Block({ - forL1Block, - provider: l1Provider, + const childChainBlockRange = await getBlockRangesForL1Block({ + forL1Block: forParentChainBlock, + provider: parentProvider, }) - setL2BlockRangeCache(key, l2BlockRange) + setChildChainBlockRangeCache(key, childChainBlockRange) } finally { release() } - return l2BlockRangeCache[key] + return childChainBlockRangeCache[key] } /** - * Base functionality for nitro L2->L1 messages + * Base functionality for nitro Child->Parent messages */ -export class L2ToL1MessageNitro { - protected constructor(public readonly event: EventArgs) {} +export class ChildToParentChainMessageNitro { + protected constructor( + public readonly event: EventArgs + ) {} /** - * Instantiates a new `L2ToL1MessageWriterNitro` or `L2ToL1MessageReaderNitro` object. + * Instantiates a new `ChildToParentChainMessageWriterNitro` or `ChildToParentChainMessageReaderNitro` object. * - * @param {SignerOrProvider} l1SignerOrProvider Signer or provider to be used for executing or reading the L2-to-L1 message. - * @param {EventArgs} event The event containing the data of the L2-to-L1 message. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1SignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. + * @param {SignerOrProvider} parentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. + * @param {EventArgs} event The event containing the data of the Child-to-Parent message. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromEvent( - l1SignerOrProvider: T, - event: EventArgs, - l1Provider?: Provider - ): L2ToL1MessageReaderOrWriterNitro + parentSignerOrProvider: T, + event: EventArgs, + parentProvider?: Provider + ): ChildToParentChainMessageReaderOrWriterNitro public static fromEvent( - l1SignerOrProvider: T, - event: EventArgs, - l1Provider?: Provider - ): L2ToL1MessageReaderNitro | L2ToL1MessageWriterNitro { - return SignerProviderUtils.isSigner(l1SignerOrProvider) - ? new L2ToL1MessageWriterNitro(l1SignerOrProvider, event, l1Provider) - : new L2ToL1MessageReaderNitro(l1SignerOrProvider, event) + parentSignerOrProvider: T, + event: EventArgs, + parentProvider?: Provider + ): + | ChildToParentChainMessageReaderNitro + | ChildToParentChainMessageWriterNitro { + return SignerProviderUtils.isSigner(parentSignerOrProvider) + ? new ChildToParentChainMessageWriterNitro( + parentSignerOrProvider, + event, + parentProvider + ) + : new ChildToParentChainMessageReaderNitro(parentSignerOrProvider, event) } - public static async getL2ToL1Events( - l2Provider: Provider, + public static async getChildToParentChainEvents( + childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, position?: BigNumber, destination?: string, hash?: BigNumber - ): Promise<(EventArgs & { transactionHash: string })[]> { - const eventFetcher = new EventFetcher(l2Provider) + ): Promise< + (EventArgs & { transactionHash: string })[] + > { + const eventFetcher = new EventFetcher(childProvider) return ( await eventFetcher.getEvents( ArbSys__factory, @@ -167,9 +184,9 @@ export class L2ToL1MessageNitro { } /** - * Provides read-only access nitro for l2-to-l1-messages + * Provides read-only access nitro for child-to-parent-messages */ -export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { +export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMessageNitro { protected sendRootHash?: string protected sendRootSize?: BigNumber protected sendRootConfirmed?: boolean @@ -177,19 +194,19 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { protected l1BatchNumber?: number constructor( - protected readonly l1Provider: Provider, - event: EventArgs + protected readonly parentProvider: Provider, + event: EventArgs ) { super(event) } - public async getOutboxProof(l2Provider: Provider) { - const { sendRootSize } = await this.getSendProps(l2Provider) + public async getOutboxProof(childProvider: Provider) { + const { sendRootSize } = await this.getSendProps(childProvider) if (!sendRootSize) throw new ArbSdkError('Node not yet created, cannot get proof.') const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childProvider ) const outboxProofParams = @@ -204,11 +221,11 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { /** * Check if this message has already been executed in the Outbox */ - protected async hasExecuted(l2Provider: Provider): Promise { - const l2Network = await getChildChain(l2Provider) + protected async hasExecuted(childProvider: Provider): Promise { + const childChain = await getChildChain(childProvider) const outbox = Outbox__factory.connect( - l2Network.ethBridge.outbox, - this.l1Provider + childChain.ethBridge.outbox, + this.parentProvider ) return outbox.callStatic.isSpent(this.event.position) @@ -219,12 +236,14 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { * In order to check if the message has been executed proof info must be provided. * @returns */ - public async status(l2Provider: Provider): Promise { - const { sendRootConfirmed } = await this.getSendProps(l2Provider) - if (!sendRootConfirmed) return L2ToL1MessageStatus.UNCONFIRMED - return (await this.hasExecuted(l2Provider)) - ? L2ToL1MessageStatus.EXECUTED - : L2ToL1MessageStatus.CONFIRMED + public async status( + childProvider: Provider + ): Promise { + const { sendRootConfirmed } = await this.getSendProps(childProvider) + if (!sendRootConfirmed) return ChildToParentChainMessageStatus.UNCONFIRMED + return (await this.hasExecuted(childProvider)) + ? ChildToParentChainMessageStatus.EXECUTED + : ChildToParentChainMessageStatus.CONFIRMED } private parseNodeCreatedAssertion(event: FetchedEvent) { @@ -237,10 +256,10 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { } private async getBlockFromNodeLog( - l2Provider: JsonRpcProvider, + childProvider: JsonRpcProvider, log: FetchedEvent | undefined ) { - const arbitrumProvider = new ArbitrumProvider(l2Provider) + const arbitrumProvider = new ArbitrumProvider(childProvider) if (!log) { console.warn('No NodeCreated events found, defaulting to block 0') @@ -248,42 +267,42 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { } const parsedLog = this.parseNodeCreatedAssertion(log) - const l2Block = await arbitrumProvider.getBlock( + const childChainBlock = await arbitrumProvider.getBlock( parsedLog.afterState.blockHash ) - if (!l2Block) { + if (!childChainBlock) { throw new ArbSdkError( `Block not found. ${parsedLog.afterState.blockHash}` ) } - if (l2Block.sendRoot !== parsedLog.afterState.sendRoot) { + if (childChainBlock.sendRoot !== parsedLog.afterState.sendRoot) { throw new ArbSdkError( - `L2 block send root doesn't match parsed log. ${l2Block.sendRoot} ${parsedLog.afterState.sendRoot}` + `Child chain block send root doesn't match parsed log. ${childChainBlock.sendRoot} ${parsedLog.afterState.sendRoot}` ) } - return l2Block + return childChainBlock } private async getBlockFromNodeNum( rollup: RollupUserLogic, nodeNum: BigNumber, - l2Provider: Provider + childProvider: Provider ): Promise { const { createdAtBlock } = await rollup.getNode(nodeNum) let createdFromBlock = createdAtBlock let createdToBlock = createdAtBlock - // If L1 is Arbitrum, then L2 is an Orbit chain. - if (await isArbitrumChain(this.l1Provider)) { + // If Parent is Arbitrum, then Child is an Orbit chain. + if (await isArbitrumChain(this.parentProvider)) { try { - const l2BlockRange = await getBlockRangesForL1BlockWithCache({ - l1Provider: this.l1Provider as JsonRpcProvider, - l2Provider: l2Provider as JsonRpcProvider, - forL1Block: createdAtBlock.toNumber(), + const childChainBlockRange = await getBlockRangesForL1BlockWithCache({ + parentProvider: this.parentProvider as JsonRpcProvider, + childProvider: childProvider as JsonRpcProvider, + forParentChainBlock: createdAtBlock.toNumber(), }) - const startBlock = l2BlockRange[0] - const endBlock = l2BlockRange[1] + const startBlock = childChainBlockRange[0] + const endBlock = childChainBlockRange[1] if (!startBlock || !endBlock) { throw new Error() } @@ -314,18 +333,18 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { ) return await this.getBlockFromNodeLog( - l2Provider as JsonRpcProvider, + childProvider as JsonRpcProvider, logs[0] ) } - protected async getBatchNumber(l2Provider: Provider) { + protected async getBatchNumber(childProvider: Provider) { if (this.l1BatchNumber == undefined) { // findBatchContainingBlock errors if block number does not exist try { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childProvider ) const res = await nodeInterface.findBatchContainingBlock( this.event.arbBlockNum @@ -339,26 +358,28 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { return this.l1BatchNumber } - protected async getSendProps(l2Provider: Provider) { + protected async getSendProps(childProvider: Provider) { if (!this.sendRootConfirmed) { - const l2Network = await getChildChain(l2Provider) + const childChain = await getChildChain(childProvider) const rollup = RollupUserLogic__factory.connect( - l2Network.ethBridge.rollup, - this.l1Provider + childChain.ethBridge.rollup, + this.parentProvider ) const latestConfirmedNodeNum = await rollup.callStatic.latestConfirmed() - const l2BlockConfirmed = await this.getBlockFromNodeNum( + const childChainBlockConfirmed = await this.getBlockFromNodeNum( rollup, latestConfirmedNodeNum, - l2Provider + childProvider ) - const sendRootSizeConfirmed = BigNumber.from(l2BlockConfirmed.sendCount) + const sendRootSizeConfirmed = BigNumber.from( + childChainBlockConfirmed.sendCount + ) if (sendRootSizeConfirmed.gt(this.event.position)) { this.sendRootSize = sendRootSizeConfirmed - this.sendRootHash = l2BlockConfirmed.sendRoot + this.sendRootHash = childChainBlockConfirmed.sendRoot this.sendRootConfirmed = true } else { // if the node has yet to be confirmed we'll still try to find proof info from unconfirmed nodes @@ -366,16 +387,16 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { if (latestNodeNum.gt(latestConfirmedNodeNum)) { // In rare case latestNodeNum can be equal to latestConfirmedNodeNum // eg immediately after an upgrade, or at genesis, or on a chain where confirmation time = 0 like AnyTrust may have - const l2Block = await this.getBlockFromNodeNum( + const childChainBlock = await this.getBlockFromNodeNum( rollup, latestNodeNum, - l2Provider + childProvider ) - const sendRootSize = BigNumber.from(l2Block.sendCount) + const sendRootSize = BigNumber.from(childChainBlock.sendCount) if (sendRootSize.gt(this.event.position)) { this.sendRootSize = sendRootSize - this.sendRootHash = l2Block.sendRoot + this.sendRootHash = childChainBlock.sendRoot } } } @@ -395,47 +416,47 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { * @returns */ public async waitUntilReadyToExecute( - l2Provider: Provider, + childProvider: Provider, retryDelay = 500 ): Promise { - const status = await this.status(l2Provider) + const status = await this.status(childProvider) if ( - status === L2ToL1MessageStatus.CONFIRMED || - status === L2ToL1MessageStatus.EXECUTED + status === ChildToParentChainMessageStatus.CONFIRMED || + status === ChildToParentChainMessageStatus.EXECUTED ) { return } else { await wait(retryDelay) - await this.waitUntilReadyToExecute(l2Provider, retryDelay) + await this.waitUntilReadyToExecute(childProvider, retryDelay) } } /** - * Estimates the L1 block number in which this L2 to L1 tx will be available for execution. + * Estimates the parent chain block number in which this child chain to parent chain tx will be available for execution. * If the message can or already has been executed, this returns null - * @param l2Provider - * @returns expected L1 block number where the L2 to L1 message will be executable. Returns null if the message can be or already has been executed + * @param childProvider + * @returns expected parent chain block number where the child chain to parent chain message will be executable. Returns null if the message can be or already has been executed */ public async getFirstExecutableBlock( - l2Provider: Provider + childProvider: Provider ): Promise { - const l2Network = await getChildChain(l2Provider) + const childChain = await getChildChain(childProvider) const rollup = RollupUserLogic__factory.connect( - l2Network.ethBridge.rollup, - this.l1Provider + childChain.ethBridge.rollup, + this.parentProvider ) - const status = await this.status(l2Provider) - if (status === L2ToL1MessageStatus.EXECUTED) return null - if (status === L2ToL1MessageStatus.CONFIRMED) return null + const status = await this.status(childProvider) + if (status === ChildToParentChainMessageStatus.EXECUTED) return null + if (status === ChildToParentChainMessageStatus.CONFIRMED) return null // consistency check in case we change the enum in the future - if (status !== L2ToL1MessageStatus.UNCONFIRMED) - throw new ArbSdkError('L2ToL1Msg expected to be unconfirmed') + if (status !== ChildToParentChainMessageStatus.UNCONFIRMED) + throw new ArbSdkError('ChildToParentChainMsg expected to be unconfirmed') - const latestBlock = await this.l1Provider.getBlockNumber() - const eventFetcher = new EventFetcher(this.l1Provider) + const latestBlock = await this.parentProvider.getBlockNumber() + const eventFetcher = new EventFetcher(this.parentProvider) const logs = ( await eventFetcher.getEvents( RollupUserLogic__factory, @@ -443,7 +464,7 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { { fromBlock: Math.max( latestBlock - - BigNumber.from(l2Network.confirmPeriodBlocks) + BigNumber.from(childChain.confirmPeriodBlocks) .add(ASSERTION_CONFIRMED_PADDING) .toNumber(), 0 @@ -454,21 +475,21 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { ) ).sort((a, b) => a.event.nodeNum.toNumber() - b.event.nodeNum.toNumber()) - const lastL2Block = + const lastChildChainBlock = logs.length === 0 ? undefined : await this.getBlockFromNodeLog( - l2Provider as JsonRpcProvider, + childProvider as JsonRpcProvider, logs[logs.length - 1] ) - const lastSendCount = lastL2Block - ? BigNumber.from(lastL2Block.sendCount) + const lastSendCount = lastChildChainBlock + ? BigNumber.from(lastChildChainBlock.sendCount) : BigNumber.from(0) - // here we assume the L2 to L1 tx is actually valid, so the user needs to wait the max time + // here we assume the Child to Parent tx is actually valid, so the user needs to wait the max time // since there isn't a pending node that includes this message yet if (lastSendCount.lte(this.event.position)) - return BigNumber.from(l2Network.confirmPeriodBlocks) + return BigNumber.from(childChain.confirmPeriodBlocks) .add(ASSERTION_CREATED_PADDING) .add(ASSERTION_CONFIRMED_PADDING) .add(latestBlock) @@ -481,11 +502,11 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { while (left <= right) { const mid = Math.floor((left + right) / 2) const log = logs[mid] - const l2Block = await this.getBlockFromNodeLog( - l2Provider as JsonRpcProvider, + const childChainBlock = await this.getBlockFromNodeLog( + childProvider as JsonRpcProvider, log ) - const sendCount = BigNumber.from(l2Block.sendCount) + const sendCount = BigNumber.from(childChainBlock.sendCount) if (sendCount.gt(this.event.position)) { foundLog = log right = mid - 1 @@ -501,45 +522,45 @@ export class L2ToL1MessageReaderNitro extends L2ToL1MessageNitro { } /** - * Provides read and write access for nitro l2-to-l1-messages + * Provides read and write access for nitro child-to-Parent-messages */ -export class L2ToL1MessageWriterNitro extends L2ToL1MessageReaderNitro { +export class ChildToParentChainMessageWriterNitro extends ChildToParentChainMessageReaderNitro { /** - * Instantiates a new `L2ToL1MessageWriterNitro` object. + * Instantiates a new `ChildToParentChainMessageWriterNitro` object. * - * @param {Signer} l1Signer The signer to be used for executing the L2-to-L1 message. - * @param {EventArgs} event The event containing the data of the L2-to-L1 message. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1Signer` in case you need more control. This will be a required parameter in a future major version update. + * @param {Signer} parentSigner The signer to be used for executing the Child-to-Parent message. + * @param {EventArgs} event The event containing the data of the Child-to-Parent message. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( - private readonly l1Signer: Signer, - event: EventArgs, - l1Provider?: Provider + private readonly parentSigner: Signer, + event: EventArgs, + parentProvider?: Provider ) { - super(l1Provider ?? l1Signer.provider!, event) + super(parentProvider ?? parentSigner.provider!, event) } /** - * Executes the L2ToL1Message on L1. + * Executes the ChildToParentChainMessage on Parent Chain. * Will throw an error if the outbox entry has not been created, which happens when the * corresponding assertion is confirmed. * @returns */ public async execute( - l2Provider: Provider, + childProvider: Provider, overrides?: Overrides ): Promise { - const status = await this.status(l2Provider) - if (status !== L2ToL1MessageStatus.CONFIRMED) { + const status = await this.status(childProvider) + if (status !== ChildToParentChainMessageStatus.CONFIRMED) { throw new ArbSdkError( - `Cannot execute message. Status is: ${status} but must be ${L2ToL1MessageStatus.CONFIRMED}.` + `Cannot execute message. Status is: ${status} but must be ${ChildToParentChainMessageStatus.CONFIRMED}.` ) } - const proof = await this.getOutboxProof(l2Provider) - const l2Network = await getChildChain(l2Provider) + const proof = await this.getOutboxProof(childProvider) + const childChain = await getChildChain(childProvider) const outbox = Outbox__factory.connect( - l2Network.ethBridge.outbox, - this.l1Signer + childChain.ethBridge.outbox, + this.parentSigner ) return await outbox.executeTransaction( From 4300c4bf9a2150e3316db16638acc73ae68990a7 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:55:00 -0500 Subject: [PATCH 07/74] fix issues with merge --- scripts/testSetup.ts | 45 ++++---- src/index.ts | 12 +-- src/lib/assetBridger/assetBridger.ts | 6 +- src/lib/assetBridger/erc20Bridger.ts | 5 +- src/lib/assetBridger/ethBridger.ts | 4 +- src/lib/dataEntities/networks.ts | 100 +++++++++--------- src/lib/inbox/inbox.ts | 6 +- src/lib/message/L1Transaction.ts | 2 +- src/lib/message/L2ToL1Message.ts | 5 +- src/lib/message/L2ToL1MessageNitro.ts | 11 +- src/lib/utils/lib.ts | 4 +- src/lib/utils/multicall.ts | 20 ++-- .../customFeeTokenEthBridger.test.ts | 2 +- tests/integration/sendL2msg.test.ts | 5 +- tests/integration/testHelpers.ts | 2 +- 15 files changed, 117 insertions(+), 112 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index cec562127e..b16cbc8b6c 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -21,21 +21,19 @@ import { Wallet } from '@ethersproject/wallet' import { Provider } from '@ethersproject/abstract-provider' import dotenv from 'dotenv' -import { Signer } from 'ethers' -import * as fs from 'fs' -import * as path from 'path' -import { Erc20Bridger, EthBridger, InboxTools } from '../src' -import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' -import { ArbSdkError } from '../src/lib/dataEntities/errors' +import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { - ChildChain, - ChildChain as L1Network, - ParentChain as L2Network, - ParentChain, + L1Network, + L2Network, + getL1Network, + getL2Network, addCustomNetwork, - getChildChain, - getParentChain, } from '../src/lib/dataEntities/networks' +import { Signer } from 'ethers' +import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' +import * as path from 'path' +import * as fs from 'fs' +import { ArbSdkError } from '../src/lib/dataEntities/errors' import { approveL1CustomFeeToken, fundL1CustomFeeToken, @@ -74,8 +72,8 @@ export const getSigner = (provider: JsonRpcProvider, key?: string) => { } export const testSetup = async (): Promise<{ - l1Network: ParentChain - l2Network: ChildChain + l1Network: L1Network | L2Network + l2Network: L2Network l1Signer: Signer l2Signer: Signer l1Provider: Provider @@ -97,10 +95,12 @@ export const testSetup = async (): Promise<{ const l1Signer = seed.connect(ethProvider) const l2Signer = seed.connect(arbProvider) - let setL1Network: ParentChain, setL2Network: ChildChain + let setL1Network: L1Network | L2Network, setL2Network: L2Network try { - const l1Network = await getParentChain(l1Deployer) - const l2Network = await getChildChain(l2Deployer) + const l1Network = isTestingOrbitChains + ? await getL2Network(l1Deployer) + : await getL1Network(l1Deployer) + const l2Network = await getL2Network(l2Deployer) setL1Network = l1Network setL2Network = l2Network } catch (err) { @@ -124,21 +124,20 @@ export const testSetup = async (): Promise<{ } addCustomNetwork({ - customParentChain: ethLocal, - customChildChain: _l1Network, + customL1Network: ethLocal, + customL2Network: _l1Network, }) addCustomNetwork({ - customParentChain: l1Network, - customChildChain: l2Network, + customL2Network: l2Network, }) setL1Network = l1Network setL2Network = l2Network } else { addCustomNetwork({ - customParentChain: l1Network as L1Network, - customChildChain: l2Network, + customL1Network: l1Network as L1Network, + customL2Network: l2Network, }) setL1Network = l1Network diff --git a/src/index.ts b/src/index.ts index 316fc790c5..dbbab7dc57 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,12 +43,12 @@ export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimat export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { - ParentChains as L1Networks, - ChildChains as L2Networks, - ParentChain as L1Network, - ChildChain as L2Network, - getParentChain as getL1Network, - getChildChain as getL2Network, + L1Networks, + L2Networks, + L1Network, + L2Network, + getL1Network, + getL2Network, addCustomNetwork, addDefaultLocalNetwork, } from './lib/dataEntities/networks' diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 47ddb71a04..f6eeb77389 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -22,16 +22,14 @@ import { L1ContractTransaction } from '../message/L1Transaction' import { L2ContractTransaction } from '../message/L2Transaction' import { + L1Network, + L2Network, getParentForNetwork, - parentChains as l1Networks, - ChildChain as L2Network, - ParentChain, } from '../dataEntities/networks' import { SignerOrProvider, SignerProviderUtils, } from '../dataEntities/signerOrProvider' -import { L1Network } from '../..' /** * Base for bridging assets from l1 to l2 and back diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index f54637f992..29a4e54d46 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -45,7 +45,10 @@ import { L1ToL2MessageGasEstimator, } from '../message/L1ToL2MessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' -import { ChildChain, getChildChain } from '../dataEntities/networks' +import { + L2Network as ChildChain, + getL2Network as getChildChain, +} from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' import { DISABLED_GATEWAY } from '../dataEntities/constants' import { EventFetcher } from '../utils/eventFetcher' diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index f21dfbe968..b540b24432 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -46,7 +46,7 @@ import { import { OmitTyped } from '../utils/types' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' -import { getChildChain } from '../dataEntities/networks' +import { getL2Network as getChildChain } from '../dataEntities/networks' import { ERC20__factory } from '../abi/factories/ERC20__factory' import { isArbitrumChain } from '../utils/lib' @@ -175,7 +175,7 @@ export class EthBridger extends AssetBridger< } /** - * Asserts that the provided argument is of type `ApproveGasTokenParams` and not `ApproveGasTokenTxRequest`. + * Asserts that the provided argument is of type `ApproveGasTokenParams` and not `ApproveGasTokenTxRequest`. * @param params */ private isApproveGasTokenParams( diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 0b0a6594bb..1d42c47ed3 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -14,7 +14,7 @@ * limitations under the License. */ /* eslint-env node */ -'use strict' +;('use strict') import { SignerOrProvider, SignerProviderUtils } from './signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' @@ -23,7 +23,6 @@ import { ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, } from './constants' import { RollupAdminLogic__factory } from '../abi/factories/RollupAdminLogic__factory' -import { L1Network, L1Networks, L2Network, L2Networks } from '../..' export interface Network { chainID: number @@ -38,22 +37,25 @@ export interface Network { /** * Chain ids of children chains, i.e. chains that settle to this chain. */ - partnerChainIDs?: number[] + partnerChainIDs: number[] } /** - * Represents a parent chain, e.g. Ethereum Mainnet or Sepolia. + * Represents an L1 chain, e.g. Ethereum Mainnet or Sepolia. */ -export interface ParentChain extends Network { +export interface L1Network extends Network { isArbitrum: false } /** * Represents an Arbitrum chain, e.g. Arbitrum One, Arbitrum Sepolia, or an L3 chain. */ -export interface ChildChain extends Network { +export interface L2Network extends Network { tokenBridge: TokenBridge ethBridge: EthBridge + /** + * Chain id of the parent chain, i.e. the chain on which this chain settles to. + */ partnerChainID: number isArbitrum: true confirmPeriodBlocks: number @@ -100,16 +102,16 @@ export interface EthBridge { } } -export interface ParentChains { - [id: string]: ParentChain +export interface L1Networks { + [id: string]: L1Network } -export interface ChildChains { - [id: string]: ChildChain +export interface L2Networks { + [id: string]: L2Network } export interface Networks { - [id: string]: ParentChain | ChildChain + [id: string]: L1Network | L2Network } const mainnetTokenBridge: TokenBridge = { @@ -369,8 +371,8 @@ export const networks: Networks = { /** * Determines if a chain is a parent of *any* other chain. Could be an L1 or an L2 chain. */ -const isParentChain = (chain: ParentChain | ChildChain): boolean => { - return Boolean(chain.partnerChainIDs) && chain.partnerChainIDs?.length > 0 +const isParentChain = (chain: L1Network | L2Network): boolean => { + return chain.partnerChainIDs.length > 0 } /** @@ -474,7 +476,7 @@ export const getNetwork = async ( return chainId })() - let network: ParentChain | ChildChain | undefined = undefined + let network: L1Network | L2Network | undefined = undefined if (layer === 1) { network = getL1Chains()[chainID] @@ -494,10 +496,10 @@ export const getNetwork = async ( * * @note Throws if the chain is not an L1 chain. */ -export const getParentChain = ( +export const getL1Network = ( signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 1) as Promise +): Promise => { + return getNetwork(signerOrProviderOrChainID, 1) as Promise } /** @@ -505,10 +507,10 @@ export const getParentChain = ( * * @note Throws if the chain is not an Arbitrum chain. */ -export const getChildChain = ( +export const getL2Network = ( signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 2) as Promise +): Promise => { + return getNetwork(signerOrProviderOrChainID, 2) as Promise } /** @@ -579,59 +581,58 @@ const addNetwork = (network: L1Network | L2Network) => { /** * Registers a pair of custom L1 and L2 chains, or a single custom Arbitrum chain (L2 or L3). * - * @param customParentChain the custom L1 chain (optional) - * @param customChildChain the custom L2 or L3 chain + * @param customL1Network the custom L1 chain (optional) + * @param customL2Network the custom L2 or L3 chain */ export const addCustomNetwork = ({ - customParentChain, - customChildChain, + customL1Network, + customL2Network, }: { - customParentChain?: L1Network - customChildChain: L2Network + customL1Network?: L1Network + customL2Network: L2Network }): void => { - if (customParentChain) { - if (customParentChain.chainID !== customChildChain.partnerChainID) { + if (customL1Network) { + if (customL1Network.chainID !== customL2Network.partnerChainID) { throw new ArbSdkError( - `Partner chain id for L2 network ${customChildChain.chainID} doesn't match the provided L1 network. Expected ${customParentChain.chainID} but got ${customChildChain.partnerChainID}.` + `Partner chain id for L2 network ${customL2Network.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customL2Network.partnerChainID}.` ) } // check the if the parent chain is in any of the lists - if (l1Networks[customParentChain.chainID]) { + if (l1Networks[customL1Network.chainID]) { throw new ArbSdkError( - `Network ${customParentChain.chainID} already included` + `Network ${customL1Network.chainID} already included` ) - } else if (!customParentChain.isCustom) { + } else if (!customL1Network.isCustom) { throw new ArbSdkError( - `Custom network ${customParentChain.chainID} must have isCustom flag set to true` + `Custom network ${customL1Network.chainID} must have isCustom flag set to true` ) } - addNetwork(customParentChain) + addNetwork(customL1Network) } - if (l2Networks[customChildChain.chainID]) { + if (l2Networks[customL2Network.chainID]) { + throw new ArbSdkError(`Network ${customL2Network.chainID} already included`) + } else if (!customL2Network.isCustom) { throw new ArbSdkError( - `Network ${customChildChain.chainID} already included` - ) - } else if (!customChildChain.isCustom) { - throw new ArbSdkError( - `Custom network ${customChildChain.chainID} must have isCustom flag set to true` + `Custom network ${customL2Network.chainID} must have isCustom flag set to true` ) } - addNetwork(customChildChain) + addNetwork(customL2Network) } + /** * Registers a custom network that matches the one created by a Nitro local node. Useful in development. * * @see {@link https://github.com/OffchainLabs/nitro} */ export const addDefaultLocalNetwork = (): { - parentChain: ParentChain - chain: ChildChain + l1Network: L1Network + l2Network: L2Network } => { - const defaultLocalParentChain: ParentChain = { + const defaultLocalL1Network: L1Network = { blockTime: 10, chainID: 1337, explorerUrl: '', @@ -641,7 +642,7 @@ export const addDefaultLocalNetwork = (): { isArbitrum: false, } - const defaultLocalChain: ChildChain = { + const defaultLocalL2Network: L2Network = { chainID: 412346, confirmPeriodBlocks: 20, ethBridge: { @@ -681,13 +682,13 @@ export const addDefaultLocalNetwork = (): { } addCustomNetwork({ - customParentChain: defaultLocalParentChain, - customChildChain: defaultLocalChain, + customL1Network: defaultLocalL1Network, + customL2Network: defaultLocalL2Network, }) return { - parentChain: defaultLocalParentChain, - chain: defaultLocalChain, + l1Network: defaultLocalL1Network, + l2Network: defaultLocalL2Network, } } @@ -710,3 +711,4 @@ const createNetworkStateHandler = () => { const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } +export const getChildChain = getL2Network diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index b330c00c21..a275e95749 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -29,8 +29,8 @@ import { IInbox__factory } from '../abi/factories/IInbox__factory' import { RequiredPick } from '../utils/types' import { MessageDeliveredEvent } from '../abi/Bridge' import { - ChildChain, - ParentChain, + L2Network as ChildChain, + L1Network as ParentChain, getParentForNetwork, } from '../dataEntities/networks' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' @@ -68,7 +68,7 @@ export class InboxTools { /** * Parent chain for the given Arbitrum chain, can be an L1 or an L2 */ - private readonly parentChain: ParentChain + private readonly parentChain: ParentChain | ChildChain constructor( private readonly parentChainSigner: Signer, diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/L1Transaction.ts index 0cc8e150fb..463376aa09 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/L1Transaction.ts @@ -46,7 +46,7 @@ import { MessageDeliveredEvent } from '../abi/Bridge' import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' -import { getChildChain } from '../dataEntities/networks' +import { getL2Network as getChildChain } from '../dataEntities/networks' export interface L1ContractTransaction< TReceipt extends L1TransactionReceipt = L1TransactionReceipt diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index 64820bea25..a1a1fed6cd 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -249,7 +249,10 @@ export class ChildToParentMessageReader extends ChildToParentMessage { public async waitUntilReadyToExecute( childChainProvider: Provider, retryDelay = 500 - ): Promise { + ): Promise< + | ChildToParentChainMessageStatus.EXECUTED + | ChildToParentChainMessageStatus.CONFIRMED + > { if (this.nitroReader) return this.nitroReader.waitUntilReadyToExecute( childChainProvider, diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index 1d9fcd3b91..1dc8408d61 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -294,11 +294,11 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess let createdToBlock = createdAtBlock // If L1 is Arbitrum, then L2 is an Orbit chain. - if (await isArbitrumChain(this.l1Provider)) { + if (await isArbitrumChain(this.parentProvider)) { try { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - this.l1Provider + this.parentProvider ) const l2BlockRangeFromNode = await nodeInterface.l2BlockRangeForL1( @@ -433,7 +433,10 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess public async waitUntilReadyToExecute( childProvider: Provider, retryDelay = 500 - ): Promise { + ): Promise< + | ChildToParentChainMessageStatus.EXECUTED + | ChildToParentChainMessageStatus.CONFIRMED + > { const status = await this.status(childProvider) if ( status === ChildToParentChainMessageStatus.CONFIRMED || @@ -442,7 +445,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess return status } else { await wait(retryDelay) - await this.waitUntilReadyToExecute(childProvider, retryDelay) + return await this.waitUntilReadyToExecute(childProvider, retryDelay) } } diff --git a/src/lib/utils/lib.ts b/src/lib/utils/lib.ts index cf6a7558fe..b53c6f6f29 100644 --- a/src/lib/utils/lib.ts +++ b/src/lib/utils/lib.ts @@ -2,7 +2,7 @@ import { Provider } from '@ethersproject/abstract-provider' import { TransactionReceipt, JsonRpcProvider } from '@ethersproject/providers' import { ArbSdkError } from '../dataEntities/errors' import { ArbitrumProvider } from './arbProvider' -import { childChains } from '../dataEntities/networks' +import { l2Networks } from '../dataEntities/networks' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ARB_SYS_ADDRESS } from '../dataEntities/constants' import { BigNumber } from 'ethers' @@ -101,7 +101,7 @@ export async function getFirstBlockForL1Block({ const arbProvider = new ArbitrumProvider(provider) const currentArbBlock = await arbProvider.getBlockNumber() const arbitrumChainId = (await arbProvider.getNetwork()).chainId - const { nitroGenesisBlock } = childChains[arbitrumChainId] + const { nitroGenesisBlock } = l2Networks[arbitrumChainId] async function getL1Block(forL2Block: number) { const { l1BlockNumber } = await arbProvider.getBlock(forL2Block) diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index 9f6b1255ea..187b170c1f 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -24,11 +24,11 @@ import { Multicall2 } from '../abi/Multicall2' import { Multicall2__factory } from '../abi/factories/Multicall2__factory' import { ArbSdkError } from '../dataEntities/errors' import { - isParentChain, - ParentChain, - parentChains, - ChildChain, - childChains, + isL1Network, + L1Network, + l1Networks, + L2Network, + l2Networks, } from '../dataEntities/networks' /** @@ -131,8 +131,8 @@ export class MultiCaller { */ public static async fromProvider(provider: Provider): Promise { const chainId = (await provider.getNetwork()).chainId - const l2Network = childChains[chainId] as ChildChain | undefined - const l1Network = parentChains[chainId] as ParentChain | undefined + const l2Network = l2Networks[chainId] as L2Network | undefined + const l1Network = l1Networks[chainId] as L1Network | undefined const network = l2Network || l1Network if (!network) { @@ -142,11 +142,11 @@ export class MultiCaller { } let multiCallAddr: string - if (isParentChain(network)) { - const firstL2 = childChains[network.childChainIds[0]] + if (isL1Network(network)) { + const firstL2 = l2Networks[network.partnerChainIDs[0]] if (!firstL2) throw new ArbSdkError( - `No child chain found l1 network: ${network.chainID} : child chain ids ${network.childChainIds}` + `No partner chain found l1 network: ${network.chainID} : partner chain ids ${network.partnerChainIDs}` ) multiCallAddr = firstL2.tokenBridge.l1MultiCall } else { diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 0e5593bee8..481caf2856 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -204,7 +204,7 @@ describeOnlyWhenCustomGasToken( 'custom fee token withdraw getWithdrawalsInL2Transaction query came back empty' ) - const withdrawalEvents = await L2ToL1Message.getL2ToL1Events( + const withdrawalEvents = await L2ToL1Message.getChildToParentEvents( l2Provider, { fromBlock: withdrawalTxReceipt.blockNumber, toBlock: 'latest' }, undefined, diff --git a/tests/integration/sendL2msg.test.ts b/tests/integration/sendL2msg.test.ts index 591d4f994c..e9bcdd97ae 100644 --- a/tests/integration/sendL2msg.test.ts +++ b/tests/integration/sendL2msg.test.ts @@ -19,10 +19,7 @@ import { BigNumber, ethers, Signer } from 'ethers' import { InboxTools } from '../../src/lib/inbox/inbox' -import { - getChildChain as getL2Network, - ChildChain as L2Network, -} from '../../src/lib/dataEntities/networks' +import { getL2Network, L2Network } from '../../src/lib/dataEntities/networks' import { testSetup } from '../../scripts/testSetup' import { greeter } from './helper/greeter' import { expect } from 'chai' diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 2eee9f9955..3d7cc0ba1f 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -31,7 +31,7 @@ import { L1ToL2MessageStatus, L2ToL1MessageStatus, } from '../../src' -import { ChildChain as L2Network } from '../../src/lib/dataEntities/networks' +import { L2Network } from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' From 5ba0408b419e77e540f2a981b5177ec3c0d97709 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:01:18 -0500 Subject: [PATCH 08/74] fix lint issue --- src/lib/message/L1ToL2MessageCreator.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/L1ToL2MessageCreator.ts index 2a03c16913..5336dee6cf 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/L1ToL2MessageCreator.ts @@ -146,7 +146,6 @@ export class L1ToL2MessageCreator { options ) - const l2Network = await getChildChain(l2Provider) const nativeTokenIsEth = typeof l2Network.nativeToken === 'undefined' From 4157f3ad112c17b74b072febba335c66e30ade94 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:14:29 -0500 Subject: [PATCH 09/74] swap to use release for testnode --- .github/workflows/build-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index ee6e16b19c..c75b70db47 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -161,7 +161,7 @@ jobs: - name: Set up the local node uses: OffchainLabs/actions/run-nitro-test-node@main with: - nitro-testnode-ref: master + nitro-testnode-ref: release l3-node: ${{ matrix.orbit-test == '1' }} args: ${{ matrix.custom-fee == '1' && '--l3-fee-token' || '' }} From 551ba58e3d214eafa32e84340e119668835374ec Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:17:05 -0400 Subject: [PATCH 10/74] chore: renames L2ToL1MessageClassic to Child/ParentChain (#352) --- src/index.ts | 2 +- src/lib/dataEntities/message.ts | 2 +- src/lib/message/L2ToL1Message.ts | 17 +- src/lib/message/L2ToL1MessageClassic.ts | 184 ++++++++++-------- src/lib/message/L2ToL1MessageNitro.ts | 27 ++- .../customFeeTokenEthBridger.test.ts | 5 +- tests/integration/eth.test.ts | 2 +- tests/integration/testHelpers.ts | 2 +- 8 files changed, 127 insertions(+), 114 deletions(-) diff --git a/src/index.ts b/src/index.ts index dbbab7dc57..9a7e22c9a9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -56,7 +56,7 @@ export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' export { ArbitrumProvider } from './lib/utils/arbProvider' export * as constants from './lib/dataEntities/constants' -export { L2ToL1MessageStatus } from './lib/dataEntities/message' +export { ChildToParentMessageStatus } from './lib/dataEntities/message' export { RetryableData, RetryableDataTools, diff --git a/src/lib/dataEntities/message.ts b/src/lib/dataEntities/message.ts index 46633d4573..ca274d9d7a 100644 --- a/src/lib/dataEntities/message.ts +++ b/src/lib/dataEntities/message.ts @@ -53,7 +53,7 @@ export enum InboxMessageKind { L2MessageType_signedTx = 4, } -export enum L2ToL1MessageStatus { +export enum ChildToParentMessageStatus { /** * ArbSys.sendTxToL1 called, but assertion not yet confirmed */ diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/L2ToL1Message.ts index a1a1fed6cd..4b68240a4f 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/L2ToL1Message.ts @@ -34,7 +34,7 @@ import { } from '../abi/ArbSys' import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' -import { L2ToL1MessageStatus as ChildToParentChainMessageStatus } from '../dataEntities/message' +import { ChildToParentMessageStatus } from '../dataEntities/message' import { getChildChain } from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' @@ -160,7 +160,7 @@ export class ChildToParentMessage { const logQueries = [] if (classicFilter.fromBlock !== classicFilter.toBlock) { logQueries.push( - classic.L2ToL1MessageClassic.getL2ToL1Events( + classic.ChildToParentMessageClassic.getChildToParentEvents( childChainProvider, classicFilter, position, @@ -195,7 +195,7 @@ export class ChildToParentMessage { * Provides read-only access for Chain-to-ParentChain-messages */ export class ChildToParentMessageReader extends ChildToParentMessage { - private readonly classicReader?: classic.L2ToL1MessageReaderClassic + private readonly classicReader?: classic.ChildToParentMessageReaderClassic private readonly nitroReader?: nitro.ChildToParentChainMessageReaderNitro constructor( @@ -204,7 +204,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { ) { super() if (this.isClassic(event)) { - this.classicReader = new classic.L2ToL1MessageReaderClassic( + this.classicReader = new classic.ChildToParentMessageReaderClassic( parentChainProvider, event.batchNumber, event.indexInBatch @@ -232,7 +232,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { */ public async status( childChainProvider: Provider - ): Promise { + ): Promise { // can we create an ChildToParentmessage here, we need to - the constructor is what we need if (this.nitroReader) return await this.nitroReader.status(childChainProvider) @@ -250,8 +250,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { childChainProvider: Provider, retryDelay = 500 ): Promise< - | ChildToParentChainMessageStatus.EXECUTED - | ChildToParentChainMessageStatus.CONFIRMED + ChildToParentMessageStatus.EXECUTED | ChildToParentMessageStatus.CONFIRMED > { if (this.nitroReader) return this.nitroReader.waitUntilReadyToExecute( @@ -284,7 +283,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { * Provides read and write access for Chain-to-ParentChain-messages */ export class ChildToParentMessageWriter extends ChildToParentMessageReader { - private readonly classicWriter?: classic.L2ToL1MessageWriterClassic + private readonly classicWriter?: classic.ChildToParentMessageWriterClassic private readonly nitroWriter?: nitro.ChildToParentChainMessageWriterNitro /** @@ -302,7 +301,7 @@ export class ChildToParentMessageWriter extends ChildToParentMessageReader { super(parentChainProvider ?? parentChainSigner.provider!, event) if (this.isClassic(event)) { - this.classicWriter = new classic.L2ToL1MessageWriterClassic( + this.classicWriter = new classic.ChildToParentMessageWriterClassic( parentChainSigner, event.batchNumber, event.indexInBatch, diff --git a/src/lib/message/L2ToL1MessageClassic.ts b/src/lib/message/L2ToL1MessageClassic.ts index 159e454265..d023afeef4 100644 --- a/src/lib/message/L2ToL1MessageClassic.ts +++ b/src/lib/message/L2ToL1MessageClassic.ts @@ -29,7 +29,7 @@ import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { Outbox__factory } from '../abi/classic/factories/Outbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' -import { L2ToL1TransactionEvent } from '../abi/ArbSys' +import { L2ToL1TransactionEvent as ChildToParentTransactionEvent } from '../abi/ArbSys' import { ContractTransaction, Overrides } from 'ethers' import { EventFetcher } from '../utils/eventFetcher' import { @@ -39,7 +39,7 @@ import { import { isDefined, wait } from '../utils/lib' import { ArbSdkError } from '../dataEntities/errors' import { EventArgs } from '../dataEntities/event' -import { L2ToL1MessageStatus } from '../dataEntities/message' +import { ChildToParentMessageStatus } from '../dataEntities/message' import { getChildChain } from '../dataEntities/networks' export interface MessageBatchProofInfo { @@ -91,14 +91,17 @@ export interface MessageBatchProofInfo { /** * Conditional type for Signer or Provider. If T is of type Provider - * then L2ToL1MessageReaderOrWriter will be of type L2ToL1MessageReader. - * If T is of type Signer then L2ToL1MessageReaderOrWriter will be of - * type L2ToL1MessageWriter. + * then ChildToParentMessageReaderOrWriter will be of type ChildToParentMessageReader. + * If T is of type Signer then ChildToParentMessageReaderOrWriter will be of + * type ChildToParentMessageWriter. */ -export type L2ToL1MessageReaderOrWriterClassic = - T extends Provider ? L2ToL1MessageReaderClassic : L2ToL1MessageWriterClassic +export type ChildToParentMessageReaderOrWriterClassic< + T extends SignerOrProvider +> = T extends Provider + ? ChildToParentMessageReaderClassic + : ChildToParentMessageWriterClassic -export class L2ToL1MessageClassic { +export class ChildToParentMessageClassic { /** * The number of the batch this message is part of */ @@ -115,50 +118,52 @@ export class L2ToL1MessageClassic { } /** - * Instantiates a new `L2ToL1MessageWriterClassic` or `L2ToL1MessageReaderClassic` object. + * Instantiates a new `ChildToParentMessageWriterClassic` or `ChildToParentMessageReaderClassic` object. * - * @param {SignerOrProvider} l1SignerOrProvider Signer or provider to be used for executing or reading the L2-to-L1 message. - * @param {BigNumber} batchNumber The number of the batch containing the L2-to-L1 message. - * @param {BigNumber} indexInBatch The index of the L2-to-L1 message within the batch. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1SignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. + * @param {SignerOrProvider} parentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. + * @param {BigNumber} batchNumber The number of the batch containing the Child-to-Parent message. + * @param {BigNumber} indexInBatch The index of the Child-to-Parent message within the batch. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromBatchNumber( - l1SignerOrProvider: T, + parentSignerOrProvider: T, batchNumber: BigNumber, indexInBatch: BigNumber, - l1Provider?: Provider - ): L2ToL1MessageReaderOrWriterClassic + parentProvider?: Provider + ): ChildToParentMessageReaderOrWriterClassic public static fromBatchNumber( - l1SignerOrProvider: T, + parentSignerOrProvider: T, batchNumber: BigNumber, indexInBatch: BigNumber, - l1Provider?: Provider - ): L2ToL1MessageReaderClassic | L2ToL1MessageWriterClassic { - return SignerProviderUtils.isSigner(l1SignerOrProvider) - ? new L2ToL1MessageWriterClassic( - l1SignerOrProvider, + parentProvider?: Provider + ): ChildToParentMessageReaderClassic | ChildToParentMessageWriterClassic { + return SignerProviderUtils.isSigner(parentSignerOrProvider) + ? new ChildToParentMessageWriterClassic( + parentSignerOrProvider, batchNumber, indexInBatch, - l1Provider + parentProvider ) - : new L2ToL1MessageReaderClassic( - l1SignerOrProvider, + : new ChildToParentMessageReaderClassic( + parentSignerOrProvider, batchNumber, indexInBatch ) } - public static async getL2ToL1Events( - l2Provider: Provider, + public static async getChildToParentEvents( + childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, batchNumber?: BigNumber, destination?: string, uniqueId?: BigNumber, indexInBatch?: BigNumber ): Promise< - (EventArgs & { transactionHash: string })[] + (EventArgs & { + transactionHash: string + })[] > { - const eventFetcher = new EventFetcher(l2Provider) + const eventFetcher = new EventFetcher(childProvider) const events = ( await eventFetcher.getEvents( ArbSys__factory, @@ -180,11 +185,11 @@ export class L2ToL1MessageClassic { } /** - * Provides read-only access for classic l2-to-l1-messages + * Provides read-only access for classic Child-to-Parent-messages */ -export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { +export class ChildToParentMessageReaderClassic extends ChildToParentMessageClassic { constructor( - protected readonly l1Provider: Provider, + protected readonly parentProvider: Provider, batchNumber: BigNumber, indexInBatch: BigNumber ) { @@ -199,18 +204,21 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { /** * Classic had 2 outboxes, we need to find the correct one for the provided batch number - * @param l2Provider + * @param childProvider * @param batchNumber * @returns */ - protected async getOutboxAddress(l2Provider: Provider, batchNumber: number) { + protected async getOutboxAddress( + childProvider: Provider, + batchNumber: number + ) { if (!isDefined(this.outboxAddress)) { - const l2Network = await getChildChain(l2Provider) + const childChain = await getChildChain(childProvider) // find the outbox where the activation batch number of the next outbox // is greater than the supplied batch - const outboxes = isDefined(l2Network.ethBridge.classicOutboxes) - ? Object.entries(l2Network.ethBridge.classicOutboxes) + const outboxes = isDefined(childChain.ethBridge.classicOutboxes) + ? Object.entries(childChain.ethBridge.classicOutboxes) : [] const res = outboxes @@ -233,24 +241,24 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { return this.outboxAddress } - private async outboxEntryExists(l2Provider: Provider) { + private async outboxEntryExists(childProvider: Provider) { const outboxAddress = await this.getOutboxAddress( - l2Provider, + childProvider, this.batchNumber.toNumber() ) - const outbox = Outbox__factory.connect(outboxAddress, this.l1Provider) + const outbox = Outbox__factory.connect(outboxAddress, this.parentProvider) return await outbox.outboxEntryExists(this.batchNumber) } public static async tryGetProof( - l2Provider: Provider, + childProvider: Provider, batchNumber: BigNumber, indexInBatch: BigNumber ): Promise { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childProvider ) try { return await nodeInterface.legacyLookupMessageBatchProof( @@ -271,15 +279,15 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { /** * Get the execution proof for this message. Returns null if the batch does not exist yet. - * @param l2Provider + * @param childProvider * @returns */ public async tryGetProof( - l2Provider: Provider + childProvider: Provider ): Promise { if (!isDefined(this.proof)) { - this.proof = await L2ToL1MessageReaderClassic.tryGetProof( - l2Provider, + this.proof = await ChildToParentMessageReaderClassic.tryGetProof( + childProvider, this.batchNumber, this.indexInBatch ) @@ -290,16 +298,16 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { /** * Check if given outbox message has already been executed */ - public async hasExecuted(l2Provider: Provider): Promise { - const proofInfo = await this.tryGetProof(l2Provider) + public async hasExecuted(childProvider: Provider): Promise { + const proofInfo = await this.tryGetProof(childProvider) if (!isDefined(proofInfo)) return false const outboxAddress = await this.getOutboxAddress( - l2Provider, + childProvider, this.batchNumber.toNumber() ) - const outbox = Outbox__factory.connect(outboxAddress, this.l1Provider) + const outbox = Outbox__factory.connect(outboxAddress, this.parentProvider) try { await outbox.callStatic.executeTransaction( this.batchNumber, @@ -328,19 +336,21 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { * @param proofInfo * @returns */ - public async status(l2Provider: Provider): Promise { + public async status( + childProvider: Provider + ): Promise { try { - const messageExecuted = await this.hasExecuted(l2Provider) + const messageExecuted = await this.hasExecuted(childProvider) if (messageExecuted) { - return L2ToL1MessageStatus.EXECUTED + return ChildToParentMessageStatus.EXECUTED } - const outboxEntryExists = await this.outboxEntryExists(l2Provider) + const outboxEntryExists = await this.outboxEntryExists(childProvider) return outboxEntryExists - ? L2ToL1MessageStatus.CONFIRMED - : L2ToL1MessageStatus.UNCONFIRMED + ? ChildToParentMessageStatus.CONFIRMED + : ChildToParentMessageStatus.UNCONFIRMED } catch (e) { - return L2ToL1MessageStatus.UNCONFIRMED + return ChildToParentMessageStatus.UNCONFIRMED } } @@ -352,82 +362,84 @@ export class L2ToL1MessageReaderClassic extends L2ToL1MessageClassic { * @returns outbox entry status (either executed or confirmed but not pending) */ public async waitUntilOutboxEntryCreated( - l2Provider: Provider, + childProvider: Provider, retryDelay = 500 - ): Promise { - const exists = await this.outboxEntryExists(l2Provider) + ): Promise< + ChildToParentMessageStatus.EXECUTED | ChildToParentMessageStatus.CONFIRMED + > { + const exists = await this.outboxEntryExists(childProvider) if (exists) { - return (await this.hasExecuted(l2Provider)) - ? L2ToL1MessageStatus.EXECUTED - : L2ToL1MessageStatus.CONFIRMED + return (await this.hasExecuted(childProvider)) + ? ChildToParentMessageStatus.EXECUTED + : ChildToParentMessageStatus.CONFIRMED } else { await wait(retryDelay) - return await this.waitUntilOutboxEntryCreated(l2Provider, retryDelay) + return await this.waitUntilOutboxEntryCreated(childProvider, retryDelay) } } /** - * Estimates the L1 block number in which this L2 to L1 tx will be available for execution - * @param l2Provider - * @returns Always returns null for classic l2toL1 messages since they can be executed in any block now. + * Estimates the Parent Chain block number in which this Child-to-Parent tx will be available for execution + * @param childProvider + * @returns Always returns null for classic chainToParentChain messages since they can be executed in any block now. */ public async getFirstExecutableBlock( // eslint-disable-next-line @typescript-eslint/no-unused-vars - l2Provider: Provider + childProvider: Provider ): Promise { return null } } /** - * Provides read and write access for classic l2-to-l1-messages + * Provides read and write access for classic Child-to-Parent-messages */ -export class L2ToL1MessageWriterClassic extends L2ToL1MessageReaderClassic { +export class ChildToParentMessageWriterClassic extends ChildToParentMessageReaderClassic { /** - * Instantiates a new `L2ToL1MessageWriterClassic` object. + * Instantiates a new `ChildToParentMessageWriterClassic` object. * - * @param {Signer} l1Signer The signer to be used for executing the L2-to-L1 message. - * @param {BigNumber} batchNumber The number of the batch containing the L2-to-L1 message. - * @param {BigNumber} indexInBatch The index of the L2-to-L1 message within the batch. - * @param {Provider} [l1Provider] Optional. Used to override the Provider which is attached to `l1Signer` in case you need more control. This will be a required parameter in a future major version update. + * @param {Signer} parentSigner The signer to be used for executing the Child-to-Parent message. + * @param {BigNumber} batchNumber The number of the batch containing the Child-to-Parent message. + * @param {BigNumber} indexInBatch The index of the Child-to-Parent message within the batch. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( - private readonly l1Signer: Signer, + private readonly parentSigner: Signer, batchNumber: BigNumber, indexInBatch: BigNumber, - l1Provider?: Provider + parentProvider?: Provider ) { - super(l1Provider ?? l1Signer.provider!, batchNumber, indexInBatch) + super(parentProvider ?? parentSigner.provider!, batchNumber, indexInBatch) } /** - * Executes the L2ToL1Message on L1. + * Executes the ChildToParentMessage on Parent Chain. * Will throw an error if the outbox entry has not been created, which happens when the * corresponding assertion is confirmed. * @returns */ public async execute( - l2Provider: Provider, + childProvider: Provider, overrides?: Overrides ): Promise { - const status = await this.status(l2Provider) - if (status !== L2ToL1MessageStatus.CONFIRMED) { + const status = await this.status(childProvider) + if (status !== ChildToParentMessageStatus.CONFIRMED) { throw new ArbSdkError( - `Cannot execute message. Status is: ${status} but must be ${L2ToL1MessageStatus.CONFIRMED}.` + `Cannot execute message. Status is: ${status} but must be ${ChildToParentMessageStatus.CONFIRMED}.` ) } - const proofInfo = await this.tryGetProof(l2Provider) + const proofInfo = await this.tryGetProof(childProvider) if (!isDefined(proofInfo)) { throw new ArbSdkError( `Unexpected missing proof: ${this.batchNumber.toString()} ${this.indexInBatch.toString()}}` ) } const outboxAddress = await this.getOutboxAddress( - l2Provider, + childProvider, this.batchNumber.toNumber() ) - const outbox = Outbox__factory.connect(outboxAddress, this.l1Signer) + const outbox = Outbox__factory.connect(outboxAddress, this.parentSigner) // We can predict and print number of missing blocks // if not challenged return await outbox.functions.executeTransaction( diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/L2ToL1MessageNitro.ts index 1dc8408d61..6fc2e7857e 100644 --- a/src/lib/message/L2ToL1MessageNitro.ts +++ b/src/lib/message/L2ToL1MessageNitro.ts @@ -46,7 +46,7 @@ import { ArbitrumProvider } from '../utils/arbProvider' import { ArbBlock } from '../dataEntities/rpc' import { JsonRpcProvider } from '@ethersproject/providers' import { EventArgs } from '../dataEntities/event' -import { L2ToL1MessageStatus as ChildToParentChainMessageStatus } from '../dataEntities/message' +import { ChildToParentMessageStatus } from '../dataEntities/message' /** * Conditional type for Signer or Provider. If T is of type Provider @@ -238,12 +238,12 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess */ public async status( childProvider: Provider - ): Promise { + ): Promise { const { sendRootConfirmed } = await this.getSendProps(childProvider) - if (!sendRootConfirmed) return ChildToParentChainMessageStatus.UNCONFIRMED + if (!sendRootConfirmed) return ChildToParentMessageStatus.UNCONFIRMED return (await this.hasExecuted(childProvider)) - ? ChildToParentChainMessageStatus.EXECUTED - : ChildToParentChainMessageStatus.CONFIRMED + ? ChildToParentMessageStatus.EXECUTED + : ChildToParentMessageStatus.CONFIRMED } private parseNodeCreatedAssertion(event: FetchedEvent) { @@ -434,13 +434,12 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess childProvider: Provider, retryDelay = 500 ): Promise< - | ChildToParentChainMessageStatus.EXECUTED - | ChildToParentChainMessageStatus.CONFIRMED + ChildToParentMessageStatus.EXECUTED | ChildToParentMessageStatus.CONFIRMED > { const status = await this.status(childProvider) if ( - status === ChildToParentChainMessageStatus.CONFIRMED || - status === ChildToParentChainMessageStatus.EXECUTED + status === ChildToParentMessageStatus.CONFIRMED || + status === ChildToParentMessageStatus.EXECUTED ) { return status } else { @@ -466,11 +465,11 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess ) const status = await this.status(childProvider) - if (status === ChildToParentChainMessageStatus.EXECUTED) return null - if (status === ChildToParentChainMessageStatus.CONFIRMED) return null + if (status === ChildToParentMessageStatus.EXECUTED) return null + if (status === ChildToParentMessageStatus.CONFIRMED) return null // consistency check in case we change the enum in the future - if (status !== ChildToParentChainMessageStatus.UNCONFIRMED) + if (status !== ChildToParentMessageStatus.UNCONFIRMED) throw new ArbSdkError('ChildToParentChainMsg expected to be unconfirmed') const latestBlock = await this.parentProvider.getBlockNumber() @@ -569,9 +568,9 @@ export class ChildToParentChainMessageWriterNitro extends ChildToParentChainMess overrides?: Overrides ): Promise { const status = await this.status(childProvider) - if (status !== ChildToParentChainMessageStatus.CONFIRMED) { + if (status !== ChildToParentMessageStatus.CONFIRMED) { throw new ArbSdkError( - `Cannot execute message. Status is: ${status} but must be ${ChildToParentChainMessageStatus.CONFIRMED}.` + `Cannot execute message. Status is: ${status} but must be ${ChildToParentMessageStatus.CONFIRMED}.` ) } const proof = await this.getOutboxProof(childProvider) diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 481caf2856..aebc9e96d3 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -28,7 +28,10 @@ import { skipIfMainnet, wait, } from '../testHelpers' -import { L2ToL1Message, L2ToL1MessageStatus } from '../../../src' +import { + L2ToL1Message, + ChildToParentMessageStatus as L2ToL1MessageStatus, +} from '../../../src' import { describeOnlyWhenCustomGasToken } from './mochaExtensions' dotenv.config() diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 5e0c930208..f4610462e5 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -30,7 +30,7 @@ import { skipIfMainnet, } from './testHelpers' import { ChildToParentMessage } from '../../src/lib/message/L2ToL1Message' -import { L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' +import { ChildToParentMessageStatus as L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' import { L2TransactionReceipt } from '../../src/lib/message/L2Transaction' import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' import { testSetup } from '../../scripts/testSetup' diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 3d7cc0ba1f..c3ccd2bbd2 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -29,7 +29,7 @@ import { Signer, Wallet } from 'ethers' import { Erc20Bridger, L1ToL2MessageStatus, - L2ToL1MessageStatus, + ChildToParentMessageStatus as L2ToL1MessageStatus, } from '../../src' import { L2Network } from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' From c2296fcfe029b7ded36fb462f6084c366412d8f0 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:50:34 -0400 Subject: [PATCH 11/74] chore: rename L1ToL2MessageCreator to parent/child (#422) * chore: renames L2ToL1MessageClassic l1/2 to parent/child * update with tweaks from main * chore: rename L1ToL2MessageCreator to parent/child --------- Co-authored-by: spsjvc --- src/lib/message/L1ToL2MessageCreator.ts | 129 +++++++++------- .../integration/l1ToL2MessageCreator.test.ts | 138 +++++++++--------- 2 files changed, 147 insertions(+), 120 deletions(-) diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/L1ToL2MessageCreator.ts index 5336dee6cf..0b908e7cc1 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/L1ToL2MessageCreator.ts @@ -4,9 +4,12 @@ import { Provider } from '@ethersproject/abstract-provider' import { GasOverrides, - L1ToL2MessageGasEstimator, + L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, } from './L1ToL2MessageGasEstimator' -import { L1ContractTransaction, L1TransactionReceipt } from './L1Transaction' +import { + L1ContractTransaction as ParentChainContractTransaction, + L1TransactionReceipt as ParentChainTransactionReceipt, +} from './L1Transaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' import { getChildChain } from '../dataEntities/networks' import { ERC20Inbox__factory } from '../abi/factories/ERC20Inbox__factory' @@ -15,55 +18,61 @@ import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' import { getBaseFee } from '../utils/lib' import { - isL1ToL2TransactionRequest, - L1ToL2TransactionRequest, + isL1ToL2TransactionRequest as isParentToChildTransactionRequest, + L1ToL2TransactionRequest as ParentToChildTransactionRequest, } from '../dataEntities/transactionRequest' import { RetryableData } from '../dataEntities/retryableData' import { OmitTyped, PartialPick } from '../utils/types' -type L1ToL2GasKeys = +type ParentToChildGasKeys = | 'maxSubmissionCost' | 'maxFeePerGas' | 'gasLimit' | 'deposit' -export type L1ToL2MessageGasParams = Pick -export type L1ToL2MessageNoGasParams = OmitTyped -export type L1ToL2MessageParams = PartialPick< - L1ToL2MessageNoGasParams, +export type ParentToChildMessageGasParams = Pick< + RetryableData, + ParentToChildGasKeys +> +export type ParentToChildMessageNoGasParams = OmitTyped< + RetryableData, + ParentToChildGasKeys +> +export type ParentToChildMessageParams = PartialPick< + ParentToChildMessageNoGasParams, 'excessFeeRefundAddress' | 'callValueRefundAddress' > /** - * Creates retryable tickets by directly calling the Inbox contract on L1 + * Creates retryable tickets by directly calling the Inbox contract on Parent chain */ -export class L1ToL2MessageCreator { - constructor(public readonly l1Signer: Signer) { - if (!SignerProviderUtils.signerHasProvider(l1Signer)) { - throw new MissingProviderArbSdkError('l1Signer') +export class ParentToChildMessageCreator { + constructor(public readonly parentSigner: Signer) { + if (!SignerProviderUtils.signerHasProvider(parentSigner)) { + throw new MissingProviderArbSdkError('parentSigner') } } /** * Gets a current estimate for the supplied params * @param params - * @param l1Provider - * @param l2Provider + * @param parentProvider + * @param childProvider * @param retryableGasOverrides * @returns */ protected static async getTicketEstimate( - params: L1ToL2MessageNoGasParams, - l1Provider: Provider, - l2Provider: Provider, + params: ParentToChildMessageNoGasParams, + parentProvider: Provider, + childProvider: Provider, retryableGasOverrides?: GasOverrides - ): Promise> { - const baseFee = await getBaseFee(l1Provider) + ): Promise> { + const baseFee = await getBaseFee(parentProvider) - const gasEstimator = new L1ToL2MessageGasEstimator(l2Provider) + const gasEstimator = new ParentToChildMessageGasEstimator(childProvider) return await gasEstimator.estimateAll( params, baseFee, - l1Provider, + parentProvider, retryableGasOverrides ) } @@ -78,8 +87,8 @@ export class L1ToL2MessageCreator { * @returns */ protected static getTicketCreationRequestCallData( - params: L1ToL2MessageParams, - estimates: Pick, + params: ParentToChildMessageParams, + estimates: Pick, excessFeeRefundAddress: string, callValueRefundAddress: string, nativeTokenIsEth: boolean @@ -119,37 +128,37 @@ export class L1ToL2MessageCreator { /** * Generate a transaction request for creating a retryable ticket * @param params - * @param l1Provider - * @param l2Provider + * @param parentProvider + * @param childProvider * @param options * @returns */ public static async getTicketCreationRequest( - params: L1ToL2MessageParams, - l1Provider: Provider, - l2Provider: Provider, + params: ParentToChildMessageParams, + parentProvider: Provider, + childProvider: Provider, options?: GasOverrides - ): Promise { + ): Promise { const excessFeeRefundAddress = params.excessFeeRefundAddress || params.from const callValueRefundAddress = params.callValueRefundAddress || params.from - const parsedParams: L1ToL2MessageNoGasParams = { + const parsedParams: ParentToChildMessageNoGasParams = { ...params, excessFeeRefundAddress, callValueRefundAddress, } - const estimates = await L1ToL2MessageCreator.getTicketEstimate( + const estimates = await ParentToChildMessageCreator.getTicketEstimate( parsedParams, - l1Provider, - l2Provider, + parentProvider, + childProvider, options ) - const l2Network = await getChildChain(l2Provider) - const nativeTokenIsEth = typeof l2Network.nativeToken === 'undefined' + const childChain = await getChildChain(childProvider) + const nativeTokenIsEth = typeof childChain.nativeToken === 'undefined' - const data = L1ToL2MessageCreator.getTicketCreationRequestCallData( + const data = ParentToChildMessageCreator.getTicketCreationRequestCallData( params, estimates, excessFeeRefundAddress, @@ -159,7 +168,7 @@ export class L1ToL2MessageCreator { return { txRequest: { - to: l2Network.ethBridge.inbox, + to: childChain.ethBridge.inbox, data, value: nativeTokenIsEth ? estimates.deposit : constants.Zero, from: params.from, @@ -177,42 +186,52 @@ export class L1ToL2MessageCreator { deposit: estimates.deposit, }, isValid: async () => { - const reEstimates = await L1ToL2MessageCreator.getTicketEstimate( + const reEstimates = await ParentToChildMessageCreator.getTicketEstimate( parsedParams, - l1Provider, - l2Provider, + parentProvider, + childProvider, options ) - return L1ToL2MessageGasEstimator.isValid(estimates, reEstimates) + return ParentToChildMessageGasEstimator.isValid(estimates, reEstimates) }, } } /** - * Creates a retryable ticket by directly calling the Inbox contract on L1 + * Creates a retryable ticket by directly calling the Inbox contract on Parent chain */ public async createRetryableTicket( params: - | (L1ToL2MessageParams & { overrides?: PayableOverrides }) - | (L1ToL2TransactionRequest & { overrides?: PayableOverrides }), - l2Provider: Provider, + | (ParentToChildMessageParams & { overrides?: PayableOverrides }) + | (ParentToChildTransactionRequest & { overrides?: PayableOverrides }), + childProvider: Provider, options?: GasOverrides - ): Promise { - const l1Provider = SignerProviderUtils.getProviderOrThrow(this.l1Signer) - const createRequest = isL1ToL2TransactionRequest(params) + ): Promise { + const parentProvider = SignerProviderUtils.getProviderOrThrow( + this.parentSigner + ) + const createRequest = isParentToChildTransactionRequest(params) ? params - : await L1ToL2MessageCreator.getTicketCreationRequest( + : await ParentToChildMessageCreator.getTicketCreationRequest( params, - l1Provider, - l2Provider, + parentProvider, + childProvider, options ) - const tx = await this.l1Signer.sendTransaction({ + const tx = await this.parentSigner.sendTransaction({ ...createRequest.txRequest, ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchWait(tx) + return ParentChainTransactionReceipt.monkeyPatchWait(tx) } } + +// TODO: remove after all other files have their imports updated +export { + ParentToChildMessageCreator as L1ToL2MessageCreator, + ParentToChildMessageGasParams as L1ToL2MessageGasParams, + ParentToChildMessageNoGasParams as L1ToL2MessageNoGasParams, + ParentToChildMessageParams as L1ToL2MessageParams, +} diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/l1ToL2MessageCreator.test.ts index e171096e01..5ae584ec23 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/l1ToL2MessageCreator.test.ts @@ -18,18 +18,18 @@ import { expect } from 'chai' import { providers, utils } from 'ethers' -import { fundL1, skipIfMainnet } from './testHelpers' +import { fundL1 as fundParentChain, skipIfMainnet } from './testHelpers' import { testSetup } from '../../scripts/testSetup' -import { L1ToL2MessageCreator } from '../../src/lib/message/L1ToL2MessageCreator' -import { L1ToL2MessageStatus } from '../../src' +import { ParentToChildMessageCreator } from '../../src/lib/message/L1ToL2MessageCreator' +import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' import { - fundL1CustomFeeToken, - approveL1CustomFeeToken, - isL2NetworkWithCustomFeeToken, + fundL1CustomFeeToken as fundParentChainCustomFeeToken, + approveL1CustomFeeToken as approveParentChainCustomFeeToken, + isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken, } from './custom-fee-token/customFeeTokenTestHelpers' -describe('L1ToL2MessageCreator', () => { +describe('ParentToChildMessageCreator', () => { beforeEach('skipIfMainnet', async function () { await skipIfMainnet(this) }) @@ -38,23 +38,25 @@ describe('L1ToL2MessageCreator', () => { const testAmount = utils.parseEther('0.01') it('allows the creation of Retryable Tickets sending parameters', async () => { - const { l1Signer, l2Signer } = await testSetup() - const signerAddress = await l1Signer.getAddress() - const arbProvider = l2Signer.provider as providers.Provider + const { l1Signer: parentSigner, l2Signer: childSigner } = await testSetup() + const signerAddress = await parentSigner.getAddress() + const arbProvider = childSigner.provider as providers.Provider - // Funding L1 wallet - await fundL1(l1Signer) + // Funding parent chain wallet + await fundParentChain(parentSigner) - if (isL2NetworkWithCustomFeeToken()) { - await fundL1CustomFeeToken(l1Signer) - await approveL1CustomFeeToken(l1Signer) + if (isChildChainWithCustomFeeToken()) { + await fundParentChainCustomFeeToken(parentSigner) + await approveParentChainCustomFeeToken(parentSigner) } // Instantiate the object - const l1ToL2MessageCreator = new L1ToL2MessageCreator(l1Signer) + const parentToChildMessageCreator = new ParentToChildMessageCreator( + parentSigner + ) // Getting balances - const initialL2Balance = await l2Signer.getBalance() + const initialChildChainBalance = await childSigner.getBalance() // Define parameters for Retryable const retryableTicketParams = { @@ -66,56 +68,60 @@ describe('L1ToL2MessageCreator', () => { } // And submitting the ticket - const l1SubmissionTx = await l1ToL2MessageCreator.createRetryableTicket( - retryableTicketParams, - arbProvider - ) - const l1SubmissionTxReceipt = await l1SubmissionTx.wait() + const parentChainSubmissionTx = + await parentToChildMessageCreator.createRetryableTicket( + retryableTicketParams, + arbProvider + ) + const parentChainSubmissionTxReceipt = await parentChainSubmissionTx.wait() - // Getting the L1ToL2Message - const l1ToL2messages = await l1SubmissionTxReceipt.getL1ToL2Messages( - arbProvider - ) - expect(l1ToL2messages.length).to.eq(1) - const l1ToL2message = l1ToL2messages[0] + // Getting the ParentToChildMessage + const parentToChildMessages = + await parentChainSubmissionTxReceipt.getL1ToL2Messages(arbProvider) + expect(parentToChildMessages.length).to.eq(1) + const parentToChildMessage = parentToChildMessages[0] // And waiting for it to be redeemed - const retryableTicketResult = await l1ToL2message.waitForStatus() - expect(retryableTicketResult.status).to.eq(L1ToL2MessageStatus.REDEEMED) + const retryableTicketResult = await parentToChildMessage.waitForStatus() + expect(retryableTicketResult.status).to.eq( + ParentToChildMessageStatus.REDEEMED + ) // Getting and checking updated balances - const finalL2Balance = await l2Signer.getBalance() + const finalChildChainBalance = await childSigner.getBalance() // When sending ETH through retryables, the same address will receive the ETH sent through the callvalue // plus any gas that was not used in the operation. expect( - initialL2Balance.add(testAmount).lt(finalL2Balance), - 'L2 balance not updated' + initialChildChainBalance.add(testAmount).lt(finalChildChainBalance), + 'Child chain balance not updated' ).to.be.true }) it('allows the creation of Retryable Tickets sending a request', async () => { - const { l1Signer, l2Signer } = await testSetup() - const signerAddress = await l1Signer.getAddress() - const ethProvider = l1Signer.provider as providers.Provider - const arbProvider = l2Signer.provider as providers.Provider + const { l1Signer: parentSigner, l2Signer: childSigner } = await testSetup() + const signerAddress = await parentSigner.getAddress() + const ethProvider = parentSigner.provider as providers.Provider + const arbProvider = childSigner.provider as providers.Provider - // Funding L1 wallet - await fundL1(l1Signer) + // Funding parent chain wallet + await fundParentChain(parentSigner) - if (isL2NetworkWithCustomFeeToken()) { - await fundL1CustomFeeToken(l1Signer) - await approveL1CustomFeeToken(l1Signer) + if (isChildChainWithCustomFeeToken()) { + await fundParentChainCustomFeeToken(parentSigner) + await approveParentChainCustomFeeToken(parentSigner) } // Instantiate the object - const l1ToL2MessageCreator = new L1ToL2MessageCreator(l1Signer) + const parentToChildMessageCreator = new ParentToChildMessageCreator( + parentSigner + ) // Getting balances - const initialL2Balance = await l2Signer.getBalance() + const initialChildChainBalance = await childSigner.getBalance() - // In this case, we will try to send directly an L1ToL2TransactionRequest - const l1ToL2TransactionRequestParams = { + // In this case, we will try to send directly an ParentToChildTransactionRequest + const parentToChildTransactionRequestParams = { from: signerAddress, to: signerAddress, l2CallValue: testAmount, @@ -123,39 +129,41 @@ describe('L1ToL2MessageCreator', () => { data: '0x', } - const l1ToL2TransactionRequest = - await L1ToL2MessageCreator.getTicketCreationRequest( - l1ToL2TransactionRequestParams, + const parentToChildTransactionRequest = + await ParentToChildMessageCreator.getTicketCreationRequest( + parentToChildTransactionRequestParams, ethProvider, arbProvider ) // And create the retryable ticket - const l1SubmissionTx = await l1ToL2MessageCreator.createRetryableTicket( - l1ToL2TransactionRequest, - arbProvider - ) - const l1SubmissionTxReceipt = await l1SubmissionTx.wait() + const parentChainSubmissionTx = + await parentToChildMessageCreator.createRetryableTicket( + parentToChildTransactionRequest, + arbProvider + ) + const parentChainSubmissionTxReceipt = await parentChainSubmissionTx.wait() - // Getting the L1ToL2Message - const l1ToL2messages = await l1SubmissionTxReceipt.getL1ToL2Messages( - arbProvider - ) - expect(l1ToL2messages.length).to.eq(1) - const l1ToL2message = l1ToL2messages[0] + // Getting the ParentToChildMessage + const parentToChildMessages = + await parentChainSubmissionTxReceipt.getL1ToL2Messages(arbProvider) + expect(parentToChildMessages.length).to.eq(1) + const parentToChildMessage = parentToChildMessages[0] // And waiting for it to be redeemed - const retryableTicketResult = await l1ToL2message.waitForStatus() - expect(retryableTicketResult.status).to.eq(L1ToL2MessageStatus.REDEEMED) + const retryableTicketResult = await parentToChildMessage.waitForStatus() + expect(retryableTicketResult.status).to.eq( + ParentToChildMessageStatus.REDEEMED + ) // Getting and checking updated balances - const finalL2Balance = await l2Signer.getBalance() + const finalChildChainBalance = await childSigner.getBalance() // When sending ETH through retryables, the same address will receive the ETH sent through the callvalue // plus any gas that was not used in the operation. expect( - initialL2Balance.add(testAmount).lt(finalL2Balance), - 'L2 balance not updated' + initialChildChainBalance.add(testAmount).lt(finalChildChainBalance), + 'Child chain balance not updated' ).to.be.true }) }) From dd640d6d9e3b9996203cc587bf91a2b0b825e099 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 19 Mar 2024 06:35:18 -0400 Subject: [PATCH 12/74] chore: renames L1ToL2MessageGasEstimator to Parent/Child (#423) --- src/lib/message/L1ToL2MessageGasEstimator.ts | 106 ++++++++++-------- .../L1ToL2MessageGasEstimator.test.ts | 26 +++-- 2 files changed, 71 insertions(+), 61 deletions(-) diff --git a/src/lib/message/L1ToL2MessageGasEstimator.ts b/src/lib/message/L1ToL2MessageGasEstimator.ts index 333fb91cf2..12fcb84718 100644 --- a/src/lib/message/L1ToL2MessageGasEstimator.ts +++ b/src/lib/message/L1ToL2MessageGasEstimator.ts @@ -10,17 +10,17 @@ import { RetryableData, RetryableDataTools, } from '../dataEntities/retryableData' -import { L1ToL2TransactionRequest } from '../dataEntities/transactionRequest' +import { L1ToL2TransactionRequest as ParentToChildTransactionRequest } from '../dataEntities/transactionRequest' import { getBaseFee, isDefined } from '../utils/lib' import { OmitTyped } from '../utils/types' import { - L1ToL2MessageGasParams, - L1ToL2MessageNoGasParams, + ParentToChildMessageGasParams, + ParentToChildMessageNoGasParams, } from './L1ToL2MessageCreator' /** * The default amount to increase the maximum submission cost. Submission cost is calculated - * from (call data size * some const * l1 base fee). So we need to provide some leeway for + * from (call data size * some const * parent chain base fee). So we need to provide some leeway for * base fee increase. Since submission fee is a small amount it isn't too bas for UX to increase * it by a large amount, and provide better safety. */ @@ -62,16 +62,16 @@ export interface GasOverrides { deposit?: Pick } -const defaultL1ToL2MessageEstimateOptions = { +const defaultParentToChildMessageEstimateOptions = { maxSubmissionFeePercentIncrease: DEFAULT_SUBMISSION_FEE_PERCENT_INCREASE, - // gas limit for l1->l2 messages should be predictable. If it isn't due to the nature + // gas limit for Parent->Child messages should be predictable. If it isn't due to the nature // of the specific transaction, then the caller should provide a 'min' override gasLimitPercentIncrease: constants.Zero, maxFeePerGasPercentIncrease: DEFAULT_GAS_PRICE_PERCENT_INCREASE, } -export class L1ToL2MessageGasEstimator { - constructor(public readonly l2Provider: Provider) {} +export class ParentToChildMessageGasEstimator { + constructor(public readonly childProvider: Provider) {} private percentIncrease(num: BigNumber, increase: BigNumber): BigNumber { return num.add(num.mul(increase).div(100)) @@ -84,7 +84,7 @@ export class L1ToL2MessageGasEstimator { base: maxSubmissionFeeOptions?.base, percentIncrease: maxSubmissionFeeOptions?.percentIncrease || - defaultL1ToL2MessageEstimateOptions.maxSubmissionFeePercentIncrease, + defaultParentToChildMessageEstimateOptions.maxSubmissionFeePercentIncrease, } } @@ -93,7 +93,7 @@ export class L1ToL2MessageGasEstimator { base: maxFeePerGasOptions?.base, percentIncrease: maxFeePerGasOptions?.percentIncrease || - defaultL1ToL2MessageEstimateOptions.maxFeePerGasPercentIncrease, + defaultParentToChildMessageEstimateOptions.maxFeePerGasPercentIncrease, } } @@ -104,39 +104,45 @@ export class L1ToL2MessageGasEstimator { base: gasLimitDefaults?.base, percentIncrease: gasLimitDefaults?.percentIncrease || - defaultL1ToL2MessageEstimateOptions.gasLimitPercentIncrease, + defaultParentToChildMessageEstimateOptions.gasLimitPercentIncrease, min: gasLimitDefaults?.min || constants.Zero, } } /** * Return the fee, in wei, of submitting a new retryable tx with a given calldata size. - * @param l1Provider - * @param l1BaseFee + * @param parentProvider + * @param parentBaseFee * @param callDataSize * @param options * @returns */ public async estimateSubmissionFee( - l1Provider: Provider, - l1BaseFee: BigNumber, + parentProvider: Provider, + parentBaseFee: BigNumber, callDataSize: BigNumber | number, options?: PercentIncrease - ): Promise { + ): Promise { const defaultedOptions = this.applySubmissionPriceDefaults(options) - const network = await getChildChain(this.l2Provider) - const inbox = Inbox__factory.connect(network.ethBridge.inbox, l1Provider) + const network = await getChildChain(this.childProvider) + const inbox = Inbox__factory.connect( + network.ethBridge.inbox, + parentProvider + ) return this.percentIncrease( defaultedOptions.base || - (await inbox.calculateRetryableSubmissionFee(callDataSize, l1BaseFee)), + (await inbox.calculateRetryableSubmissionFee( + callDataSize, + parentBaseFee + )), defaultedOptions.percentIncrease ) } /** - * Estimate the amount of L2 gas required for putting the transaction in the L2 inbox, and executing it. + * Estimate the amount of child chain gas required for putting the transaction in the L2 inbox, and executing it. * @param retryableData object containing retryable ticket data * @param senderDeposit we dont know how much gas the transaction will use when executing * so by default we supply a dummy amount of call value that will definately be more than we need @@ -150,12 +156,12 @@ export class L1ToL2MessageGasEstimator { excessFeeRefundAddress, callValueRefundAddress, data, - }: L1ToL2MessageNoGasParams, + }: ParentToChildMessageNoGasParams, senderDeposit: BigNumber = utils.parseEther('1').add(l2CallValue) - ): Promise { + ): Promise { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - this.l2Provider + this.childProvider ) return await nodeInterface.estimateGas.estimateRetryableTicket( @@ -170,18 +176,18 @@ export class L1ToL2MessageGasEstimator { } /** - * Provides an estimate for the L2 maxFeePerGas, adding some margin to allow for gas price variation + * Provides an estimate for the child chain maxFeePerGas, adding some margin to allow for gas price variation * @param options * @returns */ public async estimateMaxFeePerGas( options?: PercentIncrease - ): Promise { + ): Promise { const maxFeePerGasDefaults = this.applyMaxFeePerGasDefaults(options) // estimate the l2 gas price return this.percentIncrease( - maxFeePerGasDefaults.base || (await this.l2Provider.getGasPrice()), + maxFeePerGasDefaults.base || (await this.childProvider.getGasPrice()), maxFeePerGasDefaults.percentIncrease ) } @@ -193,8 +199,8 @@ export class L1ToL2MessageGasEstimator { * @returns */ public static async isValid( - estimates: L1ToL2MessageGasParams, - reEstimates: L1ToL2MessageGasParams + estimates: ParentToChildMessageGasParams, + reEstimates: ParentToChildMessageGasParams ): Promise { // L2 base fee and minimum submission cost which affect the success of the tx return ( @@ -204,29 +210,29 @@ export class L1ToL2MessageGasEstimator { } /** - * Get gas limit, gas price and submission price estimates for sending an L1->L2 message + * Get gas limit, gas price and submission price estimates for sending an Parent->Child message * @param retryableData Data of retryable ticket transaction - * @param l1BaseFee Current l1 base fee - * @param l1Provider + * @param parentBaseFee Current parent chain base fee + * @param parentProvider * @param options * @returns */ public async estimateAll( - retryableEstimateData: L1ToL2MessageNoGasParams, - l1BaseFee: BigNumber, - l1Provider: Provider, + retryableEstimateData: ParentToChildMessageNoGasParams, + parentBaseFee: BigNumber, + parentProvider: Provider, options?: GasOverrides - ): Promise { + ): Promise { const { data } = retryableEstimateData const gasLimitDefaults = this.applyGasLimitDefaults(options?.gasLimit) - // estimate the l1 gas price + // estimate the parent chain gas price const maxFeePerGasPromise = this.estimateMaxFeePerGas(options?.maxFeePerGas) // estimate the submission fee const maxSubmissionFeePromise = this.estimateSubmissionFee( - l1Provider, - l1BaseFee, + parentProvider, + parentBaseFee, utils.hexDataLength(data), options?.maxSubmissionFee ) @@ -268,26 +274,26 @@ export class L1ToL2MessageGasEstimator { } /** - * Transactions that make an L1->L2 message need to estimate L2 gas parameters + * Transactions that make an Parent->Child message need to estimate L2 gas parameters * This function does that, and populates those parameters into a transaction request * @param dataFunc - * @param l1Provider + * @param parentProvider * @param gasOverrides * @returns */ public async populateFunctionParams( /** - * Function that will internally make an L1->L2 transaction + * Function that will internally make an Parent->Child transaction * Will initially be called with dummy values to trigger a special revert containing * the real params. Then called again with the real params to form the final data to be submitted */ dataFunc: ( - params: OmitTyped - ) => L1ToL2TransactionRequest['txRequest'], - l1Provider: Provider, + params: OmitTyped + ) => ParentToChildTransactionRequest['txRequest'], + parentProvider: Provider, gasOverrides?: GasOverrides ): Promise<{ - estimates: L1ToL2MessageGasParams + estimates: ParentToChildMessageGasParams retryable: RetryableData data: BytesLike to: string @@ -308,7 +314,7 @@ export class L1ToL2MessageGasEstimator { let retryable: RetryableData | null try { // get retryable data from the null call - const res = await l1Provider.call({ + const res = await parentProvider.call({ to: to, data: nullData, value: value, @@ -329,8 +335,7 @@ export class L1ToL2MessageGasEstimator { } // use retryable data to get gas estimates - // const gasEstimator = new L1ToL2MessageGasEstimator(l2Provider) - const baseFee = await getBaseFee(l1Provider) + const baseFee = await getBaseFee(parentProvider) const estimates = await this.estimateAll( { from: retryable.from, @@ -341,7 +346,7 @@ export class L1ToL2MessageGasEstimator { callValueRefundAddress: retryable.callValueRefundAddress, }, baseFee, - l1Provider, + parentProvider, gasOverrides ) @@ -365,3 +370,6 @@ export class L1ToL2MessageGasEstimator { } } } + +// TODO: remove after all other files have their imports updated +export { ParentToChildMessageGasEstimator as L1ToL2MessageGasEstimator } diff --git a/tests/integration/L1ToL2MessageGasEstimator.test.ts b/tests/integration/L1ToL2MessageGasEstimator.test.ts index 2ea66d7d46..7370089c92 100644 --- a/tests/integration/L1ToL2MessageGasEstimator.test.ts +++ b/tests/integration/L1ToL2MessageGasEstimator.test.ts @@ -21,13 +21,13 @@ import { BigNumber } from 'ethers' import { skipIfMainnet } from './testHelpers' import { testSetup } from '../../scripts/testSetup' -import { L1ToL2MessageGasEstimator } from '../../src' +import { ParentToChildMessageGasEstimator } from '../../src/lib/message/L1ToL2MessageGasEstimator' import { itOnlyWhenEth, itOnlyWhenCustomGasToken, } from './custom-fee-token/mochaExtensions' -describe('L1ToL2MessageGasEstimator', () => { +describe('ParentToChildMessageGasEstimator', () => { beforeEach('skipIfMainnet', async function () { await skipIfMainnet(this) }) @@ -35,13 +35,14 @@ describe('L1ToL2MessageGasEstimator', () => { itOnlyWhenEth( `"estimateSubmissionFee" returns non-0 for eth chain`, async () => { - const { l1Provider, l2Provider } = await testSetup() + const { l1Provider: parentProvider, l2Provider: childProvider } = + await testSetup() - const submissionFee = await new L1ToL2MessageGasEstimator( - l2Provider + const submissionFee = await new ParentToChildMessageGasEstimator( + childProvider ).estimateSubmissionFee( - l1Provider, - await l1Provider.getGasPrice(), + parentProvider, + await parentProvider.getGasPrice(), 123456 ) @@ -52,13 +53,14 @@ describe('L1ToL2MessageGasEstimator', () => { itOnlyWhenCustomGasToken( `"estimateSubmissionFee" returns 0 for custom gas token chain`, async () => { - const { l1Provider, l2Provider } = await testSetup() + const { l1Provider: parentProvider, l2Provider: childProvider } = + await testSetup() - const submissionFee = await new L1ToL2MessageGasEstimator( - l2Provider + const submissionFee = await new ParentToChildMessageGasEstimator( + childProvider ).estimateSubmissionFee( - l1Provider, - await l1Provider.getGasPrice(), + parentProvider, + await parentProvider.getGasPrice(), 123456 ) From 8f8dbeaaaacc8ae66c39d37bc1cca48ec67630b8 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:46:09 -0400 Subject: [PATCH 13/74] chore: rename L2Transaction to parent/child (#424) --- src/lib/message/L2Transaction.ts | 76 ++++++++++--------- .../customFeeTokenEthBridger.test.ts | 4 +- tests/integration/eth.test.ts | 2 +- tests/integration/testHelpers.ts | 4 +- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/lib/message/L2Transaction.ts b/src/lib/message/L2Transaction.ts index 30804921bb..fc39fdc1eb 100644 --- a/src/lib/message/L2Transaction.ts +++ b/src/lib/message/L2Transaction.ts @@ -25,11 +25,11 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { - ChildToParentMessageReader as L2ToL1MessageReader, - ChildToParentMessageReaderOrWriter as L2ToL1MessageReaderOrWriter, - ChildToParentMessage as L2ToL1Message, - ChildToParentMessageWriter as L2ToL1MessageWriter, - ChildToParentTransactionEvent as L2ToL1TransactionEvent, + ChildToParentMessageReader, + ChildToParentMessageReaderOrWriter, + ChildToParentMessage, + ChildToParentMessageWriter, + ChildToParentTransactionEvent, } from './L2ToL1Message' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ArbRetryableTx__factory } from '../abi/factories/ArbRetryableTx__factory' @@ -41,7 +41,7 @@ import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { ArbitrumProvider } from '../utils/arbProvider' export interface L2ContractTransaction extends ContractTransaction { - wait(confirmations?: number): Promise + wait(confirmations?: number): Promise } export interface RedeemTransaction extends L2ContractTransaction { @@ -51,7 +51,7 @@ export interface RedeemTransaction extends L2ContractTransaction { /** * Extension of ethers-js TransactionReceipt, adding Arbitrum-specific functionality */ -export class L2TransactionReceipt implements TransactionReceipt { +export class ChildChainTransactionReceipt implements TransactionReceipt { public readonly to: string public readonly from: string public readonly contractAddress: string @@ -91,10 +91,10 @@ export class L2TransactionReceipt implements TransactionReceipt { } /** - * Get an L2ToL1TxEvent events created by this transaction + * Get an ChildToParentTxEvent events created by this transaction * @returns */ - public getL2ToL1Events(): L2ToL1TransactionEvent[] { + public getChildToParentEvents(): ChildToParentTransactionEvent[] { const classicLogs = parseTypedLogs( ArbSys__factory, this.logs, @@ -113,47 +113,47 @@ export class L2TransactionReceipt implements TransactionReceipt { } /** - * Get any l2-to-l1-messages created by this transaction + * Get any child-to-parent-messages created by this transaction * @param l2SignerOrProvider */ - public async getL2ToL1Messages( - l1SignerOrProvider: T - ): Promise[]> - public async getL2ToL1Messages( - l1SignerOrProvider: T - ): Promise { - const provider = SignerProviderUtils.getProvider(l1SignerOrProvider) + public async getChildToParentMessages( + parentSignerOrProvider: T + ): Promise[]> + public async getChildToParentMessages( + parentSignerOrProvider: T + ): Promise { + const provider = SignerProviderUtils.getProvider(parentSignerOrProvider) if (!provider) throw new ArbSdkError('Signer not connected to provider.') - return this.getL2ToL1Events().map(log => - L2ToL1Message.fromEvent(l1SignerOrProvider, log) + return this.getChildToParentEvents().map(log => + ChildToParentMessage.fromEvent(parentSignerOrProvider, log) ) } /** - * Get number of L1 confirmations that the batch including this tx has - * @param l2Provider + * Get number of parent chain confirmations that the batch including this tx has + * @param childProvider * @returns number of confirmations of batch including tx, or 0 if no batch included this tx */ - public getBatchConfirmations(l2Provider: providers.JsonRpcProvider) { + public getBatchConfirmations(childProvider: providers.JsonRpcProvider) { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childProvider ) return nodeInterface.getL1Confirmations(this.blockHash) } /** * Get the number of the batch that included this tx (will throw if no such batch exists) - * @param l2Provider + * @param childProvider * @returns number of batch in which tx was included, or errors if no batch includes the current tx */ - public async getBatchNumber(l2Provider: providers.JsonRpcProvider) { + public async getBatchNumber(childProvider: providers.JsonRpcProvider) { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - l2Provider + childProvider ) - const arbProvider = new ArbitrumProvider(l2Provider) + const arbProvider = new ArbitrumProvider(childProvider) const rec = await arbProvider.getTransactionReceipt(this.transactionHash) if (rec == null) throw new ArbSdkError( @@ -165,16 +165,16 @@ export class L2TransactionReceipt implements TransactionReceipt { /** * Whether the data associated with this transaction has been - * made available on L1 - * @param l2Provider + * made available on parent chain + * @param childProvider * @param confirmations The number of confirmations on the batch before data is to be considered available * @returns */ public async isDataAvailable( - l2Provider: providers.JsonRpcProvider, + childProvider: providers.JsonRpcProvider, confirmations = 10 ): Promise { - const res = await this.getBatchConfirmations(l2Provider) + const res = await this.getBatchConfirmations(childProvider) // is there a batch with enough confirmations return res.toNumber() > confirmations } @@ -189,12 +189,12 @@ export class L2TransactionReceipt implements TransactionReceipt { ): L2ContractTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (_confirmations?: number) => { - // we ignore the confirmations for now since L2 transactions shouldn't re-org + // we ignore the confirmations for now since child chain transactions shouldn't re-org // in future we should give users a more fine grained way to check the finality of - // an l2 transaction - check if a batch is on L1, if an assertion has been made, and if + // an child chain transaction - check if a batch is on a parent chain, if an assertion has been made, and if // it has been confirmed. const result = await wait() - return new L2TransactionReceipt(result) + return new ChildChainTransactionReceipt(result) } return contractTransaction as L2ContractTransaction } @@ -202,12 +202,12 @@ export class L2TransactionReceipt implements TransactionReceipt { /** * Adds a waitForRedeem function to a redeem transaction * @param redeemTx - * @param l2Provider + * @param childProvider * @returns */ public static toRedeemTransaction( redeemTx: L2ContractTransaction, - l2Provider: providers.Provider + childProvider: providers.Provider ): RedeemTransaction { const returnRec = redeemTx as RedeemTransaction returnRec.waitForRedeem = async () => { @@ -221,10 +221,12 @@ export class L2TransactionReceipt implements TransactionReceipt { ) } - return await l2Provider.getTransactionReceipt( + return await childProvider.getTransactionReceipt( redeemScheduledEvents[0].retryTxHash ) } return returnRec } } + +export { ChildChainTransactionReceipt as L2TransactionReceipt } diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index aebc9e96d3..828cb949db 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -201,7 +201,9 @@ describeOnlyWhenCustomGasToken( 'initiate withdrawal tx failed' ) - const messages = await withdrawalTxReceipt.getL2ToL1Messages(l1Signer) + const messages = await withdrawalTxReceipt.getChildToParentMessages( + l1Signer + ) expect(messages.length).to.equal( 1, 'custom fee token withdraw getWithdrawalsInL2Transaction query came back empty' diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index f4610462e5..539c55eb56 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -242,7 +242,7 @@ describe('Ether', async () => { ) const withdrawMessage = ( - await withdrawEthRec.getL2ToL1Messages(l1Signer) + await withdrawEthRec.getChildToParentMessages(l1Signer) )[0] expect( withdrawMessage, diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index c3ccd2bbd2..ae6a249e25 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -105,7 +105,9 @@ export const withdrawToken = async (params: WithdrawalParams) => { const withdrawRec = await withdrawRes.wait() expect(withdrawRec.status).to.equal(1, 'initiate token withdraw txn failed') - const message = (await withdrawRec.getL2ToL1Messages(params.l1Signer))[0] + const message = ( + await withdrawRec.getChildToParentMessages(params.l1Signer) + )[0] expect(message, 'withdraw message not found').to.exist const messageStatus = await message.status(params.l2Signer.provider!) From 20e6341712b687bad5221f6bcc6fddd65881af1a Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:37:52 -0400 Subject: [PATCH 14/74] chore: rename L1Transaction to parent/child (#425) --- scripts/lib.ts | 4 +- src/lib/message/L1Transaction.ts | 167 ++++++++++-------- tests/integration/customerc20.test.ts | 4 +- tests/integration/eth.test.ts | 6 +- .../integration/l1ToL2MessageCreator.test.ts | 4 +- tests/integration/testHelpers.ts | 2 +- tests/unit/l1toL2MessageEvents.test.ts | 38 ++-- 7 files changed, 127 insertions(+), 98 deletions(-) diff --git a/scripts/lib.ts b/scripts/lib.ts index 4fe83cc892..15771b2f60 100644 --- a/scripts/lib.ts +++ b/scripts/lib.ts @@ -110,7 +110,7 @@ export const setGateWays = async ( } console.log('redeeming retryable ticket:') - const l2Tx = (await rec.getL1ToL2Messages(l2Signer))[0] + const l2Tx = (await rec.getParentToChildMessages(l2Signer))[0] if (!l2Tx) throw new Error('No l1 to l2 message found.') const messageRes = await l2Tx.waitForStatus() if (messageRes.status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { @@ -128,7 +128,7 @@ export const checkRetryableStatus = async (l1Hash: string): Promise => { const l2Provider = l2Signer.provider! const rec = await l1Provider.getTransactionReceipt(l1Hash) if (!rec) throw new Error('L1 tx not found!') - const messages = await new L1TransactionReceipt(rec).getL1ToL2Messages( + const messages = await new L1TransactionReceipt(rec).getParentToChildMessages( l2Provider ) diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/L1Transaction.ts index 463376aa09..d894629933 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/L1Transaction.ts @@ -21,13 +21,13 @@ import { Log, Provider } from '@ethersproject/abstract-provider' import { ContractTransaction } from '@ethersproject/contracts' import { BigNumber } from '@ethersproject/bignumber' import { - ParentToChildMessage as L1ToL2Message, - ParentToChildMessageReaderOrWriter as L1ToL2MessageReaderOrWriter, - ParentToChildMessageReader as L1ToL2MessageReader, - ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic, - ParentToChildMessageWriter as L1ToL2MessageWriter, - ParentToChildMessageStatus as L1ToL2MessageStatus, - ParentToChildMessageWaitResult as L1ToL2MessageWaitResult, + ParentToChildMessage, + ParentToChildMessageReaderOrWriter, + ParentToChildMessageReader, + ParentToChildMessageReaderClassic, + ParentToChildMessageWriter, + ParentToChildMessageStatus, + ParentToChildMessageWaitResult, EthDepositMessage, EthDepositMessageWaitResult, } from './L1ToL2Message' @@ -48,18 +48,18 @@ import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' import { getL2Network as getChildChain } from '../dataEntities/networks' -export interface L1ContractTransaction< - TReceipt extends L1TransactionReceipt = L1TransactionReceipt +export interface ParentChainContractTransaction< + TReceipt extends ParentChainTransactionReceipt = ParentChainTransactionReceipt > extends ContractTransaction { wait(confirmations?: number): Promise } // some helper interfaces to reduce the verbosity elsewhere -export type L1EthDepositTransaction = - L1ContractTransaction -export type L1ContractCallTransaction = - L1ContractTransaction +export type ParentChainEthDepositTransaction = + ParentChainContractTransaction +export type ParentChainContractCallTransaction = + ParentChainContractTransaction -export class L1TransactionReceipt implements TransactionReceipt { +export class ParentChainTransactionReceipt implements TransactionReceipt { public readonly to: string public readonly from: string public readonly contractAddress: string @@ -100,12 +100,14 @@ export class L1TransactionReceipt implements TransactionReceipt { /** * Check if is a classic transaction - * @param l2SignerOrProvider + * @param childSignerOrProvider */ public async isClassic( - l2SignerOrProvider: T + childSignerOrProvider: T ): Promise { - const provider = SignerProviderUtils.getProviderOrThrow(l2SignerOrProvider) + const provider = SignerProviderUtils.getProviderOrThrow( + childSignerOrProvider + ) const network = await getChildChain(provider) return this.blockNumber < network.nitroGenesisL1Block } @@ -177,10 +179,10 @@ export class L1TransactionReceipt implements TransactionReceipt { /** * Get any eth deposit messages created by this transaction - * @param l2SignerOrProvider + * @param childSignerOrProvider */ public async getEthDeposits( - l2Provider: Provider + childProvider: Provider ): Promise { return Promise.all( this.getMessageEvents() @@ -191,7 +193,7 @@ export class L1TransactionReceipt implements TransactionReceipt { ) .map(m => EthDepositMessage.fromEventComponents( - l2Provider, + childProvider, m.inboxMessageEvent.messageNum, m.bridgeMessageEvent.sender, m.inboxMessageEvent.data @@ -201,20 +203,20 @@ export class L1TransactionReceipt implements TransactionReceipt { } /** - * Get classic l1tol2 messages created by this transaction - * @param l2Provider + * Get classic parent-to-child messages created by this transaction + * @param childProvider */ - public async getL1ToL2MessagesClassic( - l2Provider: Provider - ): Promise { - const network = await getChildChain(l2Provider) + public async getParentToChildMessagesClassic( + childProvider: Provider + ): Promise { + const network = await getChildChain(childProvider) const chainID = network.chainID.toString() - const isClassic = await this.isClassic(l2Provider) + const isClassic = await this.isClassic(childProvider) // throw on nitro events if (!isClassic) { throw new Error( - "This method is only for classic transactions. Use 'getL1ToL2Messages' for nitro transactions." + "This method is only for classic transactions. Use 'getParentToChildMessages' for nitro transactions." ) } @@ -224,8 +226,8 @@ export class L1TransactionReceipt implements TransactionReceipt { return messageNums.map( messageNum => - new L1ToL2MessageReaderClassic( - l2Provider, + new ParentToChildMessageReaderClassic( + childProvider, BigNumber.from(chainID).toNumber(), messageNum ) @@ -233,16 +235,18 @@ export class L1TransactionReceipt implements TransactionReceipt { } /** - * Get any l1tol2 messages created by this transaction - * @param l2SignerOrProvider + * Get any parent-to-child messages created by this transaction + * @param childSignerOrProvider */ - public async getL1ToL2Messages( - l2SignerOrProvider: T - ): Promise[]> - public async getL1ToL2Messages( - l2SignerOrProvider: T - ): Promise { - const provider = SignerProviderUtils.getProviderOrThrow(l2SignerOrProvider) + public async getParentToChildMessages( + childSignerOrProvider: T + ): Promise[]> + public async getParentToChildMessages( + childSignerOrProvider: T + ): Promise { + const provider = SignerProviderUtils.getProviderOrThrow( + childSignerOrProvider + ) const network = await getChildChain(provider) const chainID = network.chainID.toString() const isClassic = await this.isClassic(provider) @@ -250,7 +254,7 @@ export class L1TransactionReceipt implements TransactionReceipt { // throw on classic events if (isClassic) { throw new Error( - "This method is only for nitro transactions. Use 'getL1ToL2MessagesClassic' for classic transactions." + "This method is only for nitro transactions. Use 'getParentToChildMessagesClassic' for classic transactions." ) } @@ -269,8 +273,8 @@ export class L1TransactionReceipt implements TransactionReceipt { mn.inboxMessageEvent.data ) - return L1ToL2Message.fromEventComponents( - l2SignerOrProvider, + return ParentToChildMessage.fromEventComponents( + childSignerOrProvider, BigNumber.from(chainID).toNumber(), mn.bridgeMessageEvent.sender, mn.inboxMessageEvent.messageNum, @@ -293,70 +297,70 @@ export class L1TransactionReceipt implements TransactionReceipt { } /** - * Replaces the wait function with one that returns an L1TransactionReceipt + * Replaces the wait function with one that returns an ParentChainTransactionReceipt * @param contractTransaction * @returns */ public static monkeyPatchWait = ( contractTransaction: ContractTransaction - ): L1ContractTransaction => { + ): ParentChainContractTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new L1TransactionReceipt(result) + return new ParentChainTransactionReceipt(result) } - return contractTransaction as L1ContractTransaction + return contractTransaction as ParentChainContractTransaction } /** - * Replaces the wait function with one that returns an L1EthDepositTransactionReceipt + * Replaces the wait function with one that returns an ParentChainEthDepositTransactionReceipt * @param contractTransaction * @returns */ public static monkeyPatchEthDepositWait = ( contractTransaction: ContractTransaction - ): L1EthDepositTransaction => { + ): ParentChainEthDepositTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new L1EthDepositTransactionReceipt(result) + return new ParentChainEthDepositTransactionReceipt(result) } - return contractTransaction as L1EthDepositTransaction + return contractTransaction as ParentChainEthDepositTransaction } /** - * Replaces the wait function with one that returns an L1ContractCallTransactionReceipt + * Replaces the wait function with one that returns an ParentChainContractCallTransactionReceipt * @param contractTransaction * @returns */ public static monkeyPatchContractCallWait = ( contractTransaction: ContractTransaction - ): L1ContractCallTransaction => { + ): ParentChainContractCallTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new L1ContractCallTransactionReceipt(result) + return new ParentChainContractCallTransactionReceipt(result) } - return contractTransaction as L1ContractCallTransaction + return contractTransaction as ParentChainContractCallTransaction } } /** - * An L1TransactionReceipt with additional functionality that only exists + * An ParentChainTransactionReceipt with additional functionality that only exists * if the transaction created a single eth deposit. */ -export class L1EthDepositTransactionReceipt extends L1TransactionReceipt { +export class ParentChainEthDepositTransactionReceipt extends ParentChainTransactionReceipt { /** - * Wait for the funds to arrive on L2 + * Wait for the funds to arrive on the child chain * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created - * Defaults to 15 minutes, as by this time all transactions are expected to be included on L2. Throws on timeout. - * @returns The wait result contains `complete`, a `status`, the L1ToL2Message and optionally the `l2TxReceipt` + * Defaults to 15 minutes, as by this time all transactions are expected to be included on the child chain. Throws on timeout. + * @returns The wait result contains `complete`, a `status`, the ParentToChildMessage and optionally the `childChainTxReceipt` * If `complete` is true then this message is in the terminal state. * For eth deposits complete this is when the status is FUNDS_DEPOSITED, EXPIRED or REDEEMED. */ - public async waitForL2( - l2Provider: Provider, + public async waitForChildTx( + childProvider: Provider, confirmations?: number, timeout?: number ): Promise< @@ -365,7 +369,7 @@ export class L1EthDepositTransactionReceipt extends L1TransactionReceipt { message: EthDepositMessage } & EthDepositMessageWaitResult > { - const message = (await this.getEthDeposits(l2Provider))[0] + const message = (await this.getEthDeposits(childProvider))[0] if (!message) throw new ArbSdkError('Unexpected missing Eth Deposit message.') const res = await message.wait(confirmations, timeout) @@ -379,38 +383,51 @@ export class L1EthDepositTransactionReceipt extends L1TransactionReceipt { } /** - * An L1TransactionReceipt with additional functionality that only exists - * if the transaction created a single call to an L2 contract - this includes + * An ParentChainTransactionReceipt with additional functionality that only exists + * if the transaction created a single call to a child chain contract - this includes * token deposits. */ -export class L1ContractCallTransactionReceipt extends L1TransactionReceipt { +export class ParentChainContractCallTransactionReceipt extends ParentChainTransactionReceipt { /** - * Wait for the transaction to arrive and be executed on L2 + * Wait for the transaction to arrive and be executed on the child chain * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created - * Defaults to 15 minutes, as by this time all transactions are expected to be included on L2. Throws on timeout. - * @returns The wait result contains `complete`, a `status`, an L1ToL2Message and optionally the `l2TxReceipt`. + * Defaults to 15 minutes, as by this time all transactions are expected to be included on the child chain. Throws on timeout. + * @returns The wait result contains `complete`, a `status`, an ParentToChildMessage and optionally the `childChainTxReceipt`. * If `complete` is true then this message is in the terminal state. * For contract calls this is true only if the status is REDEEMED. */ - public async waitForL2( - l2SignerOrProvider: T, + public async waitForChildTx( + childSignerOrProvider: T, confirmations?: number, timeout?: number ): Promise< { complete: boolean - message: L1ToL2MessageReaderOrWriter - } & L1ToL2MessageWaitResult + message: ParentToChildMessageReaderOrWriter + } & ParentToChildMessageWaitResult > { - const message = (await this.getL1ToL2Messages(l2SignerOrProvider))[0] - if (!message) throw new ArbSdkError('Unexpected missing L1ToL2 message.') + const message = ( + await this.getParentToChildMessages(childSignerOrProvider) + )[0] + if (!message) + throw new ArbSdkError('Unexpected missing Parent-to-child message.') const res = await message.waitForStatus(confirmations, timeout) return { - complete: res.status === L1ToL2MessageStatus.REDEEMED, + complete: res.status === ParentToChildMessageStatus.REDEEMED, ...res, message, } } } + +// TODO: remove when all consumers have been renamed +export { + ParentChainTransactionReceipt as L1TransactionReceipt, + ParentChainContractCallTransactionReceipt as L1ContractCallTransactionReceipt, + ParentChainEthDepositTransactionReceipt as L1EthDepositTransactionReceipt, + ParentChainContractTransaction as L1ContractTransaction, + ParentChainEthDepositTransaction as L1EthDepositTransaction, + ParentChainContractCallTransaction as L1ContractCallTransaction, +} diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 5ae55acb42..dd2274da78 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -229,7 +229,9 @@ const registerCustomToken = async ( const regRec = await regTx.wait() // wait on messages - const l1ToL2Messages = await regRec.getL1ToL2Messages(l2Signer.provider!) + const l1ToL2Messages = await regRec.getParentToChildMessages( + l2Signer.provider! + ) expect(l1ToL2Messages.length, 'Should be 2 messages.').to.eq(2) const setTokenTx = await l1ToL2Messages[0].waitForStatus() diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 539c55eb56..ae8baa0db1 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -119,7 +119,7 @@ describe('Ether', async () => { 'balance failed to update after eth deposit' ) - const waitResult = await rec.waitForL2(l2Signer.provider!) + const waitResult = await rec.waitForChildTx(l2Signer.provider!) const l1ToL2Messages = await rec.getEthDeposits(l2Signer.provider!) expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') @@ -169,7 +169,9 @@ describe('Ether', async () => { 'balance failed to update after eth deposit' ) - const l1ToL2Messages = await rec.getL1ToL2Messages(l2Signer.provider!) + const l1ToL2Messages = await rec.getParentToChildMessages( + l2Signer.provider! + ) expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') const l1ToL2Message = l1ToL2Messages[0] diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/l1ToL2MessageCreator.test.ts index 5ae584ec23..af96e1f087 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/l1ToL2MessageCreator.test.ts @@ -77,7 +77,7 @@ describe('ParentToChildMessageCreator', () => { // Getting the ParentToChildMessage const parentToChildMessages = - await parentChainSubmissionTxReceipt.getL1ToL2Messages(arbProvider) + await parentChainSubmissionTxReceipt.getParentToChildMessages(arbProvider) expect(parentToChildMessages.length).to.eq(1) const parentToChildMessage = parentToChildMessages[0] @@ -146,7 +146,7 @@ describe('ParentToChildMessageCreator', () => { // Getting the ParentToChildMessage const parentToChildMessages = - await parentChainSubmissionTxReceipt.getL1ToL2Messages(arbProvider) + await parentChainSubmissionTxReceipt.getParentToChildMessages(arbProvider) expect(parentToChildMessages.length).to.eq(1) const parentToChildMessage = parentToChildMessages[0] diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index ae6a249e25..6f86b53fc9 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -329,7 +329,7 @@ export const depositToken = async ({ tokenBalL1Before.sub(depositAmount).toString() ) - const waitRes = await depositRec.waitForL2(l2Signer) + const waitRes = await depositRec.waitForChildTx(l2Signer) const ethBalL2After = await l2Signer.provider!.getBalance( destinationAddress || senderAddress diff --git a/tests/unit/l1toL2MessageEvents.test.ts b/tests/unit/l1toL2MessageEvents.test.ts index 8e01e4c2b9..81ef1a4e51 100644 --- a/tests/unit/l1toL2MessageEvents.test.ts +++ b/tests/unit/l1toL2MessageEvents.test.ts @@ -1,4 +1,4 @@ -import { L1TransactionReceipt } from '../../src' +import { ParentChainTransactionReceipt } from './../../src/lib/message/L1Transaction' import { BigNumber, constants, providers } from 'ethers' import { JsonRpcProvider } from '@ethersproject/providers' import { expect } from 'chai' @@ -150,17 +150,19 @@ describe('ParentToChildMessage events', () => { } const arbProvider = new JsonRpcProvider('https://arb1.arbitrum.io/rpc') - const l1TxnReceipt = new L1TransactionReceipt(receipt) + const parentChainTxnReceipt = new ParentChainTransactionReceipt(receipt) let txReceipt try { // Try getting classic messages using a nitro tx - txReceipt = await l1TxnReceipt.getL1ToL2MessagesClassic(arbProvider) + txReceipt = await parentChainTxnReceipt.getParentToChildMessagesClassic( + arbProvider + ) } catch (err) { // This call should throw an error expect(err).to.be.an('error') expect((err as Error).message).to.be.eq( - "This method is only for classic transactions. Use 'getL1ToL2Messages' for nitro transactions." + "This method is only for classic transactions. Use 'getParentToChildMessages' for nitro transactions." ) } finally { // Should not successfully get classic messages @@ -170,8 +172,10 @@ describe('ParentToChildMessage events', () => { ).to.be.undefined } - const isClassic = await l1TxnReceipt.isClassic(arbProvider) - const msg = (await l1TxnReceipt.getL1ToL2Messages(arbProvider))[0] + const isClassic = await parentChainTxnReceipt.isClassic(arbProvider) + const msg = ( + await parentChainTxnReceipt.getParentToChildMessages(arbProvider) + )[0] expect(isClassic, 'incorrect tx type returned by isClassic call').to.be .false @@ -185,7 +189,7 @@ describe('ParentToChildMessage events', () => { ).to.be.true expect( msg.parentChainBaseFee.eq(BigNumber.from('0x05e0fc4c58')), - 'incorrect l1 base fee' + 'incorrect parent chain base fee' ).to.be.true expect( msg.messageData.destAddress, @@ -193,11 +197,11 @@ describe('ParentToChildMessage events', () => { ).to.be.eq('0x6c411aD3E74De3E7Bd422b94A27770f5B86C623B') expect( msg.messageData.l2CallValue.eq(BigNumber.from('0x0853a0d2313c0000')), - 'incorrect l2 call value on messageData' + 'incorrect child chain call value on messageData' ).to.be.true expect( msg.messageData.l1Value.eq(BigNumber.from('0x0854e8ab1802ca80')), - 'incorrect l1 value on messageData' + 'incorrect parent chain value on messageData' ).to.be.true expect( msg.messageData.maxSubmissionFee.eq(BigNumber.from('0x01270f6740d880')), @@ -286,17 +290,19 @@ describe('ParentToChildMessage events', () => { } const arbProvider = new JsonRpcProvider('https://arb1.arbitrum.io/rpc') - const l1TxnReceipt = new L1TransactionReceipt(receipt) + const parentChainTxnReceipt = new ParentChainTransactionReceipt(receipt) let txReceipt try { // Try getting nitro messages using a classic tx - txReceipt = await l1TxnReceipt.getL1ToL2Messages(arbProvider) + txReceipt = await parentChainTxnReceipt.getParentToChildMessages( + arbProvider + ) } catch (err) { // This call should throw an error expect(err).to.be.an('error') expect((err as Error).message).to.be.eq( - "This method is only for nitro transactions. Use 'getL1ToL2MessagesClassic' for classic transactions." + "This method is only for nitro transactions. Use 'getParentToChildMessagesClassic' for classic transactions." ) } finally { // Should not successfully get nitro messages @@ -306,8 +312,10 @@ describe('ParentToChildMessage events', () => { ).to.be.undefined } - const isClassic = await l1TxnReceipt.isClassic(arbProvider) - const msg = (await l1TxnReceipt.getL1ToL2MessagesClassic(arbProvider))[0] + const isClassic = await parentChainTxnReceipt.isClassic(arbProvider) + const msg = ( + await parentChainTxnReceipt.getParentToChildMessagesClassic(arbProvider) + )[0] const status = await msg.status() expect(isClassic, 'incorrect tx type returned by isClassic call').to.be.true @@ -322,7 +330,7 @@ describe('ParentToChildMessage events', () => { expect(msg.autoRedeemId, 'incorrect auto redeem id').to.be.eq( '0x38c5c31151344c7a1433a849bbc80472786ebe911630255a6e25d6a2efd39526' ) - expect(msg.chainTxHash, 'incorrect l2 tx hash').to.be.eq( + expect(msg.chainTxHash, 'incorrect child chain tx hash').to.be.eq( '0xf91e7d2e7526927e915a2357360a3f1108dce0f9c7fa88a7492669adf5c1e53b' ) }) From 253bd13a91ce6f214b5b18b9629475581d2a7c64 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:58:21 -0400 Subject: [PATCH 15/74] chore: renames networks.ts to parent/child (#430) --- scripts/testSetup.ts | 6 +- src/lib/dataEntities/networks.ts | 79 ++++++++++--------- tests/unit/network.test.ts | 126 ++++++++++++++++--------------- 3 files changed, 115 insertions(+), 96 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index b16cbc8b6c..fde71efaef 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -125,11 +125,11 @@ export const testSetup = async (): Promise<{ addCustomNetwork({ customL1Network: ethLocal, - customL2Network: _l1Network, + customArbitrumNetwork: _l1Network, }) addCustomNetwork({ - customL2Network: l2Network, + customArbitrumNetwork: l2Network, }) setL1Network = l1Network @@ -137,7 +137,7 @@ export const testSetup = async (): Promise<{ } else { addCustomNetwork({ customL1Network: l1Network as L1Network, - customL2Network: l2Network, + customArbitrumNetwork: l2Network, }) setL1Network = l1Network diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 1d42c47ed3..86090d7a39 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -50,7 +50,7 @@ export interface L1Network extends Network { /** * Represents an Arbitrum chain, e.g. Arbitrum One, Arbitrum Sepolia, or an L3 chain. */ -export interface L2Network extends Network { +export interface ArbitrumNetwork extends Network { tokenBridge: TokenBridge ethBridge: EthBridge /** @@ -106,12 +106,12 @@ export interface L1Networks { [id: string]: L1Network } -export interface L2Networks { - [id: string]: L2Network +export interface ArbitrumNetworks { + [id: string]: ArbitrumNetwork } export interface Networks { - [id: string]: L1Network | L2Network + [id: string]: L1Network | ArbitrumNetwork } const mainnetTokenBridge: TokenBridge = { @@ -371,7 +371,7 @@ export const networks: Networks = { /** * Determines if a chain is a parent of *any* other chain. Could be an L1 or an L2 chain. */ -const isParentChain = (chain: L1Network | L2Network): boolean => { +const isParentChain = (chain: L1Network | ArbitrumNetwork): boolean => { return chain.partnerChainIDs.length > 0 } @@ -379,8 +379,8 @@ const isParentChain = (chain: L1Network | L2Network): boolean => { * Determines if a chain is an Arbitrum chain. Could be an L2 or an L3 chain. */ const isArbitrumNetwork = ( - chain: L1Network | L2Network -): chain is L2Network => { + chain: L1Network | ArbitrumNetwork +): chain is ArbitrumNetwork => { return chain.isArbitrum } @@ -388,7 +388,7 @@ const isArbitrumNetwork = ( * Determines if a chain is specifically an L1 chain (not L2 or L3). */ export const isL1Network = ( - chain: L1Network | L2Network + chain: L1Network | ArbitrumNetwork ): chain is L1Network => { return !chain.isArbitrum } @@ -399,7 +399,7 @@ export const isL1Network = ( * @return An object with only the filtered chains. */ const getChainsByType = ( - filterFn: (chain: L1Network | L2Network) => boolean + filterFn: (chain: L1Network | ArbitrumNetwork) => boolean ): T => { return Object.entries(networks).reduce( (accumulator, [chainId, chainData]) => { @@ -413,17 +413,18 @@ const getChainsByType = ( } const getL1Chains = () => getChainsByType(isL1Network) -const getArbitrumChains = () => getChainsByType(isArbitrumNetwork) +const getArbitrumChains = () => + getChainsByType(isArbitrumNetwork) /** * Returns the parent chain for the given chain. */ -export const getParentForNetwork = (chain: L1Network | L2Network) => { +export const getParentForNetwork = (chain: L1Network | ArbitrumNetwork) => { if (!isArbitrumNetwork(chain)) { throw new ArbSdkError(`Chain ${chain.chainID} is not an Arbitrum chain.`) } - const parentChain: L1Network | L2Network | undefined = + const parentChain: L1Network | ArbitrumNetwork | undefined = networks[chain.partnerChainID] if (!parentChain || !isParentChain(parentChain)) { @@ -438,7 +439,9 @@ export const getParentForNetwork = (chain: L1Network | L2Network) => { /** * Returns a list of children chains for the given chain. */ -const getChildrenForNetwork = (chain: L1Network | L2Network): L2Network[] => { +const getChildrenForNetwork = ( + chain: L1Network | ArbitrumNetwork +): ArbitrumNetwork[] => { const arbitrumChains = getArbitrumChains() return Object.values(arbitrumChains).filter( @@ -454,7 +457,7 @@ export let l1Networks: L1Networks = getL1Chains() /** * Index of all Arbitrum chains that have been added. */ -export let l2Networks: L2Networks = getArbitrumChains() +export let l2Networks: ArbitrumNetworks = getArbitrumChains() /** * Returns the network associated with the given Signer, Provider or chain id. @@ -476,7 +479,7 @@ export const getNetwork = async ( return chainId })() - let network: L1Network | L2Network | undefined = undefined + let network: L1Network | ArbitrumNetwork | undefined = undefined if (layer === 1) { network = getL1Chains()[chainID] @@ -507,10 +510,10 @@ export const getL1Network = ( * * @note Throws if the chain is not an Arbitrum chain. */ -export const getL2Network = ( +export const getArbitrumNetwork = ( signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 2) as Promise +): Promise => { + return getNetwork(signerOrProviderOrChainID, 2) as Promise } /** @@ -547,7 +550,7 @@ export const getEthBridgeInformation = async ( /** * Adds any chain to the global index of networks and updates the parent/child relationships. */ -const addNetwork = (network: L1Network | L2Network) => { +const addNetwork = (network: L1Network | ArbitrumNetwork) => { // store the network with the rest of the networks networks[network.chainID] = network @@ -562,7 +565,7 @@ const addNetwork = (network: L1Network | L2Network) => { // if it's an arbitrum chain, add it to the parent's list of children if (isArbitrumNetwork(network)) { - const parent: L1Network | L2Network | undefined = + const parent: L1Network | ArbitrumNetwork | undefined = networks[network.partnerChainID] if (!parent) { @@ -582,19 +585,19 @@ const addNetwork = (network: L1Network | L2Network) => { * Registers a pair of custom L1 and L2 chains, or a single custom Arbitrum chain (L2 or L3). * * @param customL1Network the custom L1 chain (optional) - * @param customL2Network the custom L2 or L3 chain + * @param customArbitrumNetwork the custom L2 or L3 chain */ export const addCustomNetwork = ({ customL1Network, - customL2Network, + customArbitrumNetwork, }: { customL1Network?: L1Network - customL2Network: L2Network + customArbitrumNetwork: ArbitrumNetwork }): void => { if (customL1Network) { - if (customL1Network.chainID !== customL2Network.partnerChainID) { + if (customL1Network.chainID !== customArbitrumNetwork.partnerChainID) { throw new ArbSdkError( - `Partner chain id for L2 network ${customL2Network.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customL2Network.partnerChainID}.` + `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customArbitrumNetwork.partnerChainID}.` ) } @@ -612,15 +615,17 @@ export const addCustomNetwork = ({ addNetwork(customL1Network) } - if (l2Networks[customL2Network.chainID]) { - throw new ArbSdkError(`Network ${customL2Network.chainID} already included`) - } else if (!customL2Network.isCustom) { + if (l2Networks[customArbitrumNetwork.chainID]) { throw new ArbSdkError( - `Custom network ${customL2Network.chainID} must have isCustom flag set to true` + `Network ${customArbitrumNetwork.chainID} already included` + ) + } else if (!customArbitrumNetwork.isCustom) { + throw new ArbSdkError( + `Custom network ${customArbitrumNetwork.chainID} must have isCustom flag set to true` ) } - addNetwork(customL2Network) + addNetwork(customArbitrumNetwork) } /** @@ -630,7 +635,7 @@ export const addCustomNetwork = ({ */ export const addDefaultLocalNetwork = (): { l1Network: L1Network - l2Network: L2Network + l2Network: ArbitrumNetwork } => { const defaultLocalL1Network: L1Network = { blockTime: 10, @@ -642,7 +647,7 @@ export const addDefaultLocalNetwork = (): { isArbitrum: false, } - const defaultLocalL2Network: L2Network = { + const defaultLocalL2Network: ArbitrumNetwork = { chainID: 412346, confirmPeriodBlocks: 20, ethBridge: { @@ -683,7 +688,7 @@ export const addDefaultLocalNetwork = (): { addCustomNetwork({ customL1Network: defaultLocalL1Network, - customL2Network: defaultLocalL2Network, + customArbitrumNetwork: defaultLocalL2Network, }) return { @@ -711,4 +716,10 @@ const createNetworkStateHandler = () => { const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } -export const getChildChain = getL2Network +export const getChildChain = getArbitrumNetwork + +export { + ArbitrumNetwork as L2Network, + ArbitrumNetworks as L2Networks, + getArbitrumNetwork as getL2Network, +} diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 8c428a4b3a..5c50a84d27 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -3,9 +3,9 @@ import { resetNetworksToDefault, addCustomNetwork, getL1Network, - getL2Network, + getArbitrumNetwork, l1Networks, - l2Networks, + l2Networks as arbitrumNetworks, } from '../../src/lib/dataEntities/networks' const ethereumMainnetChainId = 1 @@ -21,10 +21,10 @@ describe('Networks', async () => { }) describe('adding networks', () => { - it('adds a custom L2 network', async function () { - const arbitrumOne = await getL2Network(arbitrumOneChainId) + it('adds a custom Arbitrum network', async function () { + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - const customL2Network = { + const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL2ChainId, partnerChainID: ethereumMainnetChainId, @@ -32,21 +32,23 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL2Network }) + addCustomNetwork({ customArbitrumNetwork }) - expect(await getL2Network(mockL2ChainId)).to.be.ok + expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok // assert network was added as child - const l1Network = await getL1Network(customL2Network.partnerChainID) + const l1Network = await getL1Network(customArbitrumNetwork.partnerChainID) expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent - const l2Network = await getL2Network(customL2Network.chainID) - expect(l2Network.partnerChainID).to.equal(ethereumMainnetChainId) + const arbitrumNetwork = await getArbitrumNetwork( + customArbitrumNetwork.chainID + ) + expect(arbitrumNetwork.partnerChainID).to.equal(ethereumMainnetChainId) }) - it('adds a custom L1 and L2 network', async function () { + it('adds a custom L1 and Arbitrum network', async function () { const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getL2Network(arbitrumOneChainId) + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) const customL1Network = { ...ethereumMainnet, @@ -55,7 +57,7 @@ describe('Networks', async () => { isCustom: true, } as const - const customL2Network = { + const customArbitrumNetwork = { ...arbitrumOne, partnerChainID: mockL1ChainId, chainID: mockL2ChainId, @@ -63,23 +65,25 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL1Network, customL2Network }) + addCustomNetwork({ customL1Network, customArbitrumNetwork }) expect(await getL1Network(mockL1ChainId)).to.be.ok - expect(await getL2Network(mockL2ChainId)).to.be.ok + expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok // assert network was added as child const l1Network = await getL1Network(mockL1ChainId) expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent - const l2Network = await getL2Network(customL2Network.chainID) - expect(l2Network.partnerChainID).to.equal(mockL1ChainId) + const arbitrumNetwork = await getArbitrumNetwork( + customArbitrumNetwork.chainID + ) + expect(arbitrumNetwork.partnerChainID).to.equal(mockL1ChainId) }) it('adds a custom L3 network', async function () { - const arbitrumOne = await getL2Network(arbitrumOneChainId) + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - const customL2Network = { + const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL3ChainId, partnerChainID: arbitrumOneChainId, @@ -87,21 +91,23 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL2Network }) + addCustomNetwork({ customArbitrumNetwork }) - expect(await getL2Network(mockL3ChainId)).to.be.ok + expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok // assert network was added as child - const l2Network = await getL2Network(customL2Network.partnerChainID) - expect(l2Network.partnerChainIDs).to.include(mockL3ChainId) + const arbitrumNetwork = await getArbitrumNetwork( + customArbitrumNetwork.partnerChainID + ) + expect(arbitrumNetwork.partnerChainIDs).to.include(mockL3ChainId) // assert network has correct parent - const l3Network = await getL2Network(mockL3ChainId) + const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.partnerChainID).to.equal(arbitrumOneChainId) }) it('adds a custom L1, L2, and L3 network', async function () { const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getL2Network(arbitrumOneChainId) + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) const customL1Network = { ...ethereumMainnet, @@ -110,7 +116,7 @@ describe('Networks', async () => { isCustom: true, } as const - const customL2Network = { + const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL2ChainId, partnerChainID: mockL1ChainId, @@ -118,17 +124,17 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL1Network, customL2Network }) + addCustomNetwork({ customL1Network, customArbitrumNetwork }) expect(await getL1Network(mockL1ChainId)).to.be.ok - expect(await getL2Network(mockL2ChainId)).to.be.ok + expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok // assert network was added as child const l1Network = await getL1Network(mockL1ChainId) expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent - const l2Network = await getL2Network(mockL2ChainId) - expect(l2Network.partnerChainID).to.equal(mockL1ChainId) + const arbitrumNetwork = await getArbitrumNetwork(mockL2ChainId) + expect(arbitrumNetwork.partnerChainID).to.equal(mockL1ChainId) const customL3Network = { ...arbitrumOne, @@ -138,21 +144,21 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL2Network: customL3Network }) + addCustomNetwork({ customArbitrumNetwork: customL3Network }) - expect(await getL2Network(mockL3ChainId)).to.be.ok + expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok // assert network was added as child - const l2NetworkAgain = await getL2Network(mockL2ChainId) - expect(l2NetworkAgain.partnerChainIDs).to.include(mockL3ChainId) + const arbitrumNetworkAgain = await getArbitrumNetwork(mockL2ChainId) + expect(arbitrumNetworkAgain.partnerChainIDs).to.include(mockL3ChainId) // assert network has correct parent - const l3Network = await getL2Network(mockL3ChainId) + const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.partnerChainID).to.equal(mockL2ChainId) }) - it('fails to add a custom L1 and L2 network if they do not match', async function () { + it('fails to add a custom L1 and Arbitrum network if they do not match', async function () { const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getL2Network(arbitrumOneChainId) + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) const wrongPartnerChainId = 1241244 @@ -163,7 +169,7 @@ describe('Networks', async () => { isCustom: true, } as const - const customL2Network = { + const customArbitrumNetwork = { ...arbitrumOne, partnerChainID: wrongPartnerChainId, chainID: mockL2ChainId, @@ -172,22 +178,22 @@ describe('Networks', async () => { } as const try { - addCustomNetwork({ customL1Network, customL2Network }) + addCustomNetwork({ customL1Network, customArbitrumNetwork }) } catch (err) { // should fail expect(err).to.be.an('error') expect((err as Error).message).to.be.eq( - `Partner chain id for L2 network ${customL2Network.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${wrongPartnerChainId}.` + `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${wrongPartnerChainId}.` ) } }) it('fails to add a custom L3 without previously registering L2', async function () { - const arbitrumOne = await getL2Network(arbitrumOneChainId) + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) try { addCustomNetwork({ - customL2Network: { + customArbitrumNetwork: { ...arbitrumOne, chainID: mockL3ChainId, partnerChainID: mockL2ChainId, @@ -211,12 +217,12 @@ describe('Networks', async () => { expect(network.chainID).to.be.eq(ethereumMainnetChainId) }) - it('successfully fetches an L2 network with `getL2Network`', async function () { - const network = await getL2Network(arbitrumOneChainId) + it('successfully fetches an Arbitrum network with `getArbitrumNetwork`', async function () { + const network = await getArbitrumNetwork(arbitrumOneChainId) expect(network.chainID).to.be.eq(arbitrumOneChainId) }) - it('fails to fetch a registered L2 network with `getL1Network`', async function () { + it('fails to fetch a registered Arbitrum network with `getL1Network`', async function () { try { await getL1Network(arbitrumOneChainId) } catch (err) { @@ -228,9 +234,9 @@ describe('Networks', async () => { } }) - it('fails to fetch a registered L1 network with `getL2Network`', async function () { + it('fails to fetch a registered L1 network with `getArbitrumNetwork`', async function () { try { - await getL2Network(ethereumMainnetChainId) + await getArbitrumNetwork(ethereumMainnetChainId) } catch (err) { // should fail expect(err).to.be.an('error') @@ -240,8 +246,8 @@ describe('Networks', async () => { } }) - it('successfully fetches an L3 chain with `getL2Network`', async function () { - const arbitrumOne = await getL2Network(arbitrumOneChainId) + it('successfully fetches an L3 chain with `getArbitrumNetwork`', async function () { + const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) const customL3Network = { ...arbitrumOne, @@ -251,16 +257,18 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customL2Network: customL3Network }) + addCustomNetwork({ customArbitrumNetwork: customL3Network }) - const l3Network = await getL2Network(mockL3ChainId) + const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.chainID).to.be.eq(mockL3ChainId) // assert network has correct parent expect(l3Network.partnerChainID).to.equal(arbitrumOneChainId) // assert network was added as child - const l2Network = await getL2Network(customL3Network.partnerChainID) - expect(l2Network.partnerChainIDs).to.include(mockL3ChainId) + const arbitrumNetwork = await getArbitrumNetwork( + customL3Network.partnerChainID + ) + expect(arbitrumNetwork.partnerChainIDs).to.include(mockL3ChainId) }) it('fails to fetch an unrecognized L1 network', async () => { @@ -280,7 +288,7 @@ describe('Networks', async () => { const chainId = 9999 try { - await getL2Network(chainId) + await getArbitrumNetwork(chainId) } catch (err) { expect(err).to.be.instanceOf(Error) expect((err as Error).message).to.be.eq( @@ -303,16 +311,16 @@ describe('Networks', async () => { }) // todo: this could be a snapshot test - it('returns correct L2 networks', () => { - const l2NetworksEntries = Object.entries(l2Networks) - const l2NetworksKeys = l2NetworksEntries.map(([key]) => key) + it('returns correct Arbitrum networks', () => { + const arbitrumNetworksEntries = Object.entries(arbitrumNetworks) + const arbitrumNetworksKeys = arbitrumNetworksEntries.map(([key]) => key) const expected = [42161, 421613, 42170, 421614, 23011913] // .map(id => id.toString()) - expect(l2NetworksKeys).to.have.length(expected.length) - expect(l2NetworksKeys).to.have.members(expected) + expect(arbitrumNetworksKeys).to.have.length(expected.length) + expect(arbitrumNetworksKeys).to.have.members(expected) }) }) }) From 5f377de7b341f31cd89bab916e38d45cf6b7db95 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:21:42 -0400 Subject: [PATCH 16/74] chore: rename erc20bridger to parent/child (#431) --- src/lib/assetBridger/assetBridger.ts | 28 +- src/lib/assetBridger/erc20Bridger.ts | 409 +++++++++--------- src/lib/assetBridger/ethBridger.ts | 12 +- .../customFeeTokenEthBridger.test.ts | 8 +- .../customFeeTokenTestHelpers.ts | 7 +- tests/integration/customerc20.test.ts | 2 +- tests/integration/eth.test.ts | 4 +- tests/integration/retryableData.test.ts | 12 +- tests/integration/standarderc20.test.ts | 6 +- tests/integration/testHelpers.ts | 22 +- tests/integration/weth.test.ts | 2 +- 11 files changed, 267 insertions(+), 245 deletions(-) diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index f6eeb77389..e8f28bd7ea 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -23,7 +23,7 @@ import { L2ContractTransaction } from '../message/L2Transaction' import { L1Network, - L2Network, + ArbitrumNetwork, getParentForNetwork, } from '../dataEntities/networks' import { @@ -32,13 +32,13 @@ import { } from '../dataEntities/signerOrProvider' /** - * Base for bridging assets from l1 to l2 and back + * Base for bridging assets from parent-to-child and back */ export abstract class AssetBridger { /** * Parent chain for the given Arbitrum chain, can be an L1 or an L2 */ - public readonly l1Network: L1Network | L2Network + public readonly parentChain: L1Network | ArbitrumNetwork /** * In case of a chain that uses ETH as its native/gas token, this is either `undefined` or the zero address @@ -47,25 +47,25 @@ export abstract class AssetBridger { */ public readonly nativeToken?: string - public constructor(public readonly l2Network: L2Network) { - this.l1Network = getParentForNetwork(l2Network) - this.nativeToken = l2Network.nativeToken + public constructor(public readonly childChain: ArbitrumNetwork) { + this.parentChain = getParentForNetwork(childChain) + this.nativeToken = childChain.nativeToken } /** - * Check the signer/provider matches the l1Network, throws if not + * Check the signer/provider matches the parentChain, throws if not * @param sop */ - protected async checkL1Network(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.l1Network.chainID) + protected async checkParentChain(sop: SignerOrProvider): Promise { + await SignerProviderUtils.checkNetworkMatches(sop, this.parentChain.chainID) } /** - * Check the signer/provider matches the l2Network, throws if not + * Check the signer/provider matches the childChain, throws if not * @param sop */ - protected async checkL2Network(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.l2Network.chainID) + protected async checkChildChain(sop: SignerOrProvider): Promise { + await SignerProviderUtils.checkNetworkMatches(sop, this.childChain.chainID) } /** @@ -77,13 +77,13 @@ export abstract class AssetBridger { } /** - * Transfer assets from L1 to L2 + * Transfer assets from parent-to-child * @param params */ public abstract deposit(params: DepositParams): Promise /** - * Transfer assets from L2 to L1 + * Transfer assets from child-to-parent * @param params */ public abstract withdraw( diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 29a4e54d46..ffaef8569f 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -42,13 +42,10 @@ import { WithdrawalInitiatedEvent } from '../abi/L2ArbitrumGateway' import { GatewaySetEvent } from '../abi/L1GatewayRouter' import { GasOverrides, - L1ToL2MessageGasEstimator, + L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, } from '../message/L1ToL2MessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' -import { - L2Network as ChildChain, - getL2Network as getChildChain, -} from '../dataEntities/networks' +import { ArbitrumNetwork, getArbitrumNetwork } from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' import { DISABLED_GATEWAY } from '../dataEntities/constants' import { EventFetcher } from '../utils/eventFetcher' @@ -64,23 +61,24 @@ import { L2TransactionReceipt, } from '../message/L2Transaction' import { - isL1ToL2TransactionRequest, - isL2ToL1TransactionRequest, + isL1ToL2TransactionRequest as isParentToChildTransactionRequest, + isL2ToL1TransactionRequest as isChildToParentTransactionRequest, L1ToL2TransactionRequest, L2ToL1TransactionRequest, + L1ToL2TransactionRequest as ParentToChildTransactionRequest, } from '../dataEntities/transactionRequest' import { defaultAbiCoder } from 'ethers/lib/utils' import { OmitTyped, RequiredPick } from '../utils/types' import { RetryableDataTools } from '../dataEntities/retryableData' import { EventArgs } from '../dataEntities/event' -import { L1ToL2MessageGasParams } from '../message/L1ToL2MessageCreator' +import { ParentToChildMessageGasParams } from '../message/L1ToL2MessageCreator' import { isArbitrumChain } from '../utils/lib' export interface TokenApproveParams { /** * L1 address of the ERC20 token contract */ - erc20L1Address: string + erc20ParentAddress: string /** * Amount to approve. Defaults to max int. */ @@ -93,13 +91,13 @@ export interface TokenApproveParams { export interface Erc20DepositParams extends EthDepositParams { /** - * An L2 provider + * A child provider */ - l2Provider: Provider + childProvider: Provider /** * L1 address of the token ERC20 contract */ - erc20L1Address: string + erc20ParentAddress: string /** * L2 address of the entity receiving the funds. Defaults to the l1FromAddress */ @@ -130,21 +128,23 @@ export interface Erc20WithdrawParams extends EthWithdrawParams { /** * L1 address of the token ERC20 contract */ - erc20l1Address: string + erc20ParentAddress: string } -export type L1ToL2TxReqAndSignerProvider = L1ToL2TransactionRequest & { +export type ParentToChildTxReqAndSignerProvider = L1ToL2TransactionRequest & { l1Signer: Signer overrides?: Overrides } -export type L2ToL1TxReqAndSigner = L2ToL1TransactionRequest & { +export type ChildToParentTxReqAndSigner = L2ToL1TransactionRequest & { l2Signer: Signer overrides?: Overrides } type SignerTokenApproveParams = TokenApproveParams & { l1Signer: Signer } -type ProviderTokenApproveParams = TokenApproveParams & { l1Provider: Provider } +type ProviderTokenApproveParams = TokenApproveParams & { + parentProvider: Provider +} export type ApproveParamsOrTxRequest = | SignerTokenApproveParams | { @@ -161,7 +161,7 @@ type DepositRequest = OmitTyped< Erc20DepositParams, 'overrides' | 'l1Signer' > & { - l1Provider: Provider + parentProvider: Provider /** * Address that is depositing the assets */ @@ -174,65 +174,65 @@ type DefaultedDepositRequest = RequiredPick< > /** - * Bridger for moving ERC20 tokens back and forth between L1 to L2 + * Bridger for moving ERC20 tokens back and forth between parent-to-child */ export class Erc20Bridger extends AssetBridger< - Erc20DepositParams | L1ToL2TxReqAndSignerProvider, + Erc20DepositParams | ParentToChildTxReqAndSignerProvider, OmitTyped | L2ToL1TransactionRequest > { public static MAX_APPROVAL: BigNumber = MaxUint256 public static MIN_CUSTOM_DEPOSIT_GAS_LIMIT = BigNumber.from(275000) /** - * Bridger for moving ERC20 tokens back and forth between L1 to L2 + * Bridger for moving ERC20 tokens back and forth between parent-to-child */ - public constructor(l2Network: ChildChain) { - super(l2Network) + public constructor(childChain: ArbitrumNetwork) { + super(childChain) } /** - * Instantiates a new Erc20Bridger from an L2 Provider - * @param l2Provider + * Instantiates a new Erc20Bridger from a child provider + * @param childProvider * @returns */ - public static async fromProvider(l2Provider: Provider) { - return new Erc20Bridger(await getChildChain(l2Provider)) + public static async fromProvider(childProvider: Provider) { + return new Erc20Bridger(await getArbitrumNetwork(childProvider)) } /** * Get the address of the l1 gateway for this token - * @param erc20L1Address - * @param l1Provider + * @param erc20ParentAddress + * @param parentProvider * @returns */ public async getL1GatewayAddress( - erc20L1Address: string, - l1Provider: Provider + erc20ParentAddress: string, + parentProvider: Provider ): Promise { - await this.checkL1Network(l1Provider) + await this.checkParentChain(parentProvider) return await L1GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l1GatewayRouter, - l1Provider - ).getGateway(erc20L1Address) + this.childChain.tokenBridge.l1GatewayRouter, + parentProvider + ).getGateway(erc20ParentAddress) } /** * Get the address of the l2 gateway for this token - * @param erc20L1Address - * @param l2Provider + * @param erc20ParentAddress + * @param childProvider * @returns */ public async getL2GatewayAddress( - erc20L1Address: string, - l2Provider: Provider + erc20ParentAddress: string, + childProvider: Provider ): Promise { - await this.checkL2Network(l2Provider) + await this.checkChildChain(childProvider) return await L2GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l2GatewayRouter, - l2Provider - ).getGateway(erc20L1Address) + this.childChain.tokenBridge.l2GatewayRouter, + childProvider + ).getGateway(erc20ParentAddress) } /** @@ -262,12 +262,14 @@ export class Erc20Bridger extends AssetBridger< throw new Error('chain uses ETH as its native/gas token') } - await this.checkL1Network(params.l1Signer) + await this.checkParentChain(params.l1Signer) const approveGasTokenRequest = this.isApproveParams(params) ? await this.getApproveGasTokenRequest({ ...params, - l1Provider: SignerProviderUtils.getProviderOrThrow(params.l1Signer), + parentProvider: SignerProviderUtils.getProviderOrThrow( + params.l1Signer + ), }) : params.txRequest @@ -288,8 +290,8 @@ export class Erc20Bridger extends AssetBridger< ): Promise>> { // you approve tokens to the gateway that the router will use const gatewayAddress = await this.getL1GatewayAddress( - params.erc20L1Address, - SignerProviderUtils.getProviderOrThrow(params.l1Provider) + params.erc20ParentAddress, + SignerProviderUtils.getProviderOrThrow(params.parentProvider) ) const iErc20Interface = ERC20__factory.createInterface() @@ -299,7 +301,7 @@ export class Erc20Bridger extends AssetBridger< ]) return { - to: params.erc20L1Address, + to: params.erc20ParentAddress, data, value: BigNumber.from(0), } @@ -308,7 +310,7 @@ export class Erc20Bridger extends AssetBridger< private isApproveParams( params: ApproveParamsOrTxRequest ): params is SignerTokenApproveParams { - return (params as SignerTokenApproveParams).erc20L1Address != undefined + return (params as SignerTokenApproveParams).erc20ParentAddress != undefined } /** @@ -319,12 +321,14 @@ export class Erc20Bridger extends AssetBridger< public async approveToken( params: ApproveParamsOrTxRequest ): Promise { - await this.checkL1Network(params.l1Signer) + await this.checkParentChain(params.l1Signer) const approveRequest = this.isApproveParams(params) ? await this.getApproveTokenRequest({ ...params, - l1Provider: SignerProviderUtils.getProviderOrThrow(params.l1Signer), + parentProvider: SignerProviderUtils.getProviderOrThrow( + params.l1Signer + ), }) : params.txRequest return await params.l1Signer.sendTransaction({ @@ -334,25 +338,25 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the L2 events created by a withdrawal - * @param l2Provider + * Get the child chain events created by a withdrawal + * @param childProvider * @param gatewayAddress - * @param l1TokenAddress + * @param parentChainTokenAddress * @param fromAddress * @param filter * @returns */ public async getL2WithdrawalEvents( - l2Provider: Provider, + childProvider: Provider, gatewayAddress: string, filter: { fromBlock: BlockTag; toBlock: BlockTag }, - l1TokenAddress?: string, + parentChainTokenAddress?: string, fromAddress?: string, toAddress?: string ): Promise<(EventArgs & { txHash: string })[]> { - await this.checkL2Network(l2Provider) + await this.checkChildChain(childProvider) - const eventFetcher = new EventFetcher(l2Provider) + const eventFetcher = new EventFetcher(childProvider) const events = ( await eventFetcher.getEvents( L2ArbitrumGateway__factory, @@ -366,11 +370,11 @@ export class Erc20Bridger extends AssetBridger< ) ).map(a => ({ txHash: a.transactionHash, ...a.event })) - return l1TokenAddress + return parentChainTokenAddress ? events.filter( log => log.l1Token.toLocaleLowerCase() === - l1TokenAddress.toLocaleLowerCase() + parentChainTokenAddress.toLocaleLowerCase() ) : events } @@ -378,17 +382,17 @@ export class Erc20Bridger extends AssetBridger< /** * Does the provided address look like a weth gateway * @param potentialWethGatewayAddress - * @param l1Provider + * @param parentProvider * @returns */ private async looksLikeWethGateway( potentialWethGatewayAddress: string, - l1Provider: Provider + parentProvider: Provider ) { try { const potentialWethGateway = L1WethGateway__factory.connect( potentialWethGatewayAddress, - l1Provider + parentProvider ) await potentialWethGateway.callStatic.l1Weth() return true @@ -408,17 +412,17 @@ export class Erc20Bridger extends AssetBridger< /** * Is this a known or unknown WETH gateway * @param gatewayAddress - * @param l1Provider + * @param parentProvider * @returns */ private async isWethGateway( gatewayAddress: string, - l1Provider: Provider + parentProvider: Provider ): Promise { - const wethAddress = this.l2Network.tokenBridge.l1WethGateway - if (this.l2Network.isCustom) { + const wethAddress = this.childChain.tokenBridge.l1WethGateway + if (this.childChain.isCustom) { // For custom network, we do an ad-hoc check to see if it's a WETH gateway - if (await this.looksLikeWethGateway(gatewayAddress, l1Provider)) { + if (await this.looksLikeWethGateway(gatewayAddress, parentProvider)) { return true } // ...otherwise we directly check it against the config file @@ -433,15 +437,15 @@ export class Erc20Bridger extends AssetBridger< * Note: This function just returns a typed ethers object for the provided address, it doesnt * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. - * @param l2Provider + * @param childProvider * @param l2TokenAddr * @returns */ - public getL2TokenContract( - l2Provider: Provider, + public getChildTokenContract( + childProvider: Provider, l2TokenAddr: string ): L2GatewayToken { - return L2GatewayToken__factory.connect(l2TokenAddr, l2Provider) + return L2GatewayToken__factory.connect(l2TokenAddr, childProvider) } /** @@ -449,70 +453,76 @@ export class Erc20Bridger extends AssetBridger< * Note: This function just returns a typed ethers object for the provided address, it doesnt * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. - * @param l1Provider - * @param l1TokenAddr + * @param parentProvider + * @param parentChainTokenAddr * @returns */ - public getL1TokenContract(l1Provider: Provider, l1TokenAddr: string): ERC20 { - return ERC20__factory.connect(l1TokenAddr, l1Provider) + public getParentChainTokenContract( + parentProvider: Provider, + parentChainTokenAddr: string + ): ERC20 { + return ERC20__factory.connect(parentChainTokenAddr, parentProvider) } /** - * Get the corresponding L2 for the provided L1 token - * @param erc20L1Address - * @param l1Provider + * Get the corresponding child chain token address for the provided parent chain token + * @param erc20ParentAddress + * @param parentProvider * @returns */ public async getL2ERC20Address( - erc20L1Address: string, - l1Provider: Provider + erc20ParentAddress: string, + parentProvider: Provider ): Promise { - await this.checkL1Network(l1Provider) + await this.checkParentChain(parentProvider) const l1GatewayRouter = L1GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l1GatewayRouter, - l1Provider + this.childChain.tokenBridge.l1GatewayRouter, + parentProvider ) return await l1GatewayRouter.functions - .calculateL2TokenAddress(erc20L1Address) + .calculateL2TokenAddress(erc20ParentAddress) .then(([res]) => res) } /** - * Get the corresponding L1 for the provided L2 token - * Validates the returned address against the l2 router to ensure it is correctly mapped to the provided erc20L2Address - * @param erc20L2Address - * @param l2Provider + * Get the corresponding parent chain address for the provided child chain token + * Validates the returned address against the child chain router to ensure it is correctly mapped to the provided erc20ChildChainAddress + * @param erc20ChildChainAddress + * @param childProvider * @returns */ public async getL1ERC20Address( - erc20L2Address: string, - l2Provider: Provider + erc20ChildChainAddress: string, + childProvider: Provider ): Promise { - await this.checkL2Network(l2Provider) + await this.checkChildChain(childProvider) - // L2 WETH contract doesn't have the l1Address method on it + // child chain WETH contract doesn't have the l1Address method on it if ( - erc20L2Address.toLowerCase() === - this.l2Network.tokenBridge.l2Weth.toLowerCase() + erc20ChildChainAddress.toLowerCase() === + this.childChain.tokenBridge.l2Weth.toLowerCase() ) { - return this.l2Network.tokenBridge.l1Weth + return this.childChain.tokenBridge.l1Weth } - const arbERC20 = L2GatewayToken__factory.connect(erc20L2Address, l2Provider) + const arbERC20 = L2GatewayToken__factory.connect( + erc20ChildChainAddress, + childProvider + ) const l1Address = await arbERC20.functions.l1Address().then(([res]) => res) // check that this l1 address is indeed registered to this l2 token const l2GatewayRouter = L2GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l2GatewayRouter, - l2Provider + this.childChain.tokenBridge.l2GatewayRouter, + childProvider ) const l2Address = await l2GatewayRouter.calculateL2TokenAddress(l1Address) - if (l2Address.toLowerCase() !== erc20L2Address.toLowerCase()) { + if (l2Address.toLowerCase() !== erc20ChildChainAddress.toLowerCase()) { throw new ArbSdkError( - `Unexpected l1 address. L1 address from token is not registered to the provided l2 address. ${l1Address} ${l2Address} ${erc20L2Address}` + `Unexpected l1 address. L1 address from token is not registered to the provided l2 address. ${l1Address} ${l2Address} ${erc20ChildChainAddress}` ) } @@ -521,23 +531,23 @@ export class Erc20Bridger extends AssetBridger< /** * Whether the token has been disabled on the router - * @param l1TokenAddress - * @param l1Provider + * @param parentChainTokenAddress + * @param parentProvider * @returns */ - public async l1TokenIsDisabled( - l1TokenAddress: string, - l1Provider: Provider + public async parentChainTokenIsDisabled( + parentChainTokenAddress: string, + parentProvider: Provider ): Promise { - await this.checkL1Network(l1Provider) + await this.checkParentChain(parentProvider) const l1GatewayRouter = L1GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l1GatewayRouter, - l1Provider + this.childChain.tokenBridge.l1GatewayRouter, + parentProvider ) return ( - (await l1GatewayRouter.l1TokenToGateway(l1TokenAddress)) === + (await l1GatewayRouter.l1TokenToGateway(parentChainTokenAddress)) === DISABLED_GATEWAY ) } @@ -559,7 +569,7 @@ export class Erc20Bridger extends AssetBridger< * @returns */ private getDepositRequestCallValue( - depositParams: OmitTyped + depositParams: OmitTyped ) { // the call value should be zero when paying with a custom gas token, // as the fee amount is packed inside the last parameter (`data`) of the call to `outboundTransfer`, see `getDepositRequestOutboundTransferInnerData` @@ -582,7 +592,7 @@ export class Erc20Bridger extends AssetBridger< * @returns */ private getDepositRequestOutboundTransferInnerData( - depositParams: OmitTyped + depositParams: OmitTyped ) { if (!this.nativeTokenIsEth) { return defaultAbiCoder.encode( @@ -618,27 +628,26 @@ export class Erc20Bridger extends AssetBridger< */ public async getDepositRequest( params: DepositRequest - ): Promise { - await this.checkL1Network(params.l1Provider) - await this.checkL2Network(params.l2Provider) + ): Promise { + await this.checkParentChain(params.parentProvider) + await this.checkChildChain(params.childProvider) const defaultedParams = this.applyDefaults(params) const { amount, destinationAddress, - erc20L1Address, - l1Provider, - l2Provider, + erc20ParentAddress, + parentProvider, + childProvider, retryableGasOverrides, } = defaultedParams const l1GatewayAddress = await this.getL1GatewayAddress( - erc20L1Address, - l1Provider + erc20ParentAddress, + parentProvider ) let tokenGasOverrides: GasOverrides | undefined = retryableGasOverrides - // we also add a hardcoded minimum gas limit for custom gateway deposits - if (l1GatewayAddress === this.l2Network.tokenBridge.l1CustomGateway) { + if (l1GatewayAddress === this.childChain.tokenBridge.l1CustomGateway) { if (!tokenGasOverrides) tokenGasOverrides = {} if (!tokenGasOverrides.gasLimit) tokenGasOverrides.gasLimit = {} if (!tokenGasOverrides.gasLimit.min) { @@ -648,7 +657,7 @@ export class Erc20Bridger extends AssetBridger< } const depositFunc = ( - depositParams: OmitTyped + depositParams: OmitTyped ) => { depositParams.maxSubmissionCost = params.maxSubmissionCost || depositParams.maxSubmissionCost @@ -660,7 +669,7 @@ export class Erc20Bridger extends AssetBridger< const functionData = defaultedParams.excessFeeRefundAddress !== defaultedParams.from ? iGatewayRouter.encodeFunctionData('outboundTransferCustomRefund', [ - erc20L1Address, + erc20ParentAddress, defaultedParams.excessFeeRefundAddress, destinationAddress, amount, @@ -669,7 +678,7 @@ export class Erc20Bridger extends AssetBridger< innerData, ]) : iGatewayRouter.encodeFunctionData('outboundTransfer', [ - erc20L1Address, + erc20ParentAddress, destinationAddress, amount, depositParams.gasLimit, @@ -679,22 +688,22 @@ export class Erc20Bridger extends AssetBridger< return { data: functionData, - to: this.l2Network.tokenBridge.l1GatewayRouter, + to: this.childChain.tokenBridge.l1GatewayRouter, from: defaultedParams.from, value: this.getDepositRequestCallValue(depositParams), } } - const gasEstimator = new L1ToL2MessageGasEstimator(l2Provider) + const gasEstimator = new ParentToChildMessageGasEstimator(childProvider) const estimates = await gasEstimator.populateFunctionParams( depositFunc, - l1Provider, + parentProvider, tokenGasOverrides ) return { txRequest: { - to: this.l2Network.tokenBridge.l1GatewayRouter, + to: this.childChain.tokenBridge.l1GatewayRouter, data: estimates.data, value: estimates.value, from: params.from, @@ -706,10 +715,10 @@ export class Erc20Bridger extends AssetBridger< isValid: async () => { const reEstimates = await gasEstimator.populateFunctionParams( depositFunc, - l1Provider, + parentProvider, tokenGasOverrides ) - return L1ToL2MessageGasEstimator.isValid( + return ParentToChildMessageGasEstimator.isValid( estimates.estimates, reEstimates.estimates ) @@ -718,14 +727,14 @@ export class Erc20Bridger extends AssetBridger< } /** - * Execute a token deposit from L1 to L2 + * Execute a token deposit from parent-to-child * @param params * @returns */ public async deposit( - params: Erc20DepositParams | L1ToL2TxReqAndSignerProvider + params: Erc20DepositParams | ParentToChildTxReqAndSignerProvider ): Promise { - await this.checkL1Network(params.l1Signer) + await this.checkParentChain(params.l1Signer) // Although the types prevent should alert callers that value is not // a valid override, it is possible that they pass it in anyway as it's a common override @@ -736,12 +745,15 @@ export class Erc20Bridger extends AssetBridger< ) } - const l1Provider = SignerProviderUtils.getProviderOrThrow(params.l1Signer) - const tokenDeposit = isL1ToL2TransactionRequest(params) + const parentProvider = SignerProviderUtils.getProviderOrThrow( + params.l1Signer + ) + + const tokenDeposit = isParentToChildTransactionRequest(params) ? params : await this.getDepositRequest({ ...params, - l1Provider, + parentProvider, from: await params.l1Signer.getAddress(), }) @@ -775,7 +787,7 @@ export class Erc20Bridger extends AssetBridger< ): string } ).encodeFunctionData('outboundTransfer(address,address,uint256,bytes)', [ - params.erc20l1Address, + params.erc20ParentAddress, to, params.amount, '0x', @@ -784,13 +796,13 @@ export class Erc20Bridger extends AssetBridger< return { txRequest: { data: functionData, - to: this.l2Network.tokenBridge.l2GatewayRouter, + to: this.childChain.tokenBridge.l2GatewayRouter, value: BigNumber.from(0), from: params.from, }, // todo: do proper estimation - estimateL1GasLimit: async (l1Provider: Provider) => { - if (await isArbitrumChain(l1Provider)) { + estimateL1GasLimit: async (parentProvider: Provider) => { + if (await isArbitrumChain(parentProvider)) { // values for L3 are dependent on the L1 base fee, so hardcoding can never be accurate // however, this is only an estimate used for display, so should be good enough // @@ -799,13 +811,16 @@ export class Erc20Bridger extends AssetBridger< } const l1GatewayAddress = await this.getL1GatewayAddress( - params.erc20l1Address, - l1Provider + params.erc20ParentAddress, + parentProvider ) // The WETH gateway is the only deposit that requires callvalue in the L2 user-tx (i.e., the recently un-wrapped ETH) // Here we check if this is a WETH deposit, and include the callvalue for the gas estimate query if so - const isWeth = await this.isWethGateway(l1GatewayAddress, l1Provider) + const isWeth = await this.isWethGateway( + l1GatewayAddress, + parentProvider + ) // measured 157421 - add some padding return isWeth ? BigNumber.from(190000) : BigNumber.from(160000) @@ -821,14 +836,14 @@ export class Erc20Bridger extends AssetBridger< public async withdraw( params: | (OmitTyped & { l2Signer: Signer }) - | L2ToL1TxReqAndSigner + | ChildToParentTxReqAndSigner ): Promise { if (!SignerProviderUtils.signerHasProvider(params.l2Signer)) { throw new MissingProviderArbSdkError('l2Signer') } - await this.checkL2Network(params.l2Signer) + await this.checkChildChain(params.l2Signer) - const withdrawalRequest = isL2ToL1TransactionRequest< + const withdrawalRequest = isChildToParentTransactionRequest< OmitTyped & { l2Signer: Signer } >(params) ? params @@ -860,37 +875,40 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Register a custom token on the Arbitrum bridge * See https://developer.offchainlabs.com/docs/bridging_assets#the-arbitrum-generic-custom-gateway for more details - * @param l1TokenAddress Address of the already deployed l1 token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/ethereum/icustomtoken. + * @param parentChainTokenAddress Address of the already deployed l1 token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/ethereum/icustomtoken. * @param l2TokenAddress Address of the already deployed l2 token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/arbitrum/iarbtoken. - * @param l1Signer The signer with the rights to call registerTokenOnL2 on the l1 token - * @param l2Provider Arbitrum rpc provider + * @param parentSigner The signer with the rights to call registerTokenOnL2 on the l1 token + * @param childProvider Arbitrum rpc provider * @returns */ public async registerCustomToken( - l1TokenAddress: string, + parentChainTokenAddress: string, l2TokenAddress: string, - l1Signer: Signer, - l2Provider: Provider + parentSigner: Signer, + childProvider: Provider ): Promise { - if (!SignerProviderUtils.signerHasProvider(l1Signer)) { - throw new MissingProviderArbSdkError('l1Signer') + if (!SignerProviderUtils.signerHasProvider(parentSigner)) { + throw new MissingProviderArbSdkError('parentSigner') } - await this.checkL1Network(l1Signer) - await this.checkL2Network(l2Provider) + await this.checkParentChain(parentSigner) + await this.checkChildChain(childProvider) - const l1SenderAddress = await l1Signer.getAddress() + const l1SenderAddress = await parentSigner.getAddress() - const l1Token = ICustomToken__factory.connect(l1TokenAddress, l1Signer) - const l2Token = IArbToken__factory.connect(l2TokenAddress, l2Provider) + const l1Token = ICustomToken__factory.connect( + parentChainTokenAddress, + parentSigner + ) + const l2Token = IArbToken__factory.connect(l2TokenAddress, childProvider) // sanity checks await l1Token.deployed() await l2Token.deployed() const l1AddressFromL2 = await l2Token.l1Address() - if (l1AddressFromL2 !== l1TokenAddress) { + if (l1AddressFromL2 !== parentChainTokenAddress) { throw new ArbSdkError( - `L2 token does not have l1 address set. Set address: ${l1AddressFromL2}, expected address: ${l1TokenAddress}.` + `L2 token does not have l1 address set. Set address: ${l1AddressFromL2}, expected address: ${parentChainTokenAddress}.` ) } @@ -898,7 +916,7 @@ export class AdminErc20Bridger extends Erc20Bridger { maxSubmissionCost: BigNumber gasLimit: BigNumber } - const from = await l1Signer.getAddress() + const from = await parentSigner.getAddress() const encodeFuncData = ( setTokenGas: GasParams, setGatewayGas: GasParams, @@ -939,10 +957,10 @@ export class AdminErc20Bridger extends Erc20Bridger { } } - const l1Provider = l1Signer.provider! - const gEstimator = new L1ToL2MessageGasEstimator(l2Provider) + const parentProvider = parentSigner.provider! + const gEstimator = new ParentToChildMessageGasEstimator(childProvider) const setTokenEstimates2 = await gEstimator.populateFunctionParams( - (params: OmitTyped) => + (params: OmitTyped) => encodeFuncData( { gasLimit: params.gasLimit, @@ -954,11 +972,11 @@ export class AdminErc20Bridger extends Erc20Bridger { }, params.maxFeePerGas ), - l1Provider + parentProvider ) const setGatewayEstimates2 = await gEstimator.populateFunctionParams( - (params: OmitTyped) => + (params: OmitTyped) => encodeFuncData( { gasLimit: setTokenEstimates2.estimates.gasLimit, @@ -970,10 +988,10 @@ export class AdminErc20Bridger extends Erc20Bridger { }, params.maxFeePerGas ), - l1Provider + parentProvider ) - const registerTx = await l1Signer.sendTransaction({ + const registerTx = await parentSigner.sendTransaction({ to: l1Token.address, data: setGatewayEstimates2.data, value: setGatewayEstimates2.value, @@ -984,18 +1002,18 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Get all the gateway set events on the L1 gateway router - * @param l1Provider + * @param parentProvider * @param customNetworkL1GatewayRouter * @returns */ public async getL1GatewaySetEvents( - l1Provider: Provider, + parentProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag } ): Promise[]> { - await this.checkL1Network(l1Provider) + await this.checkParentChain(parentProvider) - const l1GatewayRouterAddress = this.l2Network.tokenBridge.l1GatewayRouter - const eventFetcher = new EventFetcher(l1Provider) + const l1GatewayRouterAddress = this.childChain.tokenBridge.l1GatewayRouter + const eventFetcher = new EventFetcher(parentProvider) return ( await eventFetcher.getEvents( L1GatewayRouter__factory, @@ -1007,26 +1025,27 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Get all the gateway set events on the L2 gateway router - * @param l1Provider + * @param parentProvider * @param customNetworkL1GatewayRouter * @returns */ public async getL2GatewaySetEvents( - l2Provider: Provider, + childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, customNetworkL2GatewayRouter?: string ): Promise[]> { - if (this.l2Network.isCustom && !customNetworkL2GatewayRouter) { + if (this.childChain.isCustom && !customNetworkL2GatewayRouter) { throw new ArbSdkError( 'Must supply customNetworkL2GatewayRouter for custom network ' ) } - await this.checkL2Network(l2Provider) + await this.checkChildChain(childProvider) const l2GatewayRouterAddress = - customNetworkL2GatewayRouter || this.l2Network.tokenBridge.l2GatewayRouter + customNetworkL2GatewayRouter || + this.childChain.tokenBridge.l2GatewayRouter - const eventFetcher = new EventFetcher(l2Provider) + const eventFetcher = new EventFetcher(childProvider) return ( await eventFetcher.getEvents( L1GatewayRouter__factory, @@ -1038,32 +1057,32 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Register the provided token addresses against the provided gateways - * @param l1Signer - * @param l2Provider + * @param parentSigner + * @param childProvider * @param tokenGateways * @returns */ public async setGateways( - l1Signer: Signer, - l2Provider: Provider, + parentSigner: Signer, + childProvider: Provider, tokenGateways: TokenAndGateway[], options?: GasOverrides ): Promise { - if (!SignerProviderUtils.signerHasProvider(l1Signer)) { - throw new MissingProviderArbSdkError('l1Signer') + if (!SignerProviderUtils.signerHasProvider(parentSigner)) { + throw new MissingProviderArbSdkError('parentSigner') } - await this.checkL1Network(l1Signer) - await this.checkL2Network(l2Provider) + await this.checkParentChain(parentSigner) + await this.checkChildChain(childProvider) - const from = await l1Signer.getAddress() + const from = await parentSigner.getAddress() const l1GatewayRouter = L1GatewayRouter__factory.connect( - this.l2Network.tokenBridge.l1GatewayRouter, - l1Signer + this.childChain.tokenBridge.l1GatewayRouter, + parentSigner ) const setGatewaysFunc = ( - params: OmitTyped + params: OmitTyped ) => { return { data: l1GatewayRouter.interface.encodeFunctionData('setGateways', [ @@ -1080,14 +1099,14 @@ export class AdminErc20Bridger extends Erc20Bridger { to: l1GatewayRouter.address, } } - const gEstimator = new L1ToL2MessageGasEstimator(l2Provider) + const gEstimator = new ParentToChildMessageGasEstimator(childProvider) const estimates = await gEstimator.populateFunctionParams( setGatewaysFunc, - l1Signer.provider, + parentSigner.provider, options ) - const res = await l1Signer.sendTransaction({ + const res = await parentSigner.sendTransaction({ to: estimates.to, data: estimates.data, value: estimates.estimates.deposit, diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index b540b24432..dc37159eb0 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -199,7 +199,7 @@ export class EthBridger extends AssetBridger< 'approve', [ // spender - this.l2Network.ethBridge.inbox, + this.childChain.ethBridge.inbox, // value params?.amount ?? constants.MaxUint256, ] @@ -270,7 +270,7 @@ export class EthBridger extends AssetBridger< ): Promise> { return { txRequest: { - to: this.l2Network.ethBridge.inbox, + to: this.childChain.ethBridge.inbox, value: this.nativeTokenIsEth ? params.amount : 0, data: this.getDepositRequestData(params), from: params.from, @@ -287,7 +287,7 @@ export class EthBridger extends AssetBridger< public async deposit( params: EthDepositParams | L1ToL2TxReqAndSigner ): Promise { - await this.checkL1Network(params.l1Signer) + await this.checkParentChain(params.l1Signer) const ethDeposit = isL1ToL2TransactionRequest(params) ? params @@ -341,8 +341,8 @@ export class EthBridger extends AssetBridger< | EthDepositToParams | (L1ToL2TxReqAndSigner & { l2Provider: Provider }) ): Promise { - await this.checkL1Network(params.l1Signer) - await this.checkL2Network(params.l2Provider) + await this.checkParentChain(params.l1Signer) + await this.checkChildChain(params.l2Provider) const retryableTicketRequest = isL1ToL2TransactionRequest(params) ? params @@ -407,7 +407,7 @@ export class EthBridger extends AssetBridger< if (!SignerProviderUtils.signerHasProvider(params.l2Signer)) { throw new MissingProviderArbSdkError('l2Signer') } - await this.checkL2Network(params.l2Signer) + await this.checkChildChain(params.l2Signer) const request = isL2ToL1TransactionRequest< EthWithdrawParams & { l2Signer: Signer } diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 828cb949db..1995e4fb6b 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -65,7 +65,7 @@ describeOnlyWhenCustomGasToken( const allowance = await nativeTokenContract.allowance( await l1Signer.getAddress(), - ethBridger.l2Network.ethBridge.inbox + ethBridger.childChain.ethBridge.inbox ) expect(allowance.toString()).to.equal( @@ -88,7 +88,7 @@ describeOnlyWhenCustomGasToken( const allowance = await nativeTokenContract.allowance( await l1Signer.getAddress(), - ethBridger.l2Network.ethBridge.inbox + ethBridger.childChain.ethBridge.inbox ) expect(allowance.toString()).to.equal( @@ -105,7 +105,7 @@ describeOnlyWhenCustomGasToken( l2Signer, l2Provider, } = await testSetup() - const bridge = ethBridger.l2Network.ethBridge.bridge + const bridge = ethBridger.childChain.ethBridge.bridge const amount = parseEther('2') await fundL1Ether(l1Signer) @@ -164,7 +164,7 @@ describeOnlyWhenCustomGasToken( ethBridger, nativeTokenContract, } = await testSetup() - const bridge = ethBridger.l2Network.ethBridge.bridge + const bridge = ethBridger.childChain.ethBridge.bridge const amount = parseEther('0.2') await fundL1Ether(l1Signer) diff --git a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts index 2a9f127e08..7ee5d54242 100644 --- a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts +++ b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts @@ -74,11 +74,14 @@ export async function getL1CustomFeeTokenAllowance( export async function approveL1CustomFeeTokenForErc20Deposit( l1Signer: Signer, - erc20L1Address: string + erc20ParentAddress: string ) { const erc20Bridger = await Erc20Bridger.fromProvider(arbProvider()) - const tx = await erc20Bridger.approveGasToken({ erc20L1Address, l1Signer }) + const tx = await erc20Bridger.approveGasToken({ + erc20ParentAddress: erc20ParentAddress, + l1Signer, + }) await tx.wait() } diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index dd2274da78..d82a87f881 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -129,7 +129,7 @@ describe('Custom ERC20', () => { }) }) - it('deposits erc20 with extra ETH to a specific L2 address', async () => { + it('deposits erc20 with extra ETH to a specific child chain address', async () => { const randomAddress = Wallet.createRandom().address await depositToken({ depositAmount, diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index ae8baa0db1..5aac64e7af 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -100,7 +100,7 @@ describe('Ether', async () => { const { ethBridger, l1Signer, l2Signer } = await testSetup() await fundL1(l1Signer) - const inboxAddress = ethBridger.l2Network.ethBridge.inbox + const inboxAddress = ethBridger.childChain.ethBridge.inbox const initialInboxBalance = await l1Signer.provider!.getBalance( inboxAddress @@ -147,7 +147,7 @@ describe('Ether', async () => { const { ethBridger, l1Signer, l2Signer } = await testSetup() await fundL1(l1Signer) - const inboxAddress = ethBridger.l2Network.ethBridge.inbox + const inboxAddress = ethBridger.childChain.ethBridge.inbox const destWallet = Wallet.createRandom() const initialInboxBalance = await l1Signer.provider!.getBalance( diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index a8d6e95999..58acd53111 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -157,7 +157,7 @@ describe('RevertData', () => { await ( await erc20Bridger.approveToken({ - erc20L1Address: l1TokenAddress, + erc20ParentAddress: l1TokenAddress, l1Signer: l1Signer, }) ).wait() @@ -166,7 +166,7 @@ describe('RevertData', () => { // approve the custom fee token await ( await erc20Bridger.approveGasToken({ - erc20L1Address: l1TokenAddress, + erc20ParentAddress: l1TokenAddress, l1Signer: l1Signer, }) ).wait() @@ -188,22 +188,22 @@ describe('RevertData', () => { l1Signer: l1Signer, l2SignerOrProvider: l2Signer.provider!, from: await l1Signer.getAddress(), - erc20L1Address: l1TokenAddress, + erc20ParentAddress: l1TokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, } const depositParams = await erc20Bridger.getDepositRequest({ ...erc20Params, - l1Provider: l1Signer.provider!, - l2Provider: l2Signer.provider!, + parentProvider: l1Signer.provider!, + childProvider: l2Signer.provider!, }) try { await erc20Bridger.deposit({ ...erc20Params, l1Signer: l1Signer, - l2Provider: l2Signer.provider!, + childProvider: l2Signer.provider!, }) assert.fail('Expected estimateGas to fail') } catch (err) { diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 51816d6fa2..bca6383610 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -103,7 +103,7 @@ describe('standard ERC20', () => { const tx = await erc20Bridger.approveGasToken({ l1Signer: l1Signer, - erc20L1Address: testState.l1Token.address, + erc20ParentAddress: testState.l1Token.address, }) await tx.wait() @@ -271,7 +271,7 @@ describe('standard ERC20', () => { testState.l1Token.address, testState.l1Signer.provider! ) - const l2Token = testState.erc20Bridger.getL2TokenContract( + const l2Token = testState.erc20Bridger.getChildTokenContract( testState.l2Signer.provider!, l2TokenAddr ) @@ -309,7 +309,7 @@ describe('standard ERC20', () => { }) }) - it('deposits erc20 with extra ETH to a specific L2 address', async () => { + it('deposits erc20 with extra ETH to a specific child chain address', async () => { const randomAddress = Wallet.createRandom().address await depositToken({ depositAmount, diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 6f86b53fc9..4866152fea 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -88,7 +88,7 @@ export const mineUntilStop = async ( export const withdrawToken = async (params: WithdrawalParams) => { const withdrawalParams = await params.erc20Bridger.getWithdrawalRequest({ amount: params.amount, - erc20l1Address: params.l1Token.address, + erc20ParentAddress: params.l1Token.address, destinationAddress: await params.l2Signer.getAddress(), from: await params.l2Signer.getAddress(), }) @@ -99,7 +99,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { const withdrawRes = await params.erc20Bridger.withdraw({ destinationAddress: await params.l2Signer.getAddress(), amount: params.amount, - erc20l1Address: params.l1Token.address, + erc20ParentAddress: params.l1Token.address, l2Signer: params.l2Signer, }) const withdrawRec = await withdrawRes.wait() @@ -119,7 +119,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { params.l1Token.address, params.l1Signer.provider! ) - const l2Token = params.erc20Bridger.getL2TokenContract( + const l2Token = params.erc20Bridger.getChildTokenContract( params.l2Signer.provider!, l2TokenAddr ) @@ -139,7 +139,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { const { expectedL2Gateway } = getGateways( params.gatewayType, - params.erc20Bridger.l2Network + params.erc20Bridger.childChain ) expect(gatewayAddress, 'Gateway is not custom gateway').to.eq( expectedL2Gateway @@ -252,7 +252,7 @@ export const depositToken = async ({ }) => { await ( await erc20Bridger.approveToken({ - erc20L1Address: l1TokenAddress, + erc20ParentAddress: l1TokenAddress, l1Signer: l1Signer, }) ).wait() @@ -262,7 +262,7 @@ export const depositToken = async ({ l1TokenAddress, l1Signer.provider! ) - const l1Token = erc20Bridger.getL1TokenContract( + const l1Token = erc20Bridger.getParentChainTokenContract( l1Signer.provider!, l1TokenAddress ) @@ -277,7 +277,7 @@ export const depositToken = async ({ await ( await erc20Bridger.approveGasToken({ l1Signer, - erc20L1Address: l1TokenAddress, + erc20ParentAddress: l1TokenAddress, }) ).wait() @@ -302,8 +302,8 @@ export const depositToken = async ({ const depositRes = await erc20Bridger.deposit({ l1Signer: l1Signer, - l2Provider: l2Signer.provider!, - erc20L1Address: l1TokenAddress, + childProvider: l2Signer.provider!, + erc20ParentAddress: l1TokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, maxSubmissionCost: ethDepositAmount, @@ -345,7 +345,7 @@ export const depositToken = async ({ const { expectedL1Gateway, expectedL2Gateway } = getGateways( expectedGatewayType, - erc20Bridger.l2Network + erc20Bridger.childChain ) const l1Gateway = await erc20Bridger.getL1GatewayAddress( @@ -364,7 +364,7 @@ export const depositToken = async ({ l1TokenAddress, l1Signer.provider! ) - const l2Token = erc20Bridger.getL2TokenContract( + const l2Token = erc20Bridger.getChildTokenContract( l2Signer.provider!, l2Erc20Addr ) diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index 2a68c7eba3..89fb3e46e9 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -79,7 +79,7 @@ describeOnlyWhenEth('WETH', async () => { expect(l2WethGateway, 'l2 weth gateway').to.eq( l2Network.tokenBridge.l2WethGateway ) - const l2Token = erc20Bridger.getL2TokenContract( + const l2Token = erc20Bridger.getChildTokenContract( l2Signer.provider!, l2Network.tokenBridge.l2Weth ) From ea10ca37a43a97d89acc596c7a1b2d4e8b4cee11 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:00:20 -0400 Subject: [PATCH 17/74] chore: rename `testSetup` to parent/child (#438) --- scripts/lib.ts | 29 ++--- scripts/redeemRetryable.ts | 8 +- scripts/testSetup.ts | 99 +++++++++-------- .../L1ToL2MessageGasEstimator.test.ts | 6 +- .../customFeeTokenTestHelpers.ts | 9 +- tests/integration/customerc20.test.ts | 87 ++++++++------- tests/integration/eth.test.ts | 105 ++++++++++-------- .../integration/l1ToL2MessageCreator.test.ts | 4 +- .../integration/l2TransactionReceipt.test.ts | 12 +- tests/integration/retryableData.test.ts | 46 ++++---- tests/integration/sanity.test.ts | 91 ++++++++------- tests/integration/sendL2msg.test.ts | 52 +++++---- tests/integration/standarderc20.test.ts | 105 +++++++++--------- tests/integration/testHelpers.ts | 4 +- tests/integration/weth.test.ts | 56 +++++----- 15 files changed, 372 insertions(+), 341 deletions(-) diff --git a/scripts/lib.ts b/scripts/lib.ts index 15771b2f60..ad45cc2dbb 100644 --- a/scripts/lib.ts +++ b/scripts/lib.ts @@ -39,9 +39,10 @@ export const setGateWays = async ( type: 'standard' | 'arbCustom', overrideGateways: string[] = [] ): Promise => { - const { adminErc20Bridger, l1Signer, l2Network, l2Signer } = await testSetup() - const l1Provider = l1Signer.provider! - const l2Provider = l2Signer.provider! + const { adminErc20Bridger, parentSigner, childChain, childSigner } = + await testSetup() + const parentProvider = parentSigner.provider! + const childProvider = childSigner.provider! if (tokens.length === 0) { throw new Error('Include some tokens to set') } @@ -55,7 +56,7 @@ export const setGateWays = async ( for (const tokenAddress of tokens) { try { - const token = await ERC20__factory.connect(tokenAddress, l1Provider) + const token = await ERC20__factory.connect(tokenAddress, parentProvider) console.warn('calling name for ', tokenAddress) const symbol = await token.symbol() @@ -85,17 +86,17 @@ export const setGateWays = async ( if (overrideGateways.length > 0) { return overrideGateways } else if (type === 'standard') { - return tokens.map(() => l2Network.tokenBridge.l1ERC20Gateway) + return tokens.map(() => childChain.tokenBridge.l1ERC20Gateway) } else if (type === 'arbCustom') { - return tokens.map(() => l2Network.tokenBridge.l1CustomGateway) + return tokens.map(() => childChain.tokenBridge.l1CustomGateway) } else { throw new Error('Unhandled else case') } })() const res = await adminErc20Bridger.setGateways( - l1Signer, - l2Provider, + parentSigner, + childProvider, gateways.map((g, i) => ({ tokenAddr: tokens[i], gatewayAddr: gateways[i], @@ -110,7 +111,7 @@ export const setGateWays = async ( } console.log('redeeming retryable ticket:') - const l2Tx = (await rec.getParentToChildMessages(l2Signer))[0] + const l2Tx = (await rec.getParentToChildMessages(childSigner))[0] if (!l2Tx) throw new Error('No l1 to l2 message found.') const messageRes = await l2Tx.waitForStatus() if (messageRes.status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { @@ -123,13 +124,13 @@ export const setGateWays = async ( } export const checkRetryableStatus = async (l1Hash: string): Promise => { - const { l1Signer, l2Signer } = await testSetup() - const l1Provider = l1Signer.provider! - const l2Provider = l2Signer.provider! - const rec = await l1Provider.getTransactionReceipt(l1Hash) + const { parentSigner, childSigner } = await testSetup() + const parentProvider = parentSigner.provider! + const childProvider = childSigner.provider! + const rec = await parentProvider.getTransactionReceipt(l1Hash) if (!rec) throw new Error('L1 tx not found!') const messages = await new L1TransactionReceipt(rec).getParentToChildMessages( - l2Provider + childProvider ) for (const message of messages) { diff --git a/scripts/redeemRetryable.ts b/scripts/redeemRetryable.ts index deedb45f5d..46d526c327 100644 --- a/scripts/redeemRetryable.ts +++ b/scripts/redeemRetryable.ts @@ -35,14 +35,14 @@ if (!l1Txn) { } ;(async () => { - const { l1Signer, l2Signer } = await testSetup() + const { parentSigner, childSigner } = await testSetup() // TODO: Should use the PRIVKEY envvar signer directly - fundL2(l2Signer) - const l1Provider = l1Signer.provider! + fundL2(childSigner) + const l1Provider = parentSigner.provider! const l1Receipt = new L1TransactionReceipt( await l1Provider.getTransactionReceipt(l1Txn) ) - const l1ToL2Message = await l1Receipt.getL1ToL2Message(l2Signer) + const l1ToL2Message = await l1Receipt.getL1ToL2Message(childSigner) if (l1ToL2Message instanceof L1ToL2MessageWriter) { const redeemStatus = (await l1ToL2Message.waitForStatus()).status if (redeemStatus == L1ToL2MessageStatus.REDEEMED) { diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index fde71efaef..4902a14bc3 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -24,9 +24,9 @@ import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { L1Network, - L2Network, + ArbitrumNetwork, getL1Network, - getL2Network, + getArbitrumNetwork, addCustomNetwork, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' @@ -72,109 +72,110 @@ export const getSigner = (provider: JsonRpcProvider, key?: string) => { } export const testSetup = async (): Promise<{ - l1Network: L1Network | L2Network - l2Network: L2Network - l1Signer: Signer - l2Signer: Signer - l1Provider: Provider - l2Provider: Provider + parentChain: L1Network | ArbitrumNetwork + childChain: ArbitrumNetwork + parentSigner: Signer + childSigner: Signer + parentProvider: Provider + childProvider: Provider erc20Bridger: Erc20Bridger ethBridger: EthBridger adminErc20Bridger: AdminErc20Bridger inboxTools: InboxTools - l1Deployer: Signer - l2Deployer: Signer + parentDeployer: Signer + childDeployer: Signer }> => { const ethProvider = new JsonRpcProvider(config.ethUrl) const arbProvider = new JsonRpcProvider(config.arbUrl) - const l1Deployer = getSigner(ethProvider, config.ethKey) - const l2Deployer = getSigner(arbProvider, config.arbKey) + const parentDeployer = getSigner(ethProvider, config.ethKey) + const childDeployer = getSigner(arbProvider, config.arbKey) const seed = Wallet.createRandom() - const l1Signer = seed.connect(ethProvider) - const l2Signer = seed.connect(arbProvider) + const parentSigner = seed.connect(ethProvider) + const childSigner = seed.connect(arbProvider) - let setL1Network: L1Network | L2Network, setL2Network: L2Network + let setParentChain: L1Network | ArbitrumNetwork, + setChildChain: ArbitrumNetwork try { const l1Network = isTestingOrbitChains - ? await getL2Network(l1Deployer) - : await getL1Network(l1Deployer) - const l2Network = await getL2Network(l2Deployer) - setL1Network = l1Network - setL2Network = l2Network + ? await getArbitrumNetwork(parentDeployer) + : await getL1Network(parentDeployer) + const l2Network = await getArbitrumNetwork(childDeployer) + setParentChain = l1Network + setChildChain = l2Network } catch (err) { // the networks havent been added yet // check if theres an existing network available const localNetworkFile = getLocalNetworksFromFile() - const { l1Network, l2Network } = localNetworkFile + const { l1Network: parentChain, l2Network: childChain } = localNetworkFile if (isTestingOrbitChains) { - const _l1Network = l1Network as L2Network + const _parentChain = parentChain as ArbitrumNetwork const ethLocal: L1Network = { blockTime: 10, - chainID: _l1Network.partnerChainID, + chainID: _parentChain.partnerChainID, explorerUrl: '', isCustom: true, name: 'EthLocal', - partnerChainIDs: [_l1Network.chainID], + partnerChainIDs: [_parentChain.chainID], isArbitrum: false, } addCustomNetwork({ customL1Network: ethLocal, - customArbitrumNetwork: _l1Network, + customArbitrumNetwork: _parentChain, }) addCustomNetwork({ - customArbitrumNetwork: l2Network, + customArbitrumNetwork: childChain, }) - setL1Network = l1Network - setL2Network = l2Network + setParentChain = parentChain + setChildChain = childChain } else { addCustomNetwork({ - customL1Network: l1Network as L1Network, - customArbitrumNetwork: l2Network, + customL1Network: parentChain as L1Network, + customArbitrumNetwork: childChain, }) - setL1Network = l1Network - setL2Network = l2Network + setParentChain = parentChain + setChildChain = childChain } } - const erc20Bridger = new Erc20Bridger(setL2Network) - const adminErc20Bridger = new AdminErc20Bridger(setL2Network) - const ethBridger = new EthBridger(setL2Network) - const inboxTools = new InboxTools(l1Signer, setL2Network) + const erc20Bridger = new Erc20Bridger(setChildChain) + const adminErc20Bridger = new AdminErc20Bridger(setChildChain) + const ethBridger = new EthBridger(setChildChain) + const inboxTools = new InboxTools(parentSigner, setChildChain) if (isL2NetworkWithCustomFeeToken()) { - await fundL1(l1Signer) - await fundL1CustomFeeToken(l1Signer) - await approveL1CustomFeeToken(l1Signer) + await fundL1(parentSigner) + await fundL1CustomFeeToken(parentSigner) + await approveL1CustomFeeToken(parentSigner) } return { - l1Signer, - l2Signer, - l1Provider: ethProvider, - l2Provider: arbProvider, - l1Network: setL1Network, - l2Network: setL2Network, + parentSigner, + childSigner, + parentProvider: ethProvider, + childProvider: arbProvider, + parentChain: setParentChain, + childChain: setChildChain, erc20Bridger, adminErc20Bridger, ethBridger, inboxTools, - l1Deployer, - l2Deployer, + parentDeployer, + childDeployer, } } export function getLocalNetworksFromFile(): { - l1Network: L1Network | L2Network - l2Network: L2Network + l1Network: L1Network | ArbitrumNetwork + l2Network: ArbitrumNetwork } { const pathToLocalNetworkFile = path.join(__dirname, '..', 'localNetwork.json') if (!fs.existsSync(pathToLocalNetworkFile)) { diff --git a/tests/integration/L1ToL2MessageGasEstimator.test.ts b/tests/integration/L1ToL2MessageGasEstimator.test.ts index 7370089c92..8e4ddeb1b1 100644 --- a/tests/integration/L1ToL2MessageGasEstimator.test.ts +++ b/tests/integration/L1ToL2MessageGasEstimator.test.ts @@ -35,8 +35,7 @@ describe('ParentToChildMessageGasEstimator', () => { itOnlyWhenEth( `"estimateSubmissionFee" returns non-0 for eth chain`, async () => { - const { l1Provider: parentProvider, l2Provider: childProvider } = - await testSetup() + const { parentProvider, childProvider } = await testSetup() const submissionFee = await new ParentToChildMessageGasEstimator( childProvider @@ -53,8 +52,7 @@ describe('ParentToChildMessageGasEstimator', () => { itOnlyWhenCustomGasToken( `"estimateSubmissionFee" returns 0 for custom gas token chain`, async () => { - const { l1Provider: parentProvider, l2Provider: childProvider } = - await testSetup() + const { parentProvider, childProvider } = await testSetup() const submissionFee = await new ParentToChildMessageGasEstimator( childProvider diff --git a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts index 7ee5d54242..16bbf369a2 100644 --- a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts +++ b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts @@ -21,10 +21,13 @@ export function isL2NetworkWithCustomFeeToken(): boolean { export async function testSetup() { const result = await _testSetup() - const { l2Network, l1Provider } = result + const { childChain, parentProvider } = result - const nativeToken = l2Network.nativeToken! - const nativeTokenContract = ERC20__factory.connect(nativeToken, l1Provider) + const nativeToken = childChain.nativeToken! + const nativeTokenContract = ERC20__factory.connect( + nativeToken, + parentProvider + ) return { ...result, nativeTokenContract } } diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index d82a87f881..62737d1bda 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -38,7 +38,8 @@ import { GatewayType, withdrawToken, } from './testHelpers' -import { L1ToL2MessageStatus, L2Network } from '../../src' +import { L1ToL2MessageStatus } from '../../src' +import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { AdminErc20Bridger } from '../../src/lib/assetBridger/erc20Bridger' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' @@ -57,10 +58,10 @@ describe('Custom ERC20', () => { // test globals let testState: { - l1Signer: Signer - l2Signer: Signer + parentSigner: Signer + childSigner: Signer adminErc20Bridger: AdminErc20Bridger - l2Network: L2Network + childChain: ArbitrumNetwork l1CustomToken: TestCustomTokenL1 | TestOrbitCustomTokenL1 } @@ -69,19 +70,19 @@ describe('Custom ERC20', () => { ...(await testSetup()), l1CustomToken: {} as any, } - await fundL1(testState.l1Signer) - await fundL2(testState.l2Signer) + await fundL1(testState.parentSigner) + await fundL2(testState.childSigner) if (isL2NetworkWithCustomFeeToken()) { - await fundL1CustomFeeToken(testState.l1Signer) + await fundL1CustomFeeToken(testState.parentSigner) } }) it('register custom token', async () => { const { l1CustomToken: l1Token } = await registerCustomToken( - testState.l2Network, - testState.l1Signer, - testState.l2Signer, + testState.childChain, + testState.parentSigner, + testState.childSigner, testState.adminErc20Bridger ) testState.l1CustomToken = l1Token @@ -89,14 +90,14 @@ describe('Custom ERC20', () => { it('deposit', async () => { await ( - await testState.l1CustomToken.connect(testState.l1Signer).mint() + await testState.l1CustomToken.connect(testState.parentSigner).mint() ).wait() await depositToken({ depositAmount, l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) @@ -105,13 +106,15 @@ describe('Custom ERC20', () => { it('withdraws erc20', async function () { await withdrawToken({ ...testState, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, erc20Bridger: testState.adminErc20Bridger, amount: withdrawalAmount, gatewayType: GatewayType.CUSTOM, startBalance: depositAmount, l1Token: ERC20__factory.connect( testState.l1CustomToken.address, - testState.l1Signer.provider! + testState.parentSigner.provider! ), }) }) @@ -122,8 +125,8 @@ describe('Custom ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) @@ -136,8 +139,8 @@ describe('Custom ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, destinationAddress: randomAddress, @@ -146,49 +149,49 @@ describe('Custom ERC20', () => { }) const registerCustomToken = async ( - l2Network: L2Network, - l1Signer: Signer, - l2Signer: Signer, + childChain: ArbitrumNetwork, + parentSigner: Signer, + childSigner: Signer, adminErc20Bridger: AdminErc20Bridger ) => { // create a custom token on L1 and L2 const l1CustomTokenFactory = isL2NetworkWithCustomFeeToken() - ? new TestOrbitCustomTokenL1__factory(l1Signer) - : new TestCustomTokenL1__factory(l1Signer) + ? new TestOrbitCustomTokenL1__factory(parentSigner) + : new TestCustomTokenL1__factory(parentSigner) const l1CustomToken = await l1CustomTokenFactory.deploy( - l2Network.tokenBridge.l1CustomGateway, - l2Network.tokenBridge.l1GatewayRouter + childChain.tokenBridge.l1CustomGateway, + childChain.tokenBridge.l1GatewayRouter ) await l1CustomToken.deployed() const amount = ethers.utils.parseEther('1') if (isL2NetworkWithCustomFeeToken()) { const approvalTx = await ERC20__factory.connect( - l2Network.nativeToken!, - l1Signer + childChain.nativeToken!, + parentSigner ).approve(l1CustomToken.address, amount) await approvalTx.wait() } - const l2CustomTokenFac = new TestArbCustomToken__factory(l2Signer) + const l2CustomTokenFac = new TestArbCustomToken__factory(childSigner) const l2CustomToken = await l2CustomTokenFac.deploy( - l2Network.tokenBridge.l2CustomGateway, + childChain.tokenBridge.l2CustomGateway, l1CustomToken.address ) await l2CustomToken.deployed() // check starting conditions - should initially use the default gateway - const l1GatewayRouter = new L1GatewayRouter__factory(l1Signer).attach( - l2Network.tokenBridge.l1GatewayRouter + const l1GatewayRouter = new L1GatewayRouter__factory(parentSigner).attach( + childChain.tokenBridge.l1GatewayRouter ) - const l2GatewayRouter = new L2GatewayRouter__factory(l2Signer).attach( - l2Network.tokenBridge.l2GatewayRouter + const l2GatewayRouter = new L2GatewayRouter__factory(childSigner).attach( + childChain.tokenBridge.l2GatewayRouter ) - const l1CustomGateway = new L1CustomGateway__factory(l1Signer).attach( - l2Network.tokenBridge.l1CustomGateway + const l1CustomGateway = new L1CustomGateway__factory(parentSigner).attach( + childChain.tokenBridge.l1CustomGateway ) - const l2CustomGateway = new L1CustomGateway__factory(l2Signer).attach( - l2Network.tokenBridge.l2CustomGateway + const l2CustomGateway = new L1CustomGateway__factory(childSigner).attach( + childChain.tokenBridge.l2CustomGateway ) const startL1GatewayAddress = await l1GatewayRouter.l1TokenToGateway( l1CustomToken.address @@ -223,14 +226,14 @@ const registerCustomToken = async ( const regTx = await adminErc20Bridger.registerCustomToken( l1CustomToken.address, l2CustomToken.address, - l1Signer, - l2Signer.provider! + parentSigner, + childSigner.provider! ) const regRec = await regTx.wait() // wait on messages const l1ToL2Messages = await regRec.getParentToChildMessages( - l2Signer.provider! + childSigner.provider! ) expect(l1ToL2Messages.length, 'Should be 2 messages.').to.eq(2) @@ -251,7 +254,7 @@ const registerCustomToken = async ( expect( endL1GatewayAddress, 'End l1GatewayAddress not equal to l1 custom gateway' - ).to.eq(l2Network.tokenBridge.l1CustomGateway) + ).to.eq(childChain.tokenBridge.l1CustomGateway) const endL2GatewayAddress = await l2GatewayRouter.l1TokenToGateway( l1CustomToken.address @@ -259,7 +262,7 @@ const registerCustomToken = async ( expect( endL2GatewayAddress, 'End l2GatewayAddress not equal to l2 custom gateway' - ).to.eq(l2Network.tokenBridge.l2CustomGateway) + ).to.eq(childChain.tokenBridge.l2CustomGateway) const endL1Erc20Address = await l1CustomGateway.l1ToL2Token( l1CustomToken.address diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 5aac64e7af..307f04366e 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -46,18 +46,18 @@ describe('Ether', async () => { }) it('transfers ether on l2', async () => { - const { l2Signer } = await testSetup() + const { childSigner } = await testSetup() - await fundL2(l2Signer) + await fundL2(childSigner) const randomAddress = Wallet.createRandom().address const amountToSend = parseEther('0.000005') - const balanceBefore = await l2Signer.provider!.getBalance( - await l2Signer.getAddress() + const balanceBefore = await childSigner.provider!.getBalance( + await childSigner.getAddress() ) const rec = await ( - await l2Signer.sendTransaction({ + await childSigner.sendTransaction({ to: randomAddress, value: amountToSend, maxFeePerGas: 15000000000, @@ -65,10 +65,10 @@ describe('Ether', async () => { }) ).wait() - const balanceAfter = await l2Signer.provider!.getBalance( - await l2Signer.getAddress() + const balanceAfter = await childSigner.provider!.getBalance( + await childSigner.getAddress() ) - const randomBalanceAfter = await l2Signer.provider!.getBalance( + const randomBalanceAfter = await childSigner.provider!.getBalance( randomAddress ) expect(randomBalanceAfter.toString(), 'random address balance after').to.eq( @@ -85,10 +85,10 @@ describe('Ether', async () => { itOnlyWhenEth( '"EthBridger.approveGasToken" throws when eth is used as native/gas token', async () => { - const { ethBridger, l1Signer } = await testSetup() + const { ethBridger, parentSigner } = await testSetup() try { - await ethBridger.approveGasToken({ l1Signer }) + await ethBridger.approveGasToken({ l1Signer: parentSigner }) expect.fail(`"EthBridger.approveGasToken" should have thrown`) } catch (error: any) { expect(error.message).to.equal('chain uses ETH as its native/gas token') @@ -97,35 +97,37 @@ describe('Ether', async () => { ) it('deposits ether', async () => { - const { ethBridger, l1Signer, l2Signer } = await testSetup() + const { ethBridger, parentSigner, childSigner } = await testSetup() - await fundL1(l1Signer) + await fundL1(parentSigner) const inboxAddress = ethBridger.childChain.ethBridge.inbox - const initialInboxBalance = await l1Signer.provider!.getBalance( + const initialInboxBalance = await parentSigner.provider!.getBalance( inboxAddress ) const ethToDeposit = parseEther('0.0002') const res = await ethBridger.deposit({ amount: ethToDeposit, - l1Signer: l1Signer, + l1Signer: parentSigner, }) const rec = await res.wait() expect(rec.status).to.equal(1, 'eth deposit L1 txn failed') - const finalInboxBalance = await l1Signer.provider!.getBalance(inboxAddress) + const finalInboxBalance = await parentSigner.provider!.getBalance( + inboxAddress + ) expect( initialInboxBalance.add(ethToDeposit).eq(finalInboxBalance), 'balance failed to update after eth deposit' ) - const waitResult = await rec.waitForChildTx(l2Signer.provider!) + const waitResult = await rec.waitForChildTx(childSigner.provider!) - const l1ToL2Messages = await rec.getEthDeposits(l2Signer.provider!) + const l1ToL2Messages = await rec.getEthDeposits(childSigner.provider!) expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') const l1ToL2Message = l1ToL2Messages[0] - const walletAddress = await l1Signer.getAddress() + const walletAddress = await parentSigner.getAddress() expect(l1ToL2Message.to).to.eq(walletAddress, 'message inputs value error') expect(l1ToL2Message.value.toString(), 'message inputs value error').to.eq( ethToDeposit.toString() @@ -137,40 +139,42 @@ describe('Ether', async () => { expect(waitResult.chainTxReceipt).to.exist expect(waitResult.chainTxReceipt).to.not.be.null - const testWalletL2EthBalance = await l2Signer.getBalance() + const testWalletL2EthBalance = await childSigner.getBalance() expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( ethToDeposit.toString() ) }) it('deposits ether to a specific L2 address', async () => { - const { ethBridger, l1Signer, l2Signer } = await testSetup() + const { ethBridger, parentSigner, childSigner } = await testSetup() - await fundL1(l1Signer) + await fundL1(parentSigner) const inboxAddress = ethBridger.childChain.ethBridge.inbox const destWallet = Wallet.createRandom() - const initialInboxBalance = await l1Signer.provider!.getBalance( + const initialInboxBalance = await parentSigner.provider!.getBalance( inboxAddress ) const ethToDeposit = parseEther('0.0002') const res = await ethBridger.depositTo({ amount: ethToDeposit, - l1Signer: l1Signer, + l1Signer: parentSigner, destinationAddress: destWallet.address, - l2Provider: l2Signer.provider!, + l2Provider: childSigner.provider!, }) const rec = await res.wait() expect(rec.status).to.equal(1, 'eth deposit L1 txn failed') - const finalInboxBalance = await l1Signer.provider!.getBalance(inboxAddress) + const finalInboxBalance = await parentSigner.provider!.getBalance( + inboxAddress + ) expect( initialInboxBalance.add(ethToDeposit).eq(finalInboxBalance), 'balance failed to update after eth deposit' ) const l1ToL2Messages = await rec.getParentToChildMessages( - l2Signer.provider! + childSigner.provider! ) expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') const l1ToL2Message = l1ToL2Messages[0] @@ -190,9 +194,10 @@ describe('Ether', async () => { 'Retryable ticket not redeemed' ) - const retryableTxReceipt = await l2Signer.provider!.getTransactionReceipt( - l1ToL2Message.retryableCreationId - ) + const retryableTxReceipt = + await childSigner.provider!.getTransactionReceipt( + l1ToL2Message.retryableCreationId + ) expect(retryableTxReceipt).to.exist expect(retryableTxReceipt).to.not.be.null @@ -205,7 +210,7 @@ describe('Ether', async () => { expect(ticketRedeemEvents[0].retryTxHash).to.exist expect(ticketRedeemEvents[0].retryTxHash).to.not.be.null - const testWalletL2EthBalance = await l2Signer.provider!.getBalance( + const testWalletL2EthBalance = await childSigner.provider!.getBalance( destWallet.address ) expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( @@ -214,9 +219,9 @@ describe('Ether', async () => { }) it('withdraw Ether transaction succeeds', async () => { - const { l2Signer, l1Signer, ethBridger } = await testSetup() - await fundL2(l2Signer) - await fundL1(l1Signer) + const { childSigner, parentSigner, ethBridger } = await testSetup() + await fundL2(childSigner) + await fundL1(parentSigner) const ethToWithdraw = parseEther('0.00000002') const randomAddress = Wallet.createRandom().address @@ -224,16 +229,18 @@ describe('Ether', async () => { const request = await ethBridger.getWithdrawalRequest({ amount: ethToWithdraw, destinationAddress: randomAddress, - from: await l2Signer.getAddress(), + from: await childSigner.getAddress(), }) - const l1GasEstimate = await request.estimateL1GasLimit(l1Signer.provider!) + const l1GasEstimate = await request.estimateL1GasLimit( + parentSigner.provider! + ) const withdrawEthRes = await ethBridger.withdraw({ amount: ethToWithdraw, - l2Signer: l2Signer, + l2Signer: childSigner, destinationAddress: randomAddress, - from: await l2Signer.getAddress(), + from: await childSigner.getAddress(), }) const withdrawEthRec = await withdrawEthRes.wait() @@ -244,7 +251,7 @@ describe('Ether', async () => { ) const withdrawMessage = ( - await withdrawEthRec.getChildToParentMessages(l1Signer) + await withdrawEthRec.getChildToParentMessages(parentSigner) )[0] expect( withdrawMessage, @@ -252,7 +259,7 @@ describe('Ether', async () => { ).to.exist const withdrawEvents = await ChildToParentMessage.getChildToParentEvents( - l2Signer.provider!, + childSigner.provider!, { fromBlock: withdrawEthRec.blockNumber, toBlock: 'latest' }, undefined, randomAddress @@ -263,14 +270,14 @@ describe('Ether', async () => { 'eth withdraw getL2ToL1EventData failed' ) - const messageStatus = await withdrawMessage.status(l2Signer.provider!) + const messageStatus = await withdrawMessage.status(childSigner.provider!) expect( messageStatus, `eth withdraw status returned ${messageStatus}` ).to.be.eq(L2ToL1MessageStatus.UNCONFIRMED) // CHRIS: TODO: comment this back in when fixed in nitro - // const actualFinalBalance = await l2Signer.getBalance() + // const actualFinalBalance = await childSigner.getBalance() // const expectedFinalBalance = initialBalance // .sub(ethToWithdraw) // .sub(withdrawEthRec.gasUsed.mul(withdrawEthRec.effectiveGasPrice)) @@ -279,24 +286,24 @@ describe('Ether', async () => { // ) // run a miner whilst withdrawing - const miner1 = Wallet.createRandom().connect(l1Signer.provider!) - const miner2 = Wallet.createRandom().connect(l2Signer.provider!) + const miner1 = Wallet.createRandom().connect(parentSigner.provider!) + const miner2 = Wallet.createRandom().connect(childSigner.provider!) await fundL1(miner1, parseEther('1')) await fundL2(miner2, parseEther('1')) const state = { mining: true } await Promise.race([ mineUntilStop(miner1, state), mineUntilStop(miner2, state), - withdrawMessage.waitUntilReadyToExecute(l2Signer.provider!), + withdrawMessage.waitUntilReadyToExecute(childSigner.provider!), ]) state.mining = false expect( - await withdrawMessage.status(l2Signer.provider!), + await withdrawMessage.status(childSigner.provider!), 'confirmed status' ).to.eq(L2ToL1MessageStatus.CONFIRMED) - const execTx = await withdrawMessage.execute(l2Signer.provider!) + const execTx = await withdrawMessage.execute(childSigner.provider!) const execRec = await execTx.wait() expect( @@ -305,16 +312,16 @@ describe('Ether', async () => { ).to.be.lessThan(l1GasEstimate.toNumber()) expect( - await withdrawMessage.status(l2Signer.provider!), + await withdrawMessage.status(childSigner.provider!), 'executed status' ).to.eq(L2ToL1MessageStatus.EXECUTED) const finalRandomBalance = isL2NetworkWithCustomFeeToken() ? await ERC20__factory.connect( ethBridger.nativeToken!, - l1Signer.provider! + parentSigner.provider! ).balanceOf(randomAddress) - : await l1Signer.provider!.getBalance(randomAddress) + : await parentSigner.provider!.getBalance(randomAddress) expect(finalRandomBalance.toString(), 'L1 final balance').to.eq( ethToWithdraw.toString() ) diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/l1ToL2MessageCreator.test.ts index af96e1f087..60a10dc14f 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/l1ToL2MessageCreator.test.ts @@ -38,7 +38,7 @@ describe('ParentToChildMessageCreator', () => { const testAmount = utils.parseEther('0.01') it('allows the creation of Retryable Tickets sending parameters', async () => { - const { l1Signer: parentSigner, l2Signer: childSigner } = await testSetup() + const { parentSigner, childSigner } = await testSetup() const signerAddress = await parentSigner.getAddress() const arbProvider = childSigner.provider as providers.Provider @@ -99,7 +99,7 @@ describe('ParentToChildMessageCreator', () => { }) it('allows the creation of Retryable Tickets sending a request', async () => { - const { l1Signer: parentSigner, l2Signer: childSigner } = await testSetup() + const { parentSigner, childSigner } = await testSetup() const signerAddress = await parentSigner.getAddress() const ethProvider = parentSigner.provider as providers.Provider const arbProvider = childSigner.provider as providers.Provider diff --git a/tests/integration/l2TransactionReceipt.test.ts b/tests/integration/l2TransactionReceipt.test.ts index c043a069f0..b0d546010d 100644 --- a/tests/integration/l2TransactionReceipt.test.ts +++ b/tests/integration/l2TransactionReceipt.test.ts @@ -37,24 +37,24 @@ describe('ArbProvider', () => { }) it('does find l1 batch info', async () => { - const { l2Signer, l1Signer } = await testSetup() - const l2Provider = l2Signer.provider! as JsonRpcProvider + const { childSigner, parentSigner } = await testSetup() + const l2Provider = childSigner.provider! as JsonRpcProvider // set up miners - const miner1 = Wallet.createRandom().connect(l1Signer.provider!) - const miner2 = Wallet.createRandom().connect(l2Signer.provider!) + const miner1 = Wallet.createRandom().connect(parentSigner.provider!) + const miner2 = Wallet.createRandom().connect(childSigner.provider!) await fundL1(miner1, parseEther('0.1')) await fundL2(miner2, parseEther('0.1')) const state = { mining: true } mineUntilStop(miner1, state) mineUntilStop(miner2, state) - await fundL2(l2Signer) + await fundL2(childSigner) const randomAddress = Wallet.createRandom().address const amountToSend = parseEther('0.000005') // send an l2 transaction, and get the receipt - const tx = await l2Signer.sendTransaction({ + const tx = await childSigner.sendTransaction({ to: randomAddress, value: amountToSend, }) diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index 58acd53111..79dff3c86e 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -29,7 +29,7 @@ import { Inbox__factory } from '../../src/lib/abi/factories/Inbox__factory' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' const depositAmount = BigNumber.from(100) import { ERC20Inbox__factory } from '../../src/lib/abi/factories/ERC20Inbox__factory' -import { isL2NetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' +import { isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' describe('RevertData', () => { beforeEach('skipIfMainnet', async function () { @@ -58,8 +58,8 @@ describe('RevertData', () => { const testRetryableDataParsing = async ( func: 'estimateGas' | 'callStatic' ) => { - const { l1Signer, l2Network } = await testSetup() - await fundL1(l1Signer) + const { parentSigner, childChain } = await testSetup() + await fundL1(parentSigner) const { to, @@ -74,10 +74,10 @@ describe('RevertData', () => { } = createRevertParams() try { - if (isL2NetworkWithCustomFeeToken()) { + if (isChildChainWithCustomFeeToken()) { const inbox = ERC20Inbox__factory.connect( - l2Network.ethBridge.inbox, - l1Signer + childChain.ethBridge.inbox, + parentSigner ) await inbox[func].createRetryableTicket( to, @@ -92,8 +92,8 @@ describe('RevertData', () => { ) } else { const inbox = Inbox__factory.connect( - l2Network.ethBridge.inbox, - l1Signer + childChain.ethBridge.inbox, + parentSigner ) await inbox[func].createRetryableTicket( to, @@ -121,7 +121,7 @@ describe('RevertData', () => { expect(parsed.excessFeeRefundAddress, 'excessFeeRefundAddress').to.eq( excessFeeRefundAddress ) - expect(parsed.from, 'from').to.eq(await l1Signer.getAddress()) + expect(parsed.from, 'from').to.eq(await parentSigner.getAddress()) expect(parsed.gasLimit.toString(), 'gasLimit').to.eq(gasLimit.toString()) expect(parsed.l2CallValue.toString(), 'l2CallValue').to.eq( l2CallValue.toString() @@ -145,10 +145,10 @@ describe('RevertData', () => { }) it('is the same as what we estimate in erc20Bridger', async () => { - const { erc20Bridger, l1Signer, l2Signer } = await testSetup() - await fundL1(l1Signer, parseEther('2')) + const { erc20Bridger, parentSigner, childSigner } = await testSetup() + await fundL1(parentSigner, parseEther('2')) - const deployErc20 = new TestERC20__factory().connect(l1Signer) + const deployErc20 = new TestERC20__factory().connect(parentSigner) const testToken = await deployErc20.deploy() await testToken.deployed() @@ -158,16 +158,16 @@ describe('RevertData', () => { await ( await erc20Bridger.approveToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: l1Signer, + l1Signer: parentSigner, }) ).wait() - if (isL2NetworkWithCustomFeeToken()) { + if (isChildChainWithCustomFeeToken()) { // approve the custom fee token await ( await erc20Bridger.approveGasToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: l1Signer, + l1Signer: parentSigner, }) ).wait() } @@ -185,9 +185,9 @@ describe('RevertData', () => { } const erc20Params = { - l1Signer: l1Signer, - l2SignerOrProvider: l2Signer.provider!, - from: await l1Signer.getAddress(), + parentSigner, + childSignerOrProvider: childSigner.provider!, + from: await parentSigner.getAddress(), erc20ParentAddress: l1TokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, @@ -195,15 +195,15 @@ describe('RevertData', () => { const depositParams = await erc20Bridger.getDepositRequest({ ...erc20Params, - parentProvider: l1Signer.provider!, - childProvider: l2Signer.provider!, + parentProvider: parentSigner.provider!, + childProvider: childSigner.provider!, }) try { await erc20Bridger.deposit({ ...erc20Params, - l1Signer: l1Signer, - childProvider: l2Signer.provider!, + l1Signer: parentSigner, + childProvider: childSigner.provider!, }) assert.fail('Expected estimateGas to fail') } catch (err) { @@ -216,7 +216,7 @@ describe('RevertData', () => { ) expect(parsed.data, 'data').to.eq(depositParams.retryableData.data) expect(parsed.deposit.toString(), 'deposit').to.eq( - isL2NetworkWithCustomFeeToken() + isChildChainWithCustomFeeToken() ? depositParams.retryableData.deposit.toString() : depositParams.txRequest.value.toString() ) diff --git a/tests/integration/sanity.test.ts b/tests/integration/sanity.test.ts index b33ba34be1..88f4ff6380 100644 --- a/tests/integration/sanity.test.ts +++ b/tests/integration/sanity.test.ts @@ -37,14 +37,14 @@ const expectIgnoreCase = (expected: string, actual: string) => { describe('sanity checks (read-only)', async () => { it('standard gateways public storage vars properly set', async () => { - const { l1Signer, l2Signer, l2Network } = await testSetup() + const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1ERC20Gateway__factory.connect( - l2Network.tokenBridge.l1ERC20Gateway, - l1Signer + childChain.tokenBridge.l1ERC20Gateway, + parentSigner ) const l2Gateway = await L2ERC20Gateway__factory.connect( - l2Network.tokenBridge.l2ERC20Gateway, - l2Signer + childChain.tokenBridge.l2ERC20Gateway, + childSigner ) const l1ClonableProxyHash = await l1Gateway.cloneableProxyHash() @@ -56,123 +56,128 @@ describe('sanity checks (read-only)', async () => { expect(l1BeaconProxyHash).to.equal(l2BeaconProxyHash) const l1GatewayCounterParty = await l1Gateway.counterpartGateway() - expect(l1GatewayCounterParty).to.equal(l2Network.tokenBridge.l2ERC20Gateway) + expect(l1GatewayCounterParty).to.equal( + childChain.tokenBridge.l2ERC20Gateway + ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() - expect(l2GatewayCounterParty).to.equal(l2Network.tokenBridge.l1ERC20Gateway) + expect(l2GatewayCounterParty).to.equal( + childChain.tokenBridge.l1ERC20Gateway + ) const l1Router = await l1Gateway.router() - expect(l1Router).to.equal(l2Network.tokenBridge.l1GatewayRouter) + expect(l1Router).to.equal(childChain.tokenBridge.l1GatewayRouter) const l2Router = await l2Gateway.router() - expect(l2Router).to.equal(l2Network.tokenBridge.l2GatewayRouter) + expect(l2Router).to.equal(childChain.tokenBridge.l2GatewayRouter) }) it('custom gateways public storage vars properly set', async () => { - const { l1Signer, l2Signer, l2Network } = await testSetup() + const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1CustomGateway__factory.connect( - l2Network.tokenBridge.l1CustomGateway, - l1Signer + childChain.tokenBridge.l1CustomGateway, + parentSigner ) const l2Gateway = await L2CustomGateway__factory.connect( - l2Network.tokenBridge.l2CustomGateway, - l2Signer + childChain.tokenBridge.l2CustomGateway, + childSigner ) const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expect(l1GatewayCounterParty).to.equal( - l2Network.tokenBridge.l2CustomGateway + childChain.tokenBridge.l2CustomGateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expect(l2GatewayCounterParty).to.equal( - l2Network.tokenBridge.l1CustomGateway + childChain.tokenBridge.l1CustomGateway ) const l1Router = await l1Gateway.router() - expect(l1Router).to.equal(l2Network.tokenBridge.l1GatewayRouter) + expect(l1Router).to.equal(childChain.tokenBridge.l1GatewayRouter) const l2Router = await l2Gateway.router() - expect(l2Router).to.equal(l2Network.tokenBridge.l2GatewayRouter) + expect(l2Router).to.equal(childChain.tokenBridge.l2GatewayRouter) }) itOnlyWhenEth( 'weth gateways gateways public storage vars properly set', async () => { - const { l1Signer, l2Signer, l2Network } = await testSetup() + const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1WethGateway__factory.connect( - l2Network.tokenBridge.l1WethGateway, - l1Signer + childChain.tokenBridge.l1WethGateway, + parentSigner ) const l2Gateway = await L2WethGateway__factory.connect( - l2Network.tokenBridge.l2WethGateway, - l2Signer + childChain.tokenBridge.l2WethGateway, + childSigner ) const l1Weth = await l1Gateway.l1Weth() - expectIgnoreCase(l1Weth, l2Network.tokenBridge.l1Weth) + expectIgnoreCase(l1Weth, childChain.tokenBridge.l1Weth) const l2Weth = await l2Gateway.l2Weth() - expectIgnoreCase(l2Weth, l2Network.tokenBridge.l2Weth) + expectIgnoreCase(l2Weth, childChain.tokenBridge.l2Weth) const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expectIgnoreCase( l1GatewayCounterParty, - l2Network.tokenBridge.l2WethGateway + childChain.tokenBridge.l2WethGateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expectIgnoreCase( l2GatewayCounterParty, - l2Network.tokenBridge.l1WethGateway + childChain.tokenBridge.l1WethGateway ) const l1Router = await l1Gateway.router() - expectIgnoreCase(l1Router, l2Network.tokenBridge.l1GatewayRouter) + expectIgnoreCase(l1Router, childChain.tokenBridge.l1GatewayRouter) const l2Router = await l2Gateway.router() - expectIgnoreCase(l2Router, l2Network.tokenBridge.l2GatewayRouter) + expectIgnoreCase(l2Router, childChain.tokenBridge.l2GatewayRouter) } ) itOnlyWhenEth('aeWETh public vars properly set', async () => { - const { l2Signer, l2Network } = await testSetup() + const { childSigner, childChain } = await testSetup() const aeWeth = AeWETH__factory.connect( - l2Network.tokenBridge.l2Weth, - l2Signer + childChain.tokenBridge.l2Weth, + childSigner ) const l2GatewayOnAeWeth = await aeWeth.l2Gateway() - expectIgnoreCase(l2GatewayOnAeWeth, l2Network.tokenBridge.l2WethGateway) + expectIgnoreCase(l2GatewayOnAeWeth, childChain.tokenBridge.l2WethGateway) const l1AddressOnAeWeth = await aeWeth.l1Address() - expectIgnoreCase(l1AddressOnAeWeth, l2Network.tokenBridge.l1Weth) + expectIgnoreCase(l1AddressOnAeWeth, childChain.tokenBridge.l1Weth) }) itOnlyWhenEth('l1 gateway router points to right weth gateways', async () => { - const { adminErc20Bridger, l1Signer, l2Network } = await testSetup() + const { adminErc20Bridger, parentSigner, childChain } = await testSetup() const gateway = await adminErc20Bridger.getL1GatewayAddress( - l2Network.tokenBridge.l1Weth, - l1Signer.provider! + childChain.tokenBridge.l1Weth, + parentSigner.provider! ) - expect(gateway).to.equal(l2Network.tokenBridge.l1WethGateway) + expect(gateway).to.equal(childChain.tokenBridge.l1WethGateway) }) - it('L1 and L2 implementations of calculateL2ERC20Address match', async () => { - const { l1Signer, l2Signer, l2Network, erc20Bridger } = await testSetup() + it('parent and child chain implementations of calculateL2ERC20Address match', async () => { + const { parentSigner, childSigner, childChain, erc20Bridger } = + await testSetup() const address = hexlify(randomBytes(20)) const erc20L2AddressAsPerL1 = await erc20Bridger.getL2ERC20Address( address, - l1Signer.provider! + parentSigner.provider! ) const l2gr = L2GatewayRouter__factory.connect( - l2Network.tokenBridge.l2GatewayRouter, - l2Signer.provider! + childChain.tokenBridge.l2GatewayRouter, + childSigner.provider! ) const erc20L2AddressAsPerL2 = await l2gr.calculateL2TokenAddress(address) diff --git a/tests/integration/sendL2msg.test.ts b/tests/integration/sendL2msg.test.ts index e9bcdd97ae..893ac1c1f8 100644 --- a/tests/integration/sendL2msg.test.ts +++ b/tests/integration/sendL2msg.test.ts @@ -19,21 +19,24 @@ import { BigNumber, ethers, Signer } from 'ethers' import { InboxTools } from '../../src/lib/inbox/inbox' -import { getL2Network, L2Network } from '../../src/lib/dataEntities/networks' +import { + getArbitrumNetwork, + ArbitrumNetwork, +} from '../../src/lib/dataEntities/networks' import { testSetup } from '../../scripts/testSetup' import { greeter } from './helper/greeter' import { expect } from 'chai' import { AdminErc20Bridger } from '../../src/lib/assetBridger/erc20Bridger' const sendSignedTx = async (testState: any, info?: any) => { - const { l1Deployer, l2Deployer } = testState - const l2Network = await getL2Network(await l2Deployer.getChainId()) - const inbox = new InboxTools(l1Deployer, l2Network) + const { parentDeployer, childDeployer } = testState + const childChain = await getArbitrumNetwork(await childDeployer.getChainId()) + const inbox = new InboxTools(parentDeployer, childChain) const message = { ...info, value: BigNumber.from(0), } - const signedTx = await inbox.signChildChainTx(message, l2Deployer) + const signedTx = await inbox.signChildChainTx(message, childDeployer) const l1Tx = await inbox.sendChildChainSignedTx(signedTx) return { @@ -45,10 +48,10 @@ const sendSignedTx = async (testState: any, info?: any) => { describe('Send signedTx to l2 using inbox', async () => { // test globals let testState: { - l1Deployer: Signer - l2Deployer: Signer + parentDeployer: Signer + childDeployer: Signer adminErc20Bridger: AdminErc20Bridger - l2Network: L2Network + childChain: ArbitrumNetwork } before('init', async () => { @@ -56,11 +59,11 @@ describe('Send signedTx to l2 using inbox', async () => { }) it('can deploy contract', async () => { - const l2Deployer = testState.l2Deployer + const childDeployer = testState.childDeployer const Greeter = new ethers.ContractFactory( greeter.abi, greeter.bytecode - ).connect(l2Deployer) + ).connect(childDeployer) const info = { value: BigNumber.from(0), @@ -74,7 +77,9 @@ describe('Send signedTx to l2 using inbox', async () => { expect(l1Status).to.equal(1, 'l1 txn failed') const l2Tx = ethers.utils.parseTransaction(signedMsg) const l2Txhash = l2Tx.hash! - const l2TxReceipt = await l2Deployer.provider!.waitForTransaction(l2Txhash) + const l2TxReceipt = await childDeployer.provider!.waitForTransaction( + l2Txhash + ) const l2Status = l2TxReceipt.status expect(l2Status).to.equal(1, 'l2 txn failed') const contractAddress = ethers.ContractFactory.getContractAddress({ @@ -87,10 +92,10 @@ describe('Send signedTx to l2 using inbox', async () => { }) it('should confirm the same tx on l2', async () => { - const l2Deployer = testState.l2Deployer + const childDeployer = testState.childDeployer const info = { data: '0x12', - to: await l2Deployer.getAddress(), + to: await childDeployer.getAddress(), } const { signedMsg, l1TransactionReceipt } = await sendSignedTx( testState, @@ -99,19 +104,21 @@ describe('Send signedTx to l2 using inbox', async () => { const l1Status = l1TransactionReceipt?.status expect(l1Status).to.equal(1) const l2Txhash = ethers.utils.parseTransaction(signedMsg).hash! - const l2TxReceipt = await l2Deployer.provider!.waitForTransaction(l2Txhash) + const l2TxReceipt = await childDeployer.provider!.waitForTransaction( + l2Txhash + ) const l2Status = l2TxReceipt.status expect(l2Status).to.equal(1) }) it('send two tx share the same nonce but with different gas price, should confirm the one which gas price higher than l2 base price', async () => { - const l2Deployer = testState.l2Deployer - const currentNonce = await l2Deployer.getTransactionCount() + const childDeployer = testState.childDeployer + const currentNonce = await childDeployer.getTransactionCount() const lowFeeInfo = { data: '0x12', nonce: currentNonce, - to: await l2Deployer.getAddress(), + to: await childDeployer.getAddress(), maxFeePerGas: BigNumber.from(10000000), //0.01gwei maxPriorityFeePerGas: BigNumber.from(1000000), //0.001gwei } @@ -120,7 +127,7 @@ describe('Send signedTx to l2 using inbox', async () => { expect(lowFeeL1Status).to.equal(1) const info = { data: '0x12', - to: await l2Deployer.getAddress(), + to: await childDeployer.getAddress(), nonce: currentNonce, } const enoughFeeTx = await sendSignedTx(testState, info) @@ -132,12 +139,13 @@ describe('Send signedTx to l2 using inbox', async () => { enoughFeeTx.signedMsg ).hash! - const l2TEnoughFeeReceipt = await l2Deployer.provider!.waitForTransaction( - l2EnoughFeeTxhash - ) + const l2TEnoughFeeReceipt = + await childDeployer.provider!.waitForTransaction(l2EnoughFeeTxhash) const l2Status = l2TEnoughFeeReceipt.status expect(l2Status).to.equal(1) - const res = await l2Deployer.provider?.getTransactionReceipt(l2LowFeeTxhash) + const res = await childDeployer.provider?.getTransactionReceipt( + l2LowFeeTxhash + ) expect(res).to.be.null }) }) diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index bca6383610..b44169e1d6 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -32,9 +32,9 @@ import { Erc20Bridger, L1ToL2MessageStatus, L1ToL2MessageWriter, - L2Network, L2TransactionReceipt, } from '../../src' +import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { TestERC20 } from '../../src/lib/abi/TestERC20' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' @@ -48,9 +48,10 @@ import { isDefined } from '../../src/lib/utils/lib' import { getL1CustomFeeTokenAllowance, approveL1CustomFeeTokenForErc20Deposit, - isL2NetworkWithCustomFeeToken, + isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken, } from './custom-fee-token/customFeeTokenTestHelpers' import { itOnlyWhenCustomGasToken } from './custom-fee-token/mochaExtensions' + const depositAmount = BigNumber.from(100) const withdrawalAmount = BigNumber.from(10) @@ -61,38 +62,38 @@ describe('standard ERC20', () => { // test globals let testState: { - l1Signer: Signer - l2Signer: Signer + parentSigner: Signer + childSigner: Signer erc20Bridger: Erc20Bridger - l2Network: L2Network - l1Token: TestERC20 + childChain: ArbitrumNetwork + parentToken: TestERC20 } before('init', async () => { const setup = await testSetup() - await fundL1(setup.l1Signer) - await fundL2(setup.l2Signer) - const deployErc20 = new TestERC20__factory().connect(setup.l1Signer) + await fundL1(setup.parentSigner) + await fundL2(setup.childSigner) + const deployErc20 = new TestERC20__factory().connect(setup.parentSigner) const testToken = await deployErc20.deploy() await testToken.deployed() await (await testToken.mint()).wait() - testState = { ...setup, l1Token: testToken } + testState = { ...setup, parentToken: testToken } }) itOnlyWhenCustomGasToken( 'approves custom gas token to be spent by the relevant gateway', async () => { - const { l1Signer, erc20Bridger } = await testSetup() + const { parentSigner, erc20Bridger } = await testSetup() const gatewayAddress = await erc20Bridger.getL1GatewayAddress( - testState.l1Token.address, - l1Signer.provider! + testState.parentToken.address, + parentSigner.provider! ) const initialAllowance = await getL1CustomFeeTokenAllowance( - await l1Signer.getAddress(), + await parentSigner.getAddress(), gatewayAddress ) @@ -102,13 +103,13 @@ describe('standard ERC20', () => { ) const tx = await erc20Bridger.approveGasToken({ - l1Signer: l1Signer, - erc20ParentAddress: testState.l1Token.address, + l1Signer: parentSigner, + erc20ParentAddress: testState.parentToken.address, }) await tx.wait() const finalAllowance = await getL1CustomFeeTokenAllowance( - await l1Signer.getAddress(), + await parentSigner.getAddress(), gatewayAddress ) @@ -120,19 +121,19 @@ describe('standard ERC20', () => { ) it('deposits erc20', async () => { - if (isL2NetworkWithCustomFeeToken()) { + if (isChildChainWithCustomFeeToken()) { await approveL1CustomFeeTokenForErc20Deposit( - testState.l1Signer, - testState.l1Token.address + testState.parentSigner, + testState.parentToken.address ) } await depositToken({ depositAmount, - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) @@ -150,7 +151,7 @@ describe('standard ERC20', () => { expect(retryRec.blockHash, 'redeemed in same block').to.eq(blockHash) expect(retryRec.to, 'redeemed in same block').to.eq( - testState.l2Network.tokenBridge.l2ERC20Gateway + testState.childChain.tokenBridge.l2ERC20Gateway ) expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( @@ -163,10 +164,10 @@ describe('standard ERC20', () => { it('deposit with no funds, manual redeem', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -181,10 +182,10 @@ describe('standard ERC20', () => { it('deposit with low funds, manual redeem', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -201,10 +202,10 @@ describe('standard ERC20', () => { // redeem transaction const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -221,7 +222,7 @@ describe('standard ERC20', () => { const redeemsScheduled = l2Receipt.getRedeemScheduledEvents() expect(redeemsScheduled.length, 'Unexpected redeem length').to.eq(1) const retryReceipt = - await testState.l2Signer.provider!.getTransactionReceipt( + await testState.childSigner.provider!.getTransactionReceipt( redeemsScheduled[0].retryTxHash ) expect(isDefined(retryReceipt), 'Retry should not exist').to.be.false @@ -233,10 +234,10 @@ describe('standard ERC20', () => { it('deposit with low funds, fails first redeem, succeeds seconds', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -246,11 +247,11 @@ describe('standard ERC20', () => { }) const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - testState.l2Signer.provider! + testState.childSigner.provider! ) const nInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - testState.l2Signer.provider! + testState.childSigner.provider! ) const gasComponents = await nInterface.callStatic.gasEstimateComponents( arbRetryableTx.address, @@ -268,17 +269,17 @@ describe('standard ERC20', () => { it('withdraws erc20', async function () { const l2TokenAddr = await testState.erc20Bridger.getL2ERC20Address( - testState.l1Token.address, - testState.l1Signer.provider! + testState.parentToken.address, + testState.parentSigner.provider! ) const l2Token = testState.erc20Bridger.getChildTokenContract( - testState.l2Signer.provider!, + testState.childSigner.provider!, l2TokenAddr ) // 5 deposits above - increase this number if more deposit tests added const startBalance = depositAmount.mul(5) const l2BalanceStart = await l2Token.balanceOf( - await testState.l2Signer.getAddress() + await testState.childSigner.getAddress() ) expect(l2BalanceStart.toString(), 'l2 balance start').to.eq( l2BalanceStart.toString() @@ -286,12 +287,14 @@ describe('standard ERC20', () => { await withdrawToken({ ...testState, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, amount: withdrawalAmount, gatewayType: GatewayType.STANDARD, startBalance: startBalance, l1Token: ERC20__factory.connect( - testState.l1Token.address, - testState.l1Signer.provider! + testState.parentToken.address, + testState.parentSigner.provider! ), }) }) @@ -300,10 +303,10 @@ describe('standard ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) @@ -314,10 +317,10 @@ describe('standard ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.l1Token.address, + l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.l1Signer, - l2Signer: testState.l2Signer, + l1Signer: testState.parentSigner, + l2Signer: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, destinationAddress: randomAddress, diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 4866152fea..7670fc7322 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -436,8 +436,8 @@ export const skipIfMainnet = (() => { let chainId: number return async (testContext: Mocha.Context) => { if (!chainId) { - const { l1Network } = await testSetup() - chainId = l1Network.chainID + const { parentChain } = await testSetup() + chainId = parentChain.chainID } if (chainId === 1) { console.error("You're writing to the chain on mainnet lol stop") diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index 89fb3e46e9..ff6bf0f4fd 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -39,25 +39,26 @@ describeOnlyWhenEth('WETH', async () => { }) it('deposit WETH', async () => { - const { l2Network, l1Signer, l2Signer, erc20Bridger } = await testSetup() + const { childChain, parentSigner, childSigner, erc20Bridger } = + await testSetup() - const l1WethAddress = l2Network.tokenBridge.l1Weth + const l1WethAddress = childChain.tokenBridge.l1Weth const wethToWrap = parseEther('0.00001') const wethToDeposit = parseEther('0.0000001') - await fundL1(l1Signer, parseEther('1')) + await fundL1(parentSigner, parseEther('1')) const l2WETH = AeWETH__factory.connect( - l2Network.tokenBridge.l2Weth, - l2Signer.provider! + childChain.tokenBridge.l2Weth, + childSigner.provider! ) expect( - (await l2WETH.balanceOf(await l2Signer.getAddress())).toString(), + (await l2WETH.balanceOf(await childSigner.getAddress())).toString(), 'start balance weth' ).to.eq('0') - const l1WETH = AeWETH__factory.connect(l1WethAddress, l1Signer) + const l1WETH = AeWETH__factory.connect(l1WethAddress, parentSigner) const res = await l1WETH.deposit({ value: wethToWrap, }) @@ -66,33 +67,33 @@ describeOnlyWhenEth('WETH', async () => { depositAmount: wethToDeposit, l1TokenAddress: l1WethAddress, erc20Bridger, - l1Signer, - l2Signer, + l1Signer: parentSigner, + l2Signer: childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.WETH, }) const l2WethGateway = await erc20Bridger.getL2GatewayAddress( l1WethAddress, - l2Signer.provider! + childSigner.provider! ) expect(l2WethGateway, 'l2 weth gateway').to.eq( - l2Network.tokenBridge.l2WethGateway + childChain.tokenBridge.l2WethGateway ) const l2Token = erc20Bridger.getChildTokenContract( - l2Signer.provider!, - l2Network.tokenBridge.l2Weth + childSigner.provider!, + childChain.tokenBridge.l2Weth ) - expect(l2Token.address, 'l2 weth').to.eq(l2Network.tokenBridge.l2Weth) + expect(l2Token.address, 'l2 weth').to.eq(childChain.tokenBridge.l2Weth) // now try to withdraw the funds - await fundL2(l2Signer) - const l2Weth = AeWETH__factory.connect(l2Token.address, l2Signer) + await fundL2(childSigner) + const l2Weth = AeWETH__factory.connect(l2Token.address, childSigner) const randomAddr = Wallet.createRandom().address await ( - await l2Weth.connect(l2Signer).withdrawTo(randomAddr, wethToDeposit) + await l2Weth.connect(childSigner).withdrawTo(randomAddr, wethToDeposit) ).wait() - const afterBalance = await l2Signer.provider!.getBalance(randomAddr) + const afterBalance = await childSigner.provider!.getBalance(randomAddr) expect(afterBalance.toString(), 'balance after').to.eq( wethToDeposit.toString() @@ -103,13 +104,14 @@ describeOnlyWhenEth('WETH', async () => { const wethToWrap = parseEther('0.00001') const wethToWithdraw = parseEther('0.00000001') - const { l2Network, l1Signer, l2Signer, erc20Bridger } = await testSetup() - await fundL1(l1Signer) - await fundL2(l2Signer) + const { childChain, parentSigner, childSigner, erc20Bridger } = + await testSetup() + await fundL1(parentSigner) + await fundL2(childSigner) const l2Weth = AeWETH__factory.connect( - l2Network.tokenBridge.l2Weth, - l2Signer + childChain.tokenBridge.l2Weth, + childSigner ) const res = await l2Weth.deposit({ value: wethToWrap, @@ -121,12 +123,12 @@ describeOnlyWhenEth('WETH', async () => { amount: wethToWithdraw, erc20Bridger: erc20Bridger, gatewayType: GatewayType.WETH, - l1Signer: l1Signer, + l1Signer: parentSigner, l1Token: ERC20__factory.connect( - l2Network.tokenBridge.l1Weth, - l1Signer.provider! + childChain.tokenBridge.l1Weth, + parentSigner.provider! ), - l2Signer: l2Signer, + l2Signer: childSigner, startBalance: wethToWrap, }) }) From 241c9248a1f2c14a555f10d5a0c58ce76b3a9f36 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 9 Apr 2024 10:09:47 -0400 Subject: [PATCH 18/74] chore: rename testHelper to parent/child (#440) --- scripts/testSetup.ts | 4 +- .../customFeeTokenEthBridger.test.ts | 88 +++---- tests/integration/customerc20.test.ts | 26 +- tests/integration/eth.test.ts | 18 +- .../integration/l1ToL2MessageCreator.test.ts | 6 +- .../integration/l2TransactionReceipt.test.ts | 10 +- tests/integration/retryableData.test.ts | 6 +- tests/integration/standarderc20.test.ts | 42 ++-- tests/integration/testHelpers.ts | 233 +++++++++--------- tests/integration/weth.test.ts | 22 +- 10 files changed, 235 insertions(+), 220 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 4902a14bc3..8c0e33a076 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -39,7 +39,7 @@ import { fundL1CustomFeeToken, isL2NetworkWithCustomFeeToken, } from '../tests/integration/custom-fee-token/customFeeTokenTestHelpers' -import { fundL1 } from '../tests/integration/testHelpers' +import { fundParentSigner } from '../tests/integration/testHelpers' dotenv.config() @@ -152,7 +152,7 @@ export const testSetup = async (): Promise<{ const inboxTools = new InboxTools(parentSigner, setChildChain) if (isL2NetworkWithCustomFeeToken()) { - await fundL1(parentSigner) + await fundParentSigner(parentSigner) await fundL1CustomFeeToken(parentSigner) await approveL1CustomFeeToken(parentSigner) } diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 1995e4fb6b..4ea85707f4 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -23,7 +23,7 @@ import dotenv from 'dotenv' import { parseEther } from '@ethersproject/units' import { - fundL1 as fundL1Ether, + fundParentSigner as fundParentSignerEther, mineUntilStop, skipIfMainnet, wait, @@ -51,20 +51,21 @@ describeOnlyWhenCustomGasToken( }) it('approves the custom fee token to be spent by the Inbox on the parent chain (arbitrary amount, using params)', async function () { - const { ethBridger, nativeTokenContract, l1Signer } = await testSetup() + const { ethBridger, nativeTokenContract, parentSigner } = + await testSetup() const amount = ethers.utils.parseEther('1') - await fundL1Ether(l1Signer) - await fundL1CustomFeeToken(l1Signer) + await fundParentSignerEther(parentSigner) + await fundL1CustomFeeToken(parentSigner) const approvalTx = await ethBridger.approveGasToken({ amount, - l1Signer, + l1Signer: parentSigner, }) await approvalTx.wait() const allowance = await nativeTokenContract.allowance( - await l1Signer.getAddress(), + await parentSigner.getAddress(), ethBridger.childChain.ethBridge.inbox ) @@ -75,19 +76,20 @@ describeOnlyWhenCustomGasToken( }) it('approves the custom fee token to be spent by the Inbox on the parent chain (max amount, using tx request)', async function () { - const { ethBridger, nativeTokenContract, l1Signer } = await testSetup() + const { ethBridger, nativeTokenContract, parentSigner } = + await testSetup() - await fundL1Ether(l1Signer) - await fundL1CustomFeeToken(l1Signer) + await fundParentSignerEther(parentSigner) + await fundL1CustomFeeToken(parentSigner) const approvalTx = await ethBridger.approveGasToken({ txRequest: ethBridger.getApproveGasTokenRequest(), - l1Signer, + l1Signer: parentSigner, }) await approvalTx.wait() const allowance = await nativeTokenContract.allowance( - await l1Signer.getAddress(), + await parentSigner.getAddress(), ethBridger.childChain.ethBridge.inbox ) @@ -101,24 +103,24 @@ describeOnlyWhenCustomGasToken( const { ethBridger, nativeTokenContract, - l1Signer, - l2Signer, - l2Provider, + parentSigner, + childSigner, + childProvider, } = await testSetup() const bridge = ethBridger.childChain.ethBridge.bridge const amount = parseEther('2') - await fundL1Ether(l1Signer) - await fundL1CustomFeeToken(l1Signer) - await approveL1CustomFeeToken(l1Signer) + await fundParentSignerEther(parentSigner) + await fundL1CustomFeeToken(parentSigner) + await approveL1CustomFeeToken(parentSigner) const initialBalanceBridge = await nativeTokenContract.balanceOf(bridge) - const initialBalanceDepositor = await l2Signer.getBalance() + const initialBalanceDepositor = await childSigner.getBalance() // perform the deposit const depositTx = await ethBridger.deposit({ amount, - l1Signer, + l1Signer: parentSigner, }) const depositTxReceipt = await depositTx.wait() expect(depositTxReceipt.status).to.equal(1, 'deposit tx failed') @@ -136,18 +138,20 @@ describeOnlyWhenCustomGasToken( await wait(30 * 1000) // check for cross-chain messages - const depositMessages = await depositTxReceipt.getEthDeposits(l2Provider) + const depositMessages = await depositTxReceipt.getEthDeposits( + childProvider + ) expect(depositMessages.length).to.equal( 1, 'failed to find deposit message' ) const [depositMessage] = depositMessages expect(depositMessage.value.toString()).to.equal(amount.toString()) - expect(depositMessage.to).to.equal(await l2Signer.getAddress()) + expect(depositMessage.to).to.equal(await childSigner.getAddress()) expect( // balance in the depositor account after the deposit - (await l2Signer.getBalance()).toString() + (await childSigner.getBalance()).toString() ).to.equal( // balance in the depositor account after the deposit should equal to the initial balance in th depositor account + the amount deposited initialBalanceDepositor.add(amount).toString(), @@ -157,21 +161,21 @@ describeOnlyWhenCustomGasToken( it('withdraws custom fee token', async () => { const { - l1Signer, - l1Provider, - l2Signer, - l2Provider, + parentSigner, + parentProvider, + childSigner, + childProvider, ethBridger, nativeTokenContract, } = await testSetup() const bridge = ethBridger.childChain.ethBridge.bridge const amount = parseEther('0.2') - await fundL1Ether(l1Signer) - await fundL2CustomFeeToken(l2Signer) + await fundParentSignerEther(parentSigner) + await fundL2CustomFeeToken(childSigner) - const from = await l2Signer.getAddress() - const destinationAddress = await l1Signer.getAddress() + const from = await childSigner.getAddress() + const destinationAddress = await parentSigner.getAddress() const initialBalanceBridge = await nativeTokenContract.balanceOf(bridge) const initialBalanceDestination = await nativeTokenContract.balanceOf( @@ -185,12 +189,12 @@ describeOnlyWhenCustomGasToken( }) const l1GasEstimate = await withdrawalTxRequest.estimateL1GasLimit( - l1Provider + parentProvider ) const withdrawalTx = await ethBridger.withdraw({ amount, - l2Signer: l2Signer, + l2Signer: childSigner, destinationAddress, from, }) @@ -202,7 +206,7 @@ describeOnlyWhenCustomGasToken( ) const messages = await withdrawalTxReceipt.getChildToParentMessages( - l1Signer + parentSigner ) expect(messages.length).to.equal( 1, @@ -210,7 +214,7 @@ describeOnlyWhenCustomGasToken( ) const withdrawalEvents = await L2ToL1Message.getChildToParentEvents( - l2Provider, + childProvider, { fromBlock: withdrawalTxReceipt.blockNumber, toBlock: 'latest' }, undefined, destinationAddress @@ -222,30 +226,30 @@ describeOnlyWhenCustomGasToken( ) const [message] = messages - const messageStatus = await message.status(l2Provider) + const messageStatus = await message.status(childProvider) expect( messageStatus, `custom fee token withdraw status returned ${messageStatus}` ).to.be.eq(L2ToL1MessageStatus.UNCONFIRMED) // run a miner whilst withdrawing - const miner1 = Wallet.createRandom().connect(l1Provider) - const miner2 = Wallet.createRandom().connect(l2Provider) - await fundL1Ether(miner1, parseEther('1')) + const miner1 = Wallet.createRandom().connect(parentProvider) + const miner2 = Wallet.createRandom().connect(childProvider) + await fundParentSignerEther(miner1, parseEther('1')) await fundL2CustomFeeToken(miner2) const state = { mining: true } await Promise.race([ mineUntilStop(miner1, state), mineUntilStop(miner2, state), - message.waitUntilReadyToExecute(l2Provider), + message.waitUntilReadyToExecute(childProvider), ]) state.mining = false - expect(await message.status(l2Provider), 'confirmed status') + expect(await message.status(childProvider), 'confirmed status') // .to.eq(L2ToL1MessageStatus.CONFIRMED) - const execTx = await message.execute(l2Provider) + const execTx = await message.execute(childProvider) const execTxReceipt = await execTx.wait() expect( @@ -253,7 +257,7 @@ describeOnlyWhenCustomGasToken( 'gas used greater than estimate' ).to.be.lessThan(l1GasEstimate.toNumber()) - expect(await message.status(l2Provider), 'executed status') + expect(await message.status(childProvider), 'executed status') // .to.eq(L2ToL1MessageStatus.EXECUTED) diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 62737d1bda..0fb8ee285e 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -31,8 +31,8 @@ import { TestCustomTokenL1 } from '../../src/lib/abi/TestCustomTokenL1' import { TestCustomTokenL1__factory } from '../../src/lib/abi/factories/TestCustomTokenL1__factory' import { - fundL1, - fundL2, + fundParentSigner, + fundChildSigner, skipIfMainnet, depositToken, GatewayType, @@ -70,8 +70,8 @@ describe('Custom ERC20', () => { ...(await testSetup()), l1CustomToken: {} as any, } - await fundL1(testState.parentSigner) - await fundL2(testState.childSigner) + await fundParentSigner(testState.parentSigner) + await fundChildSigner(testState.childSigner) if (isL2NetworkWithCustomFeeToken()) { await fundL1CustomFeeToken(testState.parentSigner) @@ -96,8 +96,8 @@ describe('Custom ERC20', () => { depositAmount, l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) @@ -106,13 +106,13 @@ describe('Custom ERC20', () => { it('withdraws erc20', async function () { await withdrawToken({ ...testState, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, erc20Bridger: testState.adminErc20Bridger, amount: withdrawalAmount, gatewayType: GatewayType.CUSTOM, startBalance: depositAmount, - l1Token: ERC20__factory.connect( + parentChainToken: ERC20__factory.connect( testState.l1CustomToken.address, testState.parentSigner.provider! ), @@ -125,8 +125,8 @@ describe('Custom ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) @@ -139,8 +139,8 @@ describe('Custom ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, destinationAddress: randomAddress, diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 307f04366e..87c77ce6a8 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -23,8 +23,8 @@ import { Wallet } from '@ethersproject/wallet' import { parseEther } from '@ethersproject/units' import { - fundL1, - fundL2, + fundParentSigner, + fundChildSigner, mineUntilStop, prettyLog, skipIfMainnet, @@ -48,7 +48,7 @@ describe('Ether', async () => { it('transfers ether on l2', async () => { const { childSigner } = await testSetup() - await fundL2(childSigner) + await fundChildSigner(childSigner) const randomAddress = Wallet.createRandom().address const amountToSend = parseEther('0.000005') @@ -99,7 +99,7 @@ describe('Ether', async () => { it('deposits ether', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() - await fundL1(parentSigner) + await fundParentSigner(parentSigner) const inboxAddress = ethBridger.childChain.ethBridge.inbox const initialInboxBalance = await parentSigner.provider!.getBalance( @@ -148,7 +148,7 @@ describe('Ether', async () => { it('deposits ether to a specific L2 address', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() - await fundL1(parentSigner) + await fundParentSigner(parentSigner) const inboxAddress = ethBridger.childChain.ethBridge.inbox const destWallet = Wallet.createRandom() @@ -220,8 +220,8 @@ describe('Ether', async () => { it('withdraw Ether transaction succeeds', async () => { const { childSigner, parentSigner, ethBridger } = await testSetup() - await fundL2(childSigner) - await fundL1(parentSigner) + await fundChildSigner(childSigner) + await fundParentSigner(parentSigner) const ethToWithdraw = parseEther('0.00000002') const randomAddress = Wallet.createRandom().address @@ -288,8 +288,8 @@ describe('Ether', async () => { // run a miner whilst withdrawing const miner1 = Wallet.createRandom().connect(parentSigner.provider!) const miner2 = Wallet.createRandom().connect(childSigner.provider!) - await fundL1(miner1, parseEther('1')) - await fundL2(miner2, parseEther('1')) + await fundParentSigner(miner1, parseEther('1')) + await fundChildSigner(miner2, parseEther('1')) const state = { mining: true } await Promise.race([ mineUntilStop(miner1, state), diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/l1ToL2MessageCreator.test.ts index 60a10dc14f..1691c539f1 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/l1ToL2MessageCreator.test.ts @@ -18,7 +18,7 @@ import { expect } from 'chai' import { providers, utils } from 'ethers' -import { fundL1 as fundParentChain, skipIfMainnet } from './testHelpers' +import { fundParentSigner, skipIfMainnet } from './testHelpers' import { testSetup } from '../../scripts/testSetup' import { ParentToChildMessageCreator } from '../../src/lib/message/L1ToL2MessageCreator' import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' @@ -43,7 +43,7 @@ describe('ParentToChildMessageCreator', () => { const arbProvider = childSigner.provider as providers.Provider // Funding parent chain wallet - await fundParentChain(parentSigner) + await fundParentSigner(parentSigner) if (isChildChainWithCustomFeeToken()) { await fundParentChainCustomFeeToken(parentSigner) @@ -105,7 +105,7 @@ describe('ParentToChildMessageCreator', () => { const arbProvider = childSigner.provider as providers.Provider // Funding parent chain wallet - await fundParentChain(parentSigner) + await fundParentSigner(parentSigner) if (isChildChainWithCustomFeeToken()) { await fundParentChainCustomFeeToken(parentSigner) diff --git a/tests/integration/l2TransactionReceipt.test.ts b/tests/integration/l2TransactionReceipt.test.ts index b0d546010d..f2025b5190 100644 --- a/tests/integration/l2TransactionReceipt.test.ts +++ b/tests/integration/l2TransactionReceipt.test.ts @@ -19,8 +19,8 @@ import { expect } from 'chai' import { - fundL1, - fundL2, + fundParentSigner, + fundChildSigner, mineUntilStop, skipIfMainnet, wait, @@ -43,13 +43,13 @@ describe('ArbProvider', () => { // set up miners const miner1 = Wallet.createRandom().connect(parentSigner.provider!) const miner2 = Wallet.createRandom().connect(childSigner.provider!) - await fundL1(miner1, parseEther('0.1')) - await fundL2(miner2, parseEther('0.1')) + await fundParentSigner(miner1, parseEther('0.1')) + await fundChildSigner(miner2, parseEther('0.1')) const state = { mining: true } mineUntilStop(miner1, state) mineUntilStop(miner2, state) - await fundL2(childSigner) + await fundChildSigner(childSigner) const randomAddress = Wallet.createRandom().address const amountToSend = parseEther('0.000005') diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index 79dff3c86e..d9b3bf1708 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -20,7 +20,7 @@ import { assert, expect } from 'chai' import { BigNumber } from '@ethersproject/bignumber' import { hexlify } from '@ethersproject/bytes' import { TestERC20__factory } from '../../src/lib/abi/factories/TestERC20__factory' -import { fundL1, skipIfMainnet } from './testHelpers' +import { fundParentSigner, skipIfMainnet } from './testHelpers' import { RetryableDataTools } from '../../src' import { Wallet } from 'ethers' import { testSetup } from '../../scripts/testSetup' @@ -59,7 +59,7 @@ describe('RevertData', () => { func: 'estimateGas' | 'callStatic' ) => { const { parentSigner, childChain } = await testSetup() - await fundL1(parentSigner) + await fundParentSigner(parentSigner) const { to, @@ -146,7 +146,7 @@ describe('RevertData', () => { it('is the same as what we estimate in erc20Bridger', async () => { const { erc20Bridger, parentSigner, childSigner } = await testSetup() - await fundL1(parentSigner, parseEther('2')) + await fundParentSigner(parentSigner, parseEther('2')) const deployErc20 = new TestERC20__factory().connect(parentSigner) const testToken = await deployErc20.deploy() diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index b44169e1d6..3f74fe33e2 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -21,12 +21,12 @@ import { Signer, Wallet, utils, constants } from 'ethers' import { BigNumber } from '@ethersproject/bignumber' import { TestERC20__factory } from '../../src/lib/abi/factories/TestERC20__factory' import { - fundL1, + fundParentSigner, skipIfMainnet, depositToken, GatewayType, withdrawToken, - fundL2, + fundChildSigner, } from './testHelpers' import { Erc20Bridger, @@ -71,8 +71,8 @@ describe('standard ERC20', () => { before('init', async () => { const setup = await testSetup() - await fundL1(setup.parentSigner) - await fundL2(setup.childSigner) + await fundParentSigner(setup.parentSigner) + await fundChildSigner(setup.childSigner) const deployErc20 = new TestERC20__factory().connect(setup.parentSigner) const testToken = await deployErc20.deploy() await testToken.deployed() @@ -132,8 +132,8 @@ describe('standard ERC20', () => { depositAmount, l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) @@ -166,8 +166,8 @@ describe('standard ERC20', () => { depositAmount, l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -184,8 +184,8 @@ describe('standard ERC20', () => { depositAmount, l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -204,8 +204,8 @@ describe('standard ERC20', () => { depositAmount, l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -236,8 +236,8 @@ describe('standard ERC20', () => { depositAmount, l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { @@ -287,12 +287,12 @@ describe('standard ERC20', () => { await withdrawToken({ ...testState, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, amount: withdrawalAmount, gatewayType: GatewayType.STANDARD, startBalance: startBalance, - l1Token: ERC20__factory.connect( + parentChainToken: ERC20__factory.connect( testState.parentToken.address, testState.parentSigner.provider! ), @@ -305,8 +305,8 @@ describe('standard ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) @@ -319,8 +319,8 @@ describe('standard ERC20', () => { ethDepositAmount: utils.parseEther('0.0005'), l1TokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, - l1Signer: testState.parentSigner, - l2Signer: testState.childSigner, + parentSigner: testState.parentSigner, + childSigner: testState.childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, destinationAddress: randomAddress, diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 7670fc7322..98b5f6ca81 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -26,12 +26,9 @@ import { parseEther } from '@ethersproject/units' import { config, getSigner, testSetup } from '../../scripts/testSetup' import { Signer, Wallet } from 'ethers' -import { - Erc20Bridger, - L1ToL2MessageStatus, - ChildToParentMessageStatus as L2ToL1MessageStatus, -} from '../../src' -import { L2Network } from '../../src/lib/dataEntities/networks' +import { Erc20Bridger, ChildToParentMessageStatus } from '../../src' +import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' +import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' @@ -60,9 +57,9 @@ interface WithdrawalParams { startBalance: BigNumber amount: BigNumber erc20Bridger: Erc20Bridger - l1Token: ERC20 - l2Signer: Signer - l1Signer: Signer + parentChainToken: ERC20 + childSigner: Signer + parentSigner: Signer gatewayType: GatewayType } @@ -88,53 +85,53 @@ export const mineUntilStop = async ( export const withdrawToken = async (params: WithdrawalParams) => { const withdrawalParams = await params.erc20Bridger.getWithdrawalRequest({ amount: params.amount, - erc20ParentAddress: params.l1Token.address, - destinationAddress: await params.l2Signer.getAddress(), - from: await params.l2Signer.getAddress(), + erc20ParentAddress: params.parentChainToken.address, + destinationAddress: await params.childSigner.getAddress(), + from: await params.childSigner.getAddress(), }) - const l1GasEstimate = await withdrawalParams.estimateL1GasLimit( - params.l1Signer.provider! + const parentChainGasEstimate = await withdrawalParams.estimateL1GasLimit( + params.parentSigner.provider! ) const withdrawRes = await params.erc20Bridger.withdraw({ - destinationAddress: await params.l2Signer.getAddress(), + destinationAddress: await params.childSigner.getAddress(), amount: params.amount, - erc20ParentAddress: params.l1Token.address, - l2Signer: params.l2Signer, + erc20ParentAddress: params.parentChainToken.address, + l2Signer: params.childSigner, }) const withdrawRec = await withdrawRes.wait() expect(withdrawRec.status).to.equal(1, 'initiate token withdraw txn failed') const message = ( - await withdrawRec.getChildToParentMessages(params.l1Signer) + await withdrawRec.getChildToParentMessages(params.parentSigner) )[0] expect(message, 'withdraw message not found').to.exist - const messageStatus = await message.status(params.l2Signer.provider!) + const messageStatus = await message.status(params.childSigner.provider!) expect(messageStatus, `invalid withdraw status`).to.eq( - L2ToL1MessageStatus.UNCONFIRMED + ChildToParentMessageStatus.UNCONFIRMED ) - const l2TokenAddr = await params.erc20Bridger.getL2ERC20Address( - params.l1Token.address, - params.l1Signer.provider! + const childChainTokenAddr = await params.erc20Bridger.getL2ERC20Address( + params.parentChainToken.address, + params.parentSigner.provider! ) - const l2Token = params.erc20Bridger.getChildTokenContract( - params.l2Signer.provider!, - l2TokenAddr + const childChainToken = params.erc20Bridger.getChildTokenContract( + params.childSigner.provider!, + childChainTokenAddr ) - const testWalletL2Balance = await l2Token.balanceOf( - await params.l2Signer.getAddress() + const testWalletChildChainBalance = await childChainToken.balanceOf( + await params.childSigner.getAddress() ) expect( - testWalletL2Balance.toNumber(), + testWalletChildChainBalance.toNumber(), 'token withdraw balance not deducted' ).to.eq(params.startBalance.sub(params.amount).toNumber()) - const walletAddress = await params.l1Signer.getAddress() + const walletAddress = await params.parentSigner.getAddress() const gatewayAddress = await params.erc20Bridger.getL2GatewayAddress( - params.l1Token.address, - params.l2Signer.provider! + params.parentChainToken.address, + params.childSigner.provider! ) const { expectedL2Gateway } = getGateways( @@ -146,58 +143,58 @@ export const withdrawToken = async (params: WithdrawalParams) => { ) const gatewayWithdrawEvents = await params.erc20Bridger.getL2WithdrawalEvents( - params.l2Signer.provider!, + params.childSigner.provider!, gatewayAddress, { fromBlock: withdrawRec.blockNumber, toBlock: 'latest' }, - params.l1Token.address, + params.parentChainToken.address, walletAddress ) expect(gatewayWithdrawEvents.length).to.equal(1, 'token query failed') - const balBefore = await params.l1Token.balanceOf( - await params.l1Signer.getAddress() + const balBefore = await params.parentChainToken.balanceOf( + await params.parentSigner.getAddress() ) // whilst waiting for status we miner on both l1 and l2 - const miner1 = Wallet.createRandom().connect(params.l1Signer.provider!) - const miner2 = Wallet.createRandom().connect(params.l2Signer.provider!) - await fundL1(miner1, parseEther('1')) - await fundL2(miner2, parseEther('1')) + const miner1 = Wallet.createRandom().connect(params.parentSigner.provider!) + const miner2 = Wallet.createRandom().connect(params.childSigner.provider!) + await fundParentSigner(miner1, parseEther('1')) + await fundChildSigner(miner2, parseEther('1')) const state = { mining: true } await Promise.race([ mineUntilStop(miner1, state), mineUntilStop(miner2, state), - message.waitUntilReadyToExecute(params.l2Signer.provider!), + message.waitUntilReadyToExecute(params.childSigner.provider!), ]) state.mining = false expect( - await message.status(params.l2Signer.provider!), + await message.status(params.childSigner.provider!), 'confirmed status' - ).to.eq(L2ToL1MessageStatus.CONFIRMED) + ).to.eq(ChildToParentMessageStatus.CONFIRMED) - const execTx = await message.execute(params.l2Signer.provider!) + const execTx = await message.execute(params.childSigner.provider!) const execRec = await execTx.wait() expect( execRec.gasUsed.toNumber(), 'Gas used greater than estimate' - ).to.be.lessThan(l1GasEstimate.toNumber()) + ).to.be.lessThan(parentChainGasEstimate.toNumber()) expect( - await message.status(params.l2Signer.provider!), + await message.status(params.childSigner.provider!), 'executed status' - ).to.eq(L2ToL1MessageStatus.EXECUTED) + ).to.eq(ChildToParentMessageStatus.EXECUTED) - const balAfter = await params.l1Token.balanceOf( - await params.l1Signer.getAddress() + const balAfter = await params.parentChainToken.balanceOf( + await params.parentSigner.getAddress() ) expect(balBefore.add(params.amount).toString(), 'Not withdrawn').to.eq( balAfter.toString() ) } -const getGateways = (gatewayType: GatewayType, l2Network: L2Network) => { +const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { switch (gatewayType) { case GatewayType.CUSTOM: return { @@ -224,16 +221,16 @@ const getGateways = (gatewayType: GatewayType, l2Network: L2Network) => { * @param depositAmount * @param l1TokenAddress * @param erc20Bridger - * @param l1Signer - * @param l2Signer + * @param parentSigner + * @param childSigner */ export const depositToken = async ({ depositAmount, ethDepositAmount, l1TokenAddress, erc20Bridger, - l1Signer, - l2Signer, + parentSigner, + childSigner, expectedStatus, expectedGatewayType, retryableOverrides, @@ -243,9 +240,9 @@ export const depositToken = async ({ ethDepositAmount?: BigNumber l1TokenAddress: string erc20Bridger: Erc20Bridger - l1Signer: Signer - l2Signer: Signer - expectedStatus: L1ToL2MessageStatus + parentSigner: Signer + childSigner: Signer + expectedStatus: ParentToChildMessageStatus expectedGatewayType: GatewayType retryableOverrides?: GasOverrides destinationAddress?: string @@ -253,22 +250,23 @@ export const depositToken = async ({ await ( await erc20Bridger.approveToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: l1Signer, + l1Signer: parentSigner, }) ).wait() - const senderAddress = await l1Signer.getAddress() - const expectedL1GatewayAddress = await erc20Bridger.getL1GatewayAddress( - l1TokenAddress, - l1Signer.provider! - ) - const l1Token = erc20Bridger.getParentChainTokenContract( - l1Signer.provider!, + const senderAddress = await parentSigner.getAddress() + const expectedParentChainGatewayAddress = + await erc20Bridger.getL1GatewayAddress( + l1TokenAddress, + parentSigner.provider! + ) + const parentChainToken = erc20Bridger.getParentChainTokenContract( + parentSigner.provider!, l1TokenAddress ) - const allowance = await l1Token.allowance( + const allowance = await parentChainToken.allowance( senderAddress, - expectedL1GatewayAddress + expectedParentChainGatewayAddress ) expect(allowance.eq(Erc20Bridger.MAX_APPROVAL), 'set token allowance failed') .to.be.true @@ -276,15 +274,18 @@ export const depositToken = async ({ if (isL2NetworkWithCustomFeeToken()) { await ( await erc20Bridger.approveGasToken({ - l1Signer, + l1Signer: parentSigner, erc20ParentAddress: l1TokenAddress, }) ).wait() const feeTokenAllowance = await ERC20__factory.connect( erc20Bridger.nativeToken!, - l1Signer - ).allowance(await l1Signer.getAddress(), expectedL1GatewayAddress) + parentSigner + ).allowance( + await parentSigner.getAddress(), + expectedParentChainGatewayAddress + ) expect( feeTokenAllowance.eq(Erc20Bridger.MAX_APPROVAL), @@ -292,17 +293,19 @@ export const depositToken = async ({ ).to.be.true } - const initialBridgeTokenBalance = await l1Token.balanceOf( - expectedL1GatewayAddress + const initialBridgeTokenBalance = await parentChainToken.balanceOf( + expectedParentChainGatewayAddress ) - const tokenBalL1Before = await l1Token.balanceOf(senderAddress) - const ethBalL2Before = await l2Signer.provider!.getBalance( + const parentTokenBalanceBefore = await parentChainToken.balanceOf( + senderAddress + ) + const childChainEthBalanceBefore = await childSigner.provider!.getBalance( destinationAddress || senderAddress ) const depositRes = await erc20Bridger.deposit({ - l1Signer: l1Signer, - childProvider: l2Signer.provider!, + l1Signer: parentSigner, + childProvider: childSigner.provider!, erc20ParentAddress: l1TokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, @@ -312,8 +315,8 @@ export const depositToken = async ({ }) const depositRec = await depositRes.wait() - const finalBridgeTokenBalance = await l1Token.balanceOf( - expectedL1GatewayAddress + const finalBridgeTokenBalance = await parentChainToken.balanceOf( + expectedParentChainGatewayAddress ) expect( finalBridgeTokenBalance.toNumber(), @@ -324,21 +327,23 @@ export const depositToken = async ({ ? 0 : initialBridgeTokenBalance.add(depositAmount).toNumber() ) - const tokenBalL1After = await l1Token.balanceOf(senderAddress) - expect(tokenBalL1After.toString(), 'user bal after').to.eq( - tokenBalL1Before.sub(depositAmount).toString() + const parentTokenBalanceAfter = await parentChainToken.balanceOf( + senderAddress + ) + expect(parentTokenBalanceAfter.toString(), 'user bal after').to.eq( + parentTokenBalanceBefore.sub(depositAmount).toString() ) - const waitRes = await depositRec.waitForChildTx(l2Signer) + const waitRes = await depositRec.waitForChildTx(childSigner) - const ethBalL2After = await l2Signer.provider!.getBalance( + const childChainEthBalanceAfter = await childSigner.provider!.getBalance( destinationAddress || senderAddress ) expect(waitRes.status, 'Unexpected status').to.eq(expectedStatus) if (retryableOverrides) { return { - l1Token, + parentChainToken, waitRes, } } @@ -348,56 +353,62 @@ export const depositToken = async ({ erc20Bridger.childChain ) - const l1Gateway = await erc20Bridger.getL1GatewayAddress( + const parentChainGateway = await erc20Bridger.getL1GatewayAddress( l1TokenAddress, - l1Signer.provider! + parentSigner.provider! + ) + expect(parentChainGateway, 'incorrect parent chain gateway address').to.eq( + expectedL1Gateway ) - expect(l1Gateway, 'incorrect l1 gateway address').to.eq(expectedL1Gateway) - const l2Gateway = await erc20Bridger.getL2GatewayAddress( + const childChainGateway = await erc20Bridger.getL2GatewayAddress( l1TokenAddress, - l2Signer.provider! + childSigner.provider! + ) + expect(childChainGateway, 'incorrect child chain gateway address').to.eq( + expectedL2Gateway ) - expect(l2Gateway, 'incorrect l2 gateway address').to.eq(expectedL2Gateway) - const l2Erc20Addr = await erc20Bridger.getL2ERC20Address( + const childChainErc20Addr = await erc20Bridger.getL2ERC20Address( l1TokenAddress, - l1Signer.provider! + parentSigner.provider! ) - const l2Token = erc20Bridger.getChildTokenContract( - l2Signer.provider!, - l2Erc20Addr + const childChainToken = erc20Bridger.getChildTokenContract( + childSigner.provider!, + childChainErc20Addr ) - const l1Erc20Addr = await erc20Bridger.getL1ERC20Address( - l2Erc20Addr, - l2Signer.provider! + const parentChainErc20Addr = await erc20Bridger.getL1ERC20Address( + childChainErc20Addr, + childSigner.provider! ) - expect(l1Erc20Addr).to.equal( + expect(parentChainErc20Addr).to.equal( l1TokenAddress, 'getERC20L1Address/getERC20L2Address failed with proper token address' ) - const tokenBalL2After = await l2Token.balanceOf( + const tokenBalOnChildChainAfter = await childChainToken.balanceOf( destinationAddress || senderAddress ) // only check for standard deposits if (!destinationAddress && !ethDepositAmount) { expect( - tokenBalL2After.eq(depositAmount), - 'l2 wallet not updated after deposit' + tokenBalOnChildChainAfter.eq(depositAmount), + 'child wallet not updated after deposit' ).to.be.true } // batched token+eth if (ethDepositAmount) { expect( - ethBalL2After.gte(ethBalL2Before.add(ethDepositAmount)), - 'l2 wallet not updated with the extra eth deposit' + childChainEthBalanceAfter.gte( + childChainEthBalanceBefore.add(ethDepositAmount) + ), + 'child wallet not updated with the extra eth deposit' ).to.be.true } - return { l1Token, waitRes, l2Token } + return { parentChainToken, waitRes, childChainToken } } const fund = async ( @@ -414,18 +425,18 @@ const fund = async ( ).wait() } -export const fundL1 = async ( - l1Signer: Signer, +export const fundParentSigner = async ( + parentSigner: Signer, amount?: BigNumber ): Promise => { - await fund(l1Signer, amount, config.ethKey) + await fund(parentSigner, amount, config.ethKey) } -export const fundL2 = async ( - l2Signer: Signer, +export const fundChildSigner = async ( + childSigner: Signer, amount?: BigNumber ): Promise => { - await fund(l2Signer, amount, config.arbKey) + await fund(childSigner, amount, config.arbKey) } export const wait = (ms = 0): Promise => { diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index ff6bf0f4fd..4f8481fe36 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -20,8 +20,8 @@ import { expect } from 'chai' import { parseEther } from '@ethersproject/units' import { AeWETH__factory } from '../../src/lib/abi/factories/AeWETH__factory' import { - fundL1, - fundL2, + fundParentSigner, + fundChildSigner, skipIfMainnet, withdrawToken, GatewayType, @@ -47,7 +47,7 @@ describeOnlyWhenEth('WETH', async () => { const wethToWrap = parseEther('0.00001') const wethToDeposit = parseEther('0.0000001') - await fundL1(parentSigner, parseEther('1')) + await fundParentSigner(parentSigner, parseEther('1')) const l2WETH = AeWETH__factory.connect( childChain.tokenBridge.l2Weth, @@ -67,8 +67,8 @@ describeOnlyWhenEth('WETH', async () => { depositAmount: wethToDeposit, l1TokenAddress: l1WethAddress, erc20Bridger, - l1Signer: parentSigner, - l2Signer: childSigner, + parentSigner, + childSigner, expectedStatus: L1ToL2MessageStatus.REDEEMED, expectedGatewayType: GatewayType.WETH, }) @@ -87,7 +87,7 @@ describeOnlyWhenEth('WETH', async () => { expect(l2Token.address, 'l2 weth').to.eq(childChain.tokenBridge.l2Weth) // now try to withdraw the funds - await fundL2(childSigner) + await fundChildSigner(childSigner) const l2Weth = AeWETH__factory.connect(l2Token.address, childSigner) const randomAddr = Wallet.createRandom().address await ( @@ -106,8 +106,8 @@ describeOnlyWhenEth('WETH', async () => { const { childChain, parentSigner, childSigner, erc20Bridger } = await testSetup() - await fundL1(parentSigner) - await fundL2(childSigner) + await fundParentSigner(parentSigner) + await fundChildSigner(childSigner) const l2Weth = AeWETH__factory.connect( childChain.tokenBridge.l2Weth, @@ -123,12 +123,12 @@ describeOnlyWhenEth('WETH', async () => { amount: wethToWithdraw, erc20Bridger: erc20Bridger, gatewayType: GatewayType.WETH, - l1Signer: parentSigner, - l1Token: ERC20__factory.connect( + parentSigner: parentSigner, + parentChainToken: ERC20__factory.connect( childChain.tokenBridge.l1Weth, parentSigner.provider! ), - l2Signer: childSigner, + childSigner: childSigner, startBalance: wethToWrap, }) }) From de63b272adcbf122978c763dc1af7595453d511a Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:20:06 -0400 Subject: [PATCH 19/74] chore: rename custom fee token files (#441) --- scripts/testSetup.ts | 12 ++--- .../customFeeTokenEthBridger.test.ts | 46 +++++++++---------- .../customFeeTokenTestHelpers.ts | 32 +++++++------ .../custom-fee-token/mochaExtensions.ts | 4 +- tests/integration/customerc20.test.ts | 12 ++--- tests/integration/eth.test.ts | 4 +- .../integration/l1ToL2MessageCreator.test.ts | 18 ++++---- tests/integration/retryableData.test.ts | 8 ++-- tests/integration/standarderc20.test.ts | 14 +++--- tests/integration/testHelpers.ts | 4 +- 10 files changed, 79 insertions(+), 75 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 8c0e33a076..d711a13556 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -35,9 +35,9 @@ import * as path from 'path' import * as fs from 'fs' import { ArbSdkError } from '../src/lib/dataEntities/errors' import { - approveL1CustomFeeToken, - fundL1CustomFeeToken, - isL2NetworkWithCustomFeeToken, + approveParentCustomFeeToken, + fundParentCustomFeeToken, + isArbitrumNetworkWithCustomFeeToken, } from '../tests/integration/custom-fee-token/customFeeTokenTestHelpers' import { fundParentSigner } from '../tests/integration/testHelpers' @@ -151,10 +151,10 @@ export const testSetup = async (): Promise<{ const ethBridger = new EthBridger(setChildChain) const inboxTools = new InboxTools(parentSigner, setChildChain) - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { await fundParentSigner(parentSigner) - await fundL1CustomFeeToken(parentSigner) - await approveL1CustomFeeToken(parentSigner) + await fundParentCustomFeeToken(parentSigner) + await approveParentCustomFeeToken(parentSigner) } return { diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 4ea85707f4..8c920cd16b 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -28,11 +28,10 @@ import { skipIfMainnet, wait, } from '../testHelpers' -import { - L2ToL1Message, - ChildToParentMessageStatus as L2ToL1MessageStatus, -} from '../../../src' + import { describeOnlyWhenCustomGasToken } from './mochaExtensions' +import { ChildToParentMessageStatus } from '../../../src' +import { ChildToParentMessage } from '../../../src/lib/message/L2ToL1Message' dotenv.config() @@ -41,9 +40,9 @@ describeOnlyWhenCustomGasToken( async () => { const { testSetup, - fundL1CustomFeeToken, - fundL2CustomFeeToken, - approveL1CustomFeeToken, + fundParentCustomFeeToken, + fundChildCustomFeeToken, + approveParentCustomFeeToken, } = await import('./customFeeTokenTestHelpers') beforeEach('skipIfMainnet', async function () { @@ -56,7 +55,7 @@ describeOnlyWhenCustomGasToken( const amount = ethers.utils.parseEther('1') await fundParentSignerEther(parentSigner) - await fundL1CustomFeeToken(parentSigner) + await fundParentCustomFeeToken(parentSigner) const approvalTx = await ethBridger.approveGasToken({ amount, @@ -80,7 +79,7 @@ describeOnlyWhenCustomGasToken( await testSetup() await fundParentSignerEther(parentSigner) - await fundL1CustomFeeToken(parentSigner) + await fundParentCustomFeeToken(parentSigner) const approvalTx = await ethBridger.approveGasToken({ txRequest: ethBridger.getApproveGasTokenRequest(), @@ -111,8 +110,8 @@ describeOnlyWhenCustomGasToken( const amount = parseEther('2') await fundParentSignerEther(parentSigner) - await fundL1CustomFeeToken(parentSigner) - await approveL1CustomFeeToken(parentSigner) + await fundParentCustomFeeToken(parentSigner) + await approveParentCustomFeeToken(parentSigner) const initialBalanceBridge = await nativeTokenContract.balanceOf(bridge) const initialBalanceDepositor = await childSigner.getBalance() @@ -153,7 +152,7 @@ describeOnlyWhenCustomGasToken( // balance in the depositor account after the deposit (await childSigner.getBalance()).toString() ).to.equal( - // balance in the depositor account after the deposit should equal to the initial balance in th depositor account + the amount deposited + // balance in the depositor account after the deposit should equal to the initial balance in the depositor account + the amount deposited initialBalanceDepositor.add(amount).toString(), 'incorrect balance in depositor account after deposit' ) @@ -172,7 +171,7 @@ describeOnlyWhenCustomGasToken( const amount = parseEther('0.2') await fundParentSignerEther(parentSigner) - await fundL2CustomFeeToken(childSigner) + await fundChildCustomFeeToken(childSigner) const from = await childSigner.getAddress() const destinationAddress = await parentSigner.getAddress() @@ -213,12 +212,13 @@ describeOnlyWhenCustomGasToken( 'custom fee token withdraw getWithdrawalsInL2Transaction query came back empty' ) - const withdrawalEvents = await L2ToL1Message.getChildToParentEvents( - childProvider, - { fromBlock: withdrawalTxReceipt.blockNumber, toBlock: 'latest' }, - undefined, - destinationAddress - ) + const withdrawalEvents = + await ChildToParentMessage.getChildToParentEvents( + childProvider, + { fromBlock: withdrawalTxReceipt.blockNumber, toBlock: 'latest' }, + undefined, + destinationAddress + ) expect(withdrawalEvents.length).to.equal( 1, @@ -230,13 +230,13 @@ describeOnlyWhenCustomGasToken( expect( messageStatus, `custom fee token withdraw status returned ${messageStatus}` - ).to.be.eq(L2ToL1MessageStatus.UNCONFIRMED) + ).to.be.eq(ChildToParentMessageStatus.UNCONFIRMED) // run a miner whilst withdrawing const miner1 = Wallet.createRandom().connect(parentProvider) const miner2 = Wallet.createRandom().connect(childProvider) await fundParentSignerEther(miner1, parseEther('1')) - await fundL2CustomFeeToken(miner2) + await fundChildCustomFeeToken(miner2) const state = { mining: true } await Promise.race([ mineUntilStop(miner1, state), @@ -247,7 +247,7 @@ describeOnlyWhenCustomGasToken( expect(await message.status(childProvider), 'confirmed status') // - .to.eq(L2ToL1MessageStatus.CONFIRMED) + .to.eq(ChildToParentMessageStatus.CONFIRMED) const execTx = await message.execute(childProvider) const execTxReceipt = await execTx.wait() @@ -259,7 +259,7 @@ describeOnlyWhenCustomGasToken( expect(await message.status(childProvider), 'executed status') // - .to.eq(L2ToL1MessageStatus.EXECUTED) + .to.eq(ChildToParentMessageStatus.EXECUTED) expect( // balance in the bridge after the withdrawal diff --git a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts index 16bbf369a2..fd157bd788 100644 --- a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts +++ b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts @@ -14,7 +14,7 @@ const ethProvider = () => new StaticJsonRpcProvider(config.ethUrl) const arbProvider = () => new StaticJsonRpcProvider(config.arbUrl) const localNetworks = () => getLocalNetworksFromFile() -export function isL2NetworkWithCustomFeeToken(): boolean { +export function isArbitrumNetworkWithCustomFeeToken(): boolean { const nt = localNetworks().l2Network.nativeToken return typeof nt !== 'undefined' && nt !== ethers.constants.AddressZero } @@ -32,16 +32,18 @@ export async function testSetup() { return { ...result, nativeTokenContract } } -export async function fundL1CustomFeeToken(l1SignerOrAddress: Signer | string) { +export async function fundParentCustomFeeToken( + parentSignerOrAddress: Signer | string +) { const nativeToken = localNetworks().l2Network.nativeToken const address = - typeof l1SignerOrAddress === 'string' - ? l1SignerOrAddress - : await l1SignerOrAddress.getAddress() + typeof parentSignerOrAddress === 'string' + ? parentSignerOrAddress + : await parentSignerOrAddress.getAddress() if (typeof nativeToken === 'undefined') { throw new Error( - `can't call "fundL1CustomFeeToken" for network that uses eth as native token` + `can't call "fundParentCustomFeeToken" for network that uses eth as native token` ) } @@ -56,14 +58,16 @@ export async function fundL1CustomFeeToken(l1SignerOrAddress: Signer | string) { await tx.wait() } -export async function approveL1CustomFeeToken(l1Signer: Signer) { +export async function approveParentCustomFeeToken(parentSigner: Signer) { const ethBridger = await EthBridger.fromProvider(arbProvider()) - const tx = await ethBridger.approveGasToken({ l1Signer }) + const tx = await ethBridger.approveGasToken({ + l1Signer: parentSigner, + }) await tx.wait() } -export async function getL1CustomFeeTokenAllowance( +export async function getParentCustomFeeTokenAllowance( owner: string, spender: string ) { @@ -75,24 +79,24 @@ export async function getL1CustomFeeTokenAllowance( return nativeTokenContract.allowance(owner, spender) } -export async function approveL1CustomFeeTokenForErc20Deposit( - l1Signer: Signer, +export async function approveParentCustomFeeTokenForErc20Deposit( + parentSigner: Signer, erc20ParentAddress: string ) { const erc20Bridger = await Erc20Bridger.fromProvider(arbProvider()) const tx = await erc20Bridger.approveGasToken({ erc20ParentAddress: erc20ParentAddress, - l1Signer, + l1Signer: parentSigner, }) await tx.wait() } -export async function fundL2CustomFeeToken(l2Signer: Signer) { +export async function fundChildCustomFeeToken(childSigner: Signer) { const deployerWallet = new Wallet(config.arbKey, arbProvider()) const tx = await deployerWallet.sendTransaction({ - to: await l2Signer.getAddress(), + to: await childSigner.getAddress(), value: utils.parseEther('1'), }) await tx.wait() diff --git a/tests/integration/custom-fee-token/mochaExtensions.ts b/tests/integration/custom-fee-token/mochaExtensions.ts index c882700a6b..a2b8ba2ad2 100644 --- a/tests/integration/custom-fee-token/mochaExtensions.ts +++ b/tests/integration/custom-fee-token/mochaExtensions.ts @@ -1,6 +1,6 @@ -import { isL2NetworkWithCustomFeeToken } from './customFeeTokenTestHelpers' +import { isArbitrumNetworkWithCustomFeeToken } from './customFeeTokenTestHelpers' -const customGasTokenEnvironment = isL2NetworkWithCustomFeeToken() +const customGasTokenEnvironment = isArbitrumNetworkWithCustomFeeToken() /** * Only run when in an eth chain environment diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 0fb8ee285e..87107fce84 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -44,8 +44,8 @@ import { AdminErc20Bridger } from '../../src/lib/assetBridger/erc20Bridger' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' import { - fundL1CustomFeeToken, - isL2NetworkWithCustomFeeToken, + fundParentCustomFeeToken, + isArbitrumNetworkWithCustomFeeToken, } from './custom-fee-token/customFeeTokenTestHelpers' const depositAmount = BigNumber.from(100) @@ -73,8 +73,8 @@ describe('Custom ERC20', () => { await fundParentSigner(testState.parentSigner) await fundChildSigner(testState.childSigner) - if (isL2NetworkWithCustomFeeToken()) { - await fundL1CustomFeeToken(testState.parentSigner) + if (isArbitrumNetworkWithCustomFeeToken()) { + await fundParentCustomFeeToken(testState.parentSigner) } }) @@ -155,7 +155,7 @@ const registerCustomToken = async ( adminErc20Bridger: AdminErc20Bridger ) => { // create a custom token on L1 and L2 - const l1CustomTokenFactory = isL2NetworkWithCustomFeeToken() + const l1CustomTokenFactory = isArbitrumNetworkWithCustomFeeToken() ? new TestOrbitCustomTokenL1__factory(parentSigner) : new TestCustomTokenL1__factory(parentSigner) const l1CustomToken = await l1CustomTokenFactory.deploy( @@ -165,7 +165,7 @@ const registerCustomToken = async ( await l1CustomToken.deployed() const amount = ethers.utils.parseEther('1') - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { const approvalTx = await ERC20__factory.connect( childChain.nativeToken!, parentSigner diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 87c77ce6a8..77782b424f 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -34,7 +34,7 @@ import { ChildToParentMessageStatus as L2ToL1MessageStatus } from '../../src/lib import { L2TransactionReceipt } from '../../src/lib/message/L2Transaction' import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' import { testSetup } from '../../scripts/testSetup' -import { isL2NetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' +import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' import { itOnlyWhenEth } from './custom-fee-token/mochaExtensions' @@ -316,7 +316,7 @@ describe('Ether', async () => { 'executed status' ).to.eq(L2ToL1MessageStatus.EXECUTED) - const finalRandomBalance = isL2NetworkWithCustomFeeToken() + const finalRandomBalance = isArbitrumNetworkWithCustomFeeToken() ? await ERC20__factory.connect( ethBridger.nativeToken!, parentSigner.provider! diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/l1ToL2MessageCreator.test.ts index 1691c539f1..3bf6454c79 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/l1ToL2MessageCreator.test.ts @@ -24,9 +24,9 @@ import { ParentToChildMessageCreator } from '../../src/lib/message/L1ToL2Message import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' import { - fundL1CustomFeeToken as fundParentChainCustomFeeToken, - approveL1CustomFeeToken as approveParentChainCustomFeeToken, - isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken, + fundParentCustomFeeToken, + approveParentCustomFeeToken, + isArbitrumNetworkWithCustomFeeToken, } from './custom-fee-token/customFeeTokenTestHelpers' describe('ParentToChildMessageCreator', () => { @@ -45,9 +45,9 @@ describe('ParentToChildMessageCreator', () => { // Funding parent chain wallet await fundParentSigner(parentSigner) - if (isChildChainWithCustomFeeToken()) { - await fundParentChainCustomFeeToken(parentSigner) - await approveParentChainCustomFeeToken(parentSigner) + if (isArbitrumNetworkWithCustomFeeToken()) { + await fundParentCustomFeeToken(parentSigner) + await approveParentCustomFeeToken(parentSigner) } // Instantiate the object @@ -107,9 +107,9 @@ describe('ParentToChildMessageCreator', () => { // Funding parent chain wallet await fundParentSigner(parentSigner) - if (isChildChainWithCustomFeeToken()) { - await fundParentChainCustomFeeToken(parentSigner) - await approveParentChainCustomFeeToken(parentSigner) + if (isArbitrumNetworkWithCustomFeeToken()) { + await fundParentCustomFeeToken(parentSigner) + await approveParentCustomFeeToken(parentSigner) } // Instantiate the object diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index d9b3bf1708..7898dd5a63 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -29,7 +29,7 @@ import { Inbox__factory } from '../../src/lib/abi/factories/Inbox__factory' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' const depositAmount = BigNumber.from(100) import { ERC20Inbox__factory } from '../../src/lib/abi/factories/ERC20Inbox__factory' -import { isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' +import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' describe('RevertData', () => { beforeEach('skipIfMainnet', async function () { @@ -74,7 +74,7 @@ describe('RevertData', () => { } = createRevertParams() try { - if (isChildChainWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { const inbox = ERC20Inbox__factory.connect( childChain.ethBridge.inbox, parentSigner @@ -162,7 +162,7 @@ describe('RevertData', () => { }) ).wait() - if (isChildChainWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { // approve the custom fee token await ( await erc20Bridger.approveGasToken({ @@ -216,7 +216,7 @@ describe('RevertData', () => { ) expect(parsed.data, 'data').to.eq(depositParams.retryableData.data) expect(parsed.deposit.toString(), 'deposit').to.eq( - isChildChainWithCustomFeeToken() + isArbitrumNetworkWithCustomFeeToken() ? depositParams.retryableData.deposit.toString() : depositParams.txRequest.value.toString() ) diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 3f74fe33e2..10e713a1fe 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -46,9 +46,9 @@ import { ArbRetryableTx__factory } from '../../src/lib/abi/factories/ArbRetryabl import { NodeInterface__factory } from '../../src/lib/abi/factories/NodeInterface__factory' import { isDefined } from '../../src/lib/utils/lib' import { - getL1CustomFeeTokenAllowance, - approveL1CustomFeeTokenForErc20Deposit, - isL2NetworkWithCustomFeeToken as isChildChainWithCustomFeeToken, + getParentCustomFeeTokenAllowance, + approveParentCustomFeeTokenForErc20Deposit, + isArbitrumNetworkWithCustomFeeToken, } from './custom-fee-token/customFeeTokenTestHelpers' import { itOnlyWhenCustomGasToken } from './custom-fee-token/mochaExtensions' @@ -92,7 +92,7 @@ describe('standard ERC20', () => { parentSigner.provider! ) - const initialAllowance = await getL1CustomFeeTokenAllowance( + const initialAllowance = await getParentCustomFeeTokenAllowance( await parentSigner.getAddress(), gatewayAddress ) @@ -108,7 +108,7 @@ describe('standard ERC20', () => { }) await tx.wait() - const finalAllowance = await getL1CustomFeeTokenAllowance( + const finalAllowance = await getParentCustomFeeTokenAllowance( await parentSigner.getAddress(), gatewayAddress ) @@ -121,8 +121,8 @@ describe('standard ERC20', () => { ) it('deposits erc20', async () => { - if (isChildChainWithCustomFeeToken()) { - await approveL1CustomFeeTokenForErc20Deposit( + if (isArbitrumNetworkWithCustomFeeToken()) { + await approveParentCustomFeeTokenForErc20Deposit( testState.parentSigner, testState.parentToken.address ) diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 98b5f6ca81..99a4e6c14f 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -32,7 +32,7 @@ import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' -import { isL2NetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' +import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' export const preFundAmount = parseEther('0.1') @@ -271,7 +271,7 @@ export const depositToken = async ({ expect(allowance.eq(Erc20Bridger.MAX_APPROVAL), 'set token allowance failed') .to.be.true - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { await ( await erc20Bridger.approveGasToken({ l1Signer: parentSigner, From 344d853e41a64ce891e43a86cc787082d7bab508 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:18:56 -0400 Subject: [PATCH 20/74] chore: rename deposit methods and associated types (#442) --- src/lib/assetBridger/erc20Bridger.ts | 70 +++++----- src/lib/assetBridger/ethBridger.ts | 120 +++++++++--------- src/lib/dataEntities/transactionRequest.ts | 48 +++---- src/lib/message/L1ToL2MessageCreator.ts | 8 +- src/lib/message/L1ToL2MessageGasEstimator.ts | 2 +- .../customFeeTokenEthBridger.test.ts | 10 +- .../customFeeTokenTestHelpers.ts | 6 +- tests/integration/eth.test.ts | 12 +- tests/integration/retryableData.test.ts | 6 +- tests/integration/standarderc20.test.ts | 2 +- tests/integration/testHelpers.ts | 10 +- 11 files changed, 150 insertions(+), 144 deletions(-) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index ffaef8569f..7fef48887b 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -61,11 +61,10 @@ import { L2TransactionReceipt, } from '../message/L2Transaction' import { - isL1ToL2TransactionRequest as isParentToChildTransactionRequest, - isL2ToL1TransactionRequest as isChildToParentTransactionRequest, - L1ToL2TransactionRequest, - L2ToL1TransactionRequest, - L1ToL2TransactionRequest as ParentToChildTransactionRequest, + isParentToChildTransactionRequest, + isChildToParentTransactionRequest, + ChildToParentTransactionRequest, + ParentToChildTransactionRequest, } from '../dataEntities/transactionRequest' import { defaultAbiCoder } from 'ethers/lib/utils' import { OmitTyped, RequiredPick } from '../utils/types' @@ -131,17 +130,18 @@ export interface Erc20WithdrawParams extends EthWithdrawParams { erc20ParentAddress: string } -export type ParentToChildTxReqAndSignerProvider = L1ToL2TransactionRequest & { - l1Signer: Signer - overrides?: Overrides -} +export type ParentToChildTxReqAndSignerProvider = + ParentToChildTransactionRequest & { + parentSigner: Signer + overrides?: Overrides + } -export type ChildToParentTxReqAndSigner = L2ToL1TransactionRequest & { - l2Signer: Signer +export type ChildToParentTxReqAndSigner = ChildToParentTransactionRequest & { + childSigner: Signer overrides?: Overrides } -type SignerTokenApproveParams = TokenApproveParams & { l1Signer: Signer } +type SignerTokenApproveParams = TokenApproveParams & { parentSigner: Signer } type ProviderTokenApproveParams = TokenApproveParams & { parentProvider: Provider } @@ -149,17 +149,17 @@ export type ApproveParamsOrTxRequest = | SignerTokenApproveParams | { txRequest: Required> - l1Signer: Signer + parentSigner: Signer overrides?: Overrides } /** - * The deposit request takes the same args as the actual deposit. Except we dont require a signer object + * The deposit request takes the same args as the actual deposit. Except we don't require a signer object * only a provider */ type DepositRequest = OmitTyped< Erc20DepositParams, - 'overrides' | 'l1Signer' + 'overrides' | 'parentSigner' > & { parentProvider: Provider /** @@ -178,7 +178,7 @@ type DefaultedDepositRequest = RequiredPick< */ export class Erc20Bridger extends AssetBridger< Erc20DepositParams | ParentToChildTxReqAndSignerProvider, - OmitTyped | L2ToL1TransactionRequest + OmitTyped | ChildToParentTransactionRequest > { public static MAX_APPROVAL: BigNumber = MaxUint256 public static MIN_CUSTOM_DEPOSIT_GAS_LIMIT = BigNumber.from(275000) @@ -262,18 +262,18 @@ export class Erc20Bridger extends AssetBridger< throw new Error('chain uses ETH as its native/gas token') } - await this.checkParentChain(params.l1Signer) + await this.checkParentChain(params.parentSigner) const approveGasTokenRequest = this.isApproveParams(params) ? await this.getApproveGasTokenRequest({ ...params, parentProvider: SignerProviderUtils.getProviderOrThrow( - params.l1Signer + params.parentSigner ), }) : params.txRequest - return params.l1Signer.sendTransaction({ + return params.parentSigner.sendTransaction({ ...approveGasTokenRequest, ...params.overrides, }) @@ -321,17 +321,17 @@ export class Erc20Bridger extends AssetBridger< public async approveToken( params: ApproveParamsOrTxRequest ): Promise { - await this.checkParentChain(params.l1Signer) + await this.checkParentChain(params.parentSigner) const approveRequest = this.isApproveParams(params) ? await this.getApproveTokenRequest({ ...params, parentProvider: SignerProviderUtils.getProviderOrThrow( - params.l1Signer + params.parentSigner ), }) : params.txRequest - return await params.l1Signer.sendTransaction({ + return await params.parentSigner.sendTransaction({ ...approveRequest, ...params.overrides, }) @@ -734,7 +734,7 @@ export class Erc20Bridger extends AssetBridger< public async deposit( params: Erc20DepositParams | ParentToChildTxReqAndSignerProvider ): Promise { - await this.checkParentChain(params.l1Signer) + await this.checkParentChain(params.parentSigner) // Although the types prevent should alert callers that value is not // a valid override, it is possible that they pass it in anyway as it's a common override @@ -746,7 +746,7 @@ export class Erc20Bridger extends AssetBridger< } const parentProvider = SignerProviderUtils.getProviderOrThrow( - params.l1Signer + params.parentSigner ) const tokenDeposit = isParentToChildTransactionRequest(params) @@ -754,10 +754,10 @@ export class Erc20Bridger extends AssetBridger< : await this.getDepositRequest({ ...params, parentProvider, - from: await params.l1Signer.getAddress(), + from: await params.parentSigner.getAddress(), }) - const tx = await params.l1Signer.sendTransaction({ + const tx = await params.parentSigner.sendTransaction({ ...tokenDeposit.txRequest, ...params.overrides, }) @@ -772,7 +772,7 @@ export class Erc20Bridger extends AssetBridger< */ public async getWithdrawalRequest( params: Erc20WithdrawParams - ): Promise { + ): Promise { const to = params.destinationAddress const routerInterface = L2GatewayRouter__factory.createInterface() @@ -801,7 +801,7 @@ export class Erc20Bridger extends AssetBridger< from: params.from, }, // todo: do proper estimation - estimateL1GasLimit: async (parentProvider: Provider) => { + estimateParentGasLimit: async (parentProvider: Provider) => { if (await isArbitrumChain(parentProvider)) { // values for L3 are dependent on the L1 base fee, so hardcoding can never be accurate // however, this is only an estimate used for display, so should be good enough @@ -835,24 +835,24 @@ export class Erc20Bridger extends AssetBridger< */ public async withdraw( params: - | (OmitTyped & { l2Signer: Signer }) + | (OmitTyped & { childSigner: Signer }) | ChildToParentTxReqAndSigner ): Promise { - if (!SignerProviderUtils.signerHasProvider(params.l2Signer)) { - throw new MissingProviderArbSdkError('l2Signer') + if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { + throw new MissingProviderArbSdkError('childSigner') } - await this.checkChildChain(params.l2Signer) + await this.checkChildChain(params.childSigner) const withdrawalRequest = isChildToParentTransactionRequest< - OmitTyped & { l2Signer: Signer } + OmitTyped & { childSigner: Signer } >(params) ? params : await this.getWithdrawalRequest({ ...params, - from: await params.l2Signer.getAddress(), + from: await params.childSigner.getAddress(), }) - const tx = await params.l2Signer.sendTransaction({ + const tx = await params.childSigner.sendTransaction({ ...withdrawalRequest.txRequest, ...params.overrides, }) diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index dc37159eb0..9b3f049df7 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -33,15 +33,15 @@ import { } from '../message/L1Transaction' import { L2ContractTransaction, - L2TransactionReceipt, + ChildChainTransactionReceipt, } from '../message/L2Transaction' import { L1ToL2MessageCreator } from '../message/L1ToL2MessageCreator' import { GasOverrides } from '../message/L1ToL2MessageGasEstimator' import { - isL1ToL2TransactionRequest, - isL2ToL1TransactionRequest, - L1ToL2TransactionRequest, - L2ToL1TransactionRequest, + isParentToChildTransactionRequest, + isChildToParentTransactionRequest, + ParentToChildTransactionRequest, + ChildToParentTransactionRequest, } from '../dataEntities/transactionRequest' import { OmitTyped } from '../utils/types' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' @@ -77,7 +77,7 @@ export type ApproveGasTokenParamsOrTxRequest = | ApproveGasTokenTxRequest type WithL1Signer = T & { - l1Signer: Signer + parentSigner: Signer } export interface EthWithdrawParams { @@ -86,7 +86,7 @@ export interface EthWithdrawParams { */ amount: BigNumber /** - * The L1 address to receive the value. + * The parent chain address to receive the value. */ destinationAddress: string /** @@ -101,9 +101,9 @@ export interface EthWithdrawParams { export type EthDepositParams = { /** - * The L1 provider or signer + * Parent chain provider or signer */ - l1Signer: Signer + parentSigner: Signer /** * The amount of ETH or tokens to be deposited */ @@ -116,11 +116,11 @@ export type EthDepositParams = { export type EthDepositToParams = EthDepositParams & { /** - * An L2 provider + * Child chain provider */ - l2Provider: Provider + childProvider: Provider /** - * L2 address of the entity receiving the funds + * Child chain address of the entity receiving the funds */ destinationAddress: string /** @@ -129,29 +129,29 @@ export type EthDepositToParams = EthDepositParams & { retryableGasOverrides?: GasOverrides } -export type L1ToL2TxReqAndSigner = L1ToL2TransactionRequest & { - l1Signer: Signer +export type ParentToChildTxReqAndSigner = ParentToChildTransactionRequest & { + parentSigner: Signer overrides?: Overrides } -export type L2ToL1TxReqAndSigner = L2ToL1TransactionRequest & { - l2Signer: Signer +export type ChildToParentTxReqAndSigner = ChildToParentTransactionRequest & { + childSigner: Signer overrides?: Overrides } type EthDepositRequestParams = OmitTyped< EthDepositParams, - 'overrides' | 'l1Signer' + 'overrides' | 'parentSigner' > & { from: string } type EthDepositToRequestParams = OmitTyped< EthDepositToParams, - 'overrides' | 'l1Signer' + 'overrides' | 'parentSigner' > & { /** - * The L1 provider + * Parent chain provider */ - l1Provider: Provider + parentProvider: Provider /** * Address that is depositing the ETH */ @@ -159,19 +159,19 @@ type EthDepositToRequestParams = OmitTyped< } /** - * Bridger for moving ETH back and forth between L1 to L2 + * Bridger for moving ETH back and forth between parent and child chain */ export class EthBridger extends AssetBridger< - EthDepositParams | EthDepositToParams | L1ToL2TxReqAndSigner, - EthWithdrawParams | L2ToL1TxReqAndSigner + EthDepositParams | EthDepositToParams | ParentToChildTxReqAndSigner, + EthWithdrawParams | ChildToParentTxReqAndSigner > { /** - * Instantiates a new EthBridger from an L2 Provider - * @param l2Provider + * Instantiates a new EthBridger from a child chain Provider + * @param childProvider * @returns */ - public static async fromProvider(l2Provider: Provider) { - return new EthBridger(await getChildChain(l2Provider)) + public static async fromProvider(childProvider: Provider) { + return new EthBridger(await getChildChain(childProvider)) } /** @@ -227,7 +227,7 @@ export class EthBridger extends AssetBridger< ? this.getApproveGasTokenRequest(params) : params.txRequest - return params.l1Signer.sendTransaction({ + return params.parentSigner.sendTransaction({ ...approveGasTokenRequest, ...params.overrides, }) @@ -267,7 +267,7 @@ export class EthBridger extends AssetBridger< */ public async getDepositRequest( params: EthDepositRequestParams - ): Promise> { + ): Promise> { return { txRequest: { to: this.childChain.ethBridge.inbox, @@ -280,23 +280,23 @@ export class EthBridger extends AssetBridger< } /** - * Deposit ETH from L1 onto L2 + * Deposit ETH from Parent onto Child chain * @param params * @returns */ public async deposit( - params: EthDepositParams | L1ToL2TxReqAndSigner + params: EthDepositParams | ParentToChildTxReqAndSigner ): Promise { - await this.checkParentChain(params.l1Signer) + await this.checkParentChain(params.parentSigner) - const ethDeposit = isL1ToL2TransactionRequest(params) + const ethDeposit = isParentToChildTransactionRequest(params) ? params : await this.getDepositRequest({ ...params, - from: await params.l1Signer.getAddress(), + from: await params.parentSigner.getAddress(), }) - const tx = await params.l1Signer.sendTransaction({ + const tx = await params.parentSigner.sendTransaction({ ...ethDeposit.txRequest, ...params.overrides, }) @@ -305,13 +305,13 @@ export class EthBridger extends AssetBridger< } /** - * Get a transaction request for an ETH deposit to a different L2 address using Retryables + * Get a transaction request for an ETH deposit to a different child chain address using Retryables * @param params * @returns */ public async getDepositToRequest( params: EthDepositToRequestParams - ): Promise { + ): Promise { const requestParams = { ...params, to: params.destinationAddress, @@ -325,34 +325,34 @@ export class EthBridger extends AssetBridger< return L1ToL2MessageCreator.getTicketCreationRequest( requestParams, - params.l1Provider, - params.l2Provider, + params.parentProvider, + params.childProvider, gasOverrides ) } /** - * Deposit ETH from L1 onto a different L2 address + * Deposit ETH from parent chain onto a different child chain address * @param params * @returns */ public async depositTo( params: | EthDepositToParams - | (L1ToL2TxReqAndSigner & { l2Provider: Provider }) + | (ParentToChildTxReqAndSigner & { childProvider: Provider }) ): Promise { - await this.checkParentChain(params.l1Signer) - await this.checkChildChain(params.l2Provider) + await this.checkParentChain(params.parentSigner) + await this.checkChildChain(params.childProvider) - const retryableTicketRequest = isL1ToL2TransactionRequest(params) + const retryableTicketRequest = isParentToChildTransactionRequest(params) ? params : await this.getDepositToRequest({ ...params, - from: await params.l1Signer.getAddress(), - l1Provider: params.l1Signer.provider!, + from: await params.parentSigner.getAddress(), + parentProvider: params.parentSigner.provider!, }) - const tx = await params.l1Signer.sendTransaction({ + const tx = await params.parentSigner.sendTransaction({ ...retryableTicketRequest.txRequest, ...params.overrides, }) @@ -367,7 +367,7 @@ export class EthBridger extends AssetBridger< */ public async getWithdrawalRequest( params: EthWithdrawParams - ): Promise { + ): Promise { const iArbSys = ArbSys__factory.createInterface() const functionData = iArbSys.encodeFunctionData('withdrawEth', [ params.destinationAddress, @@ -381,8 +381,8 @@ export class EthBridger extends AssetBridger< from: params.from, }, // todo: do proper estimation - estimateL1GasLimit: async (l1Provider: Provider) => { - if (await isArbitrumChain(l1Provider)) { + estimateParentGasLimit: async (parentProvider: Provider) => { + if (await isArbitrumChain(parentProvider)) { // values for L3 are dependent on the L1 base fee, so hardcoding can never be accurate // however, this is only an estimate used for display, so should be good enough // @@ -397,28 +397,30 @@ export class EthBridger extends AssetBridger< } /** - * Withdraw ETH from L2 onto L1 + * Withdraw ETH from child chain onto parent chain * @param params * @returns */ public async withdraw( - params: (EthWithdrawParams & { l2Signer: Signer }) | L2ToL1TxReqAndSigner + params: + | (EthWithdrawParams & { childSigner: Signer }) + | ChildToParentTxReqAndSigner ): Promise { - if (!SignerProviderUtils.signerHasProvider(params.l2Signer)) { - throw new MissingProviderArbSdkError('l2Signer') + if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { + throw new MissingProviderArbSdkError('childSigner') } - await this.checkChildChain(params.l2Signer) + await this.checkChildChain(params.childSigner) - const request = isL2ToL1TransactionRequest< - EthWithdrawParams & { l2Signer: Signer } + const request = isChildToParentTransactionRequest< + EthWithdrawParams & { childSigner: Signer } >(params) ? params : await this.getWithdrawalRequest(params) - const tx = await params.l2Signer.sendTransaction({ + const tx = await params.childSigner.sendTransaction({ ...request.txRequest, ...params.overrides, }) - return L2TransactionReceipt.monkeyPatchWait(tx) + return ChildChainTransactionReceipt.monkeyPatchWait(tx) } } diff --git a/src/lib/dataEntities/transactionRequest.ts b/src/lib/dataEntities/transactionRequest.ts index 67803ddf67..2a051b26f1 100644 --- a/src/lib/dataEntities/transactionRequest.ts +++ b/src/lib/dataEntities/transactionRequest.ts @@ -1,27 +1,27 @@ import { TransactionRequest, Provider } from '@ethersproject/providers' import { BigNumber } from 'ethers' import { - L1ToL2MessageGasParams, - L1ToL2MessageParams, + ParentToChildMessageGasParams, + ParentToChildMessageParams, } from '../message/L1ToL2MessageCreator' import { isDefined } from '../utils/lib' /** * A transaction request for a transaction that will trigger some sort of - * execution on the L2 + * execution on the child chain */ -export interface L1ToL2TransactionRequest { +export interface ParentToChildTransactionRequest { /** - * Core fields needed to form the L1 component of the transaction request + * Core fields needed to form the parent component of the transaction request */ txRequest: Required< Pick > /** * Information about the retryable ticket, and it's subsequent execution, that - * will occur on L2 + * will occur on the child chain */ - retryableData: L1ToL2MessageParams & L1ToL2MessageGasParams + retryableData: ParentToChildMessageParams & ParentToChildMessageGasParams /** * If this request were sent now, would it have enough margin to reliably succeed */ @@ -29,44 +29,48 @@ export interface L1ToL2TransactionRequest { } /** - * A transaction request for a transaction that will trigger an L2 to L1 message + * A transaction request for a transaction that will trigger a child to parent message */ -export interface L2ToL1TransactionRequest { +export interface ChildToParentTransactionRequest { txRequest: Required< Pick > /** - * Estimate the gas limit required to execute the withdrawal on L1. + * Estimate the gas limit required to execute the withdrawal on the parent chain. * Note that this is only a rough estimate as it may not be possible to know * the exact size of the proof straight away, however the real value should be * within a few thousand gas of this estimate. */ - estimateL1GasLimit: (l1Provider: Provider) => Promise + estimateParentGasLimit: (l1Provider: Provider) => Promise } /** - * Ensure the T is not of TransactionRequest type by ensure it doesnt have a specific TransactionRequest property + * Ensure the T is not of TransactionRequest type by ensure it doesn't have a specific TransactionRequest property */ type IsNotTransactionRequest = T extends { txRequest: any } ? never : T /** - * Check if an object is of L1ToL2TransactionRequest type + * Check if an object is of ParentToChildTransactionRequest type * @param possibleRequest * @returns */ -export const isL1ToL2TransactionRequest = ( - possibleRequest: IsNotTransactionRequest | L1ToL2TransactionRequest -): possibleRequest is L1ToL2TransactionRequest => { - return isDefined((possibleRequest as L1ToL2TransactionRequest).txRequest) +export const isParentToChildTransactionRequest = ( + possibleRequest: IsNotTransactionRequest | ParentToChildTransactionRequest +): possibleRequest is ParentToChildTransactionRequest => { + return isDefined( + (possibleRequest as ParentToChildTransactionRequest).txRequest + ) } /** - * Check if an object is of L2ToL1TransactionRequest type + * Check if an object is of ChildToParentTransactionRequest type * @param possibleRequest * @returns */ -export const isL2ToL1TransactionRequest = ( - possibleRequest: IsNotTransactionRequest | L2ToL1TransactionRequest -): possibleRequest is L2ToL1TransactionRequest => { - return (possibleRequest as L2ToL1TransactionRequest).txRequest != undefined +export const isChildToParentTransactionRequest = ( + possibleRequest: IsNotTransactionRequest | ChildToParentTransactionRequest +): possibleRequest is ChildToParentTransactionRequest => { + return ( + (possibleRequest as ChildToParentTransactionRequest).txRequest != undefined + ) } diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/L1ToL2MessageCreator.ts index 0b908e7cc1..d41d7c4cff 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/L1ToL2MessageCreator.ts @@ -18,8 +18,8 @@ import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' import { getBaseFee } from '../utils/lib' import { - isL1ToL2TransactionRequest as isParentToChildTransactionRequest, - L1ToL2TransactionRequest as ParentToChildTransactionRequest, + isParentToChildTransactionRequest, + ParentToChildTransactionRequest, } from '../dataEntities/transactionRequest' import { RetryableData } from '../dataEntities/retryableData' import { OmitTyped, PartialPick } from '../utils/types' @@ -203,7 +203,9 @@ export class ParentToChildMessageCreator { public async createRetryableTicket( params: | (ParentToChildMessageParams & { overrides?: PayableOverrides }) - | (ParentToChildTransactionRequest & { overrides?: PayableOverrides }), + | (ParentToChildTransactionRequest & { + overrides?: PayableOverrides + }), childProvider: Provider, options?: GasOverrides ): Promise { diff --git a/src/lib/message/L1ToL2MessageGasEstimator.ts b/src/lib/message/L1ToL2MessageGasEstimator.ts index c9ac4f778c..53fabac66a 100644 --- a/src/lib/message/L1ToL2MessageGasEstimator.ts +++ b/src/lib/message/L1ToL2MessageGasEstimator.ts @@ -10,7 +10,7 @@ import { RetryableData, RetryableDataTools, } from '../dataEntities/retryableData' -import { L1ToL2TransactionRequest as ParentToChildTransactionRequest } from '../dataEntities/transactionRequest' +import { ParentToChildTransactionRequest } from '../dataEntities/transactionRequest' import { getBaseFee, isDefined } from '../utils/lib' import { OmitTyped } from '../utils/types' import { diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 8c920cd16b..b3a37ae944 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -59,7 +59,7 @@ describeOnlyWhenCustomGasToken( const approvalTx = await ethBridger.approveGasToken({ amount, - l1Signer: parentSigner, + parentSigner, }) await approvalTx.wait() @@ -83,7 +83,7 @@ describeOnlyWhenCustomGasToken( const approvalTx = await ethBridger.approveGasToken({ txRequest: ethBridger.getApproveGasTokenRequest(), - l1Signer: parentSigner, + parentSigner, }) await approvalTx.wait() @@ -119,7 +119,7 @@ describeOnlyWhenCustomGasToken( // perform the deposit const depositTx = await ethBridger.deposit({ amount, - l1Signer: parentSigner, + parentSigner, }) const depositTxReceipt = await depositTx.wait() expect(depositTxReceipt.status).to.equal(1, 'deposit tx failed') @@ -187,13 +187,13 @@ describeOnlyWhenCustomGasToken( from, }) - const l1GasEstimate = await withdrawalTxRequest.estimateL1GasLimit( + const l1GasEstimate = await withdrawalTxRequest.estimateParentGasLimit( parentProvider ) const withdrawalTx = await ethBridger.withdraw({ amount, - l2Signer: childSigner, + childSigner, destinationAddress, from, }) diff --git a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts index fd157bd788..89abe126fb 100644 --- a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts +++ b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts @@ -61,9 +61,7 @@ export async function fundParentCustomFeeToken( export async function approveParentCustomFeeToken(parentSigner: Signer) { const ethBridger = await EthBridger.fromProvider(arbProvider()) - const tx = await ethBridger.approveGasToken({ - l1Signer: parentSigner, - }) + const tx = await ethBridger.approveGasToken({ parentSigner }) await tx.wait() } @@ -87,7 +85,7 @@ export async function approveParentCustomFeeTokenForErc20Deposit( const tx = await erc20Bridger.approveGasToken({ erc20ParentAddress: erc20ParentAddress, - l1Signer: parentSigner, + parentSigner, }) await tx.wait() } diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 77782b424f..523529d578 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -88,7 +88,7 @@ describe('Ether', async () => { const { ethBridger, parentSigner } = await testSetup() try { - await ethBridger.approveGasToken({ l1Signer: parentSigner }) + await ethBridger.approveGasToken({ parentSigner }) expect.fail(`"EthBridger.approveGasToken" should have thrown`) } catch (error: any) { expect(error.message).to.equal('chain uses ETH as its native/gas token') @@ -108,7 +108,7 @@ describe('Ether', async () => { const ethToDeposit = parseEther('0.0002') const res = await ethBridger.deposit({ amount: ethToDeposit, - l1Signer: parentSigner, + parentSigner: parentSigner, }) const rec = await res.wait() @@ -158,9 +158,9 @@ describe('Ether', async () => { const ethToDeposit = parseEther('0.0002') const res = await ethBridger.depositTo({ amount: ethToDeposit, - l1Signer: parentSigner, + parentSigner: parentSigner, destinationAddress: destWallet.address, - l2Provider: childSigner.provider!, + childProvider: childSigner.provider!, }) const rec = await res.wait() @@ -232,13 +232,13 @@ describe('Ether', async () => { from: await childSigner.getAddress(), }) - const l1GasEstimate = await request.estimateL1GasLimit( + const l1GasEstimate = await request.estimateParentGasLimit( parentSigner.provider! ) const withdrawEthRes = await ethBridger.withdraw({ amount: ethToWithdraw, - l2Signer: childSigner, + childSigner: childSigner, destinationAddress: randomAddress, from: await childSigner.getAddress(), }) diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index 7898dd5a63..f2939e91c9 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -158,7 +158,7 @@ describe('RevertData', () => { await ( await erc20Bridger.approveToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: parentSigner, + parentSigner, }) ).wait() @@ -167,7 +167,7 @@ describe('RevertData', () => { await ( await erc20Bridger.approveGasToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: parentSigner, + parentSigner, }) ).wait() } @@ -202,7 +202,7 @@ describe('RevertData', () => { try { await erc20Bridger.deposit({ ...erc20Params, - l1Signer: parentSigner, + parentSigner, childProvider: childSigner.provider!, }) assert.fail('Expected estimateGas to fail') diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 10e713a1fe..89ecf6e63e 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -103,7 +103,7 @@ describe('standard ERC20', () => { ) const tx = await erc20Bridger.approveGasToken({ - l1Signer: parentSigner, + parentSigner, erc20ParentAddress: testState.parentToken.address, }) await tx.wait() diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 99a4e6c14f..61c9bb6ede 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -89,7 +89,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { destinationAddress: await params.childSigner.getAddress(), from: await params.childSigner.getAddress(), }) - const parentChainGasEstimate = await withdrawalParams.estimateL1GasLimit( + const parentChainGasEstimate = await withdrawalParams.estimateParentGasLimit( params.parentSigner.provider! ) @@ -97,7 +97,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { destinationAddress: await params.childSigner.getAddress(), amount: params.amount, erc20ParentAddress: params.parentChainToken.address, - l2Signer: params.childSigner, + childSigner: params.childSigner, }) const withdrawRec = await withdrawRes.wait() expect(withdrawRec.status).to.equal(1, 'initiate token withdraw txn failed') @@ -250,7 +250,7 @@ export const depositToken = async ({ await ( await erc20Bridger.approveToken({ erc20ParentAddress: l1TokenAddress, - l1Signer: parentSigner, + parentSigner, }) ).wait() @@ -274,7 +274,7 @@ export const depositToken = async ({ if (isArbitrumNetworkWithCustomFeeToken()) { await ( await erc20Bridger.approveGasToken({ - l1Signer: parentSigner, + parentSigner, erc20ParentAddress: l1TokenAddress, }) ).wait() @@ -304,7 +304,7 @@ export const depositToken = async ({ ) const depositRes = await erc20Bridger.deposit({ - l1Signer: parentSigner, + parentSigner, childProvider: childSigner.provider!, erc20ParentAddress: l1TokenAddress, amount: depositAmount, From 13ad8f13cf9fd1b289859a223195c164ad616655 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:39:02 -0400 Subject: [PATCH 21/74] chore: rename L1/L2 files to parent/child (#443) --- scripts/cancelRetryable.ts | 2 +- scripts/lib.ts | 4 ++-- scripts/redeemRetryable.ts | 2 +- src/index.ts | 10 +++++----- src/lib/assetBridger/assetBridger.ts | 4 ++-- src/lib/assetBridger/erc20Bridger.ts | 8 ++++---- src/lib/assetBridger/ethBridger.ts | 8 ++++---- src/lib/dataEntities/transactionRequest.ts | 2 +- .../{L2ToL1Message.ts => ChildToParentMessage.ts} | 4 ++-- ...essageClassic.ts => ChildToParentMessageClassic.ts} | 0 ...oL1MessageNitro.ts => ChildToParentMessageNitro.ts} | 0 .../message/{L2Transaction.ts => ChildTransaction.ts} | 2 +- .../{L1ToL2Message.ts => ParentToChildMessage.ts} | 2 +- ...essageCreator.ts => ParentToChildMessageCreator.ts} | 4 ++-- ...stimator.ts => ParentToChildMessageGasEstimator.ts} | 2 +- .../message/{L1Transaction.ts => ParentTransaction.ts} | 2 +- ...Receipt.test.ts => childTransactionReceipt.test.ts} | 0 .../custom-fee-token/customFeeTokenEthBridger.test.ts | 2 +- tests/integration/eth.test.ts | 6 +++--- ...tor.test.ts => parentToChildMessageCreator.test.ts} | 4 ++-- ...est.ts => parentToChildMessageGasEstimator.test.ts} | 2 +- tests/integration/retryableData.test.ts | 2 +- .../{sendL2msg.test.ts => sendChildmsg.test.ts} | 0 tests/integration/testHelpers.ts | 4 ++-- ...Block.test.ts => childBlocksForParentBlock.test.ts} | 0 ...ents.test.ts => childToParentMessageEvents.test.ts} | 2 +- ...ents.test.ts => parentToChildMessageEvents.test.ts} | 2 +- 27 files changed, 40 insertions(+), 40 deletions(-) rename src/lib/message/{L2ToL1Message.ts => ChildToParentMessage.ts} (99%) rename src/lib/message/{L2ToL1MessageClassic.ts => ChildToParentMessageClassic.ts} (100%) rename src/lib/message/{L2ToL1MessageNitro.ts => ChildToParentMessageNitro.ts} (100%) rename src/lib/message/{L2Transaction.ts => ChildTransaction.ts} (99%) rename src/lib/message/{L1ToL2Message.ts => ParentToChildMessage.ts} (99%) rename src/lib/message/{L1ToL2MessageCreator.ts => ParentToChildMessageCreator.ts} (98%) rename src/lib/message/{L1ToL2MessageGasEstimator.ts => ParentToChildMessageGasEstimator.ts} (99%) rename src/lib/message/{L1Transaction.ts => ParentTransaction.ts} (99%) rename tests/integration/{l2TransactionReceipt.test.ts => childTransactionReceipt.test.ts} (100%) rename tests/integration/{l1ToL2MessageCreator.test.ts => parentToChildMessageCreator.test.ts} (99%) rename tests/integration/{L1ToL2MessageGasEstimator.test.ts => parentToChildMessageGasEstimator.test.ts} (98%) rename tests/integration/{sendL2msg.test.ts => sendChildmsg.test.ts} (100%) rename tests/unit/{l2BlocksForL1Block.test.ts => childBlocksForParentBlock.test.ts} (100%) rename tests/unit/{l2toL1MessageEvents.test.ts => childToParentMessageEvents.test.ts} (98%) rename tests/unit/{l1toL2MessageEvents.test.ts => parentToChildMessageEvents.test.ts} (99%) diff --git a/scripts/cancelRetryable.ts b/scripts/cancelRetryable.ts index b4623c1aab..939a341f35 100644 --- a/scripts/cancelRetryable.ts +++ b/scripts/cancelRetryable.ts @@ -20,7 +20,7 @@ import { ContractReceipt } from '@ethersproject/contracts' import { instantiateBridge } from './instantiate_bridge' import args from './getCLargs' -import { L1TransactionReceipt } from '../src/lib/message/L1Transaction' +import { L1TransactionReceipt } from '../src/lib/message/ParentTransaction' if (!args.txid) { throw new Error('Include txid (--txid 0xmytxid)') diff --git a/scripts/lib.ts b/scripts/lib.ts index ad45cc2dbb..6870536b1d 100644 --- a/scripts/lib.ts +++ b/scripts/lib.ts @@ -19,8 +19,8 @@ import { ContractReceipt } from '@ethersproject/contracts' import { ERC20__factory } from '../src/lib/abi/factories/ERC20__factory' -import { L1ToL2MessageStatus } from '../src/lib/message/L1ToL2Message' -import { L1TransactionReceipt } from '../src/lib/message/L1Transaction' +import { L1ToL2MessageStatus } from '../src/lib/message/ParentToChildMessage' +import { L1TransactionReceipt } from '../src/lib/message/ParentTransaction' import { testSetup } from '../scripts/testSetup' export const setStandardGateWays = async ( diff --git a/scripts/redeemRetryable.ts b/scripts/redeemRetryable.ts index 46d526c327..b79cd89f0e 100644 --- a/scripts/redeemRetryable.ts +++ b/scripts/redeemRetryable.ts @@ -20,7 +20,7 @@ import { ContractReceipt } from '@ethersproject/contracts' import { testSetup } from '../scripts/testSetup' import args from './getCLargs' -import { L1TransactionReceipt } from '../src/lib/message/L1Transaction' +import { L1TransactionReceipt } from '../src/lib/message/ParentTransaction' import { L1ToL2MessageStatus, L1ToL2MessageWriter } from '../src' import { fundL2 } from '../integration_test/testHelpers' diff --git a/src/index.ts b/src/index.ts index 9a7e22c9a9..b0424cbdaf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,16 +21,16 @@ export { Erc20Bridger } from './lib/assetBridger/erc20Bridger' export { L2TransactionReceipt, L2ContractTransaction, -} from './lib/message/L2Transaction' +} from './lib/message/ChildTransaction' export { ChildToParentMessage as L2ToL1Message, ChildToParentMessageWriter as L2ToL1MessageWriter, ChildToParentMessageReader as L2ToL1MessageReader, -} from './lib/message/L2ToL1Message' +} from './lib/message/ChildToParentMessage' export { L1ContractTransaction, L1TransactionReceipt, -} from './lib/message/L1Transaction' +} from './lib/message/ParentTransaction' export { ParentToChildMessageStatus as L1ToL2MessageStatus, EthDepositStatus, @@ -38,8 +38,8 @@ export { ParentToChildMessageReader as L1ToL2MessageReader, ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic, ParentToChildMessageWriter as L1ToL2MessageWriter, -} from './lib/message/L1ToL2Message' -export { L1ToL2MessageGasEstimator } from './lib/message/L1ToL2MessageGasEstimator' +} from './lib/message/ParentToChildMessage' +export { L1ToL2MessageGasEstimator } from './lib/message/ParentToChildMessageGasEstimator' export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index e8f28bd7ea..8ee476c649 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -18,8 +18,8 @@ import { constants } from 'ethers' -import { L1ContractTransaction } from '../message/L1Transaction' -import { L2ContractTransaction } from '../message/L2Transaction' +import { L1ContractTransaction } from '../message/ParentTransaction' +import { L2ContractTransaction } from '../message/ChildTransaction' import { L1Network, diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 7fef48887b..2e5034f6ba 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -43,7 +43,7 @@ import { GatewaySetEvent } from '../abi/L1GatewayRouter' import { GasOverrides, L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, -} from '../message/L1ToL2MessageGasEstimator' +} from '../message/ParentToChildMessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { ArbitrumNetwork, getArbitrumNetwork } from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' @@ -55,11 +55,11 @@ import { L1ContractCallTransaction, L1ContractTransaction, L1TransactionReceipt, -} from '../message/L1Transaction' +} from '../message/ParentTransaction' import { L2ContractTransaction, L2TransactionReceipt, -} from '../message/L2Transaction' +} from '../message/ChildTransaction' import { isParentToChildTransactionRequest, isChildToParentTransactionRequest, @@ -70,7 +70,7 @@ import { defaultAbiCoder } from 'ethers/lib/utils' import { OmitTyped, RequiredPick } from '../utils/types' import { RetryableDataTools } from '../dataEntities/retryableData' import { EventArgs } from '../dataEntities/event' -import { ParentToChildMessageGasParams } from '../message/L1ToL2MessageCreator' +import { ParentToChildMessageGasParams } from '../message/ParentToChildMessageCreator' import { isArbitrumChain } from '../utils/lib' export interface TokenApproveParams { diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 9b3f049df7..01066cc0dc 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -30,13 +30,13 @@ import { L1EthDepositTransaction, L1ContractCallTransaction, L1TransactionReceipt, -} from '../message/L1Transaction' +} from '../message/ParentTransaction' import { L2ContractTransaction, ChildChainTransactionReceipt, -} from '../message/L2Transaction' -import { L1ToL2MessageCreator } from '../message/L1ToL2MessageCreator' -import { GasOverrides } from '../message/L1ToL2MessageGasEstimator' +} from '../message/ChildTransaction' +import { L1ToL2MessageCreator } from '../message/ParentToChildMessageCreator' +import { GasOverrides } from '../message/ParentToChildMessageGasEstimator' import { isParentToChildTransactionRequest, isChildToParentTransactionRequest, diff --git a/src/lib/dataEntities/transactionRequest.ts b/src/lib/dataEntities/transactionRequest.ts index 2a051b26f1..e0ddc5c424 100644 --- a/src/lib/dataEntities/transactionRequest.ts +++ b/src/lib/dataEntities/transactionRequest.ts @@ -3,7 +3,7 @@ import { BigNumber } from 'ethers' import { ParentToChildMessageGasParams, ParentToChildMessageParams, -} from '../message/L1ToL2MessageCreator' +} from '../message/ParentToChildMessageCreator' import { isDefined } from '../utils/lib' /** diff --git a/src/lib/message/L2ToL1Message.ts b/src/lib/message/ChildToParentMessage.ts similarity index 99% rename from src/lib/message/L2ToL1Message.ts rename to src/lib/message/ChildToParentMessage.ts index 4b68240a4f..eb5fd4e48e 100644 --- a/src/lib/message/L2ToL1Message.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -26,8 +26,8 @@ import { SignerProviderUtils, SignerOrProvider, } from '../dataEntities/signerOrProvider' -import * as classic from './L2ToL1MessageClassic' -import * as nitro from './L2ToL1MessageNitro' +import * as classic from './ChildToParentMessageClassic' +import * as nitro from './ChildToParentMessageNitro' import { L2ToL1TransactionEvent as ClassicChildToParentTransactionEvent, L2ToL1TxEvent as NitroChildToParentTransactionEvent, diff --git a/src/lib/message/L2ToL1MessageClassic.ts b/src/lib/message/ChildToParentMessageClassic.ts similarity index 100% rename from src/lib/message/L2ToL1MessageClassic.ts rename to src/lib/message/ChildToParentMessageClassic.ts diff --git a/src/lib/message/L2ToL1MessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts similarity index 100% rename from src/lib/message/L2ToL1MessageNitro.ts rename to src/lib/message/ChildToParentMessageNitro.ts diff --git a/src/lib/message/L2Transaction.ts b/src/lib/message/ChildTransaction.ts similarity index 99% rename from src/lib/message/L2Transaction.ts rename to src/lib/message/ChildTransaction.ts index fc39fdc1eb..4649385ebe 100644 --- a/src/lib/message/L2Transaction.ts +++ b/src/lib/message/ChildTransaction.ts @@ -30,7 +30,7 @@ import { ChildToParentMessage, ChildToParentMessageWriter, ChildToParentTransactionEvent, -} from './L2ToL1Message' +} from './ChildToParentMessage' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ArbRetryableTx__factory } from '../abi/factories/ArbRetryableTx__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' diff --git a/src/lib/message/L1ToL2Message.ts b/src/lib/message/ParentToChildMessage.ts similarity index 99% rename from src/lib/message/L1ToL2Message.ts rename to src/lib/message/ParentToChildMessage.ts index 5efcdb02f9..2335822083 100644 --- a/src/lib/message/L1ToL2Message.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -36,7 +36,7 @@ import { ethers, Overrides } from 'ethers' import { L2TransactionReceipt as ChainTransactionReceipt, RedeemTransaction, -} from './L2Transaction' +} from './ChildTransaction' import { getChildChain } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' diff --git a/src/lib/message/L1ToL2MessageCreator.ts b/src/lib/message/ParentToChildMessageCreator.ts similarity index 98% rename from src/lib/message/L1ToL2MessageCreator.ts rename to src/lib/message/ParentToChildMessageCreator.ts index d41d7c4cff..dac05152ad 100644 --- a/src/lib/message/L1ToL2MessageCreator.ts +++ b/src/lib/message/ParentToChildMessageCreator.ts @@ -5,11 +5,11 @@ import { Provider } from '@ethersproject/abstract-provider' import { GasOverrides, L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, -} from './L1ToL2MessageGasEstimator' +} from './ParentToChildMessageGasEstimator' import { L1ContractTransaction as ParentChainContractTransaction, L1TransactionReceipt as ParentChainTransactionReceipt, -} from './L1Transaction' +} from './ParentTransaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' import { getChildChain } from '../dataEntities/networks' import { ERC20Inbox__factory } from '../abi/factories/ERC20Inbox__factory' diff --git a/src/lib/message/L1ToL2MessageGasEstimator.ts b/src/lib/message/ParentToChildMessageGasEstimator.ts similarity index 99% rename from src/lib/message/L1ToL2MessageGasEstimator.ts rename to src/lib/message/ParentToChildMessageGasEstimator.ts index 53fabac66a..197d6c6717 100644 --- a/src/lib/message/L1ToL2MessageGasEstimator.ts +++ b/src/lib/message/ParentToChildMessageGasEstimator.ts @@ -16,7 +16,7 @@ import { OmitTyped } from '../utils/types' import { ParentToChildMessageGasParams, ParentToChildMessageNoGasParams, -} from './L1ToL2MessageCreator' +} from './ParentToChildMessageCreator' /** * The default amount to increase the maximum submission cost. Submission cost is calculated diff --git a/src/lib/message/L1Transaction.ts b/src/lib/message/ParentTransaction.ts similarity index 99% rename from src/lib/message/L1Transaction.ts rename to src/lib/message/ParentTransaction.ts index d894629933..1c8e6c289a 100644 --- a/src/lib/message/L1Transaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -30,7 +30,7 @@ import { ParentToChildMessageWaitResult, EthDepositMessage, EthDepositMessageWaitResult, -} from './L1ToL2Message' +} from './ParentToChildMessage' import { L1ERC20Gateway__factory } from '../abi/factories/L1ERC20Gateway__factory' import { diff --git a/tests/integration/l2TransactionReceipt.test.ts b/tests/integration/childTransactionReceipt.test.ts similarity index 100% rename from tests/integration/l2TransactionReceipt.test.ts rename to tests/integration/childTransactionReceipt.test.ts diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index b3a37ae944..4ce32939ad 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -31,7 +31,7 @@ import { import { describeOnlyWhenCustomGasToken } from './mochaExtensions' import { ChildToParentMessageStatus } from '../../../src' -import { ChildToParentMessage } from '../../../src/lib/message/L2ToL1Message' +import { ChildToParentMessage } from '../../../src/lib/message/ChildToParentMessage' dotenv.config() diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 523529d578..5b81dea9b1 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -29,10 +29,10 @@ import { prettyLog, skipIfMainnet, } from './testHelpers' -import { ChildToParentMessage } from '../../src/lib/message/L2ToL1Message' +import { ChildToParentMessage } from '../../src/lib/message/ChildToParentMessage' import { ChildToParentMessageStatus as L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' -import { L2TransactionReceipt } from '../../src/lib/message/L2Transaction' -import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' +import { L2TransactionReceipt } from '../../src/lib/message/ChildTransaction' +import { ParentToChildMessageStatus } from '../../src/lib/message/ParentToChildMessage' import { testSetup } from '../../scripts/testSetup' import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' diff --git a/tests/integration/l1ToL2MessageCreator.test.ts b/tests/integration/parentToChildMessageCreator.test.ts similarity index 99% rename from tests/integration/l1ToL2MessageCreator.test.ts rename to tests/integration/parentToChildMessageCreator.test.ts index 3bf6454c79..9d1bb7f54a 100644 --- a/tests/integration/l1ToL2MessageCreator.test.ts +++ b/tests/integration/parentToChildMessageCreator.test.ts @@ -20,8 +20,8 @@ import { expect } from 'chai' import { providers, utils } from 'ethers' import { fundParentSigner, skipIfMainnet } from './testHelpers' import { testSetup } from '../../scripts/testSetup' -import { ParentToChildMessageCreator } from '../../src/lib/message/L1ToL2MessageCreator' -import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' +import { ParentToChildMessageCreator } from '../../src/lib/message/ParentToChildMessageCreator' +import { ParentToChildMessageStatus } from '../../src/lib/message/ParentToChildMessage' import { fundParentCustomFeeToken, diff --git a/tests/integration/L1ToL2MessageGasEstimator.test.ts b/tests/integration/parentToChildMessageGasEstimator.test.ts similarity index 98% rename from tests/integration/L1ToL2MessageGasEstimator.test.ts rename to tests/integration/parentToChildMessageGasEstimator.test.ts index 8e4ddeb1b1..56dce2fe97 100644 --- a/tests/integration/L1ToL2MessageGasEstimator.test.ts +++ b/tests/integration/parentToChildMessageGasEstimator.test.ts @@ -21,7 +21,7 @@ import { BigNumber } from 'ethers' import { skipIfMainnet } from './testHelpers' import { testSetup } from '../../scripts/testSetup' -import { ParentToChildMessageGasEstimator } from '../../src/lib/message/L1ToL2MessageGasEstimator' +import { ParentToChildMessageGasEstimator } from '../../src/lib/message/ParentToChildMessageGasEstimator' import { itOnlyWhenEth, itOnlyWhenCustomGasToken, diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index f2939e91c9..fb55d89e3e 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -26,7 +26,7 @@ import { Wallet } from 'ethers' import { testSetup } from '../../scripts/testSetup' import { parseEther, randomBytes } from 'ethers/lib/utils' import { Inbox__factory } from '../../src/lib/abi/factories/Inbox__factory' -import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' +import { GasOverrides } from '../../src/lib/message/ParentToChildMessageGasEstimator' const depositAmount = BigNumber.from(100) import { ERC20Inbox__factory } from '../../src/lib/abi/factories/ERC20Inbox__factory' import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' diff --git a/tests/integration/sendL2msg.test.ts b/tests/integration/sendChildmsg.test.ts similarity index 100% rename from tests/integration/sendL2msg.test.ts rename to tests/integration/sendChildmsg.test.ts diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 61c9bb6ede..d27e3f4f23 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -27,9 +27,9 @@ import { config, getSigner, testSetup } from '../../scripts/testSetup' import { Signer, Wallet } from 'ethers' import { Erc20Bridger, ChildToParentMessageStatus } from '../../src' -import { ParentToChildMessageStatus } from '../../src/lib/message/L1ToL2Message' +import { ParentToChildMessageStatus } from '../../src/lib/message/ParentToChildMessage' import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' -import { GasOverrides } from '../../src/lib/message/L1ToL2MessageGasEstimator' +import { GasOverrides } from '../../src/lib/message/ParentToChildMessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' diff --git a/tests/unit/l2BlocksForL1Block.test.ts b/tests/unit/childBlocksForParentBlock.test.ts similarity index 100% rename from tests/unit/l2BlocksForL1Block.test.ts rename to tests/unit/childBlocksForParentBlock.test.ts diff --git a/tests/unit/l2toL1MessageEvents.test.ts b/tests/unit/childToParentMessageEvents.test.ts similarity index 98% rename from tests/unit/l2toL1MessageEvents.test.ts rename to tests/unit/childToParentMessageEvents.test.ts index fd335eedef..71250c6f2a 100644 --- a/tests/unit/l2toL1MessageEvents.test.ts +++ b/tests/unit/childToParentMessageEvents.test.ts @@ -18,7 +18,7 @@ import { Logger, LogLevel } from '@ethersproject/logger' Logger.setLogLevel(LogLevel.ERROR) -import { ChildToParentMessage } from '../../src/lib/message/L2ToL1Message' +import { ChildToParentMessage } from '../../src/lib/message/ChildToParentMessage' import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito' diff --git a/tests/unit/l1toL2MessageEvents.test.ts b/tests/unit/parentToChildMessageEvents.test.ts similarity index 99% rename from tests/unit/l1toL2MessageEvents.test.ts rename to tests/unit/parentToChildMessageEvents.test.ts index 81ef1a4e51..712359b4ba 100644 --- a/tests/unit/l1toL2MessageEvents.test.ts +++ b/tests/unit/parentToChildMessageEvents.test.ts @@ -1,4 +1,4 @@ -import { ParentChainTransactionReceipt } from './../../src/lib/message/L1Transaction' +import { ParentChainTransactionReceipt } from './../../src/lib/message/ParentTransaction' import { BigNumber, constants, providers } from 'ethers' import { JsonRpcProvider } from '@ethersproject/providers' import { expect } from 'chai' From 1a85aa3f1327989945dbed478e7ac8dc0966792f Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:16:18 -0400 Subject: [PATCH 22/74] chore: replace temporary imports/exports with renamed versions (#444) --- src/index.ts | 26 ++++++++-------- src/lib/assetBridger/assetBridger.ts | 10 ++++--- src/lib/assetBridger/erc20Bridger.ts | 28 ++++++++--------- src/lib/assetBridger/ethBridger.ts | 30 +++++++++---------- src/lib/message/ChildTransaction.ts | 18 +++++------ src/lib/message/ParentToChildMessage.ts | 11 +++---- .../message/ParentToChildMessageCreator.ts | 14 ++------- .../ParentToChildMessageGasEstimator.ts | 3 -- src/lib/message/ParentTransaction.ts | 18 +++-------- .../childTransactionReceipt.test.ts | 4 +-- tests/integration/customerc20.test.ts | 12 ++++---- tests/integration/eth.test.ts | 12 ++++---- tests/integration/standarderc20.test.ts | 28 ++++++++--------- tests/integration/weth.test.ts | 4 +-- tests/unit/childToParentMessageEvents.test.ts | 4 +-- 15 files changed, 99 insertions(+), 123 deletions(-) diff --git a/src/index.ts b/src/index.ts index b0424cbdaf..651064f129 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,27 +19,27 @@ export { EthBridger } from './lib/assetBridger/ethBridger' export { Erc20Bridger } from './lib/assetBridger/erc20Bridger' export { - L2TransactionReceipt, - L2ContractTransaction, + ChildTransactionReceipt, + ChildContractTransaction, } from './lib/message/ChildTransaction' export { - ChildToParentMessage as L2ToL1Message, - ChildToParentMessageWriter as L2ToL1MessageWriter, - ChildToParentMessageReader as L2ToL1MessageReader, + ChildToParentMessage, + ChildToParentMessageWriter, + ChildToParentMessageReader, } from './lib/message/ChildToParentMessage' export { - L1ContractTransaction, - L1TransactionReceipt, + ParentChainContractTransaction, + ParentChainTransactionReceipt, } from './lib/message/ParentTransaction' export { - ParentToChildMessageStatus as L1ToL2MessageStatus, + ParentToChildMessageStatus, EthDepositStatus, - ParentToChildMessage as L1ToL2Message, - ParentToChildMessageReader as L1ToL2MessageReader, - ParentToChildMessageReaderClassic as L1ToL2MessageReaderClassic, - ParentToChildMessageWriter as L1ToL2MessageWriter, + ParentToChildMessage, + ParentToChildMessageReader, + ParentToChildMessageReaderClassic, + ParentToChildMessageWriter, } from './lib/message/ParentToChildMessage' -export { L1ToL2MessageGasEstimator } from './lib/message/ParentToChildMessageGasEstimator' +export { ParentToChildMessageGasEstimator } from './lib/message/ParentToChildMessageGasEstimator' export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 8ee476c649..f4a7032dde 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -18,8 +18,8 @@ import { constants } from 'ethers' -import { L1ContractTransaction } from '../message/ParentTransaction' -import { L2ContractTransaction } from '../message/ChildTransaction' +import { ParentChainContractTransaction } from '../message/ParentTransaction' +import { ChildContractTransaction } from '../message/ChildTransaction' import { L1Network, @@ -80,7 +80,9 @@ export abstract class AssetBridger { * Transfer assets from parent-to-child * @param params */ - public abstract deposit(params: DepositParams): Promise + public abstract deposit( + params: DepositParams + ): Promise /** * Transfer assets from child-to-parent @@ -88,5 +90,5 @@ export abstract class AssetBridger { */ public abstract withdraw( params: WithdrawParams - ): Promise + ): Promise } diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 2e5034f6ba..ae5df85690 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -42,7 +42,7 @@ import { WithdrawalInitiatedEvent } from '../abi/L2ArbitrumGateway' import { GatewaySetEvent } from '../abi/L1GatewayRouter' import { GasOverrides, - L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, + ParentToChildMessageGasEstimator, } from '../message/ParentToChildMessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { ArbitrumNetwork, getArbitrumNetwork } from '../dataEntities/networks' @@ -52,13 +52,13 @@ import { EventFetcher } from '../utils/eventFetcher' import { EthDepositParams, EthWithdrawParams } from './ethBridger' import { AssetBridger } from './assetBridger' import { - L1ContractCallTransaction, - L1ContractTransaction, - L1TransactionReceipt, + ParentChainContractCallTransaction, + ParentChainContractTransaction, + ParentChainTransactionReceipt, } from '../message/ParentTransaction' import { - L2ContractTransaction, - L2TransactionReceipt, + ChildContractTransaction, + ChildTransactionReceipt, } from '../message/ChildTransaction' import { isParentToChildTransactionRequest, @@ -733,7 +733,7 @@ export class Erc20Bridger extends AssetBridger< */ public async deposit( params: Erc20DepositParams | ParentToChildTxReqAndSignerProvider - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) // Although the types prevent should alert callers that value is not @@ -762,7 +762,7 @@ export class Erc20Bridger extends AssetBridger< ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentChainTransactionReceipt.monkeyPatchContractCallWait(tx) } /** @@ -837,7 +837,7 @@ export class Erc20Bridger extends AssetBridger< params: | (OmitTyped & { childSigner: Signer }) | ChildToParentTxReqAndSigner - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { throw new MissingProviderArbSdkError('childSigner') } @@ -856,7 +856,7 @@ export class Erc20Bridger extends AssetBridger< ...withdrawalRequest.txRequest, ...params.overrides, }) - return L2TransactionReceipt.monkeyPatchWait(tx) + return ChildTransactionReceipt.monkeyPatchWait(tx) } } @@ -886,7 +886,7 @@ export class AdminErc20Bridger extends Erc20Bridger { l2TokenAddress: string, parentSigner: Signer, childProvider: Provider - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } @@ -997,7 +997,7 @@ export class AdminErc20Bridger extends Erc20Bridger { value: setGatewayEstimates2.value, }) - return L1TransactionReceipt.monkeyPatchWait(registerTx) + return ParentChainTransactionReceipt.monkeyPatchWait(registerTx) } /** @@ -1067,7 +1067,7 @@ export class AdminErc20Bridger extends Erc20Bridger { childProvider: Provider, tokenGateways: TokenAndGateway[], options?: GasOverrides - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } @@ -1112,6 +1112,6 @@ export class AdminErc20Bridger extends Erc20Bridger { value: estimates.estimates.deposit, }) - return L1TransactionReceipt.monkeyPatchContractCallWait(res) + return ParentChainTransactionReceipt.monkeyPatchContractCallWait(res) } } diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 01066cc0dc..b867861b9b 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -27,15 +27,15 @@ import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ARB_SYS_ADDRESS } from '../dataEntities/constants' import { AssetBridger } from './assetBridger' import { - L1EthDepositTransaction, - L1ContractCallTransaction, - L1TransactionReceipt, + ParentChainEthDepositTransaction, + ParentChainContractCallTransaction, + ParentChainTransactionReceipt, } from '../message/ParentTransaction' import { - L2ContractTransaction, - ChildChainTransactionReceipt, + ChildContractTransaction, + ChildTransactionReceipt, } from '../message/ChildTransaction' -import { L1ToL2MessageCreator } from '../message/ParentToChildMessageCreator' +import { ParentToChildMessageCreator } from '../message/ParentToChildMessageCreator' import { GasOverrides } from '../message/ParentToChildMessageGasEstimator' import { isParentToChildTransactionRequest, @@ -46,7 +46,7 @@ import { import { OmitTyped } from '../utils/types' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { MissingProviderArbSdkError } from '../dataEntities/errors' -import { getL2Network as getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' import { ERC20__factory } from '../abi/factories/ERC20__factory' import { isArbitrumChain } from '../utils/lib' @@ -171,7 +171,7 @@ export class EthBridger extends AssetBridger< * @returns */ public static async fromProvider(childProvider: Provider) { - return new EthBridger(await getChildChain(childProvider)) + return new EthBridger(await getArbitrumNetwork(childProvider)) } /** @@ -286,7 +286,7 @@ export class EthBridger extends AssetBridger< */ public async deposit( params: EthDepositParams | ParentToChildTxReqAndSigner - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) const ethDeposit = isParentToChildTransactionRequest(params) @@ -301,7 +301,7 @@ export class EthBridger extends AssetBridger< ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchEthDepositWait(tx) + return ParentChainTransactionReceipt.monkeyPatchEthDepositWait(tx) } /** @@ -323,7 +323,7 @@ export class EthBridger extends AssetBridger< // Gas overrides can be passed in the parameters const gasOverrides = params.retryableGasOverrides || undefined - return L1ToL2MessageCreator.getTicketCreationRequest( + return ParentToChildMessageCreator.getTicketCreationRequest( requestParams, params.parentProvider, params.childProvider, @@ -340,7 +340,7 @@ export class EthBridger extends AssetBridger< params: | EthDepositToParams | (ParentToChildTxReqAndSigner & { childProvider: Provider }) - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) await this.checkChildChain(params.childProvider) @@ -357,7 +357,7 @@ export class EthBridger extends AssetBridger< ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentChainTransactionReceipt.monkeyPatchContractCallWait(tx) } /** @@ -405,7 +405,7 @@ export class EthBridger extends AssetBridger< params: | (EthWithdrawParams & { childSigner: Signer }) | ChildToParentTxReqAndSigner - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { throw new MissingProviderArbSdkError('childSigner') } @@ -421,6 +421,6 @@ export class EthBridger extends AssetBridger< ...request.txRequest, ...params.overrides, }) - return ChildChainTransactionReceipt.monkeyPatchWait(tx) + return ChildTransactionReceipt.monkeyPatchWait(tx) } } diff --git a/src/lib/message/ChildTransaction.ts b/src/lib/message/ChildTransaction.ts index 4649385ebe..b8f0ca19c2 100644 --- a/src/lib/message/ChildTransaction.ts +++ b/src/lib/message/ChildTransaction.ts @@ -40,18 +40,18 @@ import { NODE_INTERFACE_ADDRESS } from '../dataEntities/constants' import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { ArbitrumProvider } from '../utils/arbProvider' -export interface L2ContractTransaction extends ContractTransaction { - wait(confirmations?: number): Promise +export interface ChildContractTransaction extends ContractTransaction { + wait(confirmations?: number): Promise } -export interface RedeemTransaction extends L2ContractTransaction { +export interface RedeemTransaction extends ChildContractTransaction { waitForRedeem: () => Promise } /** * Extension of ethers-js TransactionReceipt, adding Arbitrum-specific functionality */ -export class ChildChainTransactionReceipt implements TransactionReceipt { +export class ChildTransactionReceipt implements TransactionReceipt { public readonly to: string public readonly from: string public readonly contractAddress: string @@ -186,7 +186,7 @@ export class ChildChainTransactionReceipt implements TransactionReceipt { */ public static monkeyPatchWait = ( contractTransaction: ContractTransaction - ): L2ContractTransaction => { + ): ChildContractTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (_confirmations?: number) => { // we ignore the confirmations for now since child chain transactions shouldn't re-org @@ -194,9 +194,9 @@ export class ChildChainTransactionReceipt implements TransactionReceipt { // an child chain transaction - check if a batch is on a parent chain, if an assertion has been made, and if // it has been confirmed. const result = await wait() - return new ChildChainTransactionReceipt(result) + return new ChildTransactionReceipt(result) } - return contractTransaction as L2ContractTransaction + return contractTransaction as ChildContractTransaction } /** @@ -206,7 +206,7 @@ export class ChildChainTransactionReceipt implements TransactionReceipt { * @returns */ public static toRedeemTransaction( - redeemTx: L2ContractTransaction, + redeemTx: ChildContractTransaction, childProvider: providers.Provider ): RedeemTransaction { const returnRec = redeemTx as RedeemTransaction @@ -228,5 +228,3 @@ export class ChildChainTransactionReceipt implements TransactionReceipt { return returnRec } } - -export { ChildChainTransactionReceipt as L2TransactionReceipt } diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index 2335822083..558a9a74c5 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -33,10 +33,7 @@ import { } from '../dataEntities/signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' -import { - L2TransactionReceipt as ChainTransactionReceipt, - RedeemTransaction, -} from './ChildTransaction' +import { ChildTransactionReceipt, RedeemTransaction } from './ChildTransaction' import { getChildChain } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' @@ -296,7 +293,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { const creationReceipt = await this.getRetryableCreationReceipt() if (creationReceipt) { - const chainReceipt = new ChainTransactionReceipt(creationReceipt) + const chainReceipt = new ChildTransactionReceipt(creationReceipt) const redeemEvents = chainReceipt.getRedeemScheduledEvents() if (redeemEvents.length === 1) { @@ -687,8 +684,8 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { ...overrides, }) - return ChainTransactionReceipt.toRedeemTransaction( - ChainTransactionReceipt.monkeyPatchWait(redeemTx), + return ChildTransactionReceipt.toRedeemTransaction( + ChildTransactionReceipt.monkeyPatchWait(redeemTx), this.chainProvider ) } else { diff --git a/src/lib/message/ParentToChildMessageCreator.ts b/src/lib/message/ParentToChildMessageCreator.ts index dac05152ad..e075d1f77a 100644 --- a/src/lib/message/ParentToChildMessageCreator.ts +++ b/src/lib/message/ParentToChildMessageCreator.ts @@ -4,11 +4,11 @@ import { Provider } from '@ethersproject/abstract-provider' import { GasOverrides, - L1ToL2MessageGasEstimator as ParentToChildMessageGasEstimator, + ParentToChildMessageGasEstimator, } from './ParentToChildMessageGasEstimator' import { - L1ContractTransaction as ParentChainContractTransaction, - L1TransactionReceipt as ParentChainTransactionReceipt, + ParentChainContractTransaction, + ParentChainTransactionReceipt, } from './ParentTransaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' import { getChildChain } from '../dataEntities/networks' @@ -229,11 +229,3 @@ export class ParentToChildMessageCreator { return ParentChainTransactionReceipt.monkeyPatchWait(tx) } } - -// TODO: remove after all other files have their imports updated -export { - ParentToChildMessageCreator as L1ToL2MessageCreator, - ParentToChildMessageGasParams as L1ToL2MessageGasParams, - ParentToChildMessageNoGasParams as L1ToL2MessageNoGasParams, - ParentToChildMessageParams as L1ToL2MessageParams, -} diff --git a/src/lib/message/ParentToChildMessageGasEstimator.ts b/src/lib/message/ParentToChildMessageGasEstimator.ts index 197d6c6717..4f2a64d318 100644 --- a/src/lib/message/ParentToChildMessageGasEstimator.ts +++ b/src/lib/message/ParentToChildMessageGasEstimator.ts @@ -370,6 +370,3 @@ export class ParentToChildMessageGasEstimator { } } } - -// TODO: remove after all other files have their imports updated -export { ParentToChildMessageGasEstimator as L1ToL2MessageGasEstimator } diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 1c8e6c289a..ff0211b9c0 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -46,7 +46,7 @@ import { MessageDeliveredEvent } from '../abi/Bridge' import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' -import { getL2Network as getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' export interface ParentChainContractTransaction< TReceipt extends ParentChainTransactionReceipt = ParentChainTransactionReceipt @@ -108,7 +108,7 @@ export class ParentChainTransactionReceipt implements TransactionReceipt { const provider = SignerProviderUtils.getProviderOrThrow( childSignerOrProvider ) - const network = await getChildChain(provider) + const network = await getArbitrumNetwork(provider) return this.blockNumber < network.nitroGenesisL1Block } @@ -209,7 +209,7 @@ export class ParentChainTransactionReceipt implements TransactionReceipt { public async getParentToChildMessagesClassic( childProvider: Provider ): Promise { - const network = await getChildChain(childProvider) + const network = await getArbitrumNetwork(childProvider) const chainID = network.chainID.toString() const isClassic = await this.isClassic(childProvider) @@ -247,7 +247,7 @@ export class ParentChainTransactionReceipt implements TransactionReceipt { const provider = SignerProviderUtils.getProviderOrThrow( childSignerOrProvider ) - const network = await getChildChain(provider) + const network = await getArbitrumNetwork(provider) const chainID = network.chainID.toString() const isClassic = await this.isClassic(provider) @@ -421,13 +421,3 @@ export class ParentChainContractCallTransactionReceipt extends ParentChainTransa } } } - -// TODO: remove when all consumers have been renamed -export { - ParentChainTransactionReceipt as L1TransactionReceipt, - ParentChainContractCallTransactionReceipt as L1ContractCallTransactionReceipt, - ParentChainEthDepositTransactionReceipt as L1EthDepositTransactionReceipt, - ParentChainContractTransaction as L1ContractTransaction, - ParentChainEthDepositTransaction as L1EthDepositTransaction, - ParentChainContractCallTransaction as L1ContractCallTransaction, -} diff --git a/tests/integration/childTransactionReceipt.test.ts b/tests/integration/childTransactionReceipt.test.ts index f2025b5190..b5fc17372e 100644 --- a/tests/integration/childTransactionReceipt.test.ts +++ b/tests/integration/childTransactionReceipt.test.ts @@ -25,7 +25,7 @@ import { skipIfMainnet, wait, } from './testHelpers' -import { L2TransactionReceipt } from '../../src' +import { ChildTransactionReceipt } from '../../src' import { JsonRpcProvider } from '@ethersproject/providers' import { BigNumber, Wallet } from 'ethers' import { parseEther } from 'ethers/lib/utils' @@ -64,7 +64,7 @@ describe('ArbProvider', () => { // eslint-disable-next-line no-constant-condition while (true) { await wait(300) - const arbTxReceipt = new L2TransactionReceipt(rec) + const arbTxReceipt = new ChildTransactionReceipt(rec) const l1BatchNumber = ( await arbTxReceipt.getBatchNumber(l2Provider).catch(() => { diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 87107fce84..603fb48ccf 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -38,7 +38,7 @@ import { GatewayType, withdrawToken, } from './testHelpers' -import { L1ToL2MessageStatus } from '../../src' +import { ParentToChildMessageStatus } from '../../src' import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { AdminErc20Bridger } from '../../src/lib/assetBridger/erc20Bridger' import { testSetup } from '../../scripts/testSetup' @@ -98,7 +98,7 @@ describe('Custom ERC20', () => { erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) }) @@ -127,7 +127,7 @@ describe('Custom ERC20', () => { erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, }) }) @@ -141,7 +141,7 @@ describe('Custom ERC20', () => { erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.CUSTOM, destinationAddress: randomAddress, }) @@ -239,12 +239,12 @@ const registerCustomToken = async ( const setTokenTx = await l1ToL2Messages[0].waitForStatus() expect(setTokenTx.status, 'Set token not redeemed.').to.eq( - L1ToL2MessageStatus.REDEEMED + ParentToChildMessageStatus.REDEEMED ) const setGateways = await l1ToL2Messages[1].waitForStatus() expect(setGateways.status, 'Set gateways not redeemed.').to.eq( - L1ToL2MessageStatus.REDEEMED + ParentToChildMessageStatus.REDEEMED ) // check end conditions diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 5b81dea9b1..ac4d3ae976 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -30,8 +30,8 @@ import { skipIfMainnet, } from './testHelpers' import { ChildToParentMessage } from '../../src/lib/message/ChildToParentMessage' -import { ChildToParentMessageStatus as L2ToL1MessageStatus } from '../../src/lib/dataEntities/message' -import { L2TransactionReceipt } from '../../src/lib/message/ChildTransaction' +import { ChildToParentMessageStatus } from '../../src/lib/dataEntities/message' +import { ChildTransactionReceipt } from '../../src/lib/message/ChildTransaction' import { ParentToChildMessageStatus } from '../../src/lib/message/ParentToChildMessage' import { testSetup } from '../../scripts/testSetup' import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' @@ -201,7 +201,7 @@ describe('Ether', async () => { expect(retryableTxReceipt).to.exist expect(retryableTxReceipt).to.not.be.null - const l2RetryableTxReceipt = new L2TransactionReceipt(retryableTxReceipt) + const l2RetryableTxReceipt = new ChildTransactionReceipt(retryableTxReceipt) const ticketRedeemEvents = l2RetryableTxReceipt.getRedeemScheduledEvents() expect(ticketRedeemEvents.length).to.eq( 1, @@ -274,7 +274,7 @@ describe('Ether', async () => { expect( messageStatus, `eth withdraw status returned ${messageStatus}` - ).to.be.eq(L2ToL1MessageStatus.UNCONFIRMED) + ).to.be.eq(ChildToParentMessageStatus.UNCONFIRMED) // CHRIS: TODO: comment this back in when fixed in nitro // const actualFinalBalance = await childSigner.getBalance() @@ -301,7 +301,7 @@ describe('Ether', async () => { expect( await withdrawMessage.status(childSigner.provider!), 'confirmed status' - ).to.eq(L2ToL1MessageStatus.CONFIRMED) + ).to.eq(ChildToParentMessageStatus.CONFIRMED) const execTx = await withdrawMessage.execute(childSigner.provider!) const execRec = await execTx.wait() @@ -314,7 +314,7 @@ describe('Ether', async () => { expect( await withdrawMessage.status(childSigner.provider!), 'executed status' - ).to.eq(L2ToL1MessageStatus.EXECUTED) + ).to.eq(ChildToParentMessageStatus.EXECUTED) const finalRandomBalance = isArbitrumNetworkWithCustomFeeToken() ? await ERC20__factory.connect( diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 89ecf6e63e..11c1e6c1e2 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -30,9 +30,9 @@ import { } from './testHelpers' import { Erc20Bridger, - L1ToL2MessageStatus, - L1ToL2MessageWriter, - L2TransactionReceipt, + ParentToChildMessageStatus, + ParentToChildMessageWriter, + ChildTransactionReceipt, } from '../../src' import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { TestERC20 } from '../../src/lib/abi/TestERC20' @@ -134,13 +134,13 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) }) const redeemAndTest = async ( - message: L1ToL2MessageWriter, + message: ParentToChildMessageWriter, expectedStatus: 0 | 1, gasLimit?: BigNumber ) => { @@ -156,8 +156,8 @@ describe('standard ERC20', () => { expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( expectedStatus === 0 - ? L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN - : L1ToL2MessageStatus.REDEEMED + ? ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + : ParentToChildMessageStatus.REDEEMED ) } @@ -168,7 +168,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(0) }, @@ -186,7 +186,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(5) }, @@ -206,7 +206,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(21000) }, @@ -218,7 +218,7 @@ describe('standard ERC20', () => { await waitRes.message.getRetryableCreationReceipt() if (!isDefined(retryableCreation)) throw new Error('Missing retryable creation.') - const l2Receipt = new L2TransactionReceipt(retryableCreation) + const l2Receipt = new ChildTransactionReceipt(retryableCreation) const redeemsScheduled = l2Receipt.getRedeemScheduledEvents() expect(redeemsScheduled.length, 'Unexpected redeem length').to.eq(1) const retryReceipt = @@ -238,7 +238,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(5) }, @@ -307,7 +307,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, }) }) @@ -321,7 +321,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.STANDARD, destinationAddress: randomAddress, }) diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index 4f8481fe36..a11910b602 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -27,7 +27,7 @@ import { GatewayType, depositToken, } from './testHelpers' -import { L1ToL2MessageStatus } from '../../src' +import { ParentToChildMessageStatus } from '../../src' import { Wallet } from 'ethers' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' @@ -69,7 +69,7 @@ describeOnlyWhenEth('WETH', async () => { erc20Bridger, parentSigner, childSigner, - expectedStatus: L1ToL2MessageStatus.REDEEMED, + expectedStatus: ParentToChildMessageStatus.REDEEMED, expectedGatewayType: GatewayType.WETH, }) diff --git a/tests/unit/childToParentMessageEvents.test.ts b/tests/unit/childToParentMessageEvents.test.ts index 71250c6f2a..77bd5863eb 100644 --- a/tests/unit/childToParentMessageEvents.test.ts +++ b/tests/unit/childToParentMessageEvents.test.ts @@ -19,7 +19,7 @@ import { Logger, LogLevel } from '@ethersproject/logger' Logger.setLogLevel(LogLevel.ERROR) import { ChildToParentMessage } from '../../src/lib/message/ChildToParentMessage' -import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' +import { getArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito' @@ -34,7 +34,7 @@ describe('ChildToParentMessage events', () => { const arbSys = '0x0000000000000000000000000000000000000064' const createProviderMock = async (networkChoiceOverride?: number) => { - const l2Network = await getL2Network(networkChoiceOverride || 42161) + const l2Network = await getArbitrumNetwork(networkChoiceOverride || 42161) const l2ProviderMock = mock(providers.JsonRpcProvider) const latestBlock = l2Network.nitroGenesisBlock + 1000 From 6b35df62655962003020bf8f72c9525df27d30d3 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 17 Apr 2024 02:59:34 -0400 Subject: [PATCH 23/74] chore: renames ParentChainTx to ParentTx and similar (#451) --- scripts/deployStandard.ts | 2 +- src/index.ts | 4 +- src/lib/assetBridger/assetBridger.ts | 4 +- src/lib/assetBridger/erc20Bridger.ts | 122 +++++++++--------- src/lib/assetBridger/ethBridger.ts | 20 +-- src/lib/message/ChildToParentMessage.ts | 2 +- src/lib/message/ChildToParentMessageNitro.ts | 2 +- src/lib/message/ChildTransaction.ts | 2 +- .../message/ParentToChildMessageCreator.ts | 8 +- .../ParentToChildMessageGasEstimator.ts | 6 +- src/lib/message/ParentTransaction.ts | 48 +++---- tests/integration/customerc20.test.ts | 8 +- .../parentToChildMessageCreator.test.ts | 2 +- tests/integration/retryableData.test.ts | 8 +- tests/integration/sanity.test.ts | 2 +- tests/integration/sendChildmsg.test.ts | 74 ++++++----- tests/integration/standarderc20.test.ts | 18 +-- tests/integration/testHelpers.ts | 68 +++++----- tests/integration/weth.test.ts | 4 +- tests/unit/childBlocksForParentBlock.test.ts | 84 ++++++------ tests/unit/parentToChildMessageEvents.test.ts | 20 ++- 21 files changed, 257 insertions(+), 251 deletions(-) diff --git a/scripts/deployStandard.ts b/scripts/deployStandard.ts index addf09a074..fd66b2b680 100644 --- a/scripts/deployStandard.ts +++ b/scripts/deployStandard.ts @@ -102,7 +102,7 @@ const main = async () => { } /* check token not yet deployed */ - const l2TokenAddress = await erc20Bridger.getL2ERC20Address( + const l2TokenAddress = await erc20Bridger.getChildERC20Address( l1TokenAddress, l1Provider ) diff --git a/src/index.ts b/src/index.ts index 651064f129..25d97aa200 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,8 +28,8 @@ export { ChildToParentMessageReader, } from './lib/message/ChildToParentMessage' export { - ParentChainContractTransaction, - ParentChainTransactionReceipt, + ParentContractTransaction, + ParentTransactionReceipt, } from './lib/message/ParentTransaction' export { ParentToChildMessageStatus, diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index f4a7032dde..2d050c4de7 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -18,7 +18,7 @@ import { constants } from 'ethers' -import { ParentChainContractTransaction } from '../message/ParentTransaction' +import { ParentContractTransaction } from '../message/ParentTransaction' import { ChildContractTransaction } from '../message/ChildTransaction' import { @@ -82,7 +82,7 @@ export abstract class AssetBridger { */ public abstract deposit( params: DepositParams - ): Promise + ): Promise /** * Transfer assets from child-to-parent diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index ae5df85690..87e452b07f 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -52,9 +52,9 @@ import { EventFetcher } from '../utils/eventFetcher' import { EthDepositParams, EthWithdrawParams } from './ethBridger' import { AssetBridger } from './assetBridger' import { - ParentChainContractCallTransaction, - ParentChainContractTransaction, - ParentChainTransactionReceipt, + ParentContractCallTransaction, + ParentContractTransaction, + ParentTransactionReceipt, } from '../message/ParentTransaction' import { ChildContractTransaction, @@ -75,7 +75,7 @@ import { isArbitrumChain } from '../utils/lib' export interface TokenApproveParams { /** - * L1 address of the ERC20 token contract + * Parent chain address of the ERC20 token contract */ erc20ParentAddress: string /** @@ -94,11 +94,11 @@ export interface Erc20DepositParams extends EthDepositParams { */ childProvider: Provider /** - * L1 address of the token ERC20 contract + * Parent chain address of the token ERC20 contract */ erc20ParentAddress: string /** - * L2 address of the entity receiving the funds. Defaults to the l1FromAddress + * Child chain address of the entity receiving the funds. Defaults to the l1FromAddress */ destinationAddress?: string /** @@ -125,7 +125,7 @@ export interface Erc20DepositParams extends EthDepositParams { export interface Erc20WithdrawParams extends EthWithdrawParams { /** - * L1 address of the token ERC20 contract + * Parent chain address of the token ERC20 contract */ erc20ParentAddress: string } @@ -341,7 +341,7 @@ export class Erc20Bridger extends AssetBridger< * Get the child chain events created by a withdrawal * @param childProvider * @param gatewayAddress - * @param parentChainTokenAddress + * @param parentTokenAddress * @param fromAddress * @param filter * @returns @@ -350,7 +350,7 @@ export class Erc20Bridger extends AssetBridger< childProvider: Provider, gatewayAddress: string, filter: { fromBlock: BlockTag; toBlock: BlockTag }, - parentChainTokenAddress?: string, + parentTokenAddress?: string, fromAddress?: string, toAddress?: string ): Promise<(EventArgs & { txHash: string })[]> { @@ -370,11 +370,11 @@ export class Erc20Bridger extends AssetBridger< ) ).map(a => ({ txHash: a.transactionHash, ...a.event })) - return parentChainTokenAddress + return parentTokenAddress ? events.filter( log => log.l1Token.toLocaleLowerCase() === - parentChainTokenAddress.toLocaleLowerCase() + parentTokenAddress.toLocaleLowerCase() ) : events } @@ -433,7 +433,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the L2 token contract at the provided address + * Get the child chain token contract at the provided address * Note: This function just returns a typed ethers object for the provided address, it doesnt * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. @@ -454,14 +454,14 @@ export class Erc20Bridger extends AssetBridger< * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. * @param parentProvider - * @param parentChainTokenAddr + * @param parentTokenAddr * @returns */ - public getParentChainTokenContract( + public getParentTokenContract( parentProvider: Provider, - parentChainTokenAddr: string + parentTokenAddr: string ): ERC20 { - return ERC20__factory.connect(parentChainTokenAddr, parentProvider) + return ERC20__factory.connect(parentTokenAddr, parentProvider) } /** @@ -470,7 +470,7 @@ export class Erc20Bridger extends AssetBridger< * @param parentProvider * @returns */ - public async getL2ERC20Address( + public async getChildERC20Address( erc20ParentAddress: string, parentProvider: Provider ): Promise { @@ -493,7 +493,7 @@ export class Erc20Bridger extends AssetBridger< * @param childProvider * @returns */ - public async getL1ERC20Address( + public async getParentERC20Address( erc20ChildChainAddress: string, childProvider: Provider ): Promise { @@ -513,7 +513,7 @@ export class Erc20Bridger extends AssetBridger< ) const l1Address = await arbERC20.functions.l1Address().then(([res]) => res) - // check that this l1 address is indeed registered to this l2 token + // check that this l1 address is indeed registered to this child token const l2GatewayRouter = L2GatewayRouter__factory.connect( this.childChain.tokenBridge.l2GatewayRouter, childProvider @@ -531,12 +531,12 @@ export class Erc20Bridger extends AssetBridger< /** * Whether the token has been disabled on the router - * @param parentChainTokenAddress + * @param parentTokenAddress * @param parentProvider * @returns */ - public async parentChainTokenIsDisabled( - parentChainTokenAddress: string, + public async parentTokenIsDisabled( + parentTokenAddress: string, parentProvider: Provider ): Promise { await this.checkParentChain(parentProvider) @@ -547,7 +547,7 @@ export class Erc20Bridger extends AssetBridger< ) return ( - (await l1GatewayRouter.l1TokenToGateway(parentChainTokenAddress)) === + (await l1GatewayRouter.l1TokenToGateway(parentTokenAddress)) === DISABLED_GATEWAY ) } @@ -727,13 +727,13 @@ export class Erc20Bridger extends AssetBridger< } /** - * Execute a token deposit from parent-to-child + * Execute a token deposit from parent to child chain * @param params * @returns */ public async deposit( params: Erc20DepositParams | ParentToChildTxReqAndSignerProvider - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) // Although the types prevent should alert callers that value is not @@ -762,7 +762,7 @@ export class Erc20Bridger extends AssetBridger< ...params.overrides, }) - return ParentChainTransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentTransactionReceipt.monkeyPatchContractCallWait(tx) } /** @@ -829,7 +829,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Withdraw tokens from L2 to L1 + * Withdraw tokens from child to parent chain * @param params * @returns */ @@ -875,40 +875,43 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Register a custom token on the Arbitrum bridge * See https://developer.offchainlabs.com/docs/bridging_assets#the-arbitrum-generic-custom-gateway for more details - * @param parentChainTokenAddress Address of the already deployed l1 token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/ethereum/icustomtoken. - * @param l2TokenAddress Address of the already deployed l2 token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/arbitrum/iarbtoken. - * @param parentSigner The signer with the rights to call registerTokenOnL2 on the l1 token + * @param parentTokenAddress Address of the already deployed parent token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/ethereum/icustomtoken. + * @param childTokenAddress Address of the already deployed child token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/arbitrum/iarbtoken. + * @param parentSigner The signer with the rights to call registerTokenOnL2 on the parent token * @param childProvider Arbitrum rpc provider * @returns */ public async registerCustomToken( - parentChainTokenAddress: string, - l2TokenAddress: string, + parentTokenAddress: string, + childTokenAddress: string, parentSigner: Signer, childProvider: Provider - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } await this.checkParentChain(parentSigner) await this.checkChildChain(childProvider) - const l1SenderAddress = await parentSigner.getAddress() + const parentSenderAddress = await parentSigner.getAddress() - const l1Token = ICustomToken__factory.connect( - parentChainTokenAddress, + const parentToken = ICustomToken__factory.connect( + parentTokenAddress, parentSigner ) - const l2Token = IArbToken__factory.connect(l2TokenAddress, childProvider) + const childToken = IArbToken__factory.connect( + childTokenAddress, + childProvider + ) // sanity checks - await l1Token.deployed() - await l2Token.deployed() + await parentToken.deployed() + await childToken.deployed() - const l1AddressFromL2 = await l2Token.l1Address() - if (l1AddressFromL2 !== parentChainTokenAddress) { + const l1AddressFromChildChain = await childToken.l1Address() + if (l1AddressFromChildChain !== parentTokenAddress) { throw new ArbSdkError( - `L2 token does not have l1 address set. Set address: ${l1AddressFromL2}, expected address: ${parentChainTokenAddress}.` + `L2 token does not have l1 address set. Set address: ${l1AddressFromChildChain}, expected address: ${parentTokenAddress}.` ) } @@ -937,22 +940,25 @@ export class AdminErc20Bridger extends Erc20Bridger { .mul(doubleFeePerGas) .add(setGatewayGas.maxSubmissionCost) - const data = l1Token.interface.encodeFunctionData('registerTokenOnL2', [ - l2TokenAddress, - setTokenGas.maxSubmissionCost, - setGatewayGas.maxSubmissionCost, - setTokenGas.gasLimit, - setGatewayGas.gasLimit, - doubleFeePerGas, - setTokenDeposit, - setGatewayDeposit, - l1SenderAddress, - ]) + const data = parentToken.interface.encodeFunctionData( + 'registerTokenOnL2', + [ + childTokenAddress, + setTokenGas.maxSubmissionCost, + setGatewayGas.maxSubmissionCost, + setTokenGas.gasLimit, + setGatewayGas.gasLimit, + doubleFeePerGas, + setTokenDeposit, + setGatewayDeposit, + parentSenderAddress, + ] + ) return { data, value: setTokenDeposit.add(setGatewayDeposit), - to: l1Token.address, + to: parentToken.address, from, } } @@ -992,12 +998,12 @@ export class AdminErc20Bridger extends Erc20Bridger { ) const registerTx = await parentSigner.sendTransaction({ - to: l1Token.address, + to: parentToken.address, data: setGatewayEstimates2.data, value: setGatewayEstimates2.value, }) - return ParentChainTransactionReceipt.monkeyPatchWait(registerTx) + return ParentTransactionReceipt.monkeyPatchWait(registerTx) } /** @@ -1067,7 +1073,7 @@ export class AdminErc20Bridger extends Erc20Bridger { childProvider: Provider, tokenGateways: TokenAndGateway[], options?: GasOverrides - ): Promise { + ): Promise { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } @@ -1112,6 +1118,6 @@ export class AdminErc20Bridger extends Erc20Bridger { value: estimates.estimates.deposit, }) - return ParentChainTransactionReceipt.monkeyPatchContractCallWait(res) + return ParentTransactionReceipt.monkeyPatchContractCallWait(res) } } diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index b867861b9b..78b63ff2e1 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -27,9 +27,9 @@ import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ARB_SYS_ADDRESS } from '../dataEntities/constants' import { AssetBridger } from './assetBridger' import { - ParentChainEthDepositTransaction, - ParentChainContractCallTransaction, - ParentChainTransactionReceipt, + ParentEthDepositTransaction, + ParentContractCallTransaction, + ParentTransactionReceipt, } from '../message/ParentTransaction' import { ChildContractTransaction, @@ -76,7 +76,7 @@ export type ApproveGasTokenParamsOrTxRequest = | ApproveGasTokenParams | ApproveGasTokenTxRequest -type WithL1Signer = T & { +type WithParentSigner = T & { parentSigner: Signer } @@ -180,7 +180,7 @@ export class EthBridger extends AssetBridger< */ private isApproveGasTokenParams( params: ApproveGasTokenParamsOrTxRequest - ): params is WithL1Signer { + ): params is WithParentSigner { return typeof (params as ApproveGasTokenTxRequest).txRequest === 'undefined' } @@ -217,7 +217,7 @@ export class EthBridger extends AssetBridger< * @param params */ public async approveGasToken( - params: WithL1Signer + params: WithParentSigner ) { if (this.nativeTokenIsEth) { throw new Error('chain uses ETH as its native/gas token') @@ -286,7 +286,7 @@ export class EthBridger extends AssetBridger< */ public async deposit( params: EthDepositParams | ParentToChildTxReqAndSigner - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) const ethDeposit = isParentToChildTransactionRequest(params) @@ -301,7 +301,7 @@ export class EthBridger extends AssetBridger< ...params.overrides, }) - return ParentChainTransactionReceipt.monkeyPatchEthDepositWait(tx) + return ParentTransactionReceipt.monkeyPatchEthDepositWait(tx) } /** @@ -340,7 +340,7 @@ export class EthBridger extends AssetBridger< params: | EthDepositToParams | (ParentToChildTxReqAndSigner & { childProvider: Provider }) - ): Promise { + ): Promise { await this.checkParentChain(params.parentSigner) await this.checkChildChain(params.childProvider) @@ -357,7 +357,7 @@ export class EthBridger extends AssetBridger< ...params.overrides, }) - return ParentChainTransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentTransactionReceipt.monkeyPatchContractCallWait(tx) } /** diff --git a/src/lib/message/ChildToParentMessage.ts b/src/lib/message/ChildToParentMessage.ts index eb5fd4e48e..a6889901a4 100644 --- a/src/lib/message/ChildToParentMessage.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -233,7 +233,7 @@ export class ChildToParentMessageReader extends ChildToParentMessage { public async status( childChainProvider: Provider ): Promise { - // can we create an ChildToParentmessage here, we need to - the constructor is what we need + // can we create a ChildToParentMessage here, we need to - the constructor is what we need if (this.nitroReader) return await this.nitroReader.status(childChainProvider) else return await this.classicReader!.status(childChainProvider) diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index 6fc2e7857e..8c9cb6f102 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -62,7 +62,7 @@ export type ChildToParentChainMessageReaderOrWriterNitro< // expected number of parent chain blocks that it takes for a Child chain tx to be included in a parent chain assertion const ASSERTION_CREATED_PADDING = 50 -// expected number of parent chain blocks that it takes for a validator to confirm an parent chain block after the node deadline is passed +// expected number of parent chain blocks that it takes for a validator to confirm a parent chain block after the node deadline is passed const ASSERTION_CONFIRMED_PADDING = 20 const childChainBlockRangeCache: { [key in string]: (number | undefined)[] } = diff --git a/src/lib/message/ChildTransaction.ts b/src/lib/message/ChildTransaction.ts index b8f0ca19c2..1f29c13854 100644 --- a/src/lib/message/ChildTransaction.ts +++ b/src/lib/message/ChildTransaction.ts @@ -91,7 +91,7 @@ export class ChildTransactionReceipt implements TransactionReceipt { } /** - * Get an ChildToParentTxEvent events created by this transaction + * Get {@link ChildToParentTransactionEvent} events created by this transaction * @returns */ public getChildToParentEvents(): ChildToParentTransactionEvent[] { diff --git a/src/lib/message/ParentToChildMessageCreator.ts b/src/lib/message/ParentToChildMessageCreator.ts index e075d1f77a..e06a0105ce 100644 --- a/src/lib/message/ParentToChildMessageCreator.ts +++ b/src/lib/message/ParentToChildMessageCreator.ts @@ -7,8 +7,8 @@ import { ParentToChildMessageGasEstimator, } from './ParentToChildMessageGasEstimator' import { - ParentChainContractTransaction, - ParentChainTransactionReceipt, + ParentContractTransaction, + ParentTransactionReceipt, } from './ParentTransaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' import { getChildChain } from '../dataEntities/networks' @@ -208,7 +208,7 @@ export class ParentToChildMessageCreator { }), childProvider: Provider, options?: GasOverrides - ): Promise { + ): Promise { const parentProvider = SignerProviderUtils.getProviderOrThrow( this.parentSigner ) @@ -226,6 +226,6 @@ export class ParentToChildMessageCreator { ...params.overrides, }) - return ParentChainTransactionReceipt.monkeyPatchWait(tx) + return ParentTransactionReceipt.monkeyPatchWait(tx) } } diff --git a/src/lib/message/ParentToChildMessageGasEstimator.ts b/src/lib/message/ParentToChildMessageGasEstimator.ts index 4f2a64d318..a4b5098d34 100644 --- a/src/lib/message/ParentToChildMessageGasEstimator.ts +++ b/src/lib/message/ParentToChildMessageGasEstimator.ts @@ -210,7 +210,7 @@ export class ParentToChildMessageGasEstimator { } /** - * Get gas limit, gas price and submission price estimates for sending an Parent->Child message + * Get gas limit, gas price and submission price estimates for sending a Parent->Child message * @param retryableData Data of retryable ticket transaction * @param parentBaseFee Current parent chain base fee * @param parentProvider @@ -274,7 +274,7 @@ export class ParentToChildMessageGasEstimator { } /** - * Transactions that make an Parent->Child message need to estimate L2 gas parameters + * Transactions that make a Parent->Child message need to estimate L2 gas parameters * This function does that, and populates those parameters into a transaction request * @param dataFunc * @param parentProvider @@ -283,7 +283,7 @@ export class ParentToChildMessageGasEstimator { */ public async populateFunctionParams( /** - * Function that will internally make an Parent->Child transaction + * Function that will internally make a Parent->Child transaction * Will initially be called with dummy values to trigger a special revert containing * the real params. Then called again with the real params to form the final data to be submitted */ diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index ff0211b9c0..2dd18b0b80 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -48,18 +48,18 @@ import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' import { getArbitrumNetwork } from '../dataEntities/networks' -export interface ParentChainContractTransaction< - TReceipt extends ParentChainTransactionReceipt = ParentChainTransactionReceipt +export interface ParentContractTransaction< + TReceipt extends ParentTransactionReceipt = ParentTransactionReceipt > extends ContractTransaction { wait(confirmations?: number): Promise } // some helper interfaces to reduce the verbosity elsewhere -export type ParentChainEthDepositTransaction = - ParentChainContractTransaction -export type ParentChainContractCallTransaction = - ParentChainContractTransaction +export type ParentEthDepositTransaction = + ParentContractTransaction +export type ParentContractCallTransaction = + ParentContractTransaction -export class ParentChainTransactionReceipt implements TransactionReceipt { +export class ParentTransactionReceipt implements TransactionReceipt { public readonly to: string public readonly from: string public readonly contractAddress: string @@ -297,59 +297,59 @@ export class ParentChainTransactionReceipt implements TransactionReceipt { } /** - * Replaces the wait function with one that returns an ParentChainTransactionReceipt + * Replaces the wait function with one that returns a {@link ParentTransactionReceipt} * @param contractTransaction * @returns */ public static monkeyPatchWait = ( contractTransaction: ContractTransaction - ): ParentChainContractTransaction => { + ): ParentContractTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new ParentChainTransactionReceipt(result) + return new ParentTransactionReceipt(result) } - return contractTransaction as ParentChainContractTransaction + return contractTransaction as ParentContractTransaction } /** - * Replaces the wait function with one that returns an ParentChainEthDepositTransactionReceipt + * Replaces the wait function with one that returns a {@link ParentEthDepositTransactionReceipt} * @param contractTransaction * @returns */ public static monkeyPatchEthDepositWait = ( contractTransaction: ContractTransaction - ): ParentChainEthDepositTransaction => { + ): ParentEthDepositTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new ParentChainEthDepositTransactionReceipt(result) + return new ParentEthDepositTransactionReceipt(result) } - return contractTransaction as ParentChainEthDepositTransaction + return contractTransaction as ParentEthDepositTransaction } /** - * Replaces the wait function with one that returns an ParentChainContractCallTransactionReceipt + * Replaces the wait function with one that returns a {@link ParentContractCallTransactionReceipt} * @param contractTransaction * @returns */ public static monkeyPatchContractCallWait = ( contractTransaction: ContractTransaction - ): ParentChainContractCallTransaction => { + ): ParentContractCallTransaction => { const wait = contractTransaction.wait contractTransaction.wait = async (confirmations?: number) => { const result = await wait(confirmations) - return new ParentChainContractCallTransactionReceipt(result) + return new ParentContractCallTransactionReceipt(result) } - return contractTransaction as ParentChainContractCallTransaction + return contractTransaction as ParentContractCallTransaction } } /** - * An ParentChainTransactionReceipt with additional functionality that only exists + * A {@link ParentTransactionReceipt} with additional functionality that only exists * if the transaction created a single eth deposit. */ -export class ParentChainEthDepositTransactionReceipt extends ParentChainTransactionReceipt { +export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt { /** * Wait for the funds to arrive on the child chain * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have @@ -383,17 +383,17 @@ export class ParentChainEthDepositTransactionReceipt extends ParentChainTransact } /** - * An ParentChainTransactionReceipt with additional functionality that only exists + * A {@link ParentTransactionReceipt} with additional functionality that only exists * if the transaction created a single call to a child chain contract - this includes * token deposits. */ -export class ParentChainContractCallTransactionReceipt extends ParentChainTransactionReceipt { +export class ParentContractCallTransactionReceipt extends ParentTransactionReceipt { /** * Wait for the transaction to arrive and be executed on the child chain * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created * Defaults to 15 minutes, as by this time all transactions are expected to be included on the child chain. Throws on timeout. - * @returns The wait result contains `complete`, a `status`, an ParentToChildMessage and optionally the `childChainTxReceipt`. + * @returns The wait result contains `complete`, a `status`, a {@link ParentToChildMessage} and optionally the `childChainTxReceipt`. * If `complete` is true then this message is in the terminal state. * For contract calls this is true only if the status is REDEEMED. */ diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 603fb48ccf..eb6b024b7e 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -94,7 +94,7 @@ describe('Custom ERC20', () => { ).wait() await depositToken({ depositAmount, - l1TokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -112,7 +112,7 @@ describe('Custom ERC20', () => { amount: withdrawalAmount, gatewayType: GatewayType.CUSTOM, startBalance: depositAmount, - parentChainToken: ERC20__factory.connect( + parentToken: ERC20__factory.connect( testState.l1CustomToken.address, testState.parentSigner.provider! ), @@ -123,7 +123,7 @@ describe('Custom ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -137,7 +137,7 @@ describe('Custom ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.l1CustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, diff --git a/tests/integration/parentToChildMessageCreator.test.ts b/tests/integration/parentToChildMessageCreator.test.ts index 9d1bb7f54a..079ea7ea3c 100644 --- a/tests/integration/parentToChildMessageCreator.test.ts +++ b/tests/integration/parentToChildMessageCreator.test.ts @@ -120,7 +120,7 @@ describe('ParentToChildMessageCreator', () => { // Getting balances const initialChildChainBalance = await childSigner.getBalance() - // In this case, we will try to send directly an ParentToChildTransactionRequest + // In this case, we will try to send directly a ParentToChildTransactionRequest const parentToChildTransactionRequestParams = { from: signerAddress, to: signerAddress, diff --git a/tests/integration/retryableData.test.ts b/tests/integration/retryableData.test.ts index fb55d89e3e..170e4836b4 100644 --- a/tests/integration/retryableData.test.ts +++ b/tests/integration/retryableData.test.ts @@ -153,11 +153,11 @@ describe('RevertData', () => { await testToken.deployed() await (await testToken.mint()).wait() - const l1TokenAddress = testToken.address + const parentTokenAddress = testToken.address await ( await erc20Bridger.approveToken({ - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, parentSigner, }) ).wait() @@ -166,7 +166,7 @@ describe('RevertData', () => { // approve the custom fee token await ( await erc20Bridger.approveGasToken({ - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, parentSigner, }) ).wait() @@ -188,7 +188,7 @@ describe('RevertData', () => { parentSigner, childSignerOrProvider: childSigner.provider!, from: await parentSigner.getAddress(), - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, } diff --git a/tests/integration/sanity.test.ts b/tests/integration/sanity.test.ts index 88f4ff6380..81e6b9e138 100644 --- a/tests/integration/sanity.test.ts +++ b/tests/integration/sanity.test.ts @@ -171,7 +171,7 @@ describe('sanity checks (read-only)', async () => { const address = hexlify(randomBytes(20)) - const erc20L2AddressAsPerL1 = await erc20Bridger.getL2ERC20Address( + const erc20L2AddressAsPerL1 = await erc20Bridger.getChildERC20Address( address, parentSigner.provider! ) diff --git a/tests/integration/sendChildmsg.test.ts b/tests/integration/sendChildmsg.test.ts index 893ac1c1f8..1f1d87bbd0 100644 --- a/tests/integration/sendChildmsg.test.ts +++ b/tests/integration/sendChildmsg.test.ts @@ -38,14 +38,14 @@ const sendSignedTx = async (testState: any, info?: any) => { } const signedTx = await inbox.signChildChainTx(message, childDeployer) - const l1Tx = await inbox.sendChildChainSignedTx(signedTx) + const parentTx = await inbox.sendChildChainSignedTx(signedTx) return { signedMsg: signedTx, - l1TransactionReceipt: await l1Tx?.wait(), + parentTransactionReceipt: await parentTx?.wait(), } } -describe('Send signedTx to l2 using inbox', async () => { +describe('Send signedTx to child chain using inbox', async () => { // test globals let testState: { parentDeployer: Signer @@ -69,49 +69,47 @@ describe('Send signedTx to l2 using inbox', async () => { value: BigNumber.from(0), } const contractCreationData = Greeter.getDeployTransaction(info) - const { signedMsg, l1TransactionReceipt } = await sendSignedTx( + const { signedMsg, parentTransactionReceipt } = await sendSignedTx( testState, contractCreationData ) - const l1Status = l1TransactionReceipt?.status - expect(l1Status).to.equal(1, 'l1 txn failed') - const l2Tx = ethers.utils.parseTransaction(signedMsg) - const l2Txhash = l2Tx.hash! - const l2TxReceipt = await childDeployer.provider!.waitForTransaction( - l2Txhash + const parentStatus = parentTransactionReceipt?.status + expect(parentStatus).to.equal(1, 'parent txn failed') + const childTx = ethers.utils.parseTransaction(signedMsg) + const childTxhash = childTx.hash! + const childTxReceipt = await childDeployer.provider!.waitForTransaction( + childTxhash ) - const l2Status = l2TxReceipt.status - expect(l2Status).to.equal(1, 'l2 txn failed') + const childStatus = childTxReceipt.status + expect(childStatus).to.equal(1, 'child txn failed') const contractAddress = ethers.ContractFactory.getContractAddress({ - from: l2Tx.from!, - nonce: l2Tx.nonce, + from: childTx.from!, + nonce: childTx.nonce, }) const greeterImp = Greeter.attach(contractAddress) const greetResult = await greeterImp.greet() expect(greetResult).to.equal('hello world', 'contract returns not expected') }) - it('should confirm the same tx on l2', async () => { + it('should confirm the same tx on child chain', async () => { const childDeployer = testState.childDeployer const info = { data: '0x12', to: await childDeployer.getAddress(), } - const { signedMsg, l1TransactionReceipt } = await sendSignedTx( - testState, - info - ) - const l1Status = l1TransactionReceipt?.status - expect(l1Status).to.equal(1) - const l2Txhash = ethers.utils.parseTransaction(signedMsg).hash! - const l2TxReceipt = await childDeployer.provider!.waitForTransaction( - l2Txhash + const { signedMsg, parentTransactionReceipt: parentTransactionReceipt } = + await sendSignedTx(testState, info) + const parentStatus = parentTransactionReceipt?.status + expect(parentStatus).to.equal(1) + const childTxhash = ethers.utils.parseTransaction(signedMsg).hash! + const childTxReceipt = await childDeployer.provider!.waitForTransaction( + childTxhash ) - const l2Status = l2TxReceipt.status - expect(l2Status).to.equal(1) + const childStatus = childTxReceipt.status + expect(childStatus).to.equal(1) }) - it('send two tx share the same nonce but with different gas price, should confirm the one which gas price higher than l2 base price', async () => { + it('send two tx share the same nonce but with different gas price, should confirm the one which gas price higher than child base price', async () => { const childDeployer = testState.childDeployer const currentNonce = await childDeployer.getTransactionCount() @@ -123,28 +121,28 @@ describe('Send signedTx to l2 using inbox', async () => { maxPriorityFeePerGas: BigNumber.from(1000000), //0.001gwei } const lowFeeTx = await sendSignedTx(testState, lowFeeInfo) - const lowFeeL1Status = lowFeeTx.l1TransactionReceipt?.status - expect(lowFeeL1Status).to.equal(1) + const lowFeeParentStatus = lowFeeTx.parentTransactionReceipt?.status + expect(lowFeeParentStatus).to.equal(1) const info = { data: '0x12', to: await childDeployer.getAddress(), nonce: currentNonce, } const enoughFeeTx = await sendSignedTx(testState, info) - const enoughFeeL1Status = enoughFeeTx.l1TransactionReceipt?.status - expect(enoughFeeL1Status).to.equal(1) - const l2LowFeeTxhash = ethers.utils.parseTransaction(lowFeeTx.signedMsg) + const enoughFeeParentStatus = enoughFeeTx.parentTransactionReceipt?.status + expect(enoughFeeParentStatus).to.equal(1) + const childLowFeeTxhash = ethers.utils.parseTransaction(lowFeeTx.signedMsg) .hash! - const l2EnoughFeeTxhash = ethers.utils.parseTransaction( + const childEnoughFeeTxhash = ethers.utils.parseTransaction( enoughFeeTx.signedMsg ).hash! - const l2TEnoughFeeReceipt = - await childDeployer.provider!.waitForTransaction(l2EnoughFeeTxhash) - const l2Status = l2TEnoughFeeReceipt.status - expect(l2Status).to.equal(1) + const childTEnoughFeeReceipt = + await childDeployer.provider!.waitForTransaction(childEnoughFeeTxhash) + const childStatus = childTEnoughFeeReceipt.status + expect(childStatus).to.equal(1) const res = await childDeployer.provider?.getTransactionReceipt( - l2LowFeeTxhash + childLowFeeTxhash ) expect(res).to.be.null }) diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 11c1e6c1e2..af08fc29ca 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -130,7 +130,7 @@ describe('standard ERC20', () => { await depositToken({ depositAmount, - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -164,7 +164,7 @@ describe('standard ERC20', () => { it('deposit with no funds, manual redeem', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -182,7 +182,7 @@ describe('standard ERC20', () => { it('deposit with low funds, manual redeem', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -202,7 +202,7 @@ describe('standard ERC20', () => { // redeem transaction const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -234,7 +234,7 @@ describe('standard ERC20', () => { it('deposit with low funds, fails first redeem, succeeds seconds', async () => { const { waitRes } = await depositToken({ depositAmount, - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -268,7 +268,7 @@ describe('standard ERC20', () => { }) it('withdraws erc20', async function () { - const l2TokenAddr = await testState.erc20Bridger.getL2ERC20Address( + const l2TokenAddr = await testState.erc20Bridger.getChildERC20Address( testState.parentToken.address, testState.parentSigner.provider! ) @@ -292,7 +292,7 @@ describe('standard ERC20', () => { amount: withdrawalAmount, gatewayType: GatewayType.STANDARD, startBalance: startBalance, - parentChainToken: ERC20__factory.connect( + parentToken: ERC20__factory.connect( testState.parentToken.address, testState.parentSigner.provider! ), @@ -303,7 +303,7 @@ describe('standard ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -317,7 +317,7 @@ describe('standard ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - l1TokenAddress: testState.parentToken.address, + parentTokenAddress: testState.parentToken.address, erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index d27e3f4f23..a2a1c6b5b6 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -57,7 +57,7 @@ interface WithdrawalParams { startBalance: BigNumber amount: BigNumber erc20Bridger: Erc20Bridger - parentChainToken: ERC20 + parentToken: ERC20 childSigner: Signer parentSigner: Signer gatewayType: GatewayType @@ -85,7 +85,7 @@ export const mineUntilStop = async ( export const withdrawToken = async (params: WithdrawalParams) => { const withdrawalParams = await params.erc20Bridger.getWithdrawalRequest({ amount: params.amount, - erc20ParentAddress: params.parentChainToken.address, + erc20ParentAddress: params.parentToken.address, destinationAddress: await params.childSigner.getAddress(), from: await params.childSigner.getAddress(), }) @@ -96,7 +96,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { const withdrawRes = await params.erc20Bridger.withdraw({ destinationAddress: await params.childSigner.getAddress(), amount: params.amount, - erc20ParentAddress: params.parentChainToken.address, + erc20ParentAddress: params.parentToken.address, childSigner: params.childSigner, }) const withdrawRec = await withdrawRes.wait() @@ -112,8 +112,8 @@ export const withdrawToken = async (params: WithdrawalParams) => { ChildToParentMessageStatus.UNCONFIRMED ) - const childChainTokenAddr = await params.erc20Bridger.getL2ERC20Address( - params.parentChainToken.address, + const childChainTokenAddr = await params.erc20Bridger.getChildERC20Address( + params.parentToken.address, params.parentSigner.provider! ) const childChainToken = params.erc20Bridger.getChildTokenContract( @@ -130,7 +130,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { const walletAddress = await params.parentSigner.getAddress() const gatewayAddress = await params.erc20Bridger.getL2GatewayAddress( - params.parentChainToken.address, + params.parentToken.address, params.childSigner.provider! ) @@ -146,16 +146,16 @@ export const withdrawToken = async (params: WithdrawalParams) => { params.childSigner.provider!, gatewayAddress, { fromBlock: withdrawRec.blockNumber, toBlock: 'latest' }, - params.parentChainToken.address, + params.parentToken.address, walletAddress ) expect(gatewayWithdrawEvents.length).to.equal(1, 'token query failed') - const balBefore = await params.parentChainToken.balanceOf( + const balBefore = await params.parentToken.balanceOf( await params.parentSigner.getAddress() ) - // whilst waiting for status we miner on both l1 and l2 + // whilst waiting for status we miner on both parent and child chains const miner1 = Wallet.createRandom().connect(params.parentSigner.provider!) const miner2 = Wallet.createRandom().connect(params.childSigner.provider!) await fundParentSigner(miner1, parseEther('1')) @@ -186,7 +186,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { 'executed status' ).to.eq(ChildToParentMessageStatus.EXECUTED) - const balAfter = await params.parentChainToken.balanceOf( + const balAfter = await params.parentToken.balanceOf( await params.parentSigner.getAddress() ) expect(balBefore.add(params.amount).toString(), 'Not withdrawn').to.eq( @@ -219,7 +219,7 @@ const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { /** * Deposits a token and tests that it occurred correctly * @param depositAmount - * @param l1TokenAddress + * @param parentTokenAddress * @param erc20Bridger * @param parentSigner * @param childSigner @@ -227,7 +227,7 @@ const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { export const depositToken = async ({ depositAmount, ethDepositAmount, - l1TokenAddress, + parentTokenAddress, erc20Bridger, parentSigner, childSigner, @@ -238,7 +238,7 @@ export const depositToken = async ({ }: { depositAmount: BigNumber ethDepositAmount?: BigNumber - l1TokenAddress: string + parentTokenAddress: string erc20Bridger: Erc20Bridger parentSigner: Signer childSigner: Signer @@ -249,7 +249,7 @@ export const depositToken = async ({ }) => { await ( await erc20Bridger.approveToken({ - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, parentSigner, }) ).wait() @@ -257,14 +257,14 @@ export const depositToken = async ({ const senderAddress = await parentSigner.getAddress() const expectedParentChainGatewayAddress = await erc20Bridger.getL1GatewayAddress( - l1TokenAddress, + parentTokenAddress, parentSigner.provider! ) - const parentChainToken = erc20Bridger.getParentChainTokenContract( + const parentToken = erc20Bridger.getParentTokenContract( parentSigner.provider!, - l1TokenAddress + parentTokenAddress ) - const allowance = await parentChainToken.allowance( + const allowance = await parentToken.allowance( senderAddress, expectedParentChainGatewayAddress ) @@ -275,7 +275,7 @@ export const depositToken = async ({ await ( await erc20Bridger.approveGasToken({ parentSigner, - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, }) ).wait() @@ -293,12 +293,10 @@ export const depositToken = async ({ ).to.be.true } - const initialBridgeTokenBalance = await parentChainToken.balanceOf( + const initialBridgeTokenBalance = await parentToken.balanceOf( expectedParentChainGatewayAddress ) - const parentTokenBalanceBefore = await parentChainToken.balanceOf( - senderAddress - ) + const parentTokenBalanceBefore = await parentToken.balanceOf(senderAddress) const childChainEthBalanceBefore = await childSigner.provider!.getBalance( destinationAddress || senderAddress ) @@ -306,7 +304,7 @@ export const depositToken = async ({ const depositRes = await erc20Bridger.deposit({ parentSigner, childProvider: childSigner.provider!, - erc20ParentAddress: l1TokenAddress, + erc20ParentAddress: parentTokenAddress, amount: depositAmount, retryableGasOverrides: retryableOverrides, maxSubmissionCost: ethDepositAmount, @@ -315,7 +313,7 @@ export const depositToken = async ({ }) const depositRec = await depositRes.wait() - const finalBridgeTokenBalance = await parentChainToken.balanceOf( + const finalBridgeTokenBalance = await parentToken.balanceOf( expectedParentChainGatewayAddress ) expect( @@ -327,9 +325,7 @@ export const depositToken = async ({ ? 0 : initialBridgeTokenBalance.add(depositAmount).toNumber() ) - const parentTokenBalanceAfter = await parentChainToken.balanceOf( - senderAddress - ) + const parentTokenBalanceAfter = await parentToken.balanceOf(senderAddress) expect(parentTokenBalanceAfter.toString(), 'user bal after').to.eq( parentTokenBalanceBefore.sub(depositAmount).toString() ) @@ -343,7 +339,7 @@ export const depositToken = async ({ expect(waitRes.status, 'Unexpected status').to.eq(expectedStatus) if (retryableOverrides) { return { - parentChainToken, + parentToken, waitRes, } } @@ -354,7 +350,7 @@ export const depositToken = async ({ ) const parentChainGateway = await erc20Bridger.getL1GatewayAddress( - l1TokenAddress, + parentTokenAddress, parentSigner.provider! ) expect(parentChainGateway, 'incorrect parent chain gateway address').to.eq( @@ -362,27 +358,27 @@ export const depositToken = async ({ ) const childChainGateway = await erc20Bridger.getL2GatewayAddress( - l1TokenAddress, + parentTokenAddress, childSigner.provider! ) expect(childChainGateway, 'incorrect child chain gateway address').to.eq( expectedL2Gateway ) - const childChainErc20Addr = await erc20Bridger.getL2ERC20Address( - l1TokenAddress, + const childChainErc20Addr = await erc20Bridger.getChildERC20Address( + parentTokenAddress, parentSigner.provider! ) const childChainToken = erc20Bridger.getChildTokenContract( childSigner.provider!, childChainErc20Addr ) - const parentChainErc20Addr = await erc20Bridger.getL1ERC20Address( + const parentChainErc20Addr = await erc20Bridger.getParentERC20Address( childChainErc20Addr, childSigner.provider! ) expect(parentChainErc20Addr).to.equal( - l1TokenAddress, + parentTokenAddress, 'getERC20L1Address/getERC20L2Address failed with proper token address' ) @@ -408,7 +404,7 @@ export const depositToken = async ({ ).to.be.true } - return { parentChainToken, waitRes, childChainToken } + return { parentToken, waitRes, childChainToken } } const fund = async ( diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index a11910b602..1d35219ad2 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -65,7 +65,7 @@ describeOnlyWhenEth('WETH', async () => { await res.wait() await depositToken({ depositAmount: wethToDeposit, - l1TokenAddress: l1WethAddress, + parentTokenAddress: l1WethAddress, erc20Bridger, parentSigner, childSigner, @@ -124,7 +124,7 @@ describeOnlyWhenEth('WETH', async () => { erc20Bridger: erc20Bridger, gatewayType: GatewayType.WETH, parentSigner: parentSigner, - parentChainToken: ERC20__factory.connect( + parentToken: ERC20__factory.connect( childChain.tokenBridge.l1Weth, parentSigner.provider! ), diff --git a/tests/unit/childBlocksForParentBlock.test.ts b/tests/unit/childBlocksForParentBlock.test.ts index 2a3e1deb1a..023e669cc1 100644 --- a/tests/unit/childBlocksForParentBlock.test.ts +++ b/tests/unit/childBlocksForParentBlock.test.ts @@ -2,32 +2,32 @@ import { BigNumber } from 'ethers' import { expect } from 'chai' import { JsonRpcProvider } from '@ethersproject/providers' import { - getBlockRangesForL1Block, - getFirstBlockForL1Block, + getBlockRangesForL1Block as getBlockRangesForParentBlock, + getFirstBlockForL1Block as getFirstBlockForParentBlock, } from '../../src/lib/utils/lib' import { ArbitrumProvider } from '../../src/lib/utils/arbProvider' import { ArbBlock } from '../../src/lib/dataEntities/rpc' -describe('L2 blocks lookup for an L1 block', () => { +describe('Child blocks lookup for a Parent block', () => { const provider = new JsonRpcProvider('https://arb1.arbitrum.io/rpc') const arbProvider = new ArbitrumProvider(provider) - async function validateL2Blocks({ - l2Blocks, - l2BlocksCount, + async function validateChildBlocks({ + childBlocks, + childBlocksCount, type = 'number', }: { - l2Blocks: (number | undefined)[] - l2BlocksCount: number + childBlocks: (number | undefined)[] + childBlocksCount: number type?: 'number' | 'undefined' }) { - if (l2Blocks.length !== l2BlocksCount) { + if (childBlocks.length !== childBlocksCount) { throw new Error( - `Expected L2 block range to have the array length of ${l2BlocksCount}, got ${l2Blocks.length}.` + `Expected Child block range to have the array length of ${childBlocksCount}, got ${childBlocks.length}.` ) } - if (l2Blocks.some(block => typeof block !== type)) { + if (childBlocks.some(block => typeof block !== type)) { throw new Error(`Expected all blocks to be ${type}.`) } @@ -37,14 +37,14 @@ describe('L2 blocks lookup for an L1 block', () => { const promises: Promise[] = [] - l2Blocks.forEach((l2Block, index) => { - if (!l2Block) { - throw new Error('L2 block is undefined.') + childBlocks.forEach((childBlock, index) => { + if (!childBlock) { + throw new Error('Child block is undefined.') } const isStartBlock = index === 0 - promises.push(arbProvider.getBlock(l2Block)) + promises.push(arbProvider.getBlock(childBlock)) // Search for previous or next block. - promises.push(arbProvider.getBlock(l2Block + (isStartBlock ? -1 : 1))) + promises.push(arbProvider.getBlock(childBlock + (isStartBlock ? -1 : 1))) }) const [startBlock, blockBeforeStartBlock, endBlock, blockAfterEndBlock] = @@ -55,48 +55,52 @@ describe('L2 blocks lookup for an L1 block', () => { if (startBlock && blockBeforeStartBlock) { const startBlockCondition = startBlock.gt(blockBeforeStartBlock) - // Check if Arbitrum start block is the first block for this L1 block. + // Check if Arbitrum start block is the first block for this parent block. expect( startBlockCondition, - `L2 block is not the first block in range for L1 block.` + `Child block is not the first block in range for parent block.` ).to.be.true } if (endBlock && blockAfterEndBlock) { const endBlockCondition = endBlock.lt(blockAfterEndBlock) - // Check if Arbitrum end block is the last block for this L1 block. + // Check if Arbitrum end block is the last block for this parent block. expect( endBlockCondition, - `L2 block is not the last block in range for L1 block.` + `Child block is not the last block in range for parent block.` ).to.be.true } } - it('successfully searches for an L2 block range', async function () { - const l2Blocks = await getBlockRangesForL1Block({ + it('successfully searches for an Child block range', async function () { + const childBlocks = await getBlockRangesForParentBlock({ provider: arbProvider, forL1Block: 17926532, // Expected result: 121907680. Narrows down the range to speed up the search. minL2Block: 121800000, maxL2Block: 122000000, }) - await validateL2Blocks({ l2Blocks, l2BlocksCount: 2 }) + await validateChildBlocks({ childBlocks, childBlocksCount: 2 }) }) - it('fails to search for an L2 block range', async function () { - const l2Blocks = await getBlockRangesForL1Block({ + it('fails to search for an Child block range', async function () { + const childBlocks = await getBlockRangesForParentBlock({ provider: arbProvider, forL1Block: 17926533, minL2Block: 121800000, maxL2Block: 122000000, }) - await validateL2Blocks({ l2Blocks, l2BlocksCount: 2, type: 'undefined' }) + await validateChildBlocks({ + childBlocks, + childBlocksCount: 2, + type: 'undefined', + }) }) - it('successfully searches for the first L2 block', async function () { - const l2Blocks = [ - await getFirstBlockForL1Block({ + it('successfully searches for the first Child block', async function () { + const childBlocks = [ + await getFirstBlockForParentBlock({ provider: arbProvider, forL1Block: 17926532, // Expected result: 121907680. Narrows down the range to speed up the search. @@ -104,12 +108,12 @@ describe('L2 blocks lookup for an L1 block', () => { maxL2Block: 122000000, }), ] - await validateL2Blocks({ l2Blocks, l2BlocksCount: 1 }) + await validateChildBlocks({ childBlocks, childBlocksCount: 1 }) }) - it('fails to search for the first L2 block, while not using `allowGreater` flag', async function () { - const l2Blocks = [ - await getFirstBlockForL1Block({ + it('fails to search for the first Child block, while not using `allowGreater` flag', async function () { + const childBlocks = [ + await getFirstBlockForParentBlock({ provider: arbProvider, forL1Block: 17926533, allowGreater: false, @@ -117,12 +121,16 @@ describe('L2 blocks lookup for an L1 block', () => { maxL2Block: 122000000, }), ] - await validateL2Blocks({ l2Blocks, l2BlocksCount: 1, type: 'undefined' }) + await validateChildBlocks({ + childBlocks, + childBlocksCount: 1, + type: 'undefined', + }) }) - it('successfully searches for the first L2 block, while using `allowGreater` flag', async function () { - const l2Blocks = [ - await getFirstBlockForL1Block({ + it('successfully searches for the first Child block, while using `allowGreater` flag', async function () { + const childBlocks = [ + await getFirstBlockForParentBlock({ provider: arbProvider, forL1Block: 17926533, allowGreater: true, @@ -131,6 +139,6 @@ describe('L2 blocks lookup for an L1 block', () => { maxL2Block: 122000000, }), ] - await validateL2Blocks({ l2Blocks, l2BlocksCount: 1 }) + await validateChildBlocks({ childBlocks, childBlocksCount: 1 }) }) }) diff --git a/tests/unit/parentToChildMessageEvents.test.ts b/tests/unit/parentToChildMessageEvents.test.ts index 712359b4ba..a71f707741 100644 --- a/tests/unit/parentToChildMessageEvents.test.ts +++ b/tests/unit/parentToChildMessageEvents.test.ts @@ -1,4 +1,4 @@ -import { ParentChainTransactionReceipt } from './../../src/lib/message/ParentTransaction' +import { ParentTransactionReceipt } from './../../src/lib/message/ParentTransaction' import { BigNumber, constants, providers } from 'ethers' import { JsonRpcProvider } from '@ethersproject/providers' import { expect } from 'chai' @@ -150,12 +150,12 @@ describe('ParentToChildMessage events', () => { } const arbProvider = new JsonRpcProvider('https://arb1.arbitrum.io/rpc') - const parentChainTxnReceipt = new ParentChainTransactionReceipt(receipt) + const parentTxnReceipt = new ParentTransactionReceipt(receipt) let txReceipt try { // Try getting classic messages using a nitro tx - txReceipt = await parentChainTxnReceipt.getParentToChildMessagesClassic( + txReceipt = await parentTxnReceipt.getParentToChildMessagesClassic( arbProvider ) } catch (err) { @@ -172,9 +172,9 @@ describe('ParentToChildMessage events', () => { ).to.be.undefined } - const isClassic = await parentChainTxnReceipt.isClassic(arbProvider) + const isClassic = await parentTxnReceipt.isClassic(arbProvider) const msg = ( - await parentChainTxnReceipt.getParentToChildMessages(arbProvider) + await parentTxnReceipt.getParentToChildMessages(arbProvider) )[0] expect(isClassic, 'incorrect tx type returned by isClassic call').to.be @@ -290,14 +290,12 @@ describe('ParentToChildMessage events', () => { } const arbProvider = new JsonRpcProvider('https://arb1.arbitrum.io/rpc') - const parentChainTxnReceipt = new ParentChainTransactionReceipt(receipt) + const parentTxnReceipt = new ParentTransactionReceipt(receipt) let txReceipt try { // Try getting nitro messages using a classic tx - txReceipt = await parentChainTxnReceipt.getParentToChildMessages( - arbProvider - ) + txReceipt = await parentTxnReceipt.getParentToChildMessages(arbProvider) } catch (err) { // This call should throw an error expect(err).to.be.an('error') @@ -312,9 +310,9 @@ describe('ParentToChildMessage events', () => { ).to.be.undefined } - const isClassic = await parentChainTxnReceipt.isClassic(arbProvider) + const isClassic = await parentTxnReceipt.isClassic(arbProvider) const msg = ( - await parentChainTxnReceipt.getParentToChildMessagesClassic(arbProvider) + await parentTxnReceipt.getParentToChildMessagesClassic(arbProvider) )[0] const status = await msg.status() From f7fe00ec24cc9b7f92198a740a5e7c5e005e274d Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 17 Apr 2024 14:34:14 +0200 Subject: [PATCH 24/74] feat: remove some network properties (#449) --- scripts/testSetup.ts | 1 - src/lib/dataEntities/constants.ts | 24 +++++++ src/lib/dataEntities/networks.ts | 67 ++++++------------- src/lib/message/ChildToParentMessage.ts | 11 +-- src/lib/message/ParentToChildMessage.ts | 22 +++--- src/lib/message/ParentTransaction.ts | 9 ++- src/lib/utils/lib.ts | 8 +-- tests/unit/childToParentMessageEvents.test.ts | 23 ++++--- tests/unit/multicall.test.ts | 7 +- 9 files changed, 89 insertions(+), 83 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index d711a13556..bd86f972d9 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -117,7 +117,6 @@ export const testSetup = async (): Promise<{ const ethLocal: L1Network = { blockTime: 10, chainID: _parentChain.partnerChainID, - explorerUrl: '', isCustom: true, name: 'EthLocal', partnerChainIDs: [_parentChain.chainID], diff --git a/src/lib/dataEntities/constants.ts b/src/lib/dataEntities/constants.ts index 4fea86d645..ce055b9fc2 100644 --- a/src/lib/dataEntities/constants.ts +++ b/src/lib/dataEntities/constants.ts @@ -52,3 +52,27 @@ export const DISABLED_GATEWAY = '0x0000000000000000000000000000000000000001' export const CUSTOM_TOKEN_IS_ENABLED = 42161 export const SEVEN_DAYS_IN_SECONDS = 7 * 24 * 60 * 60 + +/** + * How long to wait (in milliseconds) for a deposit to arrive before timing out a request. + * + * Finalisation on mainnet can be up to 2 epochs = 64 blocks. + * We add 10 minutes for the system to create and redeem the ticket, plus some extra buffer of time. + * + * Total timeout: 30 minutes. + */ +export const DEFAULT_DEPOSIT_TIMEOUT = 30 * 60 * 1000 + +/** + * The L1 block at which Nitro was activated for Arbitrum One. + * + * @see https://etherscan.io/block/15447158 + */ +export const ARB1_NITRO_GENESIS_L1_BLOCK = 15447158 + +/** + * The L2 block at which Nitro was activated for Arbitrum One. + * + * @see https://arbiscan.io/block/22207817 + */ +export const ARB1_NITRO_GENESIS_L2_BLOCK = 22207817 diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 2b3880ad13..7b07b3b60c 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -19,7 +19,7 @@ import { SignerOrProvider, SignerProviderUtils } from './signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' import { - SEVEN_DAYS_IN_SECONDS, + ARB1_NITRO_GENESIS_L2_BLOCK, ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, } from './constants' import { RollupAdminLogic__factory } from '../abi/factories/RollupAdminLogic__factory' @@ -27,8 +27,6 @@ import { RollupAdminLogic__factory } from '../abi/factories/RollupAdminLogic__fa export interface Network { chainID: number name: string - explorerUrl: string - gif?: string isCustom: boolean /** * Minimum possible block time for the chain (in seconds). @@ -59,13 +57,10 @@ export interface ArbitrumNetwork extends Network { partnerChainID: number isArbitrum: true confirmPeriodBlocks: number - retryableLifetimeSeconds: number - nitroGenesisBlock: number - nitroGenesisL1Block: number /** - * How long to wait (ms) for a deposit to arrive on l2 before timing out a request + * Represents how long a retryable ticket lasts for before it expires (in seconds). Defaults to 7 days. */ - depositTimeout: number + retryableLifetimeSeconds?: number /** * In case of a chain that uses ETH as its native/gas token, this is either `undefined` or the zero address * @@ -150,7 +145,6 @@ export const networks: Networks = { 1: { chainID: 1, name: 'Mainnet', - explorerUrl: 'https://etherscan.io', partnerChainIDs: [42161, 42170], blockTime: 14, isCustom: false, @@ -159,7 +153,6 @@ export const networks: Networks = { 1338: { chainID: 1338, name: 'Hardhat_Mainnet_Fork', - explorerUrl: 'https://etherscan.io', partnerChainIDs: [42161], blockTime: 1, isCustom: false, @@ -168,7 +161,6 @@ export const networks: Networks = { 11155111: { chainID: 11155111, name: 'Sepolia', - explorerUrl: 'https://sepolia.etherscan.io', partnerChainIDs: [421614], blockTime: 12, isCustom: false, @@ -177,7 +169,6 @@ export const networks: Networks = { 17000: { chainID: 17000, name: 'Holesky', - explorerUrl: 'https://holesky.etherscan.io', partnerChainIDs: [], blockTime: 12, isCustom: false, @@ -186,7 +177,6 @@ export const networks: Networks = { 42161: { chainID: 42161, name: 'Arbitrum One', - explorerUrl: 'https://arbiscan.io', partnerChainID: 1, partnerChainIDs: [], isArbitrum: true, @@ -194,15 +184,6 @@ export const networks: Networks = { ethBridge: mainnetETHBridge, confirmPeriodBlocks: 45818, isCustom: false, - retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, - nitroGenesisBlock: 22207817, - nitroGenesisL1Block: 15447158, - /** - * Finalisation on mainnet can be up to 2 epochs = 64 blocks on mainnet - * We add 10 minutes for the system to create and redeem the ticket, plus some extra buffer of time - * (Total timeout: 30 minutes) - */ - depositTimeout: 1800000, blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 42170: { @@ -215,13 +196,11 @@ export const networks: Networks = { rollup: '0xFb209827c58283535b744575e11953DCC4bEAD88', sequencerInbox: '0x211E1c4c7f1bF5351Ac850Ed10FD68CFfCF6c21b', }, - explorerUrl: 'https://nova.arbiscan.io', isArbitrum: true, isCustom: false, name: 'Arbitrum Nova', partnerChainID: 1, partnerChainIDs: [], - retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', l1ERC20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', @@ -238,14 +217,6 @@ export const networks: Networks = { l2Weth: '0x722E8BdD2ce80A4422E880164f2079488e115365', l2WethGateway: '0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD', }, - nitroGenesisBlock: 0, - nitroGenesisL1Block: 0, - /** - * Finalisation on mainnet can be up to 2 epochs = 64 blocks on mainnet - * We add 10 minutes for the system to create and redeem the ticket, plus some extra buffer of time - * (Total timeout: 30 minutes) - */ - depositTimeout: 1800000, blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 421614: { @@ -258,13 +229,11 @@ export const networks: Networks = { rollup: '0xd80810638dbDF9081b72C1B33c65375e807281C8', sequencerInbox: '0x6c97864CE4bEf387dE0b3310A44230f7E3F1be0D', }, - explorerUrl: 'https://sepolia-explorer.arbitrum.io', isArbitrum: true, isCustom: false, name: 'Arbitrum Rollup Sepolia Testnet', partnerChainID: 11155111, partnerChainIDs: [23011913], - retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', l1ERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', @@ -281,9 +250,6 @@ export const networks: Networks = { l2Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', l2WethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D', }, - nitroGenesisBlock: 0, - nitroGenesisL1Block: 0, - depositTimeout: 1800000, blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 23011913: { @@ -296,13 +262,11 @@ export const networks: Networks = { rollup: '0x94db9E36d9336cD6F9FfcAd399dDa6Cc05299898', sequencerInbox: '0x00A0F15b79d1D3e5991929FaAbCF2AA65623530c', }, - explorerUrl: 'https://stylus-testnet-explorer.arbitrum.io', isArbitrum: true, isCustom: false, name: 'Stylus Testnet', partnerChainID: 421614, partnerChainIDs: [], - retryableLifetimeSeconds: SEVEN_DAYS_IN_SECONDS, tokenBridge: { l1CustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', l1ERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', @@ -319,9 +283,6 @@ export const networks: Networks = { l2Weth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C', l2WethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175', }, - nitroGenesisBlock: 0, - nitroGenesisL1Block: 0, - depositTimeout: 900000, blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, } @@ -598,7 +559,6 @@ export const addDefaultLocalNetwork = (): { const defaultLocalL1Network: L1Network = { blockTime: 10, chainID: 1337, - explorerUrl: '', isCustom: true, name: 'EthLocal', partnerChainIDs: [412346], @@ -615,16 +575,11 @@ export const addDefaultLocalNetwork = (): { rollup: '0x65a59D67Da8e710Ef9A01eCa37f83f84AEdeC416', sequencerInbox: '0xE7362D0787b51d8C72D504803E5B1d6DcdA89540', }, - explorerUrl: '', isArbitrum: true, isCustom: true, name: 'ArbLocal', partnerChainID: 1337, partnerChainIDs: [], - retryableLifetimeSeconds: 604800, - nitroGenesisBlock: 0, - nitroGenesisL1Block: 0, - depositTimeout: 900000, tokenBridge: { l1CustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', l1ERC20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', @@ -671,6 +626,22 @@ const createNetworkStateHandler = () => { } } +export function getNitroGenesisBlock( + arbitrumChainOrChainId: ArbitrumNetwork | number +) { + const arbitrumChainId = + typeof arbitrumChainOrChainId === 'number' + ? arbitrumChainOrChainId + : arbitrumChainOrChainId.chainID + + // all networks except Arbitrum One started off with Nitro + if (arbitrumChainId === 42161) { + return ARB1_NITRO_GENESIS_L2_BLOCK + } + + return 0 +} + const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } diff --git a/src/lib/message/ChildToParentMessage.ts b/src/lib/message/ChildToParentMessage.ts index a6889901a4..59c9ae5c4a 100644 --- a/src/lib/message/ChildToParentMessage.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -35,7 +35,7 @@ import { import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' import { ChildToParentMessageStatus } from '../dataEntities/message' -import { getChildChain } from '../dataEntities/networks' +import { getChildChain, getNitroGenesisBlock } from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' export type ChildToParentTransactionEvent = @@ -112,6 +112,7 @@ export class ChildToParentMessage { indexInBatch?: BigNumber ): Promise<(ChildToParentTransactionEvent & { transactionHash: string })[]> { const childChain = await getChildChain(childChainProvider) + const childChainNitroGenesisBlock = getNitroGenesisBlock(childChain) const inClassicRange = (blockTag: BlockTag, nitroGenBlock: number) => { if (typeof blockTag === 'string') { @@ -154,8 +155,8 @@ export class ChildToParentMessage { // only fetch nitro events after the genesis block const classicFilter = { - fromBlock: inClassicRange(filter.fromBlock, childChain.nitroGenesisBlock), - toBlock: inClassicRange(filter.toBlock, childChain.nitroGenesisBlock), + fromBlock: inClassicRange(filter.fromBlock, childChainNitroGenesisBlock), + toBlock: inClassicRange(filter.toBlock, childChainNitroGenesisBlock), } const logQueries = [] if (classicFilter.fromBlock !== classicFilter.toBlock) { @@ -172,8 +173,8 @@ export class ChildToParentMessage { } const nitroFilter = { - fromBlock: inNitroRange(filter.fromBlock, childChain.nitroGenesisBlock), - toBlock: inNitroRange(filter.toBlock, childChain.nitroGenesisBlock), + fromBlock: inNitroRange(filter.fromBlock, childChainNitroGenesisBlock), + toBlock: inNitroRange(filter.toBlock, childChainNitroGenesisBlock), } if (nitroFilter.fromBlock !== nitroFilter.toBlock) { logQueries.push( diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index 558a9a74c5..692a34f7e2 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -26,7 +26,11 @@ import { getAddress } from '@ethersproject/address' import { keccak256 } from '@ethersproject/keccak256' import { ArbRetryableTx__factory } from '../abi/factories/ArbRetryableTx__factory' -import { ARB_RETRYABLE_TX_ADDRESS } from '../dataEntities/constants' +import { + ARB_RETRYABLE_TX_ADDRESS, + DEFAULT_DEPOSIT_TIMEOUT, + SEVEN_DAYS_IN_SECONDS, +} from '../dataEntities/constants' import { SignerProviderUtils, SignerOrProvider, @@ -356,7 +360,9 @@ export class ParentToChildMessageReader extends ParentToChildMessage { let fromBlock = await this.chainProvider.getBlock( creationReceipt.blockNumber ) - let timeout = fromBlock.timestamp + chainNetwork.retryableLifetimeSeconds + let timeout = + fromBlock.timestamp + + (chainNetwork.retryableLifetimeSeconds ?? SEVEN_DAYS_IN_SECONDS) const queriedRange: { from: number; to: number }[] = [] const maxBlock = await this.chainProvider.getBlockNumber() while (fromBlock.number < maxBlock) { @@ -487,11 +493,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { confirmations?: number, timeout?: number ): Promise { - const chainNetwork = await getChildChain(this.chainId) - - const chosenTimeout = isDefined(timeout) - ? timeout - : chainNetwork.depositTimeout + const chosenTimeout = isDefined(timeout) ? timeout : DEFAULT_DEPOSIT_TIMEOUT // try to wait for the retryable ticket to be created const _retryableCreationReceipt = await this.getRetryableCreationReceipt( @@ -873,11 +875,7 @@ export class EthDepositMessage { } public async wait(confirmations?: number, timeout?: number) { - const chainNetwork = await getChildChain(this.chainChainId) - - const chosenTimeout = isDefined(timeout) - ? timeout - : chainNetwork.depositTimeout + const chosenTimeout = isDefined(timeout) ? timeout : DEFAULT_DEPOSIT_TIMEOUT if (!this.chainDepositTxReceipt) { this.chainDepositTxReceipt = await getTransactionReceipt( diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 2dd18b0b80..7c82c1ff12 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -47,6 +47,7 @@ import { EventArgs, parseTypedLogs } from '../dataEntities/event' import { isDefined } from '../utils/lib' import { SubmitRetryableMessageDataParser } from './messageDataParser' import { getArbitrumNetwork } from '../dataEntities/networks' +import { ARB1_NITRO_GENESIS_L1_BLOCK } from '../dataEntities/constants' export interface ParentContractTransaction< TReceipt extends ParentTransactionReceipt = ParentTransactionReceipt @@ -109,7 +110,13 @@ export class ParentTransactionReceipt implements TransactionReceipt { childSignerOrProvider ) const network = await getArbitrumNetwork(provider) - return this.blockNumber < network.nitroGenesisL1Block + + // all networks except Arbitrum One started off with Nitro + if (network.chainID === 42161) { + return this.blockNumber < ARB1_NITRO_GENESIS_L1_BLOCK + } + + return false } /** diff --git a/src/lib/utils/lib.ts b/src/lib/utils/lib.ts index b53c6f6f29..a195ed23a2 100644 --- a/src/lib/utils/lib.ts +++ b/src/lib/utils/lib.ts @@ -2,9 +2,9 @@ import { Provider } from '@ethersproject/abstract-provider' import { TransactionReceipt, JsonRpcProvider } from '@ethersproject/providers' import { ArbSdkError } from '../dataEntities/errors' import { ArbitrumProvider } from './arbProvider' -import { l2Networks } from '../dataEntities/networks' import { ArbSys__factory } from '../abi/factories/ArbSys__factory' import { ARB_SYS_ADDRESS } from '../dataEntities/constants' +import { getNitroGenesisBlock } from '../dataEntities/networks' import { BigNumber } from 'ethers' export const wait = (ms: number): Promise => @@ -82,7 +82,7 @@ type GetFirstBlockForL1BlockProps = { * @param {JsonRpcProvider} provider - The L2 provider to use for the search. * @param {number} forL1Block - The L1 block number to search for. * @param {boolean} [allowGreater=false] - Whether to allow the search to go past the specified `forL1Block`. - * @param {number|string} minL2Block - The minimum L2 block number to start the search from. Cannot be below the network's `nitroGenesisBlock`. + * @param {number|string} minL2Block - The minimum L2 block number to start the search from. Cannot be below the network's Nitro genesis block. * @param {number|string} [maxL2Block='latest'] - The maximum L2 block number to end the search at. Can be a `number` or `'latest'`. `'latest'` is the current block. * @returns {Promise} - A Promise that resolves to a number if a block is found, or undefined otherwise. */ @@ -101,7 +101,7 @@ export async function getFirstBlockForL1Block({ const arbProvider = new ArbitrumProvider(provider) const currentArbBlock = await arbProvider.getBlockNumber() const arbitrumChainId = (await arbProvider.getNetwork()).chainId - const { nitroGenesisBlock } = l2Networks[arbitrumChainId] + const nitroGenesisBlock = getNitroGenesisBlock(arbitrumChainId) async function getL1Block(forL2Block: number) { const { l1BlockNumber } = await arbProvider.getBlock(forL2Block) @@ -124,7 +124,7 @@ export async function getFirstBlockForL1Block({ if (minL2Block < nitroGenesisBlock) { throw new Error( - `'minL2Block' (${minL2Block}) cannot be below 'nitroGenesisBlock', which is ${nitroGenesisBlock} for the current network.` + `'minL2Block' (${minL2Block}) cannot be below the Nitro genesis block, which is ${nitroGenesisBlock} for the current network.` ) } diff --git a/tests/unit/childToParentMessageEvents.test.ts b/tests/unit/childToParentMessageEvents.test.ts index 77bd5863eb..0d505da4c9 100644 --- a/tests/unit/childToParentMessageEvents.test.ts +++ b/tests/unit/childToParentMessageEvents.test.ts @@ -19,7 +19,10 @@ import { Logger, LogLevel } from '@ethersproject/logger' Logger.setLogLevel(LogLevel.ERROR) import { ChildToParentMessage } from '../../src/lib/message/ChildToParentMessage' -import { getArbitrumNetwork } from '../../src/lib/dataEntities/networks' +import { + getArbitrumNetwork, + getNitroGenesisBlock, +} from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito' @@ -37,7 +40,7 @@ describe('ChildToParentMessage events', () => { const l2Network = await getArbitrumNetwork(networkChoiceOverride || 42161) const l2ProviderMock = mock(providers.JsonRpcProvider) - const latestBlock = l2Network.nitroGenesisBlock + 1000 + const latestBlock = getNitroGenesisBlock(l2Network) + 1000 when(l2ProviderMock.getBlockNumber()).thenResolve(latestBlock) when(l2ProviderMock.getNetwork()).thenResolve({ chainId: l2Network.chainID, @@ -79,8 +82,8 @@ describe('ChildToParentMessage events', () => { it('does call for nitro events', async () => { const { l2Network, l2Provider, l2ProviderMock } = await createProviderMock() - const fromBlock = l2Network.nitroGenesisBlock - const toBlock = l2Network.nitroGenesisBlock + 500 + const fromBlock = getNitroGenesisBlock(l2Network) + const toBlock = getNitroGenesisBlock(l2Network) + 500 await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, @@ -103,7 +106,7 @@ describe('ChildToParentMessage events', () => { it('does call for classic and nitro events', async () => { const { l2Network, l2Provider, l2ProviderMock } = await createProviderMock() const fromBlock = 0 - const toBlock = l2Network.nitroGenesisBlock + 500 + const toBlock = getNitroGenesisBlock(l2Network) + 500 await ChildToParentMessage.getChildToParentEvents(l2Provider, { fromBlock: fromBlock, @@ -117,7 +120,7 @@ describe('ChildToParentMessage events', () => { address: arbSys, topics: [classicTopic], fromBlock: fromBlock, - toBlock: l2Network.nitroGenesisBlock, + toBlock: getNitroGenesisBlock(l2Network), }) ) ).once() @@ -126,7 +129,7 @@ describe('ChildToParentMessage events', () => { deepEqual({ address: arbSys, topics: [nitroTopic], - fromBlock: l2Network.nitroGenesisBlock, + fromBlock: getNitroGenesisBlock(l2Network), toBlock: toBlock, }) ) @@ -150,7 +153,7 @@ describe('ChildToParentMessage events', () => { address: arbSys, topics: [classicTopic], fromBlock: 0, - toBlock: l2Network.nitroGenesisBlock, + toBlock: getNitroGenesisBlock(l2Network), }) ) ).once() @@ -159,7 +162,7 @@ describe('ChildToParentMessage events', () => { deepEqual({ address: arbSys, topics: [nitroTopic], - fromBlock: l2Network.nitroGenesisBlock, + fromBlock: getNitroGenesisBlock(l2Network), toBlock: 'latest', }) ) @@ -168,7 +171,7 @@ describe('ChildToParentMessage events', () => { it('does call for only nitro for latest', async () => { const { l2Network, l2Provider, l2ProviderMock } = await createProviderMock() - const fromBlock = l2Network.nitroGenesisBlock + 2 + const fromBlock = getNitroGenesisBlock(l2Network) + 2 const toBlock = 'latest' await ChildToParentMessage.getChildToParentEvents(l2Provider, { diff --git a/tests/unit/multicall.test.ts b/tests/unit/multicall.test.ts index af6880f7bf..cef88f399c 100644 --- a/tests/unit/multicall.test.ts +++ b/tests/unit/multicall.test.ts @@ -1,6 +1,9 @@ 'use strict' -import { getChildChain as getL2Network } from '../../src/lib/dataEntities/networks' +import { + getChildChain as getL2Network, + getNitroGenesisBlock, +} from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' import { mock, when, anything, instance, deepEqual } from 'ts-mockito' import { expect } from 'chai' @@ -12,7 +15,7 @@ describe('Multicall', () => { const l2Network = await getL2Network(networkChoiceOverride || 42161) const l2ProviderMock = mock(providers.JsonRpcProvider) - const latestBlock = l2Network.nitroGenesisBlock + 1000 + const latestBlock = getNitroGenesisBlock(l2Network) + 1000 when(l2ProviderMock.getBlockNumber()).thenResolve(latestBlock) when(l2ProviderMock.getNetwork()).thenResolve({ chainId: l2Network.chainID, From 29802ba7046089428ca6b826502f85660a31a6f0 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 17 Apr 2024 20:41:13 +0200 Subject: [PATCH 25/74] feat: clean up parent/children network properties (#452) --- scripts/genNetwork.ts | 6 +- scripts/testSetup.ts | 3 +- src/index.ts | 1 + src/lib/dataEntities/networks.ts | 71 ++++++++++----------- src/lib/utils/multicall.ts | 7 +- tests/unit/network.test.ts | 106 +++++++++++++++++++------------ 6 files changed, 111 insertions(+), 83 deletions(-) diff --git a/scripts/genNetwork.ts b/scripts/genNetwork.ts index c704ee622c..7dbb1ce2fd 100644 --- a/scripts/genNetwork.ts +++ b/scripts/genNetwork.ts @@ -40,14 +40,14 @@ async function patchNetworks( l3Network: L2Network | undefined, l2Provider: ethers.providers.Provider | undefined ) { - // we need to add partnerChainIDs to the L2 network - l2Network.partnerChainIDs = l3Network ? [l3Network.chainID] : [] + l2Network.parentChainId = (l2Network as any).partnerChainID l2Network.blockTime = ARB_MINIMUM_BLOCK_TIME_IN_SECONDS // native token for l3 if (l3Network && l2Provider) { - l3Network.partnerChainIDs = [] + l3Network.parentChainId = (l3Network as any).partnerChainID l3Network.blockTime = ARB_MINIMUM_BLOCK_TIME_IN_SECONDS + try { l3Network.nativeToken = await IERC20Bridge__factory.connect( l3Network.ethBridge.bridge, diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index bd86f972d9..97c0ca3638 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -116,10 +116,9 @@ export const testSetup = async (): Promise<{ const _parentChain = parentChain as ArbitrumNetwork const ethLocal: L1Network = { blockTime: 10, - chainID: _parentChain.partnerChainID, + chainID: _parentChain.parentChainId, isCustom: true, name: 'EthLocal', - partnerChainIDs: [_parentChain.chainID], isArbitrum: false, } diff --git a/src/index.ts b/src/index.ts index 25d97aa200..c0c82efc0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -51,6 +51,7 @@ export { getL2Network, addCustomNetwork, addDefaultLocalNetwork, + getChildrenForNetwork, } from './lib/dataEntities/networks' export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 7b07b3b60c..4af9fbb072 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -32,10 +32,6 @@ export interface Network { * Minimum possible block time for the chain (in seconds). */ blockTime: number - /** - * Chain ids of children chains, i.e. chains that settle to this chain. - */ - partnerChainIDs: number[] } /** @@ -54,7 +50,7 @@ export interface ArbitrumNetwork extends Network { /** * Chain id of the parent chain, i.e. the chain on which this chain settles to. */ - partnerChainID: number + parentChainId: number isArbitrum: true confirmPeriodBlocks: number /** @@ -145,7 +141,6 @@ export const networks: Networks = { 1: { chainID: 1, name: 'Mainnet', - partnerChainIDs: [42161, 42170], blockTime: 14, isCustom: false, isArbitrum: false, @@ -153,7 +148,6 @@ export const networks: Networks = { 1338: { chainID: 1338, name: 'Hardhat_Mainnet_Fork', - partnerChainIDs: [42161], blockTime: 1, isCustom: false, isArbitrum: false, @@ -161,7 +155,6 @@ export const networks: Networks = { 11155111: { chainID: 11155111, name: 'Sepolia', - partnerChainIDs: [421614], blockTime: 12, isCustom: false, isArbitrum: false, @@ -169,7 +162,6 @@ export const networks: Networks = { 17000: { chainID: 17000, name: 'Holesky', - partnerChainIDs: [], blockTime: 12, isCustom: false, isArbitrum: false, @@ -177,8 +169,7 @@ export const networks: Networks = { 42161: { chainID: 42161, name: 'Arbitrum One', - partnerChainID: 1, - partnerChainIDs: [], + parentChainId: 1, isArbitrum: true, tokenBridge: mainnetTokenBridge, ethBridge: mainnetETHBridge, @@ -199,8 +190,7 @@ export const networks: Networks = { isArbitrum: true, isCustom: false, name: 'Arbitrum Nova', - partnerChainID: 1, - partnerChainIDs: [], + parentChainId: 1, tokenBridge: { l1CustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', l1ERC20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', @@ -232,8 +222,7 @@ export const networks: Networks = { isArbitrum: true, isCustom: false, name: 'Arbitrum Rollup Sepolia Testnet', - partnerChainID: 11155111, - partnerChainIDs: [23011913], + parentChainId: 11155111, tokenBridge: { l1CustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', l1ERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', @@ -265,8 +254,7 @@ export const networks: Networks = { isArbitrum: true, isCustom: false, name: 'Stylus Testnet', - partnerChainID: 421614, - partnerChainIDs: [], + parentChainId: 421614, tokenBridge: { l1CustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', l1ERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', @@ -290,8 +278,18 @@ export const networks: Networks = { /** * Determines if a chain is a parent of *any* other chain. Could be an L1 or an L2 chain. */ -const isParentChain = (chain: L1Network | ArbitrumNetwork): boolean => { - return chain.partnerChainIDs.length > 0 +export const isParentChain = ( + parentChainOrChainId: L1Network | ArbitrumNetwork | number +): boolean => { + const parentChainId = + typeof parentChainOrChainId === 'number' + ? parentChainOrChainId + : parentChainOrChainId.chainID + + // Check if there are any chains that have this chain as its parent chain + return [...Object.values(l2Networks)].some( + c => c.parentChainId === parentChainId + ) } /** @@ -344,11 +342,11 @@ export const getParentForNetwork = (chain: L1Network | ArbitrumNetwork) => { } const parentChain: L1Network | ArbitrumNetwork | undefined = - networks[chain.partnerChainID] + networks[chain.parentChainId] if (!parentChain || !isParentChain(parentChain)) { throw new ArbSdkError( - `Parent chain ${chain.partnerChainID} not recognized for chain ${chain.chainID}.` + `Parent chain ${chain.parentChainId} not recognized for chain ${chain.chainID}.` ) } @@ -356,15 +354,18 @@ export const getParentForNetwork = (chain: L1Network | ArbitrumNetwork) => { } /** - * Returns a list of children chains for the given chain. + * Returns a list of children chains for the given chain or chain id. */ -const getChildrenForNetwork = ( - chain: L1Network | ArbitrumNetwork +export const getChildrenForNetwork = ( + parentChainOrChainId: L1Network | ArbitrumNetwork | number ): ArbitrumNetwork[] => { - const arbitrumChains = getArbitrumChains() + const parentChainId = + typeof parentChainOrChainId === 'number' + ? parentChainOrChainId + : parentChainOrChainId.chainID - return Object.values(arbitrumChains).filter( - arbitrumChain => arbitrumChain.partnerChainID === chain.chainID + return Object.values(getArbitrumChains()).filter( + arbitrumChain => arbitrumChain.parentChainId === parentChainId ) } @@ -478,22 +479,20 @@ const addNetwork = (network: L1Network | ArbitrumNetwork) => { const children = getChildrenForNetwork(network) children.forEach(child => { - child.partnerChainID = network.chainID + child.parentChainId = network.chainID }) } // if it's an arbitrum chain, add it to the parent's list of children if (isArbitrumNetwork(network)) { const parent: L1Network | ArbitrumNetwork | undefined = - networks[network.partnerChainID] + networks[network.parentChainId] if (!parent) { throw new ArbSdkError( - `Network ${network.chainID}'s parent network ${network.partnerChainID} is not recognized` + `Network ${network.chainID}'s parent network ${network.parentChainId} is not recognized` ) } - - parent.partnerChainIDs = [...parent.partnerChainIDs, network.chainID] } l1Networks = getL1Chains() @@ -514,9 +513,9 @@ export const addCustomNetwork = ({ customArbitrumNetwork: ArbitrumNetwork }): void => { if (customL1Network) { - if (customL1Network.chainID !== customArbitrumNetwork.partnerChainID) { + if (customL1Network.chainID !== customArbitrumNetwork.parentChainId) { throw new ArbSdkError( - `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customArbitrumNetwork.partnerChainID}.` + `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customArbitrumNetwork.parentChainId}.` ) } @@ -561,7 +560,6 @@ export const addDefaultLocalNetwork = (): { chainID: 1337, isCustom: true, name: 'EthLocal', - partnerChainIDs: [412346], isArbitrum: false, } @@ -578,8 +576,7 @@ export const addDefaultLocalNetwork = (): { isArbitrum: true, isCustom: true, name: 'ArbLocal', - partnerChainID: 1337, - partnerChainIDs: [], + parentChainId: 1337, tokenBridge: { l1CustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', l1ERC20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index 187b170c1f..9d5d20c907 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -143,10 +143,13 @@ export class MultiCaller { let multiCallAddr: string if (isL1Network(network)) { - const firstL2 = l2Networks[network.partnerChainIDs[0]] + // If the network is an L1, find one of its L2s and pick up the multicall address from there + const firstL2 = [...Object.values(l2Networks)].find( + chain => chain.parentChainId === network.chainID + ) if (!firstL2) throw new ArbSdkError( - `No partner chain found l1 network: ${network.chainID} : partner chain ids ${network.partnerChainIDs}` + `No children chains found for network: ${network.chainID}` ) multiCallAddr = firstL2.tokenBridge.l1MultiCall } else { diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index c8614cd3da..dac3faf2e4 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -6,6 +6,8 @@ import { getArbitrumNetwork, l1Networks, l2Networks as arbitrumNetworks, + getChildrenForNetwork, + isParentChain, } from '../../src/lib/dataEntities/networks' const ethereumMainnetChainId = 1 @@ -27,7 +29,7 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL2ChainId, - partnerChainID: ethereumMainnetChainId, + parentChainId: ethereumMainnetChainId, isArbitrum: true, isCustom: true, } as const @@ -36,14 +38,11 @@ describe('Networks', async () => { expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok - // assert network was added as child - const l1Network = await getL1Network(customArbitrumNetwork.partnerChainID) - expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent const arbitrumNetwork = await getArbitrumNetwork( customArbitrumNetwork.chainID ) - expect(arbitrumNetwork.partnerChainID).to.equal(ethereumMainnetChainId) + expect(arbitrumNetwork.parentChainId).to.equal(ethereumMainnetChainId) }) it('adds a custom L1 and Arbitrum network', async function () { @@ -59,7 +58,7 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, - partnerChainID: mockL1ChainId, + parentChainId: mockL1ChainId, chainID: mockL2ChainId, isArbitrum: true, isCustom: true, @@ -70,14 +69,11 @@ describe('Networks', async () => { expect(await getL1Network(mockL1ChainId)).to.be.ok expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok - // assert network was added as child - const l1Network = await getL1Network(mockL1ChainId) - expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent const arbitrumNetwork = await getArbitrumNetwork( customArbitrumNetwork.chainID ) - expect(arbitrumNetwork.partnerChainID).to.equal(mockL1ChainId) + expect(arbitrumNetwork.parentChainId).to.equal(mockL1ChainId) }) it('adds a custom L3 network', async function () { @@ -86,7 +82,7 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL3ChainId, - partnerChainID: arbitrumOneChainId, + parentChainId: arbitrumOneChainId, isArbitrum: true, isCustom: true, } as const @@ -95,14 +91,9 @@ describe('Networks', async () => { expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok - // assert network was added as child - const arbitrumNetwork = await getArbitrumNetwork( - customArbitrumNetwork.partnerChainID - ) - expect(arbitrumNetwork.partnerChainIDs).to.include(mockL3ChainId) // assert network has correct parent const l3Network = await getArbitrumNetwork(mockL3ChainId) - expect(l3Network.partnerChainID).to.equal(arbitrumOneChainId) + expect(l3Network.parentChainId).to.equal(arbitrumOneChainId) }) it('adds a custom L1, L2, and L3 network', async function () { @@ -119,7 +110,7 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, chainID: mockL2ChainId, - partnerChainID: mockL1ChainId, + parentChainId: mockL1ChainId, isArbitrum: true, isCustom: true, } as const @@ -129,17 +120,14 @@ describe('Networks', async () => { expect(await getL1Network(mockL1ChainId)).to.be.ok expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok - // assert network was added as child - const l1Network = await getL1Network(mockL1ChainId) - expect(l1Network.partnerChainIDs).to.include(mockL2ChainId) // assert network has correct parent const arbitrumNetwork = await getArbitrumNetwork(mockL2ChainId) - expect(arbitrumNetwork.partnerChainID).to.equal(mockL1ChainId) + expect(arbitrumNetwork.parentChainId).to.equal(mockL1ChainId) const customL3Network = { ...arbitrumOne, chainID: mockL3ChainId, - partnerChainID: mockL2ChainId, + parentChainId: mockL2ChainId, isArbitrum: true, isCustom: true, } as const @@ -148,19 +136,16 @@ describe('Networks', async () => { expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok - // assert network was added as child - const arbitrumNetworkAgain = await getArbitrumNetwork(mockL2ChainId) - expect(arbitrumNetworkAgain.partnerChainIDs).to.include(mockL3ChainId) // assert network has correct parent const l3Network = await getArbitrumNetwork(mockL3ChainId) - expect(l3Network.partnerChainID).to.equal(mockL2ChainId) + expect(l3Network.parentChainId).to.equal(mockL2ChainId) }) it('fails to add a custom L1 and Arbitrum network if they do not match', async function () { const ethereumMainnet = await getL1Network(ethereumMainnetChainId) const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - const wrongPartnerChainId = 1241244 + const wrongParentChainId = 1241244 const customL1Network = { ...ethereumMainnet, @@ -171,7 +156,7 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, - partnerChainID: wrongPartnerChainId, + parentChainId: wrongParentChainId, chainID: mockL2ChainId, isArbitrum: true, isCustom: true, @@ -183,7 +168,7 @@ describe('Networks', async () => { // should fail expect(err).to.be.an('error') expect((err as Error).message).to.be.eq( - `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${wrongPartnerChainId}.` + `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${wrongParentChainId}.` ) } }) @@ -196,7 +181,7 @@ describe('Networks', async () => { customArbitrumNetwork: { ...arbitrumOne, chainID: mockL3ChainId, - partnerChainID: mockL2ChainId, + parentChainId: mockL2ChainId, isArbitrum: true, isCustom: true, }, @@ -252,7 +237,7 @@ describe('Networks', async () => { const customL3Network = { ...arbitrumOne, chainID: mockL3ChainId, - partnerChainID: arbitrumOneChainId, + parentChainId: arbitrumOneChainId, isArbitrum: true, isCustom: true, } as const @@ -262,13 +247,7 @@ describe('Networks', async () => { const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.chainID).to.be.eq(mockL3ChainId) // assert network has correct parent - expect(l3Network.partnerChainID).to.equal(arbitrumOneChainId) - - // assert network was added as child - const arbitrumNetwork = await getArbitrumNetwork( - customL3Network.partnerChainID - ) - expect(arbitrumNetwork.partnerChainIDs).to.include(mockL3ChainId) + expect(l3Network.parentChainId).to.equal(arbitrumOneChainId) }) it('fails to fetch an unrecognized L1 network', async () => { @@ -323,4 +302,53 @@ describe('Networks', async () => { expect(arbitrumNetworksKeys).to.have.members(expected) }) }) + + describe('getChildrenForNetwork', () => { + it('returns correct children for ethereum mainnet', () => { + const children = getChildrenForNetwork(1).map(c => c.chainID) + expect(children).to.have.members([42161, 42170]) + }) + + it('returns correct children for arbitrum one', () => { + const children = getChildrenForNetwork(42161).map(c => c.chainID) + expect(children).to.have.members([]) + }) + + it('returns correct children for arbitrum nova', () => { + const children = getChildrenForNetwork(42170).map(c => c.chainID) + expect(children).to.have.members([]) + }) + + it('returns correct children for sepolia', () => { + const children = getChildrenForNetwork(11155111).map(c => c.chainID) + expect(children).to.have.members([421614]) + }) + + it('returns correct children for arbitrum sepolia', () => { + const children = getChildrenForNetwork(421614).map(c => c.chainID) + expect(children).to.have.members([23011913]) + }) + }) + + describe('isParentChain', () => { + it('returns correct value for ethereum mainnet', () => { + expect(isParentChain(1)).to.equal(true) + }) + + it('returns correct value for arbitrum one', () => { + expect(isParentChain(42161)).to.equal(false) + }) + + it('returns correct value for arbitrum nova', () => { + expect(isParentChain(42170)).to.equal(false) + }) + + it('returns correct value for sepolia', () => { + expect(isParentChain(11155111)).to.equal(true) + }) + + it('returns correct value for arbitrum sepolia', () => { + expect(isParentChain(421614)).to.equal(true) + }) + }) }) From 0ee694c63f105c5ed8630578b33a07f9f4ab46a7 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 17 Apr 2024 21:31:03 +0200 Subject: [PATCH 26/74] refactor: add function to get multicall address (#454) --- src/lib/dataEntities/networks.ts | 34 +++++++++++++++++++++++++++++ src/lib/utils/multicall.ts | 37 ++------------------------------ tests/unit/network.test.ts | 28 ++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 4af9fbb072..0c9268dd1c 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -16,6 +16,8 @@ /* eslint-env node */ ;('use strict') +import { Provider } from '@ethersproject/abstract-provider' + import { SignerOrProvider, SignerProviderUtils } from './signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' import { @@ -639,6 +641,38 @@ export function getNitroGenesisBlock( return 0 } +export async function getMulticall( + providerOrChainId: Provider | number +): Promise { + const chains = [...Object.values(l2Networks)] + + const chainId = + typeof providerOrChainId === 'number' + ? providerOrChainId + : (await providerOrChainId.getNetwork()).chainId + const chain = chains.find(c => c.chainID === chainId) + + // The provided chain is found in the list + if (typeof chain !== 'undefined') { + // Return the address of Multicall on the chain + return chain.tokenBridge.l2Multicall + } + + // The provided chain is not found in the list + // Try to find a chain that references this chain as its parent + const child = chains.find(c => c.parentChainId === chainId) + + // No chains reference this chain as its parent + if (typeof child === 'undefined') { + throw new Error( + `Failed to retrieve Multicall address for chain: ${chainId}` + ) + } + + // Return the address of Multicall on the parent chain + return child.tokenBridge.l1MultiCall +} + const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index 9d5d20c907..e1866cab0c 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -22,14 +22,7 @@ import { BigNumber, utils } from 'ethers' import { ERC20__factory } from '../abi/factories/ERC20__factory' import { Multicall2 } from '../abi/Multicall2' import { Multicall2__factory } from '../abi/factories/Multicall2__factory' -import { ArbSdkError } from '../dataEntities/errors' -import { - isL1Network, - L1Network, - l1Networks, - L2Network, - l2Networks, -} from '../dataEntities/networks' +import { getMulticall } from '../dataEntities/networks' /** * Input to multicall aggregator @@ -130,33 +123,7 @@ export class MultiCaller { * @returns */ public static async fromProvider(provider: Provider): Promise { - const chainId = (await provider.getNetwork()).chainId - const l2Network = l2Networks[chainId] as L2Network | undefined - const l1Network = l1Networks[chainId] as L1Network | undefined - - const network = l2Network || l1Network - if (!network) { - throw new ArbSdkError( - `Unexpected network id: ${chainId}. Ensure that chain ${chainId} has been added as a network.` - ) - } - - let multiCallAddr: string - if (isL1Network(network)) { - // If the network is an L1, find one of its L2s and pick up the multicall address from there - const firstL2 = [...Object.values(l2Networks)].find( - chain => chain.parentChainId === network.chainID - ) - if (!firstL2) - throw new ArbSdkError( - `No children chains found for network: ${network.chainID}` - ) - multiCallAddr = firstL2.tokenBridge.l1MultiCall - } else { - multiCallAddr = network.tokenBridge.l2Multicall - } - - return new MultiCaller(provider, multiCallAddr) + return new MultiCaller(provider, await getMulticall(provider)) } /** diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index dac3faf2e4..6385cbd98e 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -8,6 +8,7 @@ import { l2Networks as arbitrumNetworks, getChildrenForNetwork, isParentChain, + getMulticall, } from '../../src/lib/dataEntities/networks' const ethereumMainnetChainId = 1 @@ -351,4 +352,31 @@ describe('Networks', async () => { expect(isParentChain(421614)).to.equal(true) }) }) + + describe('getMulticall', () => { + it('returns correct value for ethereum mainnet', async () => { + const multicall = await getMulticall(1) + expect(multicall).to.equal('0x5ba1e12693dc8f9c48aad8770482f4739beed696') + }) + + it('returns correct value for arbitrum one', async () => { + const multicall = await getMulticall(42161) + expect(multicall).to.equal('0x842eC2c7D803033Edf55E478F461FC547Bc54EB2') + }) + + it('returns correct value for arbitrum nova', async () => { + const multicall = await getMulticall(42170) + expect(multicall).to.equal('0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86') + }) + + it('returns correct value for sepolia', async () => { + const multicall = await getMulticall(11155111) + expect(multicall).to.equal('0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320') + }) + + it('returns correct value for arbitrum sepolia', async () => { + const multicall = await getMulticall(421614) + expect(multicall).to.equal('0xA115146782b7143fAdB3065D86eACB54c169d092') + }) + }) }) From 33df5348d76983c6db4c87d82e3857e1416877d9 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 18 Apr 2024 15:00:15 +0200 Subject: [PATCH 27/74] feat: remove all references to L1Network (#453) --- scripts/genNetwork.ts | 44 ++-- scripts/instantiate_bridge.ts | 31 +-- scripts/testSetup.ts | 60 ++--- src/index.ts | 4 - src/lib/assetBridger/assetBridger.ts | 17 +- src/lib/dataEntities/networks.ts | 316 ++++++--------------------- src/lib/inbox/inbox.ts | 19 +- src/lib/utils/types.ts | 6 + tests/integration/testHelpers.ts | 6 +- tests/unit/network.test.ts | 182 +-------------- 10 files changed, 142 insertions(+), 543 deletions(-) diff --git a/scripts/genNetwork.ts b/scripts/genNetwork.ts index 7dbb1ce2fd..23376b7604 100644 --- a/scripts/genNetwork.ts +++ b/scripts/genNetwork.ts @@ -2,10 +2,14 @@ import * as dotenv from 'dotenv' dotenv.config() import { execSync } from 'child_process' import * as fs from 'fs' -import { L2Network } from '../src' -import { ARB_MINIMUM_BLOCK_TIME_IN_SECONDS } from '../src/lib/dataEntities/constants' + import { IERC20Bridge__factory } from '../src/lib/abi/factories/IERC20Bridge__factory' import { ethers } from 'ethers' +import { + ArbitrumNetwork, + L2NetworkOld, + mapL2NetworkToArbitrumNetwork, +} from '../src/lib/dataEntities/networks' const isTestingOrbitChains = process.env.ORBIT_TEST === '1' @@ -36,27 +40,32 @@ function getLocalNetworksFromContainer(which: 'l1l2' | 'l2l3'): any { * we can remove this patchwork */ async function patchNetworks( - l2Network: L2Network, - l3Network: L2Network | undefined, + l2Network: L2NetworkOld, + l3Network: L2NetworkOld | undefined, l2Provider: ethers.providers.Provider | undefined -) { - l2Network.parentChainId = (l2Network as any).partnerChainID - l2Network.blockTime = ARB_MINIMUM_BLOCK_TIME_IN_SECONDS +): Promise<{ + patchedL2Network: ArbitrumNetwork + patchedL3Network?: ArbitrumNetwork +}> { + const patchedL2Network = mapL2NetworkToArbitrumNetwork(l2Network) // native token for l3 if (l3Network && l2Provider) { - l3Network.parentChainId = (l3Network as any).partnerChainID - l3Network.blockTime = ARB_MINIMUM_BLOCK_TIME_IN_SECONDS + const patchedL3Network = mapL2NetworkToArbitrumNetwork(l3Network) try { - l3Network.nativeToken = await IERC20Bridge__factory.connect( + patchedL3Network.nativeToken = await IERC20Bridge__factory.connect( l3Network.ethBridge.bridge, l2Provider ).nativeToken() } catch (e) { // l3 network doesn't have a native token } + + return { patchedL2Network, patchedL3Network } } + + return { patchedL2Network } } async function main() { @@ -66,17 +75,24 @@ async function main() { if (isTestingOrbitChains) { const { l2Network: l3Network } = getLocalNetworksFromContainer('l2l3') - await patchNetworks( + const { patchedL2Network, patchedL3Network } = await patchNetworks( output.l2Network, l3Network, new ethers.providers.JsonRpcProvider(process.env['ARB_URL']) ) + output = { - l1Network: output.l2Network, - l2Network: l3Network, + l1Network: patchedL2Network, + l2Network: patchedL3Network, } } else { - await patchNetworks(output.l2Network, undefined, undefined) + const { patchedL2Network } = await patchNetworks( + output.l2Network, + undefined, + undefined + ) + + output.l2Network = patchedL2Network } fs.writeFileSync('localNetwork.json', JSON.stringify(output, null, 2)) diff --git a/scripts/instantiate_bridge.ts b/scripts/instantiate_bridge.ts index af752bc640..a105e14473 100644 --- a/scripts/instantiate_bridge.ts +++ b/scripts/instantiate_bridge.ts @@ -22,15 +22,9 @@ import { Wallet } from '@ethersproject/wallet' import dotenv from 'dotenv' import args from './getCLargs' import { EthBridger, InboxTools, Erc20Bridger } from '../src' -import { - l1Networks, - l2Networks, - L1Network, - L2Network, -} from '../src/lib/dataEntities/networks' +import { L2Network, getL2Network } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' -import { isDefined } from '../src/lib/utils/lib' dotenv.config() @@ -39,11 +33,10 @@ const ethKey = process.env['ETH_KEY'] as string const defaultNetworkId = 421614 -export const instantiateBridge = ( +export const instantiateBridge = async ( l1PkParam?: string, l2PkParam?: string -): { - l1Network: L1Network +): Promise<{ l2Network: L2Network l1Signer: Signer l2Signer: Signer @@ -51,7 +44,7 @@ export const instantiateBridge = ( ethBridger: EthBridger adminErc20Bridger: AdminErc20Bridger inboxTools: InboxTools -} => { +}> => { if (!l1PkParam && !ethKey) { throw new Error('need ARB_KEY var') } @@ -68,21 +61,8 @@ export const instantiateBridge = ( l2NetworkID = defaultNetworkId } - const isL1 = isDefined(l1Networks[l2NetworkID]) - const isL2 = isDefined(l2Networks[l2NetworkID]) - if (!isL1 && !isL2) { - throw new Error(`Unrecognized network ID: ${l2NetworkID}`) - } - if (!isL2) { - throw new Error(`Tests must specify an L2 network ID: ${l2NetworkID}`) - } - const l2Network = l2Networks[l2NetworkID] - const l1Network = l1Networks[l2Network.parentChainId] - - if (!l1Network) { - throw new Error(`Unrecognised parent chain id: ${l2Network.parentChainId}`) - } + const l2Network = await getL2Network(l2NetworkID) const l1Rpc = (() => { if (l2NetworkID === 42161) return process.env['MAINNET_RPC'] as string @@ -138,7 +118,6 @@ export const instantiateBridge = ( const inboxTools = new InboxTools(l1Signer, l2Network) return { - l1Network, l2Network, l1Signer, l2Signer, diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 97c0ca3638..3787bce6c6 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -23,11 +23,11 @@ import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { - L1Network, ArbitrumNetwork, - getL1Network, getArbitrumNetwork, addCustomNetwork, + mapL2NetworkToArbitrumNetwork, + L2NetworkOld, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' @@ -72,7 +72,6 @@ export const getSigner = (provider: JsonRpcProvider, key?: string) => { } export const testSetup = async (): Promise<{ - parentChain: L1Network | ArbitrumNetwork childChain: ArbitrumNetwork parentSigner: Signer childSigner: Signer @@ -95,53 +94,18 @@ export const testSetup = async (): Promise<{ const parentSigner = seed.connect(ethProvider) const childSigner = seed.connect(arbProvider) - let setParentChain: L1Network | ArbitrumNetwork, - setChildChain: ArbitrumNetwork + let setChildChain: ArbitrumNetwork + try { - const l1Network = isTestingOrbitChains - ? await getArbitrumNetwork(parentDeployer) - : await getL1Network(parentDeployer) const l2Network = await getArbitrumNetwork(childDeployer) - setParentChain = l1Network setChildChain = l2Network } catch (err) { // the networks havent been added yet - // check if theres an existing network available - const localNetworkFile = getLocalNetworksFromFile() - - const { l1Network: parentChain, l2Network: childChain } = localNetworkFile - - if (isTestingOrbitChains) { - const _parentChain = parentChain as ArbitrumNetwork - const ethLocal: L1Network = { - blockTime: 10, - chainID: _parentChain.parentChainId, - isCustom: true, - name: 'EthLocal', - isArbitrum: false, - } - - addCustomNetwork({ - customL1Network: ethLocal, - customArbitrumNetwork: _parentChain, - }) - - addCustomNetwork({ - customArbitrumNetwork: childChain, - }) - - setParentChain = parentChain - setChildChain = childChain - } else { - addCustomNetwork({ - customL1Network: parentChain as L1Network, - customArbitrumNetwork: childChain, - }) - - setParentChain = parentChain - setChildChain = childChain - } + const { l2Network: childChain } = getLocalNetworksFromFile() + + addCustomNetwork(childChain) + setChildChain = childChain } const erc20Bridger = new Erc20Bridger(setChildChain) @@ -160,7 +124,6 @@ export const testSetup = async (): Promise<{ childSigner, parentProvider: ethProvider, childProvider: arbProvider, - parentChain: setParentChain, childChain: setChildChain, erc20Bridger, adminErc20Bridger, @@ -172,7 +135,6 @@ export const testSetup = async (): Promise<{ } export function getLocalNetworksFromFile(): { - l1Network: L1Network | ArbitrumNetwork l2Network: ArbitrumNetwork } { const pathToLocalNetworkFile = path.join(__dirname, '..', 'localNetwork.json') @@ -180,5 +142,9 @@ export function getLocalNetworksFromFile(): { throw new ArbSdkError('localNetwork.json not found, must gen:network first') } const localNetworksFile = fs.readFileSync(pathToLocalNetworkFile, 'utf8') - return JSON.parse(localNetworksFile) + const localL2: L2NetworkOld = JSON.parse(localNetworksFile).l2Network + + return { + l2Network: mapL2NetworkToArbitrumNetwork(localL2), + } } diff --git a/src/index.ts b/src/index.ts index c0c82efc0e..126de5985d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,11 +43,7 @@ export { ParentToChildMessageGasEstimator } from './lib/message/ParentToChildMes export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { - L1Networks, - L2Networks, - L1Network, L2Network, - getL1Network, getL2Network, addCustomNetwork, addDefaultLocalNetwork, diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 2d050c4de7..0308032416 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -21,11 +21,7 @@ import { constants } from 'ethers' import { ParentContractTransaction } from '../message/ParentTransaction' import { ChildContractTransaction } from '../message/ChildTransaction' -import { - L1Network, - ArbitrumNetwork, - getParentForNetwork, -} from '../dataEntities/networks' +import { ArbitrumNetwork } from '../dataEntities/networks' import { SignerOrProvider, SignerProviderUtils, @@ -35,11 +31,6 @@ import { * Base for bridging assets from parent-to-child and back */ export abstract class AssetBridger { - /** - * Parent chain for the given Arbitrum chain, can be an L1 or an L2 - */ - public readonly parentChain: L1Network | ArbitrumNetwork - /** * In case of a chain that uses ETH as its native/gas token, this is either `undefined` or the zero address * @@ -48,7 +39,6 @@ export abstract class AssetBridger { public readonly nativeToken?: string public constructor(public readonly childChain: ArbitrumNetwork) { - this.parentChain = getParentForNetwork(childChain) this.nativeToken = childChain.nativeToken } @@ -57,7 +47,10 @@ export abstract class AssetBridger { * @param sop */ protected async checkParentChain(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.parentChain.chainID) + await SignerProviderUtils.checkNetworkMatches( + sop, + this.childChain.parentChainId + ) } /** diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 0c9268dd1c..48fdbe22e4 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -20,40 +20,37 @@ import { Provider } from '@ethersproject/abstract-provider' import { SignerOrProvider, SignerProviderUtils } from './signerOrProvider' import { ArbSdkError } from '../dataEntities/errors' -import { - ARB1_NITRO_GENESIS_L2_BLOCK, - ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, -} from './constants' +import { ARB1_NITRO_GENESIS_L2_BLOCK } from './constants' import { RollupAdminLogic__factory } from '../abi/factories/RollupAdminLogic__factory' - -export interface Network { - chainID: number - name: string - isCustom: boolean - /** - * Minimum possible block time for the chain (in seconds). - */ - blockTime: number -} - -/** - * Represents an L1 chain, e.g. Ethereum Mainnet or Sepolia. - */ -export interface L1Network extends Network { - isArbitrum: false -} +import { Prettify } from '../utils/types' /** * Represents an Arbitrum chain, e.g. Arbitrum One, Arbitrum Sepolia, or an L3 chain. */ -export interface ArbitrumNetwork extends Network { - tokenBridge: TokenBridge - ethBridge: EthBridge +export interface ArbitrumNetwork { + /** + * Name of the chain. + */ + name: string + /** + * Id of the chain. + */ + chainID: number /** * Chain id of the parent chain, i.e. the chain on which this chain settles to. */ parentChainId: number - isArbitrum: true + /** + * The core contracts + */ + ethBridge: EthBridge + /** + * The token bridge contracts. + */ + tokenBridge: TokenBridge + /** + * The time allowed for validators to dispute or challenge state assertions. Measured in L1 blocks. + */ confirmPeriodBlocks: number /** * Represents how long a retryable ticket lasts for before it expires (in seconds). Defaults to 7 days. @@ -65,8 +62,26 @@ export interface ArbitrumNetwork extends Network { * In case of a chain that uses an ERC-20 token from the parent chain as its native/gas token, this is the address of said token on the parent chain */ nativeToken?: string + /** + * Whether or not the chain was registered by the user. + */ + isCustom: boolean } +/** + * This type is only here for when you want to achieve backwards compatibility between SDK v3 and v4. + * + * Please see {@link ArbitrumNetwork} for the latest type. + * + * @deprecated since v4 + */ +export type L2NetworkOld = Prettify< + // todo(spsjvc): rename to L2Network after imports are cleaned up + Omit & { + partnerChainID: number + } +> + export interface TokenBridge { l1GatewayRouter: string l2GatewayRouter: string @@ -95,16 +110,12 @@ export interface EthBridge { } } -export interface L1Networks { - [id: string]: L1Network -} - export interface ArbitrumNetworks { [id: string]: ArbitrumNetwork } export interface Networks { - [id: string]: L1Network | ArbitrumNetwork + [id: string]: ArbitrumNetwork } const mainnetTokenBridge: TokenBridge = { @@ -140,44 +151,14 @@ const mainnetETHBridge: EthBridge = { * Storage for all networks, either L1, L2 or L3. */ export const networks: Networks = { - 1: { - chainID: 1, - name: 'Mainnet', - blockTime: 14, - isCustom: false, - isArbitrum: false, - }, - 1338: { - chainID: 1338, - name: 'Hardhat_Mainnet_Fork', - blockTime: 1, - isCustom: false, - isArbitrum: false, - }, - 11155111: { - chainID: 11155111, - name: 'Sepolia', - blockTime: 12, - isCustom: false, - isArbitrum: false, - }, - 17000: { - chainID: 17000, - name: 'Holesky', - blockTime: 12, - isCustom: false, - isArbitrum: false, - }, 42161: { chainID: 42161, name: 'Arbitrum One', parentChainId: 1, - isArbitrum: true, tokenBridge: mainnetTokenBridge, ethBridge: mainnetETHBridge, confirmPeriodBlocks: 45818, isCustom: false, - blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 42170: { chainID: 42170, @@ -189,7 +170,6 @@ export const networks: Networks = { rollup: '0xFb209827c58283535b744575e11953DCC4bEAD88', sequencerInbox: '0x211E1c4c7f1bF5351Ac850Ed10FD68CFfCF6c21b', }, - isArbitrum: true, isCustom: false, name: 'Arbitrum Nova', parentChainId: 1, @@ -209,7 +189,6 @@ export const networks: Networks = { l2Weth: '0x722E8BdD2ce80A4422E880164f2079488e115365', l2WethGateway: '0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD', }, - blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 421614: { chainID: 421614, @@ -221,7 +200,6 @@ export const networks: Networks = { rollup: '0xd80810638dbDF9081b72C1B33c65375e807281C8', sequencerInbox: '0x6c97864CE4bEf387dE0b3310A44230f7E3F1be0D', }, - isArbitrum: true, isCustom: false, name: 'Arbitrum Rollup Sepolia Testnet', parentChainId: 11155111, @@ -241,7 +219,6 @@ export const networks: Networks = { l2Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', l2WethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D', }, - blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, 23011913: { chainID: 23011913, @@ -253,7 +230,6 @@ export const networks: Networks = { rollup: '0x94db9E36d9336cD6F9FfcAd399dDa6Cc05299898', sequencerInbox: '0x00A0F15b79d1D3e5991929FaAbCF2AA65623530c', }, - isArbitrum: true, isCustom: false, name: 'Stylus Testnet', parentChainId: 421614, @@ -273,7 +249,6 @@ export const networks: Networks = { l2Weth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C', l2WethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175', }, - blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, }, } @@ -281,7 +256,7 @@ export const networks: Networks = { * Determines if a chain is a parent of *any* other chain. Could be an L1 or an L2 chain. */ export const isParentChain = ( - parentChainOrChainId: L1Network | ArbitrumNetwork | number + parentChainOrChainId: ArbitrumNetwork | number ): boolean => { const parentChainId = typeof parentChainOrChainId === 'number' @@ -294,72 +269,13 @@ export const isParentChain = ( ) } -/** - * Determines if a chain is an Arbitrum chain. Could be an L2 or an L3 chain. - */ -const isArbitrumNetwork = ( - chain: L1Network | ArbitrumNetwork -): chain is ArbitrumNetwork => { - return chain.isArbitrum -} - -/** - * Determines if a chain is specifically an L1 chain (not L2 or L3). - */ -export const isL1Network = ( - chain: L1Network | ArbitrumNetwork -): chain is L1Network => { - return !chain.isArbitrum -} - -/** - * Builds an object that is a list of chains filtered by the provided predicate function indexed by their chain id - * @param filterFn - A predicate function to determine if a chain should be included. - * @return An object with only the filtered chains. - */ -const getChainsByType = ( - filterFn: (chain: L1Network | ArbitrumNetwork) => boolean -): T => { - return Object.entries(networks).reduce( - (accumulator, [chainId, chainData]) => { - if (filterFn(chainData)) { - accumulator[chainId] = chainData - } - return accumulator - }, - {} - ) as T -} - -const getL1Chains = () => getChainsByType(isL1Network) -const getArbitrumChains = () => - getChainsByType(isArbitrumNetwork) - -/** - * Returns the parent chain for the given chain. - */ -export const getParentForNetwork = (chain: L1Network | ArbitrumNetwork) => { - if (!isArbitrumNetwork(chain)) { - throw new ArbSdkError(`Chain ${chain.chainID} is not an Arbitrum chain.`) - } - - const parentChain: L1Network | ArbitrumNetwork | undefined = - networks[chain.parentChainId] - - if (!parentChain || !isParentChain(parentChain)) { - throw new ArbSdkError( - `Parent chain ${chain.parentChainId} not recognized for chain ${chain.chainID}.` - ) - } - - return parentChain -} +const getArbitrumChains = () => networks /** * Returns a list of children chains for the given chain or chain id. */ export const getChildrenForNetwork = ( - parentChainOrChainId: L1Network | ArbitrumNetwork | number + parentChainOrChainId: ArbitrumNetwork | number ): ArbitrumNetwork[] => { const parentChainId = typeof parentChainOrChainId === 'number' @@ -371,11 +287,6 @@ export const getChildrenForNetwork = ( ) } -/** - * Index of *only* L1 chains that have been added. - */ -export let l1Networks: L1Networks = getL1Chains() - /** * Index of all Arbitrum chains that have been added. */ @@ -386,8 +297,7 @@ export let l2Networks: ArbitrumNetworks = getArbitrumChains() * @note Throws if the chain is not recognized. */ export const getNetwork = async ( - signerOrProviderOrChainID: SignerOrProvider | number, - layer: 1 | 2 + signerOrProviderOrChainID: SignerOrProvider | number ) => { const chainID = await (async () => { if (typeof signerOrProviderOrChainID === 'number') { @@ -401,13 +311,9 @@ export const getNetwork = async ( return chainId })() - let network: L1Network | ArbitrumNetwork | undefined = undefined + let network: ArbitrumNetwork | undefined = undefined - if (layer === 1) { - network = getL1Chains()[chainID] - } else { - network = getArbitrumChains()[chainID] - } + network = getArbitrumChains()[chainID] if (!network) { throw new ArbSdkError(`Unrecognized network ${chainID}.`) @@ -416,17 +322,6 @@ export const getNetwork = async ( return network } -/** - * Returns the L1 chain associated with the given signer, provider or chain id. - * - * @note Throws if the chain is not an L1 chain. - */ -export const getL1Network = ( - signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID, 1) as Promise -} - /** * Returns the Arbitrum chain associated with the given signer, provider or chain id. * @@ -435,7 +330,7 @@ export const getL1Network = ( export const getArbitrumNetwork = ( signerOrProviderOrChainID: SignerOrProvider | number ): Promise => { - return getNetwork(signerOrProviderOrChainID, 2) as Promise + return getNetwork(signerOrProviderOrChainID) as Promise } /** @@ -469,83 +364,20 @@ export const getEthBridgeInformation = async ( } } -/** - * Adds any chain to the global index of networks and updates the parent/child relationships. - */ -const addNetwork = (network: L1Network | ArbitrumNetwork) => { - // store the network with the rest of the networks - networks[network.chainID] = network - - // if it's a parent chain (L1 or L2), assign it as parent to all the children - if (isParentChain(network)) { - const children = getChildrenForNetwork(network) - - children.forEach(child => { - child.parentChainId = network.chainID - }) - } - - // if it's an arbitrum chain, add it to the parent's list of children - if (isArbitrumNetwork(network)) { - const parent: L1Network | ArbitrumNetwork | undefined = - networks[network.parentChainId] - - if (!parent) { - throw new ArbSdkError( - `Network ${network.chainID}'s parent network ${network.parentChainId} is not recognized` - ) - } - } - - l1Networks = getL1Chains() - l2Networks = getArbitrumChains() -} - /** * Registers a pair of custom L1 and L2 chains, or a single custom Arbitrum chain (L2 or L3). * * @param customL1Network the custom L1 chain (optional) * @param customArbitrumNetwork the custom L2 or L3 chain */ -export const addCustomNetwork = ({ - customL1Network, - customArbitrumNetwork, -}: { - customL1Network?: L1Network - customArbitrumNetwork: ArbitrumNetwork -}): void => { - if (customL1Network) { - if (customL1Network.chainID !== customArbitrumNetwork.parentChainId) { - throw new ArbSdkError( - `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${customArbitrumNetwork.parentChainId}.` - ) - } - - // check the if the parent chain is in any of the lists - if (l1Networks[customL1Network.chainID]) { - throw new ArbSdkError( - `Network ${customL1Network.chainID} already included` - ) - } else if (!customL1Network.isCustom) { - throw new ArbSdkError( - `Custom network ${customL1Network.chainID} must have isCustom flag set to true` - ) - } - - addNetwork(customL1Network) - } - - if (l2Networks[customArbitrumNetwork.chainID]) { - throw new ArbSdkError( - `Network ${customArbitrumNetwork.chainID} already included` - ) - } else if (!customArbitrumNetwork.isCustom) { - throw new ArbSdkError( - `Custom network ${customArbitrumNetwork.chainID} must have isCustom flag set to true` - ) +export const addCustomNetwork = (network: ArbitrumNetwork): void => { + if (typeof networks[network.chainID] !== 'undefined') { + throw new Error(`Network ${network.chainID} already included`) } - addNetwork(customArbitrumNetwork) + // store the network with the rest of the networks + networks[network.chainID] = network + l2Networks = getArbitrumChains() } /** @@ -553,18 +385,7 @@ export const addCustomNetwork = ({ * * @see {@link https://github.com/OffchainLabs/nitro} */ -export const addDefaultLocalNetwork = (): { - l1Network: L1Network - l2Network: ArbitrumNetwork -} => { - const defaultLocalL1Network: L1Network = { - blockTime: 10, - chainID: 1337, - isCustom: true, - name: 'EthLocal', - isArbitrum: false, - } - +export const addDefaultLocalNetwork = (): ArbitrumNetwork => { const defaultLocalL2Network: ArbitrumNetwork = { chainID: 412346, confirmPeriodBlocks: 20, @@ -575,7 +396,6 @@ export const addDefaultLocalNetwork = (): { rollup: '0x65a59D67Da8e710Ef9A01eCa37f83f84AEdeC416', sequencerInbox: '0xE7362D0787b51d8C72D504803E5B1d6DcdA89540', }, - isArbitrum: true, isCustom: true, name: 'ArbLocal', parentChainId: 1337, @@ -595,18 +415,11 @@ export const addDefaultLocalNetwork = (): { l2Weth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', l2WethGateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', }, - blockTime: ARB_MINIMUM_BLOCK_TIME_IN_SECONDS, } - addCustomNetwork({ - customL1Network: defaultLocalL1Network, - customArbitrumNetwork: defaultLocalL2Network, - }) + addCustomNetwork(defaultLocalL2Network) - return { - l1Network: defaultLocalL1Network, - l2Network: defaultLocalL2Network, - } + return defaultLocalL2Network } /** @@ -619,7 +432,6 @@ const createNetworkStateHandler = () => { resetNetworksToDefault: () => { Object.keys(networks).forEach(key => delete networks[key]) Object.assign(networks, JSON.parse(JSON.stringify(initialState))) - l1Networks = getL1Chains() l2Networks = getArbitrumChains() }, } @@ -673,6 +485,20 @@ export async function getMulticall( return child.tokenBridge.l1MultiCall } +/** + * Maps the old {@link L2Network} (from SDK v3) to {@link ArbitrumNetwork} (from SDK v4). + */ +export function mapL2NetworkToArbitrumNetwork( + l2Network: L2NetworkOld +): ArbitrumNetwork { + return { + // Spread properties + ...l2Network, + // Map properties that were changed + parentChainId: l2Network.partnerChainID, + } +} + const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index a275e95749..8ba1f19053 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -28,11 +28,7 @@ import { SequencerInbox__factory } from '../abi/factories/SequencerInbox__factor import { IInbox__factory } from '../abi/factories/IInbox__factory' import { RequiredPick } from '../utils/types' import { MessageDeliveredEvent } from '../abi/Bridge' -import { - L2Network as ChildChain, - L1Network as ParentChain, - getParentForNetwork, -} from '../dataEntities/networks' +import { L2Network as ChildChain } from '../dataEntities/networks' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { FetchedEvent, EventFetcher } from '../utils/eventFetcher' import { MultiCaller, CallInput } from '../utils/multicall' @@ -65,10 +61,6 @@ export class InboxTools { * Parent chain provider */ private readonly parentChainProvider: Provider - /** - * Parent chain for the given Arbitrum chain, can be an L1 or an L2 - */ - private readonly parentChain: ParentChain | ChildChain constructor( private readonly parentChainSigner: Signer, @@ -77,7 +69,6 @@ export class InboxTools { this.parentChainProvider = SignerProviderUtils.getProviderOrThrow( this.parentChainSigner ) - this.parentChain = getParentForNetwork(childChain) } /** @@ -98,10 +89,10 @@ export class InboxTools { // we take a long average block time of 14s // and always move at least 10 blocks - const diffBlocks = Math.max( - Math.ceil(diff / this.parentChain.blockTime), - 10 - ) + + // todo(spsjvc): do something about this + const blockTime = 12 + const diffBlocks = Math.max(Math.ceil(diff / blockTime), 10) return await this.findFirstBlockBelow( blockNumber - diffBlocks, diff --git a/src/lib/utils/types.ts b/src/lib/utils/types.ts index dc0707ea5b..48d60a6a2e 100644 --- a/src/lib/utils/types.ts +++ b/src/lib/utils/types.ts @@ -14,3 +14,9 @@ export type PartialPick = OmitTyped & Partial * Make the specified properties required */ export type RequiredPick = Required> & T + +// https://twitter.com/mattpocockuk/status/1622730173446557697 +export type Prettify = { + [K in keyof T]: T[K] + // eslint-disable-next-line @typescript-eslint/ban-types +} & {} diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index a2a1c6b5b6..1edb612a41 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -443,10 +443,10 @@ export const skipIfMainnet = (() => { let chainId: number return async (testContext: Mocha.Context) => { if (!chainId) { - const { parentChain } = await testSetup() - chainId = parentChain.chainID + const { childChain } = await testSetup() + chainId = childChain.chainID } - if (chainId === 1) { + if (chainId === 42161 || chainId === 42170) { console.error("You're writing to the chain on mainnet lol stop") testContext.skip() } diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 6385cbd98e..c799e0c995 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -2,9 +2,7 @@ import { expect } from 'chai' import { resetNetworksToDefault, addCustomNetwork, - getL1Network, getArbitrumNetwork, - l1Networks, l2Networks as arbitrumNetworks, getChildrenForNetwork, isParentChain, @@ -14,7 +12,6 @@ import { const ethereumMainnetChainId = 1 const arbitrumOneChainId = 42161 -const mockL1ChainId = 111111 const mockL2ChainId = 222222 const mockL3ChainId = 99999999 @@ -24,7 +21,7 @@ describe('Networks', async () => { }) describe('adding networks', () => { - it('adds a custom Arbitrum network', async function () { + it('adds a custom L2 network', async function () { const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) const customArbitrumNetwork = { @@ -35,7 +32,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customArbitrumNetwork }) + addCustomNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok @@ -46,37 +43,6 @@ describe('Networks', async () => { expect(arbitrumNetwork.parentChainId).to.equal(ethereumMainnetChainId) }) - it('adds a custom L1 and Arbitrum network', async function () { - const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - - const customL1Network = { - ...ethereumMainnet, - chainID: mockL1ChainId, - isArbitrum: false, - isCustom: true, - } as const - - const customArbitrumNetwork = { - ...arbitrumOne, - parentChainId: mockL1ChainId, - chainID: mockL2ChainId, - isArbitrum: true, - isCustom: true, - } as const - - addCustomNetwork({ customL1Network, customArbitrumNetwork }) - - expect(await getL1Network(mockL1ChainId)).to.be.ok - expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok - - // assert network has correct parent - const arbitrumNetwork = await getArbitrumNetwork( - customArbitrumNetwork.chainID - ) - expect(arbitrumNetwork.parentChainId).to.equal(mockL1ChainId) - }) - it('adds a custom L3 network', async function () { const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) @@ -88,7 +54,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customArbitrumNetwork }) + addCustomNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok @@ -96,130 +62,14 @@ describe('Networks', async () => { const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.parentChainId).to.equal(arbitrumOneChainId) }) - - it('adds a custom L1, L2, and L3 network', async function () { - const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - - const customL1Network = { - ...ethereumMainnet, - chainID: mockL1ChainId, - isArbitrum: false, - isCustom: true, - } as const - - const customArbitrumNetwork = { - ...arbitrumOne, - chainID: mockL2ChainId, - parentChainId: mockL1ChainId, - isArbitrum: true, - isCustom: true, - } as const - - addCustomNetwork({ customL1Network, customArbitrumNetwork }) - - expect(await getL1Network(mockL1ChainId)).to.be.ok - expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok - - // assert network has correct parent - const arbitrumNetwork = await getArbitrumNetwork(mockL2ChainId) - expect(arbitrumNetwork.parentChainId).to.equal(mockL1ChainId) - - const customL3Network = { - ...arbitrumOne, - chainID: mockL3ChainId, - parentChainId: mockL2ChainId, - isArbitrum: true, - isCustom: true, - } as const - - addCustomNetwork({ customArbitrumNetwork: customL3Network }) - - expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok - - // assert network has correct parent - const l3Network = await getArbitrumNetwork(mockL3ChainId) - expect(l3Network.parentChainId).to.equal(mockL2ChainId) - }) - - it('fails to add a custom L1 and Arbitrum network if they do not match', async function () { - const ethereumMainnet = await getL1Network(ethereumMainnetChainId) - const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - - const wrongParentChainId = 1241244 - - const customL1Network = { - ...ethereumMainnet, - chainID: mockL1ChainId, - isArbitrum: false, - isCustom: true, - } as const - - const customArbitrumNetwork = { - ...arbitrumOne, - parentChainId: wrongParentChainId, - chainID: mockL2ChainId, - isArbitrum: true, - isCustom: true, - } as const - - try { - addCustomNetwork({ customL1Network, customArbitrumNetwork }) - } catch (err) { - // should fail - expect(err).to.be.an('error') - expect((err as Error).message).to.be.eq( - `Partner chain id for Arbitrum network ${customArbitrumNetwork.chainID} doesn't match the provided L1 network. Expected ${customL1Network.chainID} but got ${wrongParentChainId}.` - ) - } - }) - - it('fails to add a custom L3 without previously registering L2', async function () { - const arbitrumOne = await getArbitrumNetwork(arbitrumOneChainId) - - try { - addCustomNetwork({ - customArbitrumNetwork: { - ...arbitrumOne, - chainID: mockL3ChainId, - parentChainId: mockL2ChainId, - isArbitrum: true, - isCustom: true, - }, - }) - } catch (err) { - // should fail - expect(err).to.be.an('error') - expect((err as Error).message).to.be.eq( - `Network ${mockL3ChainId}'s parent network ${mockL2ChainId} is not recognized` - ) - } - }) }) describe('fetching networks', () => { - it('successfully fetches an L1 network with `getL1Network`', async function () { - const network = await getL1Network(ethereumMainnetChainId) - expect(network.chainID).to.be.eq(ethereumMainnetChainId) - }) - it('successfully fetches an Arbitrum network with `getArbitrumNetwork`', async function () { const network = await getArbitrumNetwork(arbitrumOneChainId) expect(network.chainID).to.be.eq(arbitrumOneChainId) }) - it('fails to fetch a registered Arbitrum network with `getL1Network`', async function () { - try { - await getL1Network(arbitrumOneChainId) - } catch (err) { - // should fail - expect(err).to.be.an('error') - expect((err as Error).message).to.be.eq( - `Unrecognized network ${arbitrumOneChainId}.` - ) - } - }) - it('fails to fetch a registered L1 network with `getArbitrumNetwork`', async function () { try { await getArbitrumNetwork(ethereumMainnetChainId) @@ -243,7 +93,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomNetwork({ customArbitrumNetwork: customL3Network }) + addCustomNetwork(customL3Network) const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.chainID).to.be.eq(mockL3ChainId) @@ -251,19 +101,6 @@ describe('Networks', async () => { expect(l3Network.parentChainId).to.equal(arbitrumOneChainId) }) - it('fails to fetch an unrecognized L1 network', async () => { - const chainId = 9999 - - try { - await getL1Network(chainId) - } catch (err) { - expect(err).to.be.instanceOf(Error) - expect((err as Error).message).to.be.eq( - `Unrecognized network ${chainId}.` - ) - } - }) - it('fails to fetch an unrecognized L2/L3 network', async () => { const chainId = 9999 @@ -279,17 +116,6 @@ describe('Networks', async () => { }) describe('returns correct networks', () => { - // todo: this could be a snapshot test - it('returns correct L1 networks', () => { - const l1NetworksEntries = Object.entries(l1Networks) - const l1NetworksKeys = l1NetworksEntries.map(([key]) => key) - - const expected = [1, 1338, 17000, 11155111].map(id => id.toString()) - - expect(l1NetworksKeys).to.have.length(expected.length) - expect(l1NetworksKeys).to.have.members(expected) - }) - // todo: this could be a snapshot test it('returns correct Arbitrum networks', () => { const arbitrumNetworksEntries = Object.entries(arbitrumNetworks) From a4b43b0670d05247af945e68d8f81e780bd01865 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 18 Apr 2024 18:39:28 +0200 Subject: [PATCH 28/74] feat: clean up networks names and imports (#458) --- README.md | 4 +- scripts/genNetwork.ts | 6 +- scripts/instantiate_bridge.ts | 9 +- scripts/sendL2SignedMsg.ts | 4 +- scripts/testSetup.ts | 10 +- src/index.ts | 6 +- src/lib/assetBridger/assetBridger.ts | 2 +- src/lib/dataEntities/networks.ts | 100 +++++++----------- src/lib/inbox/inbox.ts | 4 +- src/lib/message/ChildToParentMessage.ts | 7 +- .../message/ChildToParentMessageClassic.ts | 4 +- src/lib/message/ChildToParentMessageNitro.ts | 10 +- src/lib/message/ParentToChildMessage.ts | 4 +- .../message/ParentToChildMessageCreator.ts | 4 +- .../ParentToChildMessageGasEstimator.ts | 4 +- src/lib/message/ParentTransaction.ts | 10 +- src/lib/utils/multicall.ts | 4 +- tests/fork/inbox.test.ts | 8 +- tests/integration/ethBridgeAddresses.test.ts | 4 +- tests/integration/testHelpers.ts | 2 +- tests/unit/childToParentMessageEvents.test.ts | 2 +- tests/unit/multicall.test.ts | 8 +- tests/unit/network.test.ts | 58 +++++----- 23 files changed, 128 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index 09dd971682..a787f212a5 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ Below is an overview of the Arbitrum SDK functionality. See the [tutorials](http - ##### Deposit Ether Into Arbitrum ```ts -import { getL2Network, EthBridger } from '@arbitrum/sdk' +import { getArbitrumNetwork, EthBridger } from '@arbitrum/sdk' -const l2Network = await getL2Network( +const l2Network = await getArbitrumNetwork( l2ChainID /** <-- chain id of target Arbitrum chain */ ) const ethBridger = new EthBridger(l2Network) diff --git a/scripts/genNetwork.ts b/scripts/genNetwork.ts index 23376b7604..d0b7fdff45 100644 --- a/scripts/genNetwork.ts +++ b/scripts/genNetwork.ts @@ -6,8 +6,8 @@ import * as fs from 'fs' import { IERC20Bridge__factory } from '../src/lib/abi/factories/IERC20Bridge__factory' import { ethers } from 'ethers' import { + L2Network, ArbitrumNetwork, - L2NetworkOld, mapL2NetworkToArbitrumNetwork, } from '../src/lib/dataEntities/networks' @@ -40,8 +40,8 @@ function getLocalNetworksFromContainer(which: 'l1l2' | 'l2l3'): any { * we can remove this patchwork */ async function patchNetworks( - l2Network: L2NetworkOld, - l3Network: L2NetworkOld | undefined, + l2Network: L2Network, + l3Network: L2Network | undefined, l2Provider: ethers.providers.Provider | undefined ): Promise<{ patchedL2Network: ArbitrumNetwork diff --git a/scripts/instantiate_bridge.ts b/scripts/instantiate_bridge.ts index a105e14473..747a81e8b6 100644 --- a/scripts/instantiate_bridge.ts +++ b/scripts/instantiate_bridge.ts @@ -22,7 +22,10 @@ import { Wallet } from '@ethersproject/wallet' import dotenv from 'dotenv' import args from './getCLargs' import { EthBridger, InboxTools, Erc20Bridger } from '../src' -import { L2Network, getL2Network } from '../src/lib/dataEntities/networks' +import { + ArbitrumNetwork, + getArbitrumNetwork, +} from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' @@ -37,7 +40,7 @@ export const instantiateBridge = async ( l1PkParam?: string, l2PkParam?: string ): Promise<{ - l2Network: L2Network + l2Network: ArbitrumNetwork l1Signer: Signer l2Signer: Signer erc20Bridger: Erc20Bridger @@ -62,7 +65,7 @@ export const instantiateBridge = async ( l2NetworkID = defaultNetworkId } - const l2Network = await getL2Network(l2NetworkID) + const l2Network = await getArbitrumNetwork(l2NetworkID) const l1Rpc = (() => { if (l2NetworkID === 42161) return process.env['MAINNET_RPC'] as string diff --git a/scripts/sendL2SignedMsg.ts b/scripts/sendL2SignedMsg.ts index d117247518..08ccc8966f 100644 --- a/scripts/sendL2SignedMsg.ts +++ b/scripts/sendL2SignedMsg.ts @@ -18,11 +18,11 @@ import { BigNumber } from 'ethers' import { InboxTools } from '../src/lib/inbox/inbox' -import { getL2Network } from '../src/lib/dataEntities/networks' +import { getArbitrumNetwork } from '../src/lib/dataEntities/networks' import { testSetup } from '../scripts/testSetup' const sendSignedMsg = async () => { const { l1Deployer, l2Deployer } = await testSetup() - const l2Network = await getL2Network(await l2Deployer.getChainId()) + const l2Network = await getArbitrumNetwork(await l2Deployer.getChainId()) const inbox = new InboxTools(l1Deployer, l2Network) const message = { to: await l2Deployer.getAddress(), diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 3787bce6c6..a7a05d05c9 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -23,11 +23,11 @@ import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { + L2Network, ArbitrumNetwork, - getArbitrumNetwork, - addCustomNetwork, mapL2NetworkToArbitrumNetwork, - L2NetworkOld, + getArbitrumNetwork, + addCustomArbitrumNetwork, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' @@ -104,7 +104,7 @@ export const testSetup = async (): Promise<{ // check if theres an existing network available const { l2Network: childChain } = getLocalNetworksFromFile() - addCustomNetwork(childChain) + addCustomArbitrumNetwork(childChain) setChildChain = childChain } @@ -142,7 +142,7 @@ export function getLocalNetworksFromFile(): { throw new ArbSdkError('localNetwork.json not found, must gen:network first') } const localNetworksFile = fs.readFileSync(pathToLocalNetworkFile, 'utf8') - const localL2: L2NetworkOld = JSON.parse(localNetworksFile).l2Network + const localL2: L2Network = JSON.parse(localNetworksFile).l2Network return { l2Network: mapL2NetworkToArbitrumNetwork(localL2), diff --git a/src/index.ts b/src/index.ts index 126de5985d..9ab26c544b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,9 +43,9 @@ export { ParentToChildMessageGasEstimator } from './lib/message/ParentToChildMes export { argSerializerConstructor } from './lib/utils/byte_serialize_params' export { CallInput, MultiCaller } from './lib/utils/multicall' export { - L2Network, - getL2Network, - addCustomNetwork, + ArbitrumNetwork, + getArbitrumNetwork, + addCustomArbitrumNetwork, addDefaultLocalNetwork, getChildrenForNetwork, } from './lib/dataEntities/networks' diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 0308032416..75c2962611 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -58,7 +58,7 @@ export abstract class AssetBridger { * @param sop */ protected async checkChildChain(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.childChain.chainID) + await SignerProviderUtils.checkNetworkMatches(sop, this.childChain.chainId) } /** diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 48fdbe22e4..019015ba7b 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -35,7 +35,7 @@ export interface ArbitrumNetwork { /** * Id of the chain. */ - chainID: number + chainId: number /** * Chain id of the parent chain, i.e. the chain on which this chain settles to. */ @@ -75,9 +75,9 @@ export interface ArbitrumNetwork { * * @deprecated since v4 */ -export type L2NetworkOld = Prettify< - // todo(spsjvc): rename to L2Network after imports are cleaned up - Omit & { +export type L2Network = Prettify< + Omit & { + chainID: number partnerChainID: number } > @@ -110,10 +110,6 @@ export interface EthBridge { } } -export interface ArbitrumNetworks { - [id: string]: ArbitrumNetwork -} - export interface Networks { [id: string]: ArbitrumNetwork } @@ -152,7 +148,7 @@ const mainnetETHBridge: EthBridge = { */ export const networks: Networks = { 42161: { - chainID: 42161, + chainId: 42161, name: 'Arbitrum One', parentChainId: 1, tokenBridge: mainnetTokenBridge, @@ -161,7 +157,7 @@ export const networks: Networks = { isCustom: false, }, 42170: { - chainID: 42170, + chainId: 42170, confirmPeriodBlocks: 45818, ethBridge: { bridge: '0xC1Ebd02f738644983b6C4B2d440b8e77DdE276Bd', @@ -191,7 +187,7 @@ export const networks: Networks = { }, }, 421614: { - chainID: 421614, + chainId: 421614, confirmPeriodBlocks: 20, ethBridge: { bridge: '0x38f918D0E9F1b721EDaA41302E399fa1B79333a9', @@ -221,7 +217,7 @@ export const networks: Networks = { }, }, 23011913: { - chainID: 23011913, + chainId: 23011913, confirmPeriodBlocks: 20, ethBridge: { bridge: '0x35aa95ac4747D928E2Cd42FE4461F6D9d1826346', @@ -255,13 +251,13 @@ export const networks: Networks = { /** * Determines if a chain is a parent of *any* other chain. Could be an L1 or an L2 chain. */ -export const isParentChain = ( +export const isParentNetwork = ( parentChainOrChainId: ArbitrumNetwork | number ): boolean => { const parentChainId = typeof parentChainOrChainId === 'number' ? parentChainOrChainId - : parentChainOrChainId.chainID + : parentChainOrChainId.chainId // Check if there are any chains that have this chain as its parent chain return [...Object.values(l2Networks)].some( @@ -280,7 +276,7 @@ export const getChildrenForNetwork = ( const parentChainId = typeof parentChainOrChainId === 'number' ? parentChainOrChainId - : parentChainOrChainId.chainID + : parentChainOrChainId.chainId return Object.values(getArbitrumChains()).filter( arbitrumChain => arbitrumChain.parentChainId === parentChainId @@ -290,49 +286,36 @@ export const getChildrenForNetwork = ( /** * Index of all Arbitrum chains that have been added. */ -export let l2Networks: ArbitrumNetworks = getArbitrumChains() +export let l2Networks = getArbitrumChains() /** - * Returns the network associated with the given Signer, Provider or chain id. - * @note Throws if the chain is not recognized. + * Returns the Arbitrum chain associated with the given signer, provider or chain id. + * + * @note Throws if the chain is not an Arbitrum chain. */ -export const getNetwork = async ( - signerOrProviderOrChainID: SignerOrProvider | number -) => { - const chainID = await (async () => { - if (typeof signerOrProviderOrChainID === 'number') { - return signerOrProviderOrChainID +export const getArbitrumNetwork = async ( + signerOrProviderOrChainId: SignerOrProvider | number +): Promise => { + const chainId = await (async () => { + if (typeof signerOrProviderOrChainId === 'number') { + return signerOrProviderOrChainId } const provider = SignerProviderUtils.getProviderOrThrow( - signerOrProviderOrChainID + signerOrProviderOrChainId ) - const { chainId } = await provider.getNetwork() - return chainId + return (await provider.getNetwork()).chainId })() - let network: ArbitrumNetwork | undefined = undefined - - network = getArbitrumChains()[chainID] + const network: ArbitrumNetwork | undefined = getArbitrumChains()[chainId] if (!network) { - throw new ArbSdkError(`Unrecognized network ${chainID}.`) + throw new ArbSdkError(`Unrecognized network ${chainId}.`) } return network } -/** - * Returns the Arbitrum chain associated with the given signer, provider or chain id. - * - * @note Throws if the chain is not an Arbitrum chain. - */ -export const getArbitrumNetwork = ( - signerOrProviderOrChainID: SignerOrProvider | number -): Promise => { - return getNetwork(signerOrProviderOrChainID) as Promise -} - /** * Returns the addresses of all contracts that make up the ETH bridge * @param rollupContractAddress Address of the Rollup contract @@ -365,18 +348,17 @@ export const getEthBridgeInformation = async ( } /** - * Registers a pair of custom L1 and L2 chains, or a single custom Arbitrum chain (L2 or L3). + * Registers a custom Arbitrum chain (L2 or L3). * - * @param customL1Network the custom L1 chain (optional) - * @param customArbitrumNetwork the custom L2 or L3 chain + * @param network */ -export const addCustomNetwork = (network: ArbitrumNetwork): void => { - if (typeof networks[network.chainID] !== 'undefined') { - throw new Error(`Network ${network.chainID} already included`) +export const addCustomArbitrumNetwork = (network: ArbitrumNetwork): void => { + if (typeof networks[network.chainId] !== 'undefined') { + throw new Error(`Network ${network.chainId} already included`) } // store the network with the rest of the networks - networks[network.chainID] = network + networks[network.chainId] = network l2Networks = getArbitrumChains() } @@ -387,7 +369,7 @@ export const addCustomNetwork = (network: ArbitrumNetwork): void => { */ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { const defaultLocalL2Network: ArbitrumNetwork = { - chainID: 412346, + chainId: 412346, confirmPeriodBlocks: 20, ethBridge: { bridge: '0x2b360A9881F21c3d7aa0Ea6cA0De2a3341d4eF3C', @@ -417,7 +399,7 @@ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { }, } - addCustomNetwork(defaultLocalL2Network) + addCustomArbitrumNetwork(defaultLocalL2Network) return defaultLocalL2Network } @@ -443,7 +425,7 @@ export function getNitroGenesisBlock( const arbitrumChainId = typeof arbitrumChainOrChainId === 'number' ? arbitrumChainOrChainId - : arbitrumChainOrChainId.chainID + : arbitrumChainOrChainId.chainId // all networks except Arbitrum One started off with Nitro if (arbitrumChainId === 42161) { @@ -453,7 +435,7 @@ export function getNitroGenesisBlock( return 0 } -export async function getMulticall( +export async function getMulticallAddress( providerOrChainId: Provider | number ): Promise { const chains = [...Object.values(l2Networks)] @@ -462,7 +444,7 @@ export async function getMulticall( typeof providerOrChainId === 'number' ? providerOrChainId : (await providerOrChainId.getNetwork()).chainId - const chain = chains.find(c => c.chainID === chainId) + const chain = chains.find(c => c.chainId === chainId) // The provided chain is found in the list if (typeof chain !== 'undefined') { @@ -489,12 +471,13 @@ export async function getMulticall( * Maps the old {@link L2Network} (from SDK v3) to {@link ArbitrumNetwork} (from SDK v4). */ export function mapL2NetworkToArbitrumNetwork( - l2Network: L2NetworkOld + l2Network: L2Network ): ArbitrumNetwork { return { // Spread properties ...l2Network, // Map properties that were changed + chainId: l2Network.chainID, parentChainId: l2Network.partnerChainID, } } @@ -502,10 +485,3 @@ export function mapL2NetworkToArbitrumNetwork( const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } -export const getChildChain = getArbitrumNetwork - -export { - ArbitrumNetwork as L2Network, - ArbitrumNetworks as L2Networks, - getArbitrumNetwork as getL2Network, -} diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index 8ba1f19053..ca2967f59b 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -28,7 +28,7 @@ import { SequencerInbox__factory } from '../abi/factories/SequencerInbox__factor import { IInbox__factory } from '../abi/factories/IInbox__factory' import { RequiredPick } from '../utils/types' import { MessageDeliveredEvent } from '../abi/Bridge' -import { L2Network as ChildChain } from '../dataEntities/networks' +import { ArbitrumNetwork } from '../dataEntities/networks' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' import { FetchedEvent, EventFetcher } from '../utils/eventFetcher' import { MultiCaller, CallInput } from '../utils/multicall' @@ -64,7 +64,7 @@ export class InboxTools { constructor( private readonly parentChainSigner: Signer, - private readonly childChain: ChildChain + private readonly childChain: ArbitrumNetwork ) { this.parentChainProvider = SignerProviderUtils.getProviderOrThrow( this.parentChainSigner diff --git a/src/lib/message/ChildToParentMessage.ts b/src/lib/message/ChildToParentMessage.ts index 59c9ae5c4a..aefe70f1e4 100644 --- a/src/lib/message/ChildToParentMessage.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -35,7 +35,10 @@ import { import { isDefined } from '../utils/lib' import { EventArgs } from '../dataEntities/event' import { ChildToParentMessageStatus } from '../dataEntities/message' -import { getChildChain, getNitroGenesisBlock } from '../dataEntities/networks' +import { + getArbitrumNetwork, + getNitroGenesisBlock, +} from '../dataEntities/networks' import { ArbSdkError } from '../dataEntities/errors' export type ChildToParentTransactionEvent = @@ -111,7 +114,7 @@ export class ChildToParentMessage { hash?: BigNumber, indexInBatch?: BigNumber ): Promise<(ChildToParentTransactionEvent & { transactionHash: string })[]> { - const childChain = await getChildChain(childChainProvider) + const childChain = await getArbitrumNetwork(childChainProvider) const childChainNitroGenesisBlock = getNitroGenesisBlock(childChain) const inClassicRange = (blockTag: BlockTag, nitroGenBlock: number) => { diff --git a/src/lib/message/ChildToParentMessageClassic.ts b/src/lib/message/ChildToParentMessageClassic.ts index d023afeef4..e646083a7d 100644 --- a/src/lib/message/ChildToParentMessageClassic.ts +++ b/src/lib/message/ChildToParentMessageClassic.ts @@ -40,7 +40,7 @@ import { isDefined, wait } from '../utils/lib' import { ArbSdkError } from '../dataEntities/errors' import { EventArgs } from '../dataEntities/event' import { ChildToParentMessageStatus } from '../dataEntities/message' -import { getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' export interface MessageBatchProofInfo { /** @@ -213,7 +213,7 @@ export class ChildToParentMessageReaderClassic extends ChildToParentMessageClass batchNumber: number ) { if (!isDefined(this.outboxAddress)) { - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) // find the outbox where the activation batch number of the next outbox // is greater than the supplied batch diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index 8c9cb6f102..7bdc98f2ad 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -40,7 +40,7 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { getBlockRangesForL1Block, isArbitrumChain, wait } from '../utils/lib' -import { getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' import { NodeCreatedEvent, RollupUserLogic } from '../abi/RollupUserLogic' import { ArbitrumProvider } from '../utils/arbProvider' import { ArbBlock } from '../dataEntities/rpc' @@ -222,7 +222,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess * Check if this message has already been executed in the Outbox */ protected async hasExecuted(childProvider: Provider): Promise { - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) const outbox = Outbox__factory.connect( childChain.ethBridge.outbox, this.parentProvider @@ -375,7 +375,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess protected async getSendProps(childProvider: Provider) { if (!this.sendRootConfirmed) { - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) const rollup = RollupUserLogic__factory.connect( childChain.ethBridge.rollup, @@ -457,7 +457,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess public async getFirstExecutableBlock( childProvider: Provider ): Promise { - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) const rollup = RollupUserLogic__factory.connect( childChain.ethBridge.rollup, @@ -574,7 +574,7 @@ export class ChildToParentChainMessageWriterNitro extends ChildToParentChainMess ) } const proof = await this.getOutboxProof(childProvider) - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) const outbox = Outbox__factory.connect( childChain.ethBridge.outbox, this.parentSigner diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index 692a34f7e2..dd9454b13f 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -38,7 +38,7 @@ import { import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' import { ChildTransactionReceipt, RedeemTransaction } from './ChildTransaction' -import { getChildChain } from '../../lib/dataEntities/networks' +import { getArbitrumNetwork } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' import { EventFetcher } from '../utils/eventFetcher' @@ -319,7 +319,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { * @returns TransactionReceipt of the first successful redeem if exists, otherwise the current status of the message. */ public async getSuccessfulRedeem(): Promise { - const chainNetwork = await getChildChain(this.chainProvider) + const chainNetwork = await getArbitrumNetwork(this.chainProvider) const eventFetcher = new EventFetcher(this.chainProvider) const creationReceipt = await this.getRetryableCreationReceipt() diff --git a/src/lib/message/ParentToChildMessageCreator.ts b/src/lib/message/ParentToChildMessageCreator.ts index e06a0105ce..5e83c164ef 100644 --- a/src/lib/message/ParentToChildMessageCreator.ts +++ b/src/lib/message/ParentToChildMessageCreator.ts @@ -11,7 +11,7 @@ import { ParentTransactionReceipt, } from './ParentTransaction' import { Inbox__factory } from '../abi/factories/Inbox__factory' -import { getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' import { ERC20Inbox__factory } from '../abi/factories/ERC20Inbox__factory' import { PayableOverrides } from '@ethersproject/contracts' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' @@ -155,7 +155,7 @@ export class ParentToChildMessageCreator { options ) - const childChain = await getChildChain(childProvider) + const childChain = await getArbitrumNetwork(childProvider) const nativeTokenIsEth = typeof childChain.nativeToken === 'undefined' const data = ParentToChildMessageCreator.getTicketCreationRequestCallData( diff --git a/src/lib/message/ParentToChildMessageGasEstimator.ts b/src/lib/message/ParentToChildMessageGasEstimator.ts index a4b5098d34..b4c0d487d0 100644 --- a/src/lib/message/ParentToChildMessageGasEstimator.ts +++ b/src/lib/message/ParentToChildMessageGasEstimator.ts @@ -5,7 +5,7 @@ import { Inbox__factory } from '../abi/factories/Inbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' import { NODE_INTERFACE_ADDRESS } from '../dataEntities/constants' import { ArbSdkError } from '../dataEntities/errors' -import { getChildChain } from '../dataEntities/networks' +import { getArbitrumNetwork } from '../dataEntities/networks' import { RetryableData, RetryableDataTools, @@ -125,7 +125,7 @@ export class ParentToChildMessageGasEstimator { ): Promise { const defaultedOptions = this.applySubmissionPriceDefaults(options) - const network = await getChildChain(this.childProvider) + const network = await getArbitrumNetwork(this.childProvider) const inbox = Inbox__factory.connect( network.ethBridge.inbox, parentProvider diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 7c82c1ff12..2d1a864aff 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -112,7 +112,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { const network = await getArbitrumNetwork(provider) // all networks except Arbitrum One started off with Nitro - if (network.chainID === 42161) { + if (network.chainId === 42161) { return this.blockNumber < ARB1_NITRO_GENESIS_L1_BLOCK } @@ -217,7 +217,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { childProvider: Provider ): Promise { const network = await getArbitrumNetwork(childProvider) - const chainID = network.chainID.toString() + const chainId = network.chainId.toString() const isClassic = await this.isClassic(childProvider) // throw on nitro events @@ -235,7 +235,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { messageNum => new ParentToChildMessageReaderClassic( childProvider, - BigNumber.from(chainID).toNumber(), + BigNumber.from(chainId).toNumber(), messageNum ) ) @@ -255,7 +255,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { childSignerOrProvider ) const network = await getArbitrumNetwork(provider) - const chainID = network.chainID.toString() + const chainId = network.chainId.toString() const isClassic = await this.isClassic(provider) // throw on classic events @@ -282,7 +282,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { return ParentToChildMessage.fromEventComponents( childSignerOrProvider, - BigNumber.from(chainID).toNumber(), + BigNumber.from(chainId).toNumber(), mn.bridgeMessageEvent.sender, mn.inboxMessageEvent.messageNum, mn.bridgeMessageEvent.baseFeeL1, diff --git a/src/lib/utils/multicall.ts b/src/lib/utils/multicall.ts index e1866cab0c..9ca4b1996f 100644 --- a/src/lib/utils/multicall.ts +++ b/src/lib/utils/multicall.ts @@ -22,7 +22,7 @@ import { BigNumber, utils } from 'ethers' import { ERC20__factory } from '../abi/factories/ERC20__factory' import { Multicall2 } from '../abi/Multicall2' import { Multicall2__factory } from '../abi/factories/Multicall2__factory' -import { getMulticall } from '../dataEntities/networks' +import { getMulticallAddress } from '../dataEntities/networks' /** * Input to multicall aggregator @@ -123,7 +123,7 @@ export class MultiCaller { * @returns */ public static async fromProvider(provider: Provider): Promise { - return new MultiCaller(provider, await getMulticall(provider)) + return new MultiCaller(provider, await getMulticallAddress(provider)) } /** diff --git a/tests/fork/inbox.test.ts b/tests/fork/inbox.test.ts index 7ed76a4790..fd3df901be 100644 --- a/tests/fork/inbox.test.ts +++ b/tests/fork/inbox.test.ts @@ -31,8 +31,8 @@ import { InboxTools } from '../../src' import { ethers, network } from 'hardhat' import { hexZeroPad } from '@ethersproject/bytes' import { - ChildChain as L2Network, - getChildChain as getL2Network, + ArbitrumNetwork, + getArbitrumNetwork, } from '../../src/lib/dataEntities/networks' import { solidityKeccak256 } from 'ethers/lib/utils' import { ContractTransaction, Signer } from 'ethers' @@ -46,7 +46,7 @@ const submitL2Tx = async ( maxFeePerGas: BigNumber gasLimit: BigNumber }, - l2Network: L2Network, + l2Network: ArbitrumNetwork, l1Signer: Signer ): Promise => { const inbox = Inbox__factory.connect(l2Network.ethBridge.inbox, l1Signer) @@ -67,7 +67,7 @@ describe('Inbox tools', () => { const signer = signers[0] const provider = signer.provider! - const arbitrumOne = await getL2Network(42161) + const arbitrumOne = await getArbitrumNetwork(42161) const sequencerInbox = SequencerInbox__factory.connect( arbitrumOne.ethBridge.sequencerInbox, diff --git a/tests/integration/ethBridgeAddresses.test.ts b/tests/integration/ethBridgeAddresses.test.ts index 57c9eb8b62..6fa8fc0671 100644 --- a/tests/integration/ethBridgeAddresses.test.ts +++ b/tests/integration/ethBridgeAddresses.test.ts @@ -3,7 +3,7 @@ import { expect } from 'chai' import { EthBridge, getEthBridgeInformation, - getChildChain as getL2Network, + getArbitrumNetwork, } from '../../src/lib/dataEntities/networks' import dotenv from 'dotenv' dotenv.config() @@ -14,7 +14,7 @@ dotenv.config() */ describe('Obtain deployed bridge addresses', () => { it('obtains deployed ETH Bridge addresses', async () => { - const arbOneL2Network = await getL2Network(42161) + const arbOneL2Network = await getArbitrumNetwork(42161) const ethProvider = new JsonRpcProvider( process.env['MAINNET_RPC'] as string ) diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 1edb612a41..7ad2ece9a9 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -444,7 +444,7 @@ export const skipIfMainnet = (() => { return async (testContext: Mocha.Context) => { if (!chainId) { const { childChain } = await testSetup() - chainId = childChain.chainID + chainId = childChain.chainId } if (chainId === 42161 || chainId === 42170) { console.error("You're writing to the chain on mainnet lol stop") diff --git a/tests/unit/childToParentMessageEvents.test.ts b/tests/unit/childToParentMessageEvents.test.ts index 0d505da4c9..0e5d3f7316 100644 --- a/tests/unit/childToParentMessageEvents.test.ts +++ b/tests/unit/childToParentMessageEvents.test.ts @@ -43,7 +43,7 @@ describe('ChildToParentMessage events', () => { const latestBlock = getNitroGenesisBlock(l2Network) + 1000 when(l2ProviderMock.getBlockNumber()).thenResolve(latestBlock) when(l2ProviderMock.getNetwork()).thenResolve({ - chainId: l2Network.chainID, + chainId: l2Network.chainId, } as any) when(l2ProviderMock._isProvider).thenReturn(true) when(l2ProviderMock.getLogs(anything())).thenResolve([]) diff --git a/tests/unit/multicall.test.ts b/tests/unit/multicall.test.ts index cef88f399c..04e30a3b3b 100644 --- a/tests/unit/multicall.test.ts +++ b/tests/unit/multicall.test.ts @@ -1,7 +1,7 @@ 'use strict' import { - getChildChain as getL2Network, + getArbitrumNetwork, getNitroGenesisBlock, } from '../../src/lib/dataEntities/networks' import { providers } from 'ethers' @@ -12,18 +12,18 @@ import { MultiCaller } from '../../src' describe('Multicall', () => { const createProviderMock = async (networkChoiceOverride?: number) => { - const l2Network = await getL2Network(networkChoiceOverride || 42161) + const l2Network = await getArbitrumNetwork(networkChoiceOverride || 42161) const l2ProviderMock = mock(providers.JsonRpcProvider) const latestBlock = getNitroGenesisBlock(l2Network) + 1000 when(l2ProviderMock.getBlockNumber()).thenResolve(latestBlock) when(l2ProviderMock.getNetwork()).thenResolve({ - chainId: l2Network.chainID, + chainId: l2Network.chainId, } as any) when(l2ProviderMock._isProvider).thenReturn(true) when(l2ProviderMock.getLogs(anything())).thenResolve([]) - /* + /* This test data is taken from an actual example of a mainnet multicall. To produce this data we do the following: 1. Pass mainnet args to the multicall class, instantiated with a mock provider 2. Capture the .call request that was made on the provider diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index c799e0c995..75d41559d4 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -1,12 +1,12 @@ import { expect } from 'chai' import { resetNetworksToDefault, - addCustomNetwork, + addCustomArbitrumNetwork, getArbitrumNetwork, l2Networks as arbitrumNetworks, getChildrenForNetwork, - isParentChain, - getMulticall, + isParentNetwork, + getMulticallAddress, } from '../../src/lib/dataEntities/networks' const ethereumMainnetChainId = 1 @@ -26,19 +26,19 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, - chainID: mockL2ChainId, + chainId: mockL2ChainId, parentChainId: ethereumMainnetChainId, isArbitrum: true, isCustom: true, } as const - addCustomNetwork(customArbitrumNetwork) + addCustomArbitrumNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok // assert network has correct parent const arbitrumNetwork = await getArbitrumNetwork( - customArbitrumNetwork.chainID + customArbitrumNetwork.chainId ) expect(arbitrumNetwork.parentChainId).to.equal(ethereumMainnetChainId) }) @@ -48,13 +48,13 @@ describe('Networks', async () => { const customArbitrumNetwork = { ...arbitrumOne, - chainID: mockL3ChainId, + chainId: mockL3ChainId, parentChainId: arbitrumOneChainId, isArbitrum: true, isCustom: true, } as const - addCustomNetwork(customArbitrumNetwork) + addCustomArbitrumNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok @@ -67,7 +67,7 @@ describe('Networks', async () => { describe('fetching networks', () => { it('successfully fetches an Arbitrum network with `getArbitrumNetwork`', async function () { const network = await getArbitrumNetwork(arbitrumOneChainId) - expect(network.chainID).to.be.eq(arbitrumOneChainId) + expect(network.chainId).to.be.eq(arbitrumOneChainId) }) it('fails to fetch a registered L1 network with `getArbitrumNetwork`', async function () { @@ -87,16 +87,16 @@ describe('Networks', async () => { const customL3Network = { ...arbitrumOne, - chainID: mockL3ChainId, + chainId: mockL3ChainId, parentChainId: arbitrumOneChainId, isArbitrum: true, isCustom: true, } as const - addCustomNetwork(customL3Network) + addCustomArbitrumNetwork(customL3Network) const l3Network = await getArbitrumNetwork(mockL3ChainId) - expect(l3Network.chainID).to.be.eq(mockL3ChainId) + expect(l3Network.chainId).to.be.eq(mockL3ChainId) // assert network has correct parent expect(l3Network.parentChainId).to.equal(arbitrumOneChainId) }) @@ -132,76 +132,76 @@ describe('Networks', async () => { describe('getChildrenForNetwork', () => { it('returns correct children for ethereum mainnet', () => { - const children = getChildrenForNetwork(1).map(c => c.chainID) + const children = getChildrenForNetwork(1).map(c => c.chainId) expect(children).to.have.members([42161, 42170]) }) it('returns correct children for arbitrum one', () => { - const children = getChildrenForNetwork(42161).map(c => c.chainID) + const children = getChildrenForNetwork(42161).map(c => c.chainId) expect(children).to.have.members([]) }) it('returns correct children for arbitrum nova', () => { - const children = getChildrenForNetwork(42170).map(c => c.chainID) + const children = getChildrenForNetwork(42170).map(c => c.chainId) expect(children).to.have.members([]) }) it('returns correct children for sepolia', () => { - const children = getChildrenForNetwork(11155111).map(c => c.chainID) + const children = getChildrenForNetwork(11155111).map(c => c.chainId) expect(children).to.have.members([421614]) }) it('returns correct children for arbitrum sepolia', () => { - const children = getChildrenForNetwork(421614).map(c => c.chainID) + const children = getChildrenForNetwork(421614).map(c => c.chainId) expect(children).to.have.members([23011913]) }) }) - describe('isParentChain', () => { + describe('isParentNetwork', () => { it('returns correct value for ethereum mainnet', () => { - expect(isParentChain(1)).to.equal(true) + expect(isParentNetwork(1)).to.equal(true) }) it('returns correct value for arbitrum one', () => { - expect(isParentChain(42161)).to.equal(false) + expect(isParentNetwork(42161)).to.equal(false) }) it('returns correct value for arbitrum nova', () => { - expect(isParentChain(42170)).to.equal(false) + expect(isParentNetwork(42170)).to.equal(false) }) it('returns correct value for sepolia', () => { - expect(isParentChain(11155111)).to.equal(true) + expect(isParentNetwork(11155111)).to.equal(true) }) it('returns correct value for arbitrum sepolia', () => { - expect(isParentChain(421614)).to.equal(true) + expect(isParentNetwork(421614)).to.equal(true) }) }) - describe('getMulticall', () => { + describe('getMulticallAddress', () => { it('returns correct value for ethereum mainnet', async () => { - const multicall = await getMulticall(1) + const multicall = await getMulticallAddress(1) expect(multicall).to.equal('0x5ba1e12693dc8f9c48aad8770482f4739beed696') }) it('returns correct value for arbitrum one', async () => { - const multicall = await getMulticall(42161) + const multicall = await getMulticallAddress(42161) expect(multicall).to.equal('0x842eC2c7D803033Edf55E478F461FC547Bc54EB2') }) it('returns correct value for arbitrum nova', async () => { - const multicall = await getMulticall(42170) + const multicall = await getMulticallAddress(42170) expect(multicall).to.equal('0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86') }) it('returns correct value for sepolia', async () => { - const multicall = await getMulticall(11155111) + const multicall = await getMulticallAddress(11155111) expect(multicall).to.equal('0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320') }) it('returns correct value for arbitrum sepolia', async () => { - const multicall = await getMulticall(421614) + const multicall = await getMulticallAddress(421614) expect(multicall).to.equal('0xA115146782b7143fAdB3065D86eACB54c169d092') }) }) From 7992ace0fe8c5d2e69092f0783d1dd1882e0ca22 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 18 Apr 2024 18:44:29 +0200 Subject: [PATCH 29/74] chore: bump version to v4.0.0-alpha.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 47b5fd31f1..1efb710caa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "3.3.3", + "version": "4.0.0-alpha.0", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", @@ -95,4 +95,4 @@ "resolutions": { "lodash.pick": "https://github.com/lodash/lodash/archive/refs/tags/4.17.21.tar.gz" } -} \ No newline at end of file +} From 1cd6724fd821b66096424649d3983cf7a031d2b2 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 19 Apr 2024 13:05:52 +0200 Subject: [PATCH 30/74] feat: get arbitrum network information from rollup (#460) --- src/index.ts | 2 + src/lib/dataEntities/networks.ts | 55 ++++++++++++------- tests/integration/ethBridgeAddresses.test.ts | 47 ---------------- ...bitrumNetworkInformationFromRollup.test.ts | 43 +++++++++++++++ 4 files changed, 79 insertions(+), 68 deletions(-) delete mode 100644 tests/integration/ethBridgeAddresses.test.ts create mode 100644 tests/integration/getArbitrumNetworkInformationFromRollup.test.ts diff --git a/src/index.ts b/src/index.ts index 9ab26c544b..7ba463c4c0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,8 @@ export { CallInput, MultiCaller } from './lib/utils/multicall' export { ArbitrumNetwork, getArbitrumNetwork, + ArbitrumNetworkInformationFromRollup, + getArbitrumNetworkInformationFromRollup, addCustomArbitrumNetwork, addDefaultLocalNetwork, getChildrenForNetwork, diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 019015ba7b..83d7f524f1 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -316,34 +316,47 @@ export const getArbitrumNetwork = async ( return network } +export type ArbitrumNetworkInformationFromRollup = Pick< + ArbitrumNetwork, + 'parentChainId' | 'confirmPeriodBlocks' | 'ethBridge' +> + /** - * Returns the addresses of all contracts that make up the ETH bridge - * @param rollupContractAddress Address of the Rollup contract - * @param l1SignerOrProvider A parent chain signer or provider - * @returns EthBridge object with all information about the ETH bridge + * Returns all the information about an Arbitrum network that can be fetched from its Rollup contract. + * + * @param rollupAddress Address of the Rollup contract on the parent chain + * @param parentProvider Provider for the parent chain + * + * @returns An {@link ArbitrumNetworkInformationFromRollup} object */ -export const getEthBridgeInformation = async ( - rollupContractAddress: string, - l1SignerOrProvider: SignerOrProvider -): Promise => { +export async function getArbitrumNetworkInformationFromRollup( + rollupAddress: string, + parentProvider: Provider +): Promise { const rollup = RollupAdminLogic__factory.connect( - rollupContractAddress, - l1SignerOrProvider + rollupAddress, + parentProvider ) - const [bridge, inbox, sequencerInbox, outbox] = await Promise.all([ - rollup.bridge(), - rollup.inbox(), - rollup.sequencerInbox(), - rollup.outbox(), - ]) + const [bridge, inbox, sequencerInbox, outbox, confirmPeriodBlocks] = + await Promise.all([ + rollup.bridge(), + rollup.inbox(), + rollup.sequencerInbox(), + rollup.outbox(), + rollup.confirmPeriodBlocks(), + ]) return { - bridge, - inbox, - sequencerInbox, - outbox, - rollup: rollupContractAddress, + parentChainId: (await parentProvider.getNetwork()).chainId, + confirmPeriodBlocks: confirmPeriodBlocks.toNumber(), + ethBridge: { + bridge, + inbox, + sequencerInbox, + outbox, + rollup: rollupAddress, + }, } } diff --git a/tests/integration/ethBridgeAddresses.test.ts b/tests/integration/ethBridgeAddresses.test.ts deleted file mode 100644 index 6fa8fc0671..0000000000 --- a/tests/integration/ethBridgeAddresses.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { JsonRpcProvider } from '@ethersproject/providers' -import { expect } from 'chai' -import { - EthBridge, - getEthBridgeInformation, - getArbitrumNetwork, -} from '../../src/lib/dataEntities/networks' -import dotenv from 'dotenv' -dotenv.config() - -/** - * Tests the getEthBridgeInformation function against the information - * of Arbitrum One network (42161) - */ -describe('Obtain deployed bridge addresses', () => { - it('obtains deployed ETH Bridge addresses', async () => { - const arbOneL2Network = await getArbitrumNetwork(42161) - const ethProvider = new JsonRpcProvider( - process.env['MAINNET_RPC'] as string - ) - - // Obtain on-chain information - const ethBridge: EthBridge = await getEthBridgeInformation( - arbOneL2Network.ethBridge.rollup, - ethProvider - ) - - // Obtained addresses should equal the addresses - // available in Arbitrum One's l2Network configuration - expect( - arbOneL2Network.ethBridge.bridge, - 'Bridge contract is not correct' - ).to.eq(ethBridge.bridge) - expect( - arbOneL2Network.ethBridge.inbox, - 'Inbox contract is not correct' - ).to.eq(ethBridge.inbox) - expect( - arbOneL2Network.ethBridge.sequencerInbox, - 'SequencerInbox contract is not correct' - ).to.eq(ethBridge.sequencerInbox) - expect( - arbOneL2Network.ethBridge.outbox, - 'Outbox contract is not correct' - ).to.eq(ethBridge.outbox) - }) -}) diff --git a/tests/integration/getArbitrumNetworkInformationFromRollup.test.ts b/tests/integration/getArbitrumNetworkInformationFromRollup.test.ts new file mode 100644 index 0000000000..f6ed3b9134 --- /dev/null +++ b/tests/integration/getArbitrumNetworkInformationFromRollup.test.ts @@ -0,0 +1,43 @@ +import dotenv from 'dotenv' +import { JsonRpcProvider } from '@ethersproject/providers' +import { expect } from 'chai' +import { + getArbitrumNetwork, + getArbitrumNetworkInformationFromRollup, +} from '../../src/lib/dataEntities/networks' + +dotenv.config() + +describe('getArbitrumNetworkInformationFromRollup.test', () => { + it('fetches information about arbitrum one', async () => { + const arb1 = await getArbitrumNetwork(42161) + const ethProvider = new JsonRpcProvider( + process.env['MAINNET_RPC'] as string + ) + + const { parentChainId, confirmPeriodBlocks, ethBridge } = + await getArbitrumNetworkInformationFromRollup( + arb1.ethBridge.rollup, + ethProvider + ) + + expect(parentChainId, 'parentChainId is not correct').to.eq( + arb1.parentChainId + ) + + expect(confirmPeriodBlocks, 'confirmPeriodBlocks is not correct').to.eq( + arb1.confirmPeriodBlocks + ) + + const { bridge, inbox, sequencerInbox, outbox, rollup } = ethBridge + const arb1EthBridge = arb1.ethBridge + + expect(bridge, 'Bridge contract is not correct').to.eq(arb1EthBridge.bridge) + expect(inbox, 'Inbox contract is not correct').to.eq(arb1EthBridge.inbox) + expect(sequencerInbox, 'SequencerInbox contract is not correct').to.eq( + arb1EthBridge.sequencerInbox + ) + expect(outbox, 'Outbox contract is not correct').to.eq(arb1EthBridge.outbox) + expect(rollup, 'Rollup contract is not correct').to.eq(arb1EthBridge.rollup) + }) +}) From 0f728edb7404398def5c72e48db649db1355d8ac Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 19 Apr 2024 13:06:44 +0200 Subject: [PATCH 31/74] chore: bump version to v4.0.0-alpha.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1efb710caa..5402ff0c10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.0", + "version": "4.0.0-alpha.1", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 7b411ceda87f4fddb73de8150bdb751cbafe717c Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 19 Apr 2024 16:50:08 +0200 Subject: [PATCH 32/74] feat: update behaviour for registering custom networks (#461) --- scripts/testSetup.ts | 6 ++---- src/index.ts | 4 ++-- src/lib/dataEntities/networks.ts | 33 +++++++++++++++++++++++++------- tests/unit/network.test.ts | 8 ++++---- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index a7a05d05c9..cf2c23e788 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -27,7 +27,7 @@ import { ArbitrumNetwork, mapL2NetworkToArbitrumNetwork, getArbitrumNetwork, - addCustomArbitrumNetwork, + registerCustomArbitrumNetwork, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' @@ -103,9 +103,7 @@ export const testSetup = async (): Promise<{ // the networks havent been added yet // check if theres an existing network available const { l2Network: childChain } = getLocalNetworksFromFile() - - addCustomArbitrumNetwork(childChain) - setChildChain = childChain + setChildChain = registerCustomArbitrumNetwork(childChain) } const erc20Bridger = new Erc20Bridger(setChildChain) diff --git a/src/index.ts b/src/index.ts index 7ba463c4c0..378d1e4535 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,9 +47,9 @@ export { getArbitrumNetwork, ArbitrumNetworkInformationFromRollup, getArbitrumNetworkInformationFromRollup, - addCustomArbitrumNetwork, - addDefaultLocalNetwork, getChildrenForNetwork, + registerCustomArbitrumNetwork, + addDefaultLocalNetwork, } from './lib/dataEntities/networks' export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 83d7f524f1..63bbbc8eec 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -361,18 +361,39 @@ export async function getArbitrumNetworkInformationFromRollup( } /** - * Registers a custom Arbitrum chain (L2 or L3). + * Registers a custom Arbitrum network. * - * @param network + * @param network {@link ArbitrumNetwork} to be registered + * @param options Additional options + * @param options.throwIfAlreadyRegistered Whether or not the function should throw if the network is already registered, defaults to `false` */ -export const addCustomArbitrumNetwork = (network: ArbitrumNetwork): void => { +export function registerCustomArbitrumNetwork( + network: ArbitrumNetwork, + options?: { throwIfAlreadyRegistered?: boolean } +): ArbitrumNetwork { + const throwIfAlreadyRegistered = options?.throwIfAlreadyRegistered ?? false + + if (!network.isCustom) { + throw new ArbSdkError( + `Custom network ${network.chainId} must have isCustom flag set to true` + ) + } + if (typeof networks[network.chainId] !== 'undefined') { - throw new Error(`Network ${network.chainId} already included`) + const message = `Network ${network.chainId} already included` + + if (throwIfAlreadyRegistered) { + throw new ArbSdkError(message) + } + + console.warn(message) } // store the network with the rest of the networks networks[network.chainId] = network l2Networks = getArbitrumChains() + + return network } /** @@ -412,9 +433,7 @@ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { }, } - addCustomArbitrumNetwork(defaultLocalL2Network) - - return defaultLocalL2Network + return registerCustomArbitrumNetwork(defaultLocalL2Network) } /** diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 75d41559d4..b3c2e1cac5 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { resetNetworksToDefault, - addCustomArbitrumNetwork, + registerCustomArbitrumNetwork, getArbitrumNetwork, l2Networks as arbitrumNetworks, getChildrenForNetwork, @@ -32,7 +32,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomArbitrumNetwork(customArbitrumNetwork) + registerCustomArbitrumNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL2ChainId)).to.be.ok @@ -54,7 +54,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomArbitrumNetwork(customArbitrumNetwork) + registerCustomArbitrumNetwork(customArbitrumNetwork) expect(await getArbitrumNetwork(mockL3ChainId)).to.be.ok @@ -93,7 +93,7 @@ describe('Networks', async () => { isCustom: true, } as const - addCustomArbitrumNetwork(customL3Network) + registerCustomArbitrumNetwork(customL3Network) const l3Network = await getArbitrumNetwork(mockL3ChainId) expect(l3Network.chainId).to.be.eq(mockL3ChainId) From 1939dd12eca3f43858491ff5dd7166aa94b59a02 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 19 Apr 2024 17:22:02 +0200 Subject: [PATCH 33/74] chore: bump version to v4.0.0-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5402ff0c10..3d25372374 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.1", + "version": "4.0.0-alpha.2", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From a16a09d6fcef20a9c43359fccd8e413659218ffd Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 25 Apr 2024 18:18:38 +0200 Subject: [PATCH 34/74] fix: use proper type --- tests/integration/childTransactionReceipt.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/childTransactionReceipt.test.ts b/tests/integration/childTransactionReceipt.test.ts index 4fa6e426a7..fb54418aa0 100644 --- a/tests/integration/childTransactionReceipt.test.ts +++ b/tests/integration/childTransactionReceipt.test.ts @@ -32,7 +32,7 @@ import { parseEther } from 'ethers/lib/utils' import { testSetup } from '../../scripts/testSetup' async function waitForL1BatchConfirmations( - arbTxReceipt: L2TransactionReceipt, + arbTxReceipt: ChildTransactionReceipt, l2Provider: JsonRpcProvider, timeoutMs: number ) { From 0f36dd32c3cddd4e817ea68d7dcf053acf2bf298 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Thu, 25 Apr 2024 18:53:02 +0200 Subject: [PATCH 35/74] feat: clean up messages (#463) --- src/index.ts | 7 +++++-- src/lib/message/ParentToChildMessage.ts | 24 ++++++++++++------------ src/lib/message/ParentTransaction.ts | 10 +++++----- tests/integration/eth.test.ts | 4 ++-- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/index.ts b/src/index.ts index 378d1e4535..eb72c9aa20 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,12 +32,15 @@ export { ParentTransactionReceipt, } from './lib/message/ParentTransaction' export { - ParentToChildMessageStatus, - EthDepositStatus, + EthDepositMessage, + EthDepositMessageStatus, + EthDepositMessageWaitForStatusResult, ParentToChildMessage, ParentToChildMessageReader, ParentToChildMessageReaderClassic, ParentToChildMessageWriter, + ParentToChildMessageStatus, + ParentToChildMessageWaitForStatusResult, } from './lib/message/ParentToChildMessage' export { ParentToChildMessageGasEstimator } from './lib/message/ParentToChildMessageGasEstimator' export { argSerializerConstructor } from './lib/utils/byte_serialize_params' diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index dd9454b13f..4f9021b43e 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -72,7 +72,7 @@ export enum ParentToChildMessageStatus { EXPIRED = 5, } -export enum EthDepositStatus { +export enum EthDepositMessageStatus { /** * ETH is not deposited on Chain yet */ @@ -237,10 +237,10 @@ export abstract class ParentToChildMessage { * If the status is redeemed an chainTxReceipt is populated. * For all other statuses chainTxReceipt is not populated */ -export type ParentToChildMessageWaitResult = +export type ParentToChildMessageWaitForStatusResult = | { status: ParentToChildMessageStatus.REDEEMED - chainTxReceipt: TransactionReceipt + txReceipt: TransactionReceipt } | { status: Exclude< @@ -249,8 +249,8 @@ export type ParentToChildMessageWaitResult = > } -export type EthDepositMessageWaitResult = { - chainTxReceipt: TransactionReceipt | null +export type EthDepositMessageWaitForStatusResult = { + txReceipt: TransactionReceipt | null } export class ParentToChildMessageReader extends ParentToChildMessage { @@ -318,7 +318,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { * Receipt for the successful chain transaction created by this message. * @returns TransactionReceipt of the first successful redeem if exists, otherwise the current status of the message. */ - public async getSuccessfulRedeem(): Promise { + public async getSuccessfulRedeem(): Promise { const chainNetwork = await getArbitrumNetwork(this.chainProvider) const eventFetcher = new EventFetcher(this.chainProvider) const creationReceipt = await this.getRetryableCreationReceipt() @@ -337,7 +337,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { const autoRedeem = await this.getAutoRedeemAttempt() if (autoRedeem && autoRedeem.status === 1) { return { - chainTxReceipt: autoRedeem, + txReceipt: autoRedeem, status: ParentToChildMessageStatus.REDEEMED, } } @@ -395,7 +395,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { ) if (successfulRedeem.length == 1) return { - chainTxReceipt: successfulRedeem[0], + txReceipt: successfulRedeem[0], status: ParentToChildMessageStatus.REDEEMED, } @@ -492,7 +492,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { public async waitForStatus( confirmations?: number, timeout?: number - ): Promise { + ): Promise { const chosenTimeout = isDefined(timeout) ? timeout : DEFAULT_DEPOSIT_TIMEOUT // try to wait for the retryable ticket to be created @@ -866,12 +866,12 @@ export class EthDepositMessage { ) } - public async status(): Promise { + public async status(): Promise { const receipt = await this.chainProvider.getTransactionReceipt( this.chainDepositTxHash ) - if (receipt === null) return EthDepositStatus.PENDING - else return EthDepositStatus.DEPOSITED + if (receipt === null) return EthDepositMessageStatus.PENDING + else return EthDepositMessageStatus.DEPOSITED } public async wait(confirmations?: number, timeout?: number) { diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 2d1a864aff..ee53b6c00e 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -27,9 +27,9 @@ import { ParentToChildMessageReaderClassic, ParentToChildMessageWriter, ParentToChildMessageStatus, - ParentToChildMessageWaitResult, + ParentToChildMessageWaitForStatusResult, EthDepositMessage, - EthDepositMessageWaitResult, + EthDepositMessageWaitForStatusResult, } from './ParentToChildMessage' import { L1ERC20Gateway__factory } from '../abi/factories/L1ERC20Gateway__factory' @@ -374,7 +374,7 @@ export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt { complete: boolean message: EthDepositMessage - } & EthDepositMessageWaitResult + } & EthDepositMessageWaitForStatusResult > { const message = (await this.getEthDeposits(childProvider))[0] if (!message) @@ -383,7 +383,7 @@ export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt return { complete: isDefined(res), - chainTxReceipt: res, + txReceipt: res, message, } } @@ -412,7 +412,7 @@ export class ParentContractCallTransactionReceipt extends ParentTransactionRecei { complete: boolean message: ParentToChildMessageReaderOrWriter - } & ParentToChildMessageWaitResult + } & ParentToChildMessageWaitForStatusResult > { const message = ( await this.getParentToChildMessages(childSignerOrProvider) diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index ac4d3ae976..4ec661d257 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -136,8 +136,8 @@ describe('Ether', async () => { prettyLog('chainTxHash: ' + waitResult.message.chainDepositTxHash) prettyLog('chain transaction found!') expect(waitResult.complete).to.eq(true, 'eth deposit not complete') - expect(waitResult.chainTxReceipt).to.exist - expect(waitResult.chainTxReceipt).to.not.be.null + expect(waitResult.txReceipt).to.exist + expect(waitResult.txReceipt).to.not.be.null const testWalletL2EthBalance = await childSigner.getBalance() expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( From efca57ce2c57ea806e1680654007c0d0ae289ae4 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 26 Apr 2024 00:41:07 +0200 Subject: [PATCH 36/74] chore: bump version to v4.0.0-alpha.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d25372374..19437ecfb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.2", + "version": "4.0.0-alpha.3", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 8ba30752fef73eb1701c820c9d0f1cd4dd7260c9 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:42:28 -0400 Subject: [PATCH 37/74] chore: clean up older renaming changes (#470) --- .github/workflows/build-test.yml | 2 - src/lib/dataEntities/networks.ts | 6 +- src/lib/inbox/inbox.ts | 92 ++++++------ src/lib/message/ChildToParentMessage.ts | 128 ++++++++-------- src/lib/message/ChildToParentMessageNitro.ts | 132 ++++++++-------- src/lib/message/ParentToChildMessage.ts | 142 +++++++++--------- src/lib/message/ParentTransaction.ts | 4 +- tests/integration/eth.test.ts | 2 +- .../parentToChildMessageCreator.test.ts | 12 +- tests/integration/sendChildmsg.test.ts | 4 +- tests/integration/testHelpers.ts | 68 ++++----- tests/unit/parentToChildMessageEvents.test.ts | 4 +- 12 files changed, 288 insertions(+), 308 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 35b11045e8..f93977630e 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -161,8 +161,6 @@ jobs: - name: Set up the local node uses: OffchainLabs/actions/run-nitro-test-node@main with: - nitro-testnode-ref: release - nitro-contracts-branch: validator-wallet-fix l3-node: ${{ matrix.orbit-test == '1' }} args: ${{ matrix.custom-fee == '1' && '--l3-fee-token' || '' }} diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 63bbbc8eec..75fb1d2d43 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -486,17 +486,17 @@ export async function getMulticallAddress( // The provided chain is not found in the list // Try to find a chain that references this chain as its parent - const child = chains.find(c => c.parentChainId === chainId) + const childChain = chains.find(c => c.parentChainId === chainId) // No chains reference this chain as its parent - if (typeof child === 'undefined') { + if (typeof childChain === 'undefined') { throw new Error( `Failed to retrieve Multicall address for chain: ${chainId}` ) } // Return the address of Multicall on the parent chain - return child.tokenBridge.l1MultiCall + return childChain.tokenBridge.l1MultiCall } /** diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index ca2967f59b..35ff85995c 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -42,12 +42,12 @@ type ForceInclusionParams = FetchedEvent & { delayedAcc: string } -type GasComponentsWithChildChainPart = { +type GasComponentsWithChildPart = { gasEstimate: BigNumber gasEstimateForL1: BigNumber baseFee: BigNumber l1BaseFeeEstimate: BigNumber - gasEstimateForChildChain: BigNumber + gasEstimateForChild: BigNumber } type RequiredTransactionRequestType = RequiredPick< TransactionRequest, @@ -60,14 +60,14 @@ export class InboxTools { /** * Parent chain provider */ - private readonly parentChainProvider: Provider + private readonly parentProvider: Provider constructor( - private readonly parentChainSigner: Signer, + private readonly parentSigner: Signer, private readonly childChain: ArbitrumNetwork ) { - this.parentChainProvider = SignerProviderUtils.getProviderOrThrow( - this.parentChainSigner + this.parentProvider = SignerProviderUtils.getProviderOrThrow( + this.parentSigner ) } @@ -83,7 +83,7 @@ export class InboxTools { blockNumber: number, blockTimestamp: number ): Promise { - const block = await this.parentChainProvider.getBlock(blockNumber) + const block = await this.parentProvider.getBlock(blockNumber) const diff = block.timestamp - blockTimestamp if (diff < 0) return block @@ -102,12 +102,12 @@ export class InboxTools { // Check if this request is contract creation or not. private isContractCreation( - childChainTransactionRequest: TransactionRequest + childTransactionRequest: TransactionRequest ): boolean { if ( - childChainTransactionRequest.to === '0x' || - !isDefined(childChainTransactionRequest.to) || - childChainTransactionRequest.to === ethers.constants.AddressZero + childTransactionRequest.to === '0x' || + !isDefined(childTransactionRequest.to) || + childTransactionRequest.to === ethers.constants.AddressZero ) { return true } @@ -116,34 +116,32 @@ export class InboxTools { /** * We should use nodeInterface to get the gas estimate is because we - * are making a delayed inbox message which doesn't need parentChain calldata + * are making a delayed inbox message which doesn't need parent calldata * gas fee part. */ private async estimateArbitrumGas( - childChainTransactionRequest: RequiredTransactionRequestType, - childChainProvider: Provider - ): Promise { + childTransactionRequest: RequiredTransactionRequestType, + childProvider: Provider + ): Promise { const nodeInterface = NodeInterface__factory.connect( NODE_INTERFACE_ADDRESS, - childChainProvider + childProvider ) - const contractCreation = this.isContractCreation( - childChainTransactionRequest - ) + const contractCreation = this.isContractCreation(childTransactionRequest) const gasComponents = await nodeInterface.callStatic.gasEstimateComponents( - childChainTransactionRequest.to || ethers.constants.AddressZero, + childTransactionRequest.to || ethers.constants.AddressZero, contractCreation, - childChainTransactionRequest.data, + childTransactionRequest.data, { - from: childChainTransactionRequest.from, - value: childChainTransactionRequest.value, + from: childTransactionRequest.from, + value: childTransactionRequest.value, } ) - const gasEstimateForChildChain: BigNumber = gasComponents.gasEstimate.sub( + const gasEstimateForChild: BigNumber = gasComponents.gasEstimate.sub( gasComponents.gasEstimateForL1 ) - return { ...gasComponents, gasEstimateForChildChain } + return { ...gasComponents, gasEstimateForChild } } /** @@ -154,10 +152,10 @@ export class InboxTools { private async getForceIncludableBlockRange(blockNumberRangeSize: number) { const sequencerInbox = SequencerInbox__factory.connect( this.childChain.ethBridge.sequencerInbox, - this.parentChainProvider + this.parentProvider ) - const multicall = await MultiCaller.fromProvider(this.parentChainProvider) + const multicall = await MultiCaller.fromProvider(this.parentProvider) const multicallInput: [ CallInput>>, ReturnType, @@ -211,7 +209,7 @@ export class InboxTools { maxSearchRangeBlocks: number, rangeMultiplier: number ): Promise[]> { - const eFetcher = new EventFetcher(this.parentChainProvider) + const eFetcher = new EventFetcher(this.parentProvider) // events don't become eligible until they pass a delay // find a block range which will emit eligible events @@ -263,7 +261,7 @@ export class InboxTools { ): Promise { const bridge = Bridge__factory.connect( this.childChain.ethBridge.bridge, - this.parentChainProvider + this.parentProvider ) // events dont become eligible until they pass a delay @@ -282,7 +280,7 @@ export class InboxTools { const eventInfo = events[events.length - 1] const sequencerInbox = SequencerInbox__factory.connect( this.childChain.ethBridge.sequencerInbox, - this.parentChainProvider + this.parentProvider ) // has the sequencer inbox already read this latest message const totalDelayedRead = await sequencerInbox.totalDelayedMessagesRead() @@ -322,13 +320,13 @@ export class InboxTools { ): Promise { const sequencerInbox = SequencerInbox__factory.connect( this.childChain.ethBridge.sequencerInbox, - this.parentChainSigner + this.parentSigner ) const eventInfo = messageDeliveredEvent || (await this.getForceIncludableEvent()) if (!eventInfo) return null - const block = await this.parentChainProvider.getBlock(eventInfo.blockHash) + const block = await this.parentProvider.getBlock(eventInfo.blockHash) return await sequencerInbox.functions.forceInclusion( eventInfo.event.messageIndex.add(1), @@ -348,14 +346,14 @@ export class InboxTools { * within 24 hours, you can force include it * @param signedTx A signed transaction which can be sent directly to chain, * you can call inboxTools.signChainMessage to get. - * @returns The parentChain delayed inbox's transaction itself. + * @returns The parent delayed inbox's transaction itself. */ - public async sendChildChainSignedTx( + public async sendChildSignedTx( signedTx: string ): Promise { const delayedInbox = IInbox__factory.connect( this.childChain.ethBridge.inbox, - this.parentChainSigner + this.parentSigner ) const sendData = ethers.utils.solidityPack( @@ -375,36 +373,36 @@ export class InboxTools { * contractCreation is true, no need provide tx.to. tx.gasPrice and tx.nonce * can be overrided. (You can also send contract creation transaction by set tx.to * to zero address or null) - * @param childChainSigner ethers Signer type, used to sign Chain transaction - * @returns The parentChain delayed inbox's transaction signed data. + * @param childSigner ethers Signer type, used to sign Chain transaction + * @returns The parent delayed inbox's transaction signed data. */ - public async signChildChainTx( + public async signChildTx( txRequest: RequiredTransactionRequestType, - childChainSigner: Signer + childSigner: Signer ): Promise { const tx: RequiredTransactionRequestType = { ...txRequest } const contractCreation = this.isContractCreation(tx) if (!isDefined(tx.nonce)) { - tx.nonce = await childChainSigner.getTransactionCount() + tx.nonce = await childSigner.getTransactionCount() } //check transaction type (if no transaction type or gasPrice provided, use eip1559 type) if (tx.type === 1 || tx.gasPrice) { if (tx.gasPrice) { - tx.gasPrice = await childChainSigner.getGasPrice() + tx.gasPrice = await childSigner.getGasPrice() } } else { if (!isDefined(tx.maxFeePerGas)) { - const feeData = await childChainSigner.getFeeData() + const feeData = await childSigner.getFeeData() tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas! tx.maxFeePerGas = feeData.maxFeePerGas! } tx.type = 2 } - tx.from = await childChainSigner.getAddress() - tx.chainId = await childChainSigner.getChainId() + tx.from = await childSigner.getAddress() + tx.chainId = await childSigner.getChainId() // if this is contract creation, user might not input the to address, // however, it is needed when we call to estimateArbitrumGas, so @@ -416,14 +414,14 @@ export class InboxTools { //estimate gas on child chain try { tx.gasLimit = ( - await this.estimateArbitrumGas(tx, childChainSigner.provider!) - ).gasEstimateForChildChain + await this.estimateArbitrumGas(tx, childSigner.provider!) + ).gasEstimateForChild } catch (error) { throw new ArbSdkError('execution failed (estimate gas failed)') } if (contractCreation) { delete tx.to } - return await childChainSigner.signTransaction(tx) + return await childSigner.signTransaction(tx) } } diff --git a/src/lib/message/ChildToParentMessage.ts b/src/lib/message/ChildToParentMessage.ts index aefe70f1e4..37a5057470 100644 --- a/src/lib/message/ChildToParentMessage.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -55,7 +55,7 @@ export type ChildToParentMessageReaderOrWriter = T extends Provider ? ChildToParentMessageReader : ChildToParentMessageWriter /** - * Base functionality for Chain->ParentChain messages + * Base functionality for Child-to-Parent messages */ export class ChildToParentMessage { protected isClassic( @@ -69,37 +69,37 @@ export class ChildToParentMessage { /** * Instantiates a new `ChildToParentMessageWriter` or `ChildToParentMessageReader` object. * - * @param {SignerOrProvider} ParentChainSignerOrProvider Signer or provider to be used for executing or reading the Chain-to-ParentChain message. - * @param {ChildToParentTransactionEvent} event The event containing the data of the Chain-to-ParentChain message. - * @param {Provider} [ParentChainProvider] Optional. Used to override the Provider which is attached to `ParentChainSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. + * @param {SignerOrProvider} ParentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. + * @param {ChildToParentTransactionEvent} event The event containing the data of the Child-to-Parent message. + * @param {Provider} [ParentProvider] Optional. Used to override the Provider which is attached to `ParentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromEvent( - parentChainSignerOrProvider: T, + parentSignerOrProvider: T, event: ChildToParentTransactionEvent, - parentChainProvider?: Provider + parentProvider?: Provider ): ChildToParentMessageReaderOrWriter static fromEvent( - parentChainSignerOrProvider: T, + parentSignerOrProvider: T, event: ChildToParentTransactionEvent, - parentChainProvider?: Provider + parentProvider?: Provider ): ChildToParentMessageReader | ChildToParentMessageWriter { - return SignerProviderUtils.isSigner(parentChainSignerOrProvider) + return SignerProviderUtils.isSigner(parentSignerOrProvider) ? new ChildToParentMessageWriter( - parentChainSignerOrProvider, + parentSignerOrProvider, event, - parentChainProvider + parentProvider ) - : new ChildToParentMessageReader(parentChainSignerOrProvider, event) + : new ChildToParentMessageReader(parentSignerOrProvider, event) } /** * Get event logs for ChildToParent transactions. - * @param childChainProvider + * @param childProvider * @param filter Block range filter * @param position The batchnumber indexed field was removed in nitro and a position indexed field was added. * For pre-nitro events the value passed in here will be used to find events with the same batchnumber. * For post nitro events it will be used to find events with the same position. - * @param destination The ParentChain destination of the ChildToParent message + * @param destination The parent destination of the ChildToParent message * @param hash The uniqueId indexed field was removed in nitro and a hash indexed field was added. * For pre-nitro events the value passed in here will be used to find events with the same uniqueId. * For post nitro events it will be used to find events with the same hash. @@ -107,15 +107,15 @@ export class ChildToParentMessage { * @returns Any classic and nitro events that match the provided filters. */ public static async getChildToParentEvents( - childChainProvider: Provider, + childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, position?: BigNumber, destination?: string, hash?: BigNumber, indexInBatch?: BigNumber ): Promise<(ChildToParentTransactionEvent & { transactionHash: string })[]> { - const childChain = await getArbitrumNetwork(childChainProvider) - const childChainNitroGenesisBlock = getNitroGenesisBlock(childChain) + const childChain = await getArbitrumNetwork(childProvider) + const childNitroGenesisBlock = getNitroGenesisBlock(childChain) const inClassicRange = (blockTag: BlockTag, nitroGenBlock: number) => { if (typeof blockTag === 'string') { @@ -158,14 +158,14 @@ export class ChildToParentMessage { // only fetch nitro events after the genesis block const classicFilter = { - fromBlock: inClassicRange(filter.fromBlock, childChainNitroGenesisBlock), - toBlock: inClassicRange(filter.toBlock, childChainNitroGenesisBlock), + fromBlock: inClassicRange(filter.fromBlock, childNitroGenesisBlock), + toBlock: inClassicRange(filter.toBlock, childNitroGenesisBlock), } const logQueries = [] if (classicFilter.fromBlock !== classicFilter.toBlock) { logQueries.push( classic.ChildToParentMessageClassic.getChildToParentEvents( - childChainProvider, + childProvider, classicFilter, position, destination, @@ -176,13 +176,13 @@ export class ChildToParentMessage { } const nitroFilter = { - fromBlock: inNitroRange(filter.fromBlock, childChainNitroGenesisBlock), - toBlock: inNitroRange(filter.toBlock, childChainNitroGenesisBlock), + fromBlock: inNitroRange(filter.fromBlock, childNitroGenesisBlock), + toBlock: inNitroRange(filter.toBlock, childNitroGenesisBlock), } if (nitroFilter.fromBlock !== nitroFilter.toBlock) { logQueries.push( - nitro.ChildToParentChainMessageNitro.getChildToParentChainEvents( - childChainProvider, + nitro.ChildToParentMessageNitro.getChildToParentEvents( + childProvider, nitroFilter, position, destination, @@ -196,37 +196,37 @@ export class ChildToParentMessage { } /** - * Provides read-only access for Chain-to-ParentChain-messages + * Provides read-only access for Child-to-Parent messages */ export class ChildToParentMessageReader extends ChildToParentMessage { private readonly classicReader?: classic.ChildToParentMessageReaderClassic - private readonly nitroReader?: nitro.ChildToParentChainMessageReaderNitro + private readonly nitroReader?: nitro.ChildToParentMessageReaderNitro constructor( - protected readonly parentChainProvider: Provider, + protected readonly parentProvider: Provider, event: ChildToParentTransactionEvent ) { super() if (this.isClassic(event)) { this.classicReader = new classic.ChildToParentMessageReaderClassic( - parentChainProvider, + parentProvider, event.batchNumber, event.indexInBatch ) } else { - this.nitroReader = new nitro.ChildToParentChainMessageReaderNitro( - parentChainProvider, + this.nitroReader = new nitro.ChildToParentMessageReaderNitro( + parentProvider, event ) } } public async getOutboxProof( - childChainProvider: Provider + childProvider: Provider ): Promise { if (this.nitroReader) { - return await this.nitroReader.getOutboxProof(childChainProvider) - } else return await this.classicReader!.tryGetProof(childChainProvider) + return await this.nitroReader.getOutboxProof(childProvider) + } else return await this.classicReader!.tryGetProof(childProvider) } /** @@ -235,12 +235,11 @@ export class ChildToParentMessageReader extends ChildToParentMessage { * @returns */ public async status( - childChainProvider: Provider + childProvider: Provider ): Promise { // can we create a ChildToParentMessage here, we need to - the constructor is what we need - if (this.nitroReader) - return await this.nitroReader.status(childChainProvider) - else return await this.classicReader!.status(childChainProvider) + if (this.nitroReader) return await this.nitroReader.status(childProvider) + else return await this.classicReader!.status(childProvider) } /** @@ -251,87 +250,84 @@ export class ChildToParentMessageReader extends ChildToParentMessage { * @returns outbox entry status (either executed or confirmed but not pending) */ public async waitUntilReadyToExecute( - childChainProvider: Provider, + childProvider: Provider, retryDelay = 500 ): Promise< ChildToParentMessageStatus.EXECUTED | ChildToParentMessageStatus.CONFIRMED > { if (this.nitroReader) - return this.nitroReader.waitUntilReadyToExecute( - childChainProvider, - retryDelay - ) + return this.nitroReader.waitUntilReadyToExecute(childProvider, retryDelay) else return this.classicReader!.waitUntilOutboxEntryCreated( - childChainProvider, + childProvider, retryDelay ) } /** - * Estimates the ParentChain block number in which this Chain to ParentChain tx will be available for execution. + * Estimates the Parent block number in which this Child-to-Parent tx will be available for execution. * If the message can or already has been executed, this returns null - * @param childChainProvider - * @returns expected ParentChain block number where the Chain to ParentChain message will be executable. Returns null if the message can or already has been executed + * @param childProvider + * @returns expected Parent block number where the Child-to-Parent message will be executable. Returns null if the message can or already has been executed */ public async getFirstExecutableBlock( - childChainProvider: Provider + childProvider: Provider ): Promise { if (this.nitroReader) - return this.nitroReader.getFirstExecutableBlock(childChainProvider) - else return this.classicReader!.getFirstExecutableBlock(childChainProvider) + return this.nitroReader.getFirstExecutableBlock(childProvider) + else return this.classicReader!.getFirstExecutableBlock(childProvider) } } /** - * Provides read and write access for Chain-to-ParentChain-messages + * Provides read and write access for Child-to-Parent messages */ export class ChildToParentMessageWriter extends ChildToParentMessageReader { private readonly classicWriter?: classic.ChildToParentMessageWriterClassic - private readonly nitroWriter?: nitro.ChildToParentChainMessageWriterNitro + private readonly nitroWriter?: nitro.ChildToParentMessageWriterNitro /** * Instantiates a new `ChildToParentMessageWriter` object. * - * @param {Signer} ParentChainSigner The signer to be used for executing the Chain-to-ParentChain message. - * @param {ChildToParentTransactionEvent} event The event containing the data of the Chain-to-ParentChain message. - * @param {Provider} [ParentChainProvider] Optional. Used to override the Provider which is attached to `ParentChainSigner` in case you need more control. This will be a required parameter in a future major version update. + * @param {Signer} ParentSigner The signer to be used for executing the Child-to-Parent message. + * @param {ChildToParentTransactionEvent} event The event containing the data of the Child-to-Parent message. + * @param {Provider} [ParentProvider] Optional. Used to override the Provider which is attached to `ParentSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( - parentChainSigner: Signer, + parentSigner: Signer, event: ChildToParentTransactionEvent, - parentChainProvider?: Provider + parentProvider?: Provider ) { - super(parentChainProvider ?? parentChainSigner.provider!, event) + super(parentProvider ?? parentSigner.provider!, event) if (this.isClassic(event)) { this.classicWriter = new classic.ChildToParentMessageWriterClassic( - parentChainSigner, + parentSigner, event.batchNumber, event.indexInBatch, - parentChainProvider + parentProvider ) } else { - this.nitroWriter = new nitro.ChildToParentChainMessageWriterNitro( - parentChainSigner, + this.nitroWriter = new nitro.ChildToParentMessageWriterNitro( + parentSigner, event, - parentChainProvider + parentProvider ) } } /** - * Executes the ChildToParentMessage on ParentChain. + * Executes the ChildToParentMessage on Parent chain. * Will throw an error if the outbox entry has not been created, which happens when the * corresponding assertion is confirmed. * @returns */ public async execute( - childChainProvider: Provider, + childProvider: Provider, overrides?: Overrides ): Promise { if (this.nitroWriter) - return this.nitroWriter.execute(childChainProvider, overrides) - else return await this.classicWriter!.execute(childChainProvider, overrides) + return this.nitroWriter.execute(childProvider, overrides) + else return await this.classicWriter!.execute(childProvider, overrides) } } diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index 7bdc98f2ad..f7e9e25cfd 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -30,7 +30,7 @@ import { RollupUserLogic__factory } from '../abi/factories/RollupUserLogic__fact import { Outbox__factory } from '../abi/factories/Outbox__factory' import { NodeInterface__factory } from '../abi/factories/NodeInterface__factory' -import { L2ToL1TxEvent as ChildToParentChainTxEvent } from '../abi/ArbSys' +import { L2ToL1TxEvent as ChildToParentTxEvent } from '../abi/ArbSys' import { ContractTransaction, Overrides } from 'ethers' import { Mutex } from 'async-mutex' import { EventFetcher, FetchedEvent } from '../utils/eventFetcher' @@ -50,127 +50,121 @@ import { ChildToParentMessageStatus } from '../dataEntities/message' /** * Conditional type for Signer or Provider. If T is of type Provider - * then ChildToParentChainMessageReaderOrWriter will be of type ChildToParentChainMessageReader. - * If T is of type Signer then ChildToParentChainMessageReaderOrWriter will be of - * type ChildToParentChainMessageWriter. + * then ChildToParentMessageReaderOrWriter will be of type ChildToParentMessageReader. + * If T is of type Signer then ChildToParentMessageReaderOrWriter will be of + * type ChildToParentMessageWriter. */ -export type ChildToParentChainMessageReaderOrWriterNitro< +export type ChildToParentMessageReaderOrWriterNitro< T extends SignerOrProvider > = T extends Provider - ? ChildToParentChainMessageReaderNitro - : ChildToParentChainMessageWriterNitro + ? ChildToParentMessageReaderNitro + : ChildToParentMessageWriterNitro // expected number of parent chain blocks that it takes for a Child chain tx to be included in a parent chain assertion const ASSERTION_CREATED_PADDING = 50 // expected number of parent chain blocks that it takes for a validator to confirm a parent chain block after the node deadline is passed const ASSERTION_CONFIRMED_PADDING = 20 -const childChainBlockRangeCache: { [key in string]: (number | undefined)[] } = - {} +const childBlockRangeCache: { [key in string]: (number | undefined)[] } = {} const mutex = new Mutex() -function getChildChainBlockRangeCacheKey({ +function getChildBlockRangeCacheKey({ childChainId, - parentChainBlockNumber, + parentBlockNumber, }: { childChainId: number - parentChainBlockNumber: number + parentBlockNumber: number }) { - return `${childChainId}-${parentChainBlockNumber}` + return `${childChainId}-${parentBlockNumber}` } -function setChildChainBlockRangeCache( - key: string, - value: (number | undefined)[] -) { - childChainBlockRangeCache[key] = value +function setChildBlockRangeCache(key: string, value: (number | undefined)[]) { + childBlockRangeCache[key] = value } async function getBlockRangesForL1BlockWithCache({ parentProvider, childProvider, - forParentChainBlock, + forParentBlock, }: { parentProvider: JsonRpcProvider childProvider: JsonRpcProvider - forParentChainBlock: number + forParentBlock: number }) { const childChainId = (await childProvider.getNetwork()).chainId - const key = getChildChainBlockRangeCacheKey({ + const key = getChildBlockRangeCacheKey({ childChainId, - parentChainBlockNumber: forParentChainBlock, + parentBlockNumber: forParentBlock, }) - if (childChainBlockRangeCache[key]) { - return childChainBlockRangeCache[key] + if (childBlockRangeCache[key]) { + return childBlockRangeCache[key] } // implements a lock that only fetches cache once const release = await mutex.acquire() // if cache has been acquired while awaiting the lock - if (childChainBlockRangeCache[key]) { + if (childBlockRangeCache[key]) { release() - return childChainBlockRangeCache[key] + return childBlockRangeCache[key] } try { - const childChainBlockRange = await getBlockRangesForL1Block({ - forL1Block: forParentChainBlock, + const childBlockRange = await getBlockRangesForL1Block({ + forL1Block: forParentBlock, provider: parentProvider, }) - setChildChainBlockRangeCache(key, childChainBlockRange) + setChildBlockRangeCache(key, childBlockRange) } finally { release() } - return childChainBlockRangeCache[key] + return childBlockRangeCache[key] } /** * Base functionality for nitro Child->Parent messages */ -export class ChildToParentChainMessageNitro { +export class ChildToParentMessageNitro { protected constructor( - public readonly event: EventArgs + public readonly event: EventArgs ) {} /** - * Instantiates a new `ChildToParentChainMessageWriterNitro` or `ChildToParentChainMessageReaderNitro` object. + * Instantiates a new `ChildToParentMessageWriterNitro` or `ChildToParentMessageReaderNitro` object. * * @param {SignerOrProvider} parentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. - * @param {EventArgs} event The event containing the data of the Child-to-Parent message. + * @param {EventArgs} event The event containing the data of the Child-to-Parent message. * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromEvent( parentSignerOrProvider: T, - event: EventArgs, + event: EventArgs, parentProvider?: Provider - ): ChildToParentChainMessageReaderOrWriterNitro + ): ChildToParentMessageReaderOrWriterNitro public static fromEvent( parentSignerOrProvider: T, - event: EventArgs, + event: EventArgs, parentProvider?: Provider - ): - | ChildToParentChainMessageReaderNitro - | ChildToParentChainMessageWriterNitro { + ): ChildToParentMessageReaderNitro | ChildToParentMessageWriterNitro { return SignerProviderUtils.isSigner(parentSignerOrProvider) - ? new ChildToParentChainMessageWriterNitro( + ? new ChildToParentMessageWriterNitro( parentSignerOrProvider, event, parentProvider ) - : new ChildToParentChainMessageReaderNitro(parentSignerOrProvider, event) + : new ChildToParentMessageReaderNitro(parentSignerOrProvider, event) } - public static async getChildToParentChainEvents( + public static async getChildToParentEvents( childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, position?: BigNumber, destination?: string, hash?: BigNumber ): Promise< - (EventArgs & { transactionHash: string })[] + (EventArgs & { transactionHash: string })[] > { const eventFetcher = new EventFetcher(childProvider) return ( @@ -186,7 +180,7 @@ export class ChildToParentChainMessageNitro { /** * Provides read-only access nitro for child-to-parent-messages */ -export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMessageNitro { +export class ChildToParentMessageReaderNitro extends ChildToParentMessageNitro { protected sendRootHash?: string protected sendRootSize?: BigNumber protected sendRootConfirmed?: boolean @@ -195,7 +189,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess constructor( protected readonly parentProvider: Provider, - event: EventArgs + event: EventArgs ) { super(event) } @@ -267,20 +261,20 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess } const parsedLog = this.parseNodeCreatedAssertion(log) - const childChainBlock = await arbitrumProvider.getBlock( + const childBlock = await arbitrumProvider.getBlock( parsedLog.afterState.blockHash ) - if (!childChainBlock) { + if (!childBlock) { throw new ArbSdkError( `Block not found. ${parsedLog.afterState.blockHash}` ) } - if (childChainBlock.sendRoot !== parsedLog.afterState.sendRoot) { + if (childBlock.sendRoot !== parsedLog.afterState.sendRoot) { throw new ArbSdkError( - `Child chain block send root doesn't match parsed log. ${childChainBlock.sendRoot} ${parsedLog.afterState.sendRoot}` + `Child chain block send root doesn't match parsed log. ${childBlock.sendRoot} ${parsedLog.afterState.sendRoot}` ) } - return childChainBlock + return childBlock } private async getBlockFromNodeNum( @@ -313,7 +307,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess const l2BlockRange = await getBlockRangesForL1BlockWithCache({ parentProvider: this.parentProvider as JsonRpcProvider, childProvider: childProvider as JsonRpcProvider, - forParentChainBlock: createdAtBlock.toNumber(), + forParentBlock: createdAtBlock.toNumber(), }) const startBlock = l2BlockRange[0] const endBlock = l2BlockRange[1] @@ -383,18 +377,18 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess ) const latestConfirmedNodeNum = await rollup.callStatic.latestConfirmed() - const childChainBlockConfirmed = await this.getBlockFromNodeNum( + const childBlockConfirmed = await this.getBlockFromNodeNum( rollup, latestConfirmedNodeNum, childProvider ) const sendRootSizeConfirmed = BigNumber.from( - childChainBlockConfirmed.sendCount + childBlockConfirmed.sendCount ) if (sendRootSizeConfirmed.gt(this.event.position)) { this.sendRootSize = sendRootSizeConfirmed - this.sendRootHash = childChainBlockConfirmed.sendRoot + this.sendRootHash = childBlockConfirmed.sendRoot this.sendRootConfirmed = true } else { // if the node has yet to be confirmed we'll still try to find proof info from unconfirmed nodes @@ -402,16 +396,16 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess if (latestNodeNum.gt(latestConfirmedNodeNum)) { // In rare case latestNodeNum can be equal to latestConfirmedNodeNum // eg immediately after an upgrade, or at genesis, or on a chain where confirmation time = 0 like AnyTrust may have - const childChainBlock = await this.getBlockFromNodeNum( + const childBlock = await this.getBlockFromNodeNum( rollup, latestNodeNum, childProvider ) - const sendRootSize = BigNumber.from(childChainBlock.sendCount) + const sendRootSize = BigNumber.from(childBlock.sendCount) if (sendRootSize.gt(this.event.position)) { this.sendRootSize = sendRootSize - this.sendRootHash = childChainBlock.sendRoot + this.sendRootHash = childBlock.sendRoot } } } @@ -470,7 +464,7 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess // consistency check in case we change the enum in the future if (status !== ChildToParentMessageStatus.UNCONFIRMED) - throw new ArbSdkError('ChildToParentChainMsg expected to be unconfirmed') + throw new ArbSdkError('ChildToParentMsg expected to be unconfirmed') const latestBlock = await this.parentProvider.getBlockNumber() const eventFetcher = new EventFetcher(this.parentProvider) @@ -492,15 +486,15 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess ) ).sort((a, b) => a.event.nodeNum.toNumber() - b.event.nodeNum.toNumber()) - const lastChildChainBlock = + const lastChildBlock = logs.length === 0 ? undefined : await this.getBlockFromNodeLog( childProvider as JsonRpcProvider, logs[logs.length - 1] ) - const lastSendCount = lastChildChainBlock - ? BigNumber.from(lastChildChainBlock.sendCount) + const lastSendCount = lastChildBlock + ? BigNumber.from(lastChildBlock.sendCount) : BigNumber.from(0) // here we assume the Child to Parent tx is actually valid, so the user needs to wait the max time @@ -519,11 +513,11 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess while (left <= right) { const mid = Math.floor((left + right) / 2) const log = logs[mid] - const childChainBlock = await this.getBlockFromNodeLog( + const childBlock = await this.getBlockFromNodeLog( childProvider as JsonRpcProvider, log ) - const sendCount = BigNumber.from(childChainBlock.sendCount) + const sendCount = BigNumber.from(childBlock.sendCount) if (sendCount.gt(this.event.position)) { foundLog = log right = mid - 1 @@ -541,24 +535,24 @@ export class ChildToParentChainMessageReaderNitro extends ChildToParentChainMess /** * Provides read and write access for nitro child-to-Parent-messages */ -export class ChildToParentChainMessageWriterNitro extends ChildToParentChainMessageReaderNitro { +export class ChildToParentMessageWriterNitro extends ChildToParentMessageReaderNitro { /** - * Instantiates a new `ChildToParentChainMessageWriterNitro` object. + * Instantiates a new `ChildToParentMessageWriterNitro` object. * * @param {Signer} parentSigner The signer to be used for executing the Child-to-Parent message. - * @param {EventArgs} event The event containing the data of the Child-to-Parent message. + * @param {EventArgs} event The event containing the data of the Child-to-Parent message. * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( private readonly parentSigner: Signer, - event: EventArgs, + event: EventArgs, parentProvider?: Provider ) { super(parentProvider ?? parentSigner.provider!, event) } /** - * Executes the ChildToParentChainMessage on Parent Chain. + * Executes the ChildToParentMessage on Parent Chain. * Will throw an error if the outbox entry has not been created, which happens when the * corresponding assertion is confirmed. * @returns diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index 4f9021b43e..f378481955 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -51,7 +51,7 @@ export enum ParentToChildMessageStatus { NOT_YET_CREATED = 1, /** * An attempt was made to create the retryable ticket, but it failed. - * This could be due to not enough submission cost being paid by the ParentChain transaction + * This could be due to not enough submission cost being paid by the Parent transaction */ CREATION_FAILED = 2, /** @@ -100,7 +100,7 @@ export type ParentToChildMessageReaderOrWriter = export abstract class ParentToChildMessage { /** - * When messages are sent from ParentChain to Chain a retryable ticket is created on Chain. + * When messages are sent from Parent to Child a retryable ticket is created on the child chain. * The retryableCreationId can be used to retrieve information about the success or failure of the * creation of the retryable ticket. */ @@ -109,29 +109,29 @@ export abstract class ParentToChildMessage { /** * The submit retryable transactions use the typed transaction envelope 2718. * The id of these transactions is the hash of the RLP encoded transaction. - * @param chainChainId - * @param fromAddress the aliased address that called the ParentChain inbox as emitted in the bridge event. + * @param childChainId + * @param fromAddress the aliased address that called the Parent inbox as emitted in the bridge event. * @param messageNumber - * @param parentChainBaseFee + * @param parentBaseFee * @param destAddress - * @param chainCallValue - * @param parentChainValue + * @param childCallValue + * @param parentCallValue * @param maxSubmissionFee - * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. - * @param callValueRefundAddress refund address specified in the retryable creation. Note the ParentChain inbox aliases this address if it is a ParentChain smart contract. The user is expected to provide this value already aliased when needed. + * @param excessFeeRefundAddress refund address specified in the retryable creation. Note the Parent inbox aliases this address if it is a Parent smart contract. The user is expected to provide this value already aliased when needed. + * @param callValueRefundAddress refund address specified in the retryable creation. Note the Parent inbox aliases this address if it is a Parent smart contract. The user is expected to provide this value already aliased when needed. * @param gasLimit * @param maxFeePerGas * @param data * @returns */ public static calculateSubmitRetryableId( - chainChainId: number, + childChainId: number, fromAddress: string, messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + parentBaseFee: BigNumber, destAddress: string, - chainCallValue: BigNumber, - parentChainValue: BigNumber, + childCallValue: BigNumber, + parentCallValue: BigNumber, maxSubmissionFee: BigNumber, excessFeeRefundAddress: string, callValueRefundAddress: string, @@ -143,21 +143,21 @@ export abstract class ParentToChildMessage { return ethers.utils.stripZeros(value.toHexString()) } - const chainId = BigNumber.from(chainChainId) + const chainId = BigNumber.from(childChainId) const msgNum = BigNumber.from(messageNumber) const fields: any[] = [ formatNumber(chainId), zeroPad(formatNumber(msgNum), 32), fromAddress, - formatNumber(parentChainBaseFee), + formatNumber(parentBaseFee), - formatNumber(parentChainValue), + formatNumber(parentCallValue), formatNumber(maxFeePerGas), formatNumber(gasLimit), // when destAddress is 0x0, arbos treat that as nil destAddress === ethers.constants.AddressZero ? '0x' : destAddress, - formatNumber(chainCallValue), + formatNumber(childCallValue), callValueRefundAddress, formatNumber(maxSubmissionFee), excessFeeRefundAddress, @@ -178,7 +178,7 @@ export abstract class ParentToChildMessage { chainId: number, sender: string, messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + parentBaseFee: BigNumber, messageData: RetryableMessageParams ): ParentToChildMessageReaderOrWriter public static fromEventComponents( @@ -186,7 +186,7 @@ export abstract class ParentToChildMessage { chainId: number, sender: string, messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + parentBaseFee: BigNumber, messageData: RetryableMessageParams ): ParentToChildMessageReader | ParentToChildMessageWriter { return SignerProviderUtils.isSigner(chainSignerOrProvider) @@ -195,7 +195,7 @@ export abstract class ParentToChildMessage { chainId, sender, messageNumber, - parentChainBaseFee, + parentBaseFee, messageData ) : new ParentToChildMessageReader( @@ -203,7 +203,7 @@ export abstract class ParentToChildMessage { chainId, sender, messageNumber, - parentChainBaseFee, + parentBaseFee, messageData ) } @@ -212,14 +212,14 @@ export abstract class ParentToChildMessage { public readonly chainId: number, public readonly sender: string, public readonly messageNumber: BigNumber, - public readonly parentChainBaseFee: BigNumber, + public readonly parentBaseFee: BigNumber, public readonly messageData: RetryableMessageParams ) { this.retryableCreationId = ParentToChildMessage.calculateSubmitRetryableId( chainId, sender, messageNumber, - parentChainBaseFee, + parentBaseFee, messageData.destAddress, messageData.l2CallValue, messageData.l1Value, @@ -256,14 +256,14 @@ export type EthDepositMessageWaitForStatusResult = { export class ParentToChildMessageReader extends ParentToChildMessage { private retryableCreationReceipt: TransactionReceipt | undefined | null public constructor( - public readonly chainProvider: Provider, + public readonly childProvider: Provider, chainId: number, sender: string, messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + parentBaseFee: BigNumber, messageData: RetryableMessageParams ) { - super(chainId, sender, messageNumber, parentChainBaseFee, messageData) + super(chainId, sender, messageNumber, parentBaseFee, messageData) } /** @@ -278,7 +278,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.chainProvider, + this.childProvider, this.retryableCreationId, confirmations, timeout @@ -301,7 +301,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { const redeemEvents = chainReceipt.getRedeemScheduledEvents() if (redeemEvents.length === 1) { - return await this.chainProvider.getTransactionReceipt( + return await this.childProvider.getTransactionReceipt( redeemEvents[0].retryTxHash ) } else if (redeemEvents.length > 1) { @@ -319,8 +319,8 @@ export class ParentToChildMessageReader extends ParentToChildMessage { * @returns TransactionReceipt of the first successful redeem if exists, otherwise the current status of the message. */ public async getSuccessfulRedeem(): Promise { - const chainNetwork = await getArbitrumNetwork(this.chainProvider) - const eventFetcher = new EventFetcher(this.chainProvider) + const chainNetwork = await getArbitrumNetwork(this.childProvider) + const eventFetcher = new EventFetcher(this.childProvider) const creationReceipt = await this.getRetryableCreationReceipt() if (!isDefined(creationReceipt)) { @@ -357,14 +357,14 @@ export class ParentToChildMessageReader extends ParentToChildMessage { // to do this we need to filter through the whole lifetime of the ticket looking // for relevant redeem scheduled events let increment = 1000 - let fromBlock = await this.chainProvider.getBlock( + let fromBlock = await this.childProvider.getBlock( creationReceipt.blockNumber ) let timeout = fromBlock.timestamp + (chainNetwork.retryableLifetimeSeconds ?? SEVEN_DAYS_IN_SECONDS) const queriedRange: { from: number; to: number }[] = [] - const maxBlock = await this.chainProvider.getBlockNumber() + const maxBlock = await this.childProvider.getBlockNumber() while (fromBlock.number < maxBlock) { const toBlockNumber = Math.min(fromBlock.number + increment, maxBlock) @@ -384,7 +384,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { const successfulRedeem = ( await Promise.all( redeemEvents.map(e => - this.chainProvider.getTransactionReceipt(e.event.retryTxHash) + this.childProvider.getTransactionReceipt(e.event.retryTxHash) ) ) ).filter(r => isDefined(r) && r.status === 1) @@ -399,7 +399,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { status: ParentToChildMessageStatus.REDEEMED, } - const toBlock = await this.chainProvider.getBlock(toBlockNumber) + const toBlock = await this.childProvider.getBlock(toBlockNumber) if (toBlock.timestamp > timeout) { // Check for LifetimeExtended event while (queriedRange.length > 0) { @@ -453,7 +453,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { private async retryableExists(): Promise { const currentTimestamp = BigNumber.from( - (await this.chainProvider.getBlock('latest')).timestamp + (await this.childProvider.getBlock('latest')).timestamp ) try { const timeoutTimestamp = await this.getTimeout() @@ -518,10 +518,10 @@ export class ParentToChildMessageReader extends ParentToChildMessage { * The minimium lifetime of a retryable tx * @returns */ - public static async getLifetime(chainProvider: Provider): Promise { + public static async getLifetime(childProvider: Provider): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - chainProvider + childProvider ) return await arbRetryableTx.getLifetime() } @@ -533,7 +533,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { public async getTimeout(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.chainProvider + this.childProvider ) return await arbRetryableTx.getTimeout(this.retryableCreationId) } @@ -546,7 +546,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { public getBeneficiary(): Promise { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, - this.chainProvider + this.childProvider ) return arbRetryableTx.getBeneficiary(this.retryableCreationId) } @@ -557,17 +557,17 @@ export class ParentToChildMessageReaderClassic { public readonly messageNumber: BigNumber public readonly retryableCreationId: string public readonly autoRedeemId: string - public readonly chainTxHash: string - public readonly chainProvider: Provider + public readonly childTxHash: string + public readonly childProvider: Provider constructor( - chainProvider: Provider, + childProvider: Provider, chainId: number, messageNumber: BigNumber ) { const bitFlip = (num: BigNumber) => num.or(BigNumber.from(1).shl(255)) this.messageNumber = messageNumber - this.chainProvider = chainProvider + this.childProvider = childProvider this.retryableCreationId = keccak256( concat([ @@ -583,7 +583,7 @@ export class ParentToChildMessageReaderClassic { ]) ) - this.chainTxHash = keccak256( + this.childTxHash = keccak256( concat([ zeroPad(this.retryableCreationId, 32), zeroPad(BigNumber.from(0).toHexString(), 32), @@ -613,7 +613,7 @@ export class ParentToChildMessageReaderClassic { ): Promise { if (!this.retryableCreationReceipt) { this.retryableCreationReceipt = await getTransactionReceipt( - this.chainProvider, + this.childProvider, this.retryableCreationId, confirmations, timeout @@ -637,7 +637,7 @@ export class ParentToChildMessageReaderClassic { const chainDerivedHash = this.calculateChainDerivedHash( this.retryableCreationId ) - const chainTxReceipt = await this.chainProvider.getTransactionReceipt( + const chainTxReceipt = await this.childProvider.getTransactionReceipt( chainDerivedHash ) @@ -655,7 +655,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { chainId: number, sender: string, messageNumber: BigNumber, - parentChainBaseFee: BigNumber, + parentBaseFee: BigNumber, messageData: RetryableMessageParams ) { super( @@ -663,7 +663,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { chainId, sender, messageNumber, - parentChainBaseFee, + parentBaseFee, messageData ) if (!chainSigner.provider) @@ -688,7 +688,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { return ChildTransactionReceipt.toRedeemTransaction( ChildTransactionReceipt.monkeyPatchWait(redeemTx), - this.chainProvider + this.childProvider ) } else { throw new ArbSdkError( @@ -755,14 +755,14 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { } /** - * A message for Eth deposits from ParentChain to Chain + * A message for Eth deposits from Parent to Child */ export class EthDepositMessage { - public readonly chainDepositTxHash: string - private chainDepositTxReceipt: TransactionReceipt | undefined | null + public readonly childDepositTxHash: string + private childDepositTxReceipt: TransactionReceipt | undefined | null public static calculateDepositTxId( - chainChainId: number, + childChainId: number, messageNumber: BigNumber, fromAddress: string, toAddress: string, @@ -772,7 +772,7 @@ export class EthDepositMessage { return ethers.utils.stripZeros(numberVal.toHexString()) } - const chainId = BigNumber.from(chainChainId) + const chainId = BigNumber.from(childChainId) const msgNum = BigNumber.from(messageNumber) // https://github.com/OffchainLabs/go-ethereum/blob/07e017aa73e32be92aadb52fa327c552e1b7b118/core/types/arb_types.go#L302-L308 @@ -814,25 +814,25 @@ export class EthDepositMessage { /** * Create an EthDepositMessage from data emitted in event when calling ethDeposit on Inbox.sol - * @param chainProvider + * @param childProvider * @param messageNumber The message number in the Inbox.InboxMessageDelivered event * @param senderAddr The sender address from Bridge.MessageDelivered event * @param inboxMessageEventData The data field from the Inbox.InboxMessageDelivered event * @returns */ public static async fromEventComponents( - chainProvider: Provider, + childProvider: Provider, messageNumber: BigNumber, senderAddr: string, inboxMessageEventData: string ) { - const chainId = (await chainProvider.getNetwork()).chainId + const chainId = (await childProvider.getNetwork()).chainId const { to, value } = EthDepositMessage.parseEthDepositData( inboxMessageEventData ) return new EthDepositMessage( - chainProvider, + childProvider, chainId, messageNumber, senderAddr, @@ -843,22 +843,22 @@ export class EthDepositMessage { /** * - * @param chainProvider - * @param chainChainId + * @param childProvider + * @param childChainId * @param messageNumber * @param to Recipient address of the ETH on Chain * @param value */ constructor( - private readonly chainProvider: Provider, - public readonly chainChainId: number, + private readonly childProvider: Provider, + public readonly childChainId: number, public readonly messageNumber: BigNumber, public readonly from: string, public readonly to: string, public readonly value: BigNumber ) { - this.chainDepositTxHash = EthDepositMessage.calculateDepositTxId( - chainChainId, + this.childDepositTxHash = EthDepositMessage.calculateDepositTxId( + childChainId, messageNumber, from, to, @@ -867,8 +867,8 @@ export class EthDepositMessage { } public async status(): Promise { - const receipt = await this.chainProvider.getTransactionReceipt( - this.chainDepositTxHash + const receipt = await this.childProvider.getTransactionReceipt( + this.childDepositTxHash ) if (receipt === null) return EthDepositMessageStatus.PENDING else return EthDepositMessageStatus.DEPOSITED @@ -877,15 +877,15 @@ export class EthDepositMessage { public async wait(confirmations?: number, timeout?: number) { const chosenTimeout = isDefined(timeout) ? timeout : DEFAULT_DEPOSIT_TIMEOUT - if (!this.chainDepositTxReceipt) { - this.chainDepositTxReceipt = await getTransactionReceipt( - this.chainProvider, - this.chainDepositTxHash, + if (!this.childDepositTxReceipt) { + this.childDepositTxReceipt = await getTransactionReceipt( + this.childProvider, + this.childDepositTxHash, confirmations, chosenTimeout ) } - return this.chainDepositTxReceipt || null + return this.childDepositTxReceipt || null } } diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index ee53b6c00e..0f6b3a2dee 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -362,7 +362,7 @@ export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created * Defaults to 15 minutes, as by this time all transactions are expected to be included on the child chain. Throws on timeout. - * @returns The wait result contains `complete`, a `status`, the ParentToChildMessage and optionally the `childChainTxReceipt` + * @returns The wait result contains `complete`, a `status`, the ParentToChildMessage and optionally the `childTxReceipt` * If `complete` is true then this message is in the terminal state. * For eth deposits complete this is when the status is FUNDS_DEPOSITED, EXPIRED or REDEEMED. */ @@ -400,7 +400,7 @@ export class ParentContractCallTransactionReceipt extends ParentTransactionRecei * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have * @param timeout Amount of time to wait for the retryable ticket to be created * Defaults to 15 minutes, as by this time all transactions are expected to be included on the child chain. Throws on timeout. - * @returns The wait result contains `complete`, a `status`, a {@link ParentToChildMessage} and optionally the `childChainTxReceipt`. + * @returns The wait result contains `complete`, a `status`, a {@link ParentToChildMessage} and optionally the `childTxReceipt`. * If `complete` is true then this message is in the terminal state. * For contract calls this is true only if the status is REDEEMED. */ diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 4ec661d257..bc744c61ec 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -133,7 +133,7 @@ describe('Ether', async () => { ethToDeposit.toString() ) - prettyLog('chainTxHash: ' + waitResult.message.chainDepositTxHash) + prettyLog('childDepositTxHash: ' + waitResult.message.childDepositTxHash) prettyLog('chain transaction found!') expect(waitResult.complete).to.eq(true, 'eth deposit not complete') expect(waitResult.txReceipt).to.exist diff --git a/tests/integration/parentToChildMessageCreator.test.ts b/tests/integration/parentToChildMessageCreator.test.ts index 079ea7ea3c..0474878d4a 100644 --- a/tests/integration/parentToChildMessageCreator.test.ts +++ b/tests/integration/parentToChildMessageCreator.test.ts @@ -68,16 +68,16 @@ describe('ParentToChildMessageCreator', () => { } // And submitting the ticket - const parentChainSubmissionTx = + const parentSubmissionTx = await parentToChildMessageCreator.createRetryableTicket( retryableTicketParams, arbProvider ) - const parentChainSubmissionTxReceipt = await parentChainSubmissionTx.wait() + const parentSubmissionTxReceipt = await parentSubmissionTx.wait() // Getting the ParentToChildMessage const parentToChildMessages = - await parentChainSubmissionTxReceipt.getParentToChildMessages(arbProvider) + await parentSubmissionTxReceipt.getParentToChildMessages(arbProvider) expect(parentToChildMessages.length).to.eq(1) const parentToChildMessage = parentToChildMessages[0] @@ -137,16 +137,16 @@ describe('ParentToChildMessageCreator', () => { ) // And create the retryable ticket - const parentChainSubmissionTx = + const parentSubmissionTx = await parentToChildMessageCreator.createRetryableTicket( parentToChildTransactionRequest, arbProvider ) - const parentChainSubmissionTxReceipt = await parentChainSubmissionTx.wait() + const parentSubmissionTxReceipt = await parentSubmissionTx.wait() // Getting the ParentToChildMessage const parentToChildMessages = - await parentChainSubmissionTxReceipt.getParentToChildMessages(arbProvider) + await parentSubmissionTxReceipt.getParentToChildMessages(arbProvider) expect(parentToChildMessages.length).to.eq(1) const parentToChildMessage = parentToChildMessages[0] diff --git a/tests/integration/sendChildmsg.test.ts b/tests/integration/sendChildmsg.test.ts index 1f1d87bbd0..a064c2562e 100644 --- a/tests/integration/sendChildmsg.test.ts +++ b/tests/integration/sendChildmsg.test.ts @@ -36,9 +36,9 @@ const sendSignedTx = async (testState: any, info?: any) => { ...info, value: BigNumber.from(0), } - const signedTx = await inbox.signChildChainTx(message, childDeployer) + const signedTx = await inbox.signChildTx(message, childDeployer) - const parentTx = await inbox.sendChildChainSignedTx(signedTx) + const parentTx = await inbox.sendChildSignedTx(signedTx) return { signedMsg: signedTx, parentTransactionReceipt: await parentTx?.wait(), diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 7ad2ece9a9..1b08bfdbc1 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -89,7 +89,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { destinationAddress: await params.childSigner.getAddress(), from: await params.childSigner.getAddress(), }) - const parentChainGasEstimate = await withdrawalParams.estimateParentGasLimit( + const parentGasEstimate = await withdrawalParams.estimateParentGasLimit( params.parentSigner.provider! ) @@ -112,19 +112,19 @@ export const withdrawToken = async (params: WithdrawalParams) => { ChildToParentMessageStatus.UNCONFIRMED ) - const childChainTokenAddr = await params.erc20Bridger.getChildERC20Address( + const childTokenAddr = await params.erc20Bridger.getChildERC20Address( params.parentToken.address, params.parentSigner.provider! ) - const childChainToken = params.erc20Bridger.getChildTokenContract( + const childToken = params.erc20Bridger.getChildTokenContract( params.childSigner.provider!, - childChainTokenAddr + childTokenAddr ) - const testWalletChildChainBalance = await childChainToken.balanceOf( + const testWalletChildBalance = await childToken.balanceOf( await params.childSigner.getAddress() ) expect( - testWalletChildChainBalance.toNumber(), + testWalletChildBalance.toNumber(), 'token withdraw balance not deducted' ).to.eq(params.startBalance.sub(params.amount).toNumber()) const walletAddress = await params.parentSigner.getAddress() @@ -179,7 +179,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { expect( execRec.gasUsed.toNumber(), 'Gas used greater than estimate' - ).to.be.lessThan(parentChainGasEstimate.toNumber()) + ).to.be.lessThan(parentGasEstimate.toNumber()) expect( await message.status(params.childSigner.provider!), @@ -255,18 +255,17 @@ export const depositToken = async ({ ).wait() const senderAddress = await parentSigner.getAddress() - const expectedParentChainGatewayAddress = - await erc20Bridger.getL1GatewayAddress( - parentTokenAddress, - parentSigner.provider! - ) + const expectedParentGatewayAddress = await erc20Bridger.getL1GatewayAddress( + parentTokenAddress, + parentSigner.provider! + ) const parentToken = erc20Bridger.getParentTokenContract( parentSigner.provider!, parentTokenAddress ) const allowance = await parentToken.allowance( senderAddress, - expectedParentChainGatewayAddress + expectedParentGatewayAddress ) expect(allowance.eq(Erc20Bridger.MAX_APPROVAL), 'set token allowance failed') .to.be.true @@ -282,10 +281,7 @@ export const depositToken = async ({ const feeTokenAllowance = await ERC20__factory.connect( erc20Bridger.nativeToken!, parentSigner - ).allowance( - await parentSigner.getAddress(), - expectedParentChainGatewayAddress - ) + ).allowance(await parentSigner.getAddress(), expectedParentGatewayAddress) expect( feeTokenAllowance.eq(Erc20Bridger.MAX_APPROVAL), @@ -294,10 +290,10 @@ export const depositToken = async ({ } const initialBridgeTokenBalance = await parentToken.balanceOf( - expectedParentChainGatewayAddress + expectedParentGatewayAddress ) const parentTokenBalanceBefore = await parentToken.balanceOf(senderAddress) - const childChainEthBalanceBefore = await childSigner.provider!.getBalance( + const childEthBalanceBefore = await childSigner.provider!.getBalance( destinationAddress || senderAddress ) @@ -314,7 +310,7 @@ export const depositToken = async ({ const depositRec = await depositRes.wait() const finalBridgeTokenBalance = await parentToken.balanceOf( - expectedParentChainGatewayAddress + expectedParentGatewayAddress ) expect( finalBridgeTokenBalance.toNumber(), @@ -332,7 +328,7 @@ export const depositToken = async ({ const waitRes = await depositRec.waitForChildTx(childSigner) - const childChainEthBalanceAfter = await childSigner.provider!.getBalance( + const childEthBalanceAfter = await childSigner.provider!.getBalance( destinationAddress || senderAddress ) @@ -349,47 +345,47 @@ export const depositToken = async ({ erc20Bridger.childChain ) - const parentChainGateway = await erc20Bridger.getL1GatewayAddress( + const parentGateway = await erc20Bridger.getL1GatewayAddress( parentTokenAddress, parentSigner.provider! ) - expect(parentChainGateway, 'incorrect parent chain gateway address').to.eq( + expect(parentGateway, 'incorrect parent chain gateway address').to.eq( expectedL1Gateway ) - const childChainGateway = await erc20Bridger.getL2GatewayAddress( + const childGateway = await erc20Bridger.getL2GatewayAddress( parentTokenAddress, childSigner.provider! ) - expect(childChainGateway, 'incorrect child chain gateway address').to.eq( + expect(childGateway, 'incorrect child chain gateway address').to.eq( expectedL2Gateway ) - const childChainErc20Addr = await erc20Bridger.getChildERC20Address( + const childErc20Addr = await erc20Bridger.getChildERC20Address( parentTokenAddress, parentSigner.provider! ) - const childChainToken = erc20Bridger.getChildTokenContract( + const childToken = erc20Bridger.getChildTokenContract( childSigner.provider!, - childChainErc20Addr + childErc20Addr ) - const parentChainErc20Addr = await erc20Bridger.getParentERC20Address( - childChainErc20Addr, + const parentErc20Addr = await erc20Bridger.getParentERC20Address( + childErc20Addr, childSigner.provider! ) - expect(parentChainErc20Addr).to.equal( + expect(parentErc20Addr).to.equal( parentTokenAddress, 'getERC20L1Address/getERC20L2Address failed with proper token address' ) - const tokenBalOnChildChainAfter = await childChainToken.balanceOf( + const tokenBalOnChildAfter = await childToken.balanceOf( destinationAddress || senderAddress ) // only check for standard deposits if (!destinationAddress && !ethDepositAmount) { expect( - tokenBalOnChildChainAfter.eq(depositAmount), + tokenBalOnChildAfter.eq(depositAmount), 'child wallet not updated after deposit' ).to.be.true } @@ -397,14 +393,12 @@ export const depositToken = async ({ // batched token+eth if (ethDepositAmount) { expect( - childChainEthBalanceAfter.gte( - childChainEthBalanceBefore.add(ethDepositAmount) - ), + childEthBalanceAfter.gte(childEthBalanceBefore.add(ethDepositAmount)), 'child wallet not updated with the extra eth deposit' ).to.be.true } - return { parentToken, waitRes, childChainToken } + return { parentToken, waitRes, childToken } } const fund = async ( diff --git a/tests/unit/parentToChildMessageEvents.test.ts b/tests/unit/parentToChildMessageEvents.test.ts index a71f707741..3e53d14ad8 100644 --- a/tests/unit/parentToChildMessageEvents.test.ts +++ b/tests/unit/parentToChildMessageEvents.test.ts @@ -188,7 +188,7 @@ describe('ParentToChildMessage events', () => { 'incorrect message number' ).to.be.true expect( - msg.parentChainBaseFee.eq(BigNumber.from('0x05e0fc4c58')), + msg.parentBaseFee.eq(BigNumber.from('0x05e0fc4c58')), 'incorrect parent chain base fee' ).to.be.true expect( @@ -328,7 +328,7 @@ describe('ParentToChildMessage events', () => { expect(msg.autoRedeemId, 'incorrect auto redeem id').to.be.eq( '0x38c5c31151344c7a1433a849bbc80472786ebe911630255a6e25d6a2efd39526' ) - expect(msg.chainTxHash, 'incorrect child chain tx hash').to.be.eq( + expect(msg.childTxHash, 'incorrect child chain tx hash').to.be.eq( '0xf91e7d2e7526927e915a2357360a3f1108dce0f9c7fa88a7492669adf5c1e53b' ) }) From c421573a3d39284cedb8e9ce63fc25184a92d6bc Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:07:30 -0400 Subject: [PATCH 38/74] feat: make token bridge contracts optional (#471) --- scripts/testSetup.ts | 8 +++++++- src/lib/assetBridger/erc20Bridger.ts | 13 ++++++++++++- src/lib/dataEntities/networks.ts | 25 ++++++++++++++++++++++++- tests/integration/customerc20.test.ts | 7 ++++++- tests/integration/standarderc20.test.ts | 10 ++-------- tests/integration/testHelpers.ts | 7 ++++++- 6 files changed, 57 insertions(+), 13 deletions(-) diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index cf2c23e788..9edc17f58c 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -28,6 +28,8 @@ import { mapL2NetworkToArbitrumNetwork, getArbitrumNetwork, registerCustomArbitrumNetwork, + TokenBridge, + assertArbitrumNetworkHasTokenBridge, } from '../src/lib/dataEntities/networks' import { Signer } from 'ethers' import { AdminErc20Bridger } from '../src/lib/assetBridger/erc20Bridger' @@ -72,7 +74,9 @@ export const getSigner = (provider: JsonRpcProvider, key?: string) => { } export const testSetup = async (): Promise<{ - childChain: ArbitrumNetwork + childChain: ArbitrumNetwork & { + tokenBridge: TokenBridge + } parentSigner: Signer childSigner: Signer parentProvider: Provider @@ -106,6 +110,8 @@ export const testSetup = async (): Promise<{ setChildChain = registerCustomArbitrumNetwork(childChain) } + assertArbitrumNetworkHasTokenBridge(setChildChain) + const erc20Bridger = new Erc20Bridger(setChildChain) const adminErc20Bridger = new AdminErc20Bridger(setChildChain) const ethBridger = new EthBridger(setChildChain) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 740d00e065..f66994cb7b 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -45,7 +45,12 @@ import { ParentToChildMessageGasEstimator, } from '../message/ParentToChildMessageGasEstimator' import { SignerProviderUtils } from '../dataEntities/signerOrProvider' -import { ArbitrumNetwork, getArbitrumNetwork } from '../dataEntities/networks' +import { + ArbitrumNetwork, + TokenBridge, + assertArbitrumNetworkHasTokenBridge, + getArbitrumNetwork, +} from '../dataEntities/networks' import { ArbSdkError, MissingProviderArbSdkError } from '../dataEntities/errors' import { DISABLED_GATEWAY } from '../dataEntities/constants' import { EventFetcher } from '../utils/eventFetcher' @@ -183,11 +188,17 @@ export class Erc20Bridger extends AssetBridger< public static MAX_APPROVAL: BigNumber = MaxUint256 public static MIN_CUSTOM_DEPOSIT_GAS_LIMIT = BigNumber.from(275000) + public readonly childChain: ArbitrumNetwork & { + tokenBridge: TokenBridge + } + /** * Bridger for moving ERC20 tokens back and forth between parent-to-child */ public constructor(childChain: ArbitrumNetwork) { super(childChain) + assertArbitrumNetworkHasTokenBridge(childChain) + this.childChain = childChain } /** diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index f0d3f1acc9..3d1f1a24fd 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -47,7 +47,7 @@ export interface ArbitrumNetwork { /** * The token bridge contracts. */ - tokenBridge: TokenBridge + tokenBridge?: TokenBridge /** * The time allowed for validators to dispute or challenge state assertions. Measured in L1 blocks. */ @@ -510,6 +510,7 @@ export async function getMulticallAddress( // The provided chain is found in the list if (typeof chain !== 'undefined') { + assertArbitrumNetworkHasTokenBridge(chain) // Return the address of Multicall on the chain return chain.tokenBridge.l2Multicall } @@ -525,6 +526,7 @@ export async function getMulticallAddress( ) } + assertArbitrumNetworkHasTokenBridge(childChain) // Return the address of Multicall on the parent chain return childChain.tokenBridge.l1MultiCall } @@ -544,6 +546,27 @@ export function mapL2NetworkToArbitrumNetwork( } } +/** + * Asserts that the given object has a token bridge. This is useful because not all Arbitrum network + * operations require a token bridge. + * + * @param network {@link ArbitrumNetwork} object + * @throws ArbSdkError if the object does not have a token bridge + */ +export function assertArbitrumNetworkHasTokenBridge( + network: T +): asserts network is T & { tokenBridge: TokenBridge } { + if ( + typeof network === 'undefined' || + !('tokenBridge' in network) || + typeof network.tokenBridge === 'undefined' + ) { + throw new ArbSdkError( + `The ArbitrumNetwork object with chainId ${network.chainId} is missing the token bridge contracts addresses. Please add them in the "tokenBridge" property.` + ) + } +} + const { resetNetworksToDefault } = createNetworkStateHandler() export { resetNetworksToDefault } diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index f54e3784e8..b9e8906bff 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -39,7 +39,10 @@ import { withdrawToken, } from './testHelpers' import { ParentToChildMessageStatus } from '../../src' -import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' +import { + ArbitrumNetwork, + assertArbitrumNetworkHasTokenBridge, +} from '../../src/lib/dataEntities/networks' import { AdminErc20Bridger } from '../../src/lib/assetBridger/erc20Bridger' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' @@ -154,6 +157,8 @@ const registerCustomToken = async ( childSigner: Signer, adminErc20Bridger: AdminErc20Bridger ) => { + assertArbitrumNetworkHasTokenBridge(childChain) + // create a custom token on L1 and L2 const l1CustomTokenFactory = isArbitrumNetworkWithCustomFeeToken() ? new TestOrbitCustomTokenL1__factory(parentSigner) diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index af08fc29ca..b7b3033781 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -17,7 +17,7 @@ 'use strict' import { expect } from 'chai' -import { Signer, Wallet, utils, constants } from 'ethers' +import { Wallet, utils, constants } from 'ethers' import { BigNumber } from '@ethersproject/bignumber' import { TestERC20__factory } from '../../src/lib/abi/factories/TestERC20__factory' import { @@ -29,12 +29,10 @@ import { fundChildSigner, } from './testHelpers' import { - Erc20Bridger, ParentToChildMessageStatus, ParentToChildMessageWriter, ChildTransactionReceipt, } from '../../src' -import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' import { TestERC20 } from '../../src/lib/abi/TestERC20' import { testSetup } from '../../scripts/testSetup' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' @@ -61,11 +59,7 @@ describe('standard ERC20', () => { }) // test globals - let testState: { - parentSigner: Signer - childSigner: Signer - erc20Bridger: Erc20Bridger - childChain: ArbitrumNetwork + let testState: Awaited> & { parentToken: TestERC20 } diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 1b08bfdbc1..599acad0c1 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -28,7 +28,10 @@ import { config, getSigner, testSetup } from '../../scripts/testSetup' import { Signer, Wallet } from 'ethers' import { Erc20Bridger, ChildToParentMessageStatus } from '../../src' import { ParentToChildMessageStatus } from '../../src/lib/message/ParentToChildMessage' -import { ArbitrumNetwork } from '../../src/lib/dataEntities/networks' +import { + ArbitrumNetwork, + assertArbitrumNetworkHasTokenBridge, +} from '../../src/lib/dataEntities/networks' import { GasOverrides } from '../../src/lib/message/ParentToChildMessageGasEstimator' import { ArbSdkError } from '../../src/lib/dataEntities/errors' import { ERC20 } from '../../src/lib/abi/ERC20' @@ -195,6 +198,8 @@ export const withdrawToken = async (params: WithdrawalParams) => { } const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { + assertArbitrumNetworkHasTokenBridge(l2Network) + switch (gatewayType) { case GatewayType.CUSTOM: return { From 965c5035bc8b5c5e5f3d5f8c766e23f0b7bacf1c Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 13 Jun 2024 04:58:58 -0400 Subject: [PATCH 39/74] feat: rename erc20 bridger methods (#473) Co-authored-by: spsjvc --- scripts/deployStandard.ts | 2 +- src/lib/assetBridger/erc20Bridger.ts | 95 +++++++++++++------------ tests/integration/sanity.test.ts | 15 ++-- tests/integration/standarderc20.test.ts | 2 +- tests/integration/testHelpers.ts | 17 ++--- tests/integration/weth.test.ts | 2 +- 6 files changed, 69 insertions(+), 64 deletions(-) diff --git a/scripts/deployStandard.ts b/scripts/deployStandard.ts index fd66b2b680..71beb2a26d 100644 --- a/scripts/deployStandard.ts +++ b/scripts/deployStandard.ts @@ -26,7 +26,7 @@ const main = async () => { ) const l1Provider = l1Signer.provider! const l2Provider = l2Signer.provider! - const gatewayAddress = await erc20Bridger.getL1GatewayAddress( + const gatewayAddress = await erc20Bridger.getParentGatewayAddress( l1TokenAddress, l1Provider ) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index f66994cb7b..d1b0142801 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -211,12 +211,12 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the address of the l1 gateway for this token + * Get the address of the parent gateway for this token * @param erc20ParentAddress * @param parentProvider * @returns */ - public async getL1GatewayAddress( + public async getParentGatewayAddress( erc20ParentAddress: string, parentProvider: Provider ): Promise { @@ -229,12 +229,12 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the address of the l2 gateway for this token + * Get the address of the child gateway for this token * @param erc20ParentAddress * @param childProvider * @returns */ - public async getL2GatewayAddress( + public async getChildGatewayAddress( erc20ParentAddress: string, childProvider: Provider ): Promise { @@ -300,7 +300,7 @@ export class Erc20Bridger extends AssetBridger< params: ProviderTokenApproveParams ): Promise>> { // you approve tokens to the gateway that the router will use - const gatewayAddress = await this.getL1GatewayAddress( + const gatewayAddress = await this.getParentGatewayAddress( params.erc20ParentAddress, SignerProviderUtils.getProviderOrThrow(params.parentProvider) ) @@ -357,7 +357,7 @@ export class Erc20Bridger extends AssetBridger< * @param filter * @returns */ - public async getL2WithdrawalEvents( + public async getWithdrawalEvents( childProvider: Provider, gatewayAddress: string, filter: { fromBlock: BlockTag; toBlock: BlockTag }, @@ -373,7 +373,7 @@ export class Erc20Bridger extends AssetBridger< L2ArbitrumGateway__factory, contract => contract.filters.WithdrawalInitiated( - null, // l1Token + null, // parentToken fromAddress || null, // _from toAddress || null // _to ), @@ -445,22 +445,22 @@ export class Erc20Bridger extends AssetBridger< /** * Get the child chain token contract at the provided address - * Note: This function just returns a typed ethers object for the provided address, it doesnt + * Note: This function just returns a typed ethers object for the provided address, it doesn't * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. * @param childProvider - * @param l2TokenAddr + * @param childTokenAddr * @returns */ public getChildTokenContract( childProvider: Provider, - l2TokenAddr: string + childTokenAddr: string ): L2GatewayToken { - return L2GatewayToken__factory.connect(l2TokenAddr, childProvider) + return L2GatewayToken__factory.connect(childTokenAddr, childProvider) } /** - * Get the L1 token contract at the provided address + * Get the parent token contract at the provided address * Note: This function just returns a typed ethers object for the provided address, it doesnt * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. @@ -487,12 +487,12 @@ export class Erc20Bridger extends AssetBridger< ): Promise { await this.checkParentChain(parentProvider) - const l1GatewayRouter = L1GatewayRouter__factory.connect( + const parentGatewayRouter = L1GatewayRouter__factory.connect( this.childChain.tokenBridge.l1GatewayRouter, parentProvider ) - return await l1GatewayRouter.functions + return await parentGatewayRouter.functions .calculateL2TokenAddress(erc20ParentAddress) .then(([res]) => res) } @@ -510,7 +510,7 @@ export class Erc20Bridger extends AssetBridger< ): Promise { await this.checkChildChain(childProvider) - // child chain WETH contract doesn't have the l1Address method on it + // child chain WETH contract doesn't have the parentAddress method on it if ( erc20ChildChainAddress.toLowerCase() === this.childChain.tokenBridge.l2Weth.toLowerCase() @@ -522,22 +522,26 @@ export class Erc20Bridger extends AssetBridger< erc20ChildChainAddress, childProvider ) - const l1Address = await arbERC20.functions.l1Address().then(([res]) => res) + const parentAddress = await arbERC20.functions + .l1Address() + .then(([res]) => res) // check that this l1 address is indeed registered to this child token - const l2GatewayRouter = L2GatewayRouter__factory.connect( + const childGatewayRouter = L2GatewayRouter__factory.connect( this.childChain.tokenBridge.l2GatewayRouter, childProvider ) - const l2Address = await l2GatewayRouter.calculateL2TokenAddress(l1Address) - if (l2Address.toLowerCase() !== erc20ChildChainAddress.toLowerCase()) { + const childAddress = await childGatewayRouter.calculateL2TokenAddress( + parentAddress + ) + if (childAddress.toLowerCase() !== erc20ChildChainAddress.toLowerCase()) { throw new ArbSdkError( - `Unexpected l1 address. L1 address from token is not registered to the provided l2 address. ${l1Address} ${l2Address} ${erc20ChildChainAddress}` + `Unexpected parent address. Parent address from token is not registered to the provided child address. ${parentAddress} ${childAddress} ${erc20ChildChainAddress}` ) } - return l1Address + return parentAddress } /** @@ -546,19 +550,19 @@ export class Erc20Bridger extends AssetBridger< * @param parentProvider * @returns */ - public async parentTokenIsDisabled( + public async isDepositDisabled( parentTokenAddress: string, parentProvider: Provider ): Promise { await this.checkParentChain(parentProvider) - const l1GatewayRouter = L1GatewayRouter__factory.connect( + const parentGatewayRouter = L1GatewayRouter__factory.connect( this.childChain.tokenBridge.l1GatewayRouter, parentProvider ) return ( - (await l1GatewayRouter.l1TokenToGateway(parentTokenAddress)) === + (await parentGatewayRouter.l1TokenToGateway(parentTokenAddress)) === DISABLED_GATEWAY ) } @@ -588,9 +592,9 @@ export class Erc20Bridger extends AssetBridger< return constants.Zero } - // we dont include the l2 call value for token deposits because + // we dont include the child call value for token deposits because // they either have 0 call value, or their call value is withdrawn from - // a contract by the gateway (weth). So in both of these cases the l2 call value + // a contract by the gateway (weth). So in both of these cases the child call value // is not actually deposited in the value field return depositParams.gasLimit .mul(depositParams.maxFeePerGas) @@ -652,13 +656,13 @@ export class Erc20Bridger extends AssetBridger< retryableGasOverrides, } = defaultedParams - const l1GatewayAddress = await this.getL1GatewayAddress( + const parentGatewayAddress = await this.getParentGatewayAddress( erc20ParentAddress, parentProvider ) let tokenGasOverrides: GasOverrides | undefined = retryableGasOverrides // we also add a hardcoded minimum gas limit for custom gateway deposits - if (l1GatewayAddress === this.childChain.tokenBridge.l1CustomGateway) { + if (parentGatewayAddress === this.childChain.tokenBridge.l1CustomGateway) { if (!tokenGasOverrides) tokenGasOverrides = {} if (!tokenGasOverrides.gasLimit) tokenGasOverrides.gasLimit = {} if (!tokenGasOverrides.gasLimit.min) { @@ -752,7 +756,7 @@ export class Erc20Bridger extends AssetBridger< // We do a safety check here if ((params.overrides as PayableOverrides | undefined)?.value) { throw new ArbSdkError( - 'L1 call value should be set through l1CallValue param' + 'Parent call value should be set through `l1CallValue` param' ) } @@ -821,15 +825,15 @@ export class Erc20Bridger extends AssetBridger< return BigNumber.from(8_000_000) } - const l1GatewayAddress = await this.getL1GatewayAddress( + const parentGatewayAddress = await this.getParentGatewayAddress( params.erc20ParentAddress, parentProvider ) - // The WETH gateway is the only deposit that requires callvalue in the L2 user-tx (i.e., the recently un-wrapped ETH) + // The WETH gateway is the only deposit that requires callvalue in the Child user-tx (i.e., the recently un-wrapped ETH) // Here we check if this is a WETH deposit, and include the callvalue for the gas estimate query if so const isWeth = await this.isWethGateway( - l1GatewayAddress, + parentGatewayAddress, parentProvider ) @@ -936,7 +940,7 @@ export class AdminErc20Bridger extends Erc20Bridger { * See https://developer.offchainlabs.com/docs/bridging_assets#the-arbitrum-generic-custom-gateway for more details * @param parentTokenAddress Address of the already deployed parent token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/ethereum/icustomtoken. * @param childTokenAddress Address of the already deployed child token. Must inherit from https://developer.offchainlabs.com/docs/sol_contract_docs/md_docs/arb-bridge-peripherals/tokenbridge/arbitrum/iarbtoken. - * @param parentSigner The signer with the rights to call registerTokenOnL2 on the parent token + * @param parentSigner The signer with the rights to call `registerTokenOnL2` on the parent token * @param childProvider Arbitrum rpc provider * @returns */ @@ -1093,24 +1097,25 @@ export class AdminErc20Bridger extends Erc20Bridger { } /** - * Get all the gateway set events on the L1 gateway router + * Get all the gateway set events on the Parent gateway router * @param parentProvider - * @param customNetworkL1GatewayRouter + * @param customNetworkParentGatewayRouter * @returns */ - public async getL1GatewaySetEvents( + public async getParentGatewaySetEvents( parentProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag } ): Promise[]> { await this.checkParentChain(parentProvider) - const l1GatewayRouterAddress = this.childChain.tokenBridge.l1GatewayRouter + const parentGatewayRouterAddress = + this.childChain.tokenBridge.l1GatewayRouter const eventFetcher = new EventFetcher(parentProvider) return ( await eventFetcher.getEvents( L1GatewayRouter__factory, t => t.filters.GatewaySet(), - { ...filter, address: l1GatewayRouterAddress } + { ...filter, address: parentGatewayRouterAddress } ) ).map(a => a.event) } @@ -1118,10 +1123,10 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Get all the gateway set events on the L2 gateway router * @param parentProvider - * @param customNetworkL1GatewayRouter + * @param customNetworkParentGatewayRouter * @returns */ - public async getL2GatewaySetEvents( + public async getChildGatewaySetEvents( childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, customNetworkL2GatewayRouter?: string @@ -1133,7 +1138,7 @@ export class AdminErc20Bridger extends Erc20Bridger { } await this.checkChildChain(childProvider) - const l2GatewayRouterAddress = + const childGatewayRouterAddress = customNetworkL2GatewayRouter || this.childChain.tokenBridge.l2GatewayRouter @@ -1142,7 +1147,7 @@ export class AdminErc20Bridger extends Erc20Bridger { await eventFetcher.getEvents( L1GatewayRouter__factory, t => t.filters.GatewaySet(), - { ...filter, address: l2GatewayRouterAddress } + { ...filter, address: childGatewayRouterAddress } ) ).map(a => a.event) } @@ -1168,7 +1173,7 @@ export class AdminErc20Bridger extends Erc20Bridger { const from = await parentSigner.getAddress() - const l1GatewayRouter = L1GatewayRouter__factory.connect( + const parentGatewayRouter = L1GatewayRouter__factory.connect( this.childChain.tokenBridge.l1GatewayRouter, parentSigner ) @@ -1177,7 +1182,7 @@ export class AdminErc20Bridger extends Erc20Bridger { params: OmitTyped ) => { return { - data: l1GatewayRouter.interface.encodeFunctionData('setGateways', [ + data: parentGatewayRouter.interface.encodeFunctionData('setGateways', [ tokenGateways.map(tG => tG.tokenAddr), tokenGateways.map(tG => tG.gatewayAddr), params.gasLimit, @@ -1188,7 +1193,7 @@ export class AdminErc20Bridger extends Erc20Bridger { value: params.gasLimit .mul(params.maxFeePerGas) .add(params.maxSubmissionCost), - to: l1GatewayRouter.address, + to: parentGatewayRouter.address, } } const gEstimator = new ParentToChildMessageGasEstimator(childProvider) diff --git a/tests/integration/sanity.test.ts b/tests/integration/sanity.test.ts index 81e6b9e138..43aba62d01 100644 --- a/tests/integration/sanity.test.ts +++ b/tests/integration/sanity.test.ts @@ -157,7 +157,7 @@ describe('sanity checks (read-only)', async () => { itOnlyWhenEth('l1 gateway router points to right weth gateways', async () => { const { adminErc20Bridger, parentSigner, childChain } = await testSetup() - const gateway = await adminErc20Bridger.getL1GatewayAddress( + const gateway = await adminErc20Bridger.getParentGatewayAddress( childChain.tokenBridge.l1Weth, parentSigner.provider! ) @@ -171,16 +171,15 @@ describe('sanity checks (read-only)', async () => { const address = hexlify(randomBytes(20)) - const erc20L2AddressAsPerL1 = await erc20Bridger.getChildERC20Address( - address, - parentSigner.provider! - ) - const l2gr = L2GatewayRouter__factory.connect( + const erc20ChildAddressAsPerParent = + await erc20Bridger.getChildERC20Address(address, parentSigner.provider!) + const childGatewayRouter = L2GatewayRouter__factory.connect( childChain.tokenBridge.l2GatewayRouter, childSigner.provider! ) - const erc20L2AddressAsPerL2 = await l2gr.calculateL2TokenAddress(address) + const erc20ChildAddressAsPerChild = + await childGatewayRouter.calculateL2TokenAddress(address) - expect(erc20L2AddressAsPerL2).to.equal(erc20L2AddressAsPerL1) + expect(erc20ChildAddressAsPerChild).to.equal(erc20ChildAddressAsPerParent) }) }) diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index b7b3033781..03621e7f7a 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -81,7 +81,7 @@ describe('standard ERC20', () => { async () => { const { parentSigner, erc20Bridger } = await testSetup() - const gatewayAddress = await erc20Bridger.getL1GatewayAddress( + const gatewayAddress = await erc20Bridger.getParentGatewayAddress( testState.parentToken.address, parentSigner.provider! ) diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 599acad0c1..bb17f568ae 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -132,7 +132,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { ).to.eq(params.startBalance.sub(params.amount).toNumber()) const walletAddress = await params.parentSigner.getAddress() - const gatewayAddress = await params.erc20Bridger.getL2GatewayAddress( + const gatewayAddress = await params.erc20Bridger.getChildGatewayAddress( params.parentToken.address, params.childSigner.provider! ) @@ -145,7 +145,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { expectedL2Gateway ) - const gatewayWithdrawEvents = await params.erc20Bridger.getL2WithdrawalEvents( + const gatewayWithdrawEvents = await params.erc20Bridger.getWithdrawalEvents( params.childSigner.provider!, gatewayAddress, { fromBlock: withdrawRec.blockNumber, toBlock: 'latest' }, @@ -260,10 +260,11 @@ export const depositToken = async ({ ).wait() const senderAddress = await parentSigner.getAddress() - const expectedParentGatewayAddress = await erc20Bridger.getL1GatewayAddress( - parentTokenAddress, - parentSigner.provider! - ) + const expectedParentGatewayAddress = + await erc20Bridger.getParentGatewayAddress( + parentTokenAddress, + parentSigner.provider! + ) const parentToken = erc20Bridger.getParentTokenContract( parentSigner.provider!, parentTokenAddress @@ -350,7 +351,7 @@ export const depositToken = async ({ erc20Bridger.childChain ) - const parentGateway = await erc20Bridger.getL1GatewayAddress( + const parentGateway = await erc20Bridger.getParentGatewayAddress( parentTokenAddress, parentSigner.provider! ) @@ -358,7 +359,7 @@ export const depositToken = async ({ expectedL1Gateway ) - const childGateway = await erc20Bridger.getL2GatewayAddress( + const childGateway = await erc20Bridger.getChildGatewayAddress( parentTokenAddress, childSigner.provider! ) diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index 1d35219ad2..f72f2f360f 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -73,7 +73,7 @@ describeOnlyWhenEth('WETH', async () => { expectedGatewayType: GatewayType.WETH, }) - const l2WethGateway = await erc20Bridger.getL2GatewayAddress( + const l2WethGateway = await erc20Bridger.getChildGatewayAddress( l1WethAddress, childSigner.provider! ) From 15e04d1e0f056359a83dc046d9447e0061e8eef9 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:01:50 -0400 Subject: [PATCH 40/74] chore: rename L1/L2 in `registerCustomToken` to Parent/Child (#483) * fixes issues from merge * undo removal of `retryableLifetimeSeconds` * restore the timeout function * fix linting * fix token bridge assertion --------- Co-authored-by: spsjvc --- src/lib/assetBridger/erc20Bridger.ts | 23 ++--- src/lib/assetBridger/ethBridger.ts | 4 +- src/lib/message/ParentToChildMessage.ts | 2 +- tests/integration/customerc20.test.ts | 126 ++++++++++++------------ tests/integration/eth.test.ts | 89 ++++++++++------- 5 files changed, 132 insertions(+), 112 deletions(-) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index d1b0142801..b61a59a077 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -957,7 +957,7 @@ export class AdminErc20Bridger extends Erc20Bridger { await this.checkChildChain(childProvider) const parentProvider = parentSigner.provider! - const l1SenderAddress = await parentSigner.getAddress() + const parentSenderAddress = await parentSigner.getAddress() const parentToken = ICustomToken__factory.connect( parentTokenAddress, @@ -978,31 +978,32 @@ export class AdminErc20Bridger extends Erc20Bridger { parentProvider ) const allowance = await nativeTokenContract.allowance( - l1SenderAddress, + parentSenderAddress, parentToken.address ) - const maxFeePerGasOnL2 = (await childProvider.getFeeData()).maxFeePerGas - const maxFeePerGasOnL2WithBuffer = this.percentIncrease( - maxFeePerGasOnL2!, + const maxFeePerGasOnChild = (await childProvider.getFeeData()) + .maxFeePerGas + const maxFeePerGasOnChildWithBuffer = this.percentIncrease( + maxFeePerGasOnChild!, BigNumber.from(500) ) // hardcode gas limit to 60k const estimatedGasFee = BigNumber.from(60_000).mul( - maxFeePerGasOnL2WithBuffer + maxFeePerGasOnChildWithBuffer ) if (allowance.lt(estimatedGasFee)) { throw new Error( - `Insufficient allowance. Please increase spending for: owner - ${l1SenderAddress}, spender - ${parentToken.address}.` + `Insufficient allowance. Please increase spending for: owner - ${parentSenderAddress}, spender - ${parentToken.address}.` ) } } - const l1AddressFromL2 = await childToken.l1Address() - if (l1AddressFromL2 !== parentTokenAddress) { + const parentAddressFromChild = await childToken.l1Address() + if (parentAddressFromChild !== parentTokenAddress) { throw new ArbSdkError( - `L2 token does not have l1 address set. Set address: ${l1AddressFromL2}, expected address: ${parentTokenAddress}.` + `child token does not have parent address set. Set address: ${parentAddressFromChild}, expected address: ${parentTokenAddress}.` ) } @@ -1042,7 +1043,7 @@ export class AdminErc20Bridger extends Erc20Bridger { doubleFeePerGas, setTokenDeposit, setGatewayDeposit, - l1SenderAddress, + parentSenderAddress, ] ) diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 2176286c00..9e74462fce 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -352,11 +352,11 @@ export class EthBridger extends AssetBridger< parentProvider: params.parentSigner.provider!, }) - const l1ToL2MessageCreator = new ParentToChildMessageCreator( + const parentToChildMessageCreator = new ParentToChildMessageCreator( params.parentSigner ) - const tx = await l1ToL2MessageCreator.createRetryableTicket( + const tx = await parentToChildMessageCreator.createRetryableTicket( retryableTicketRequest, params.childProvider ) diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index f378481955..c37f1e866e 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -38,11 +38,11 @@ import { import { ArbSdkError } from '../dataEntities/errors' import { ethers, Overrides } from 'ethers' import { ChildTransactionReceipt, RedeemTransaction } from './ChildTransaction' -import { getArbitrumNetwork } from '../../lib/dataEntities/networks' import { RetryableMessageParams } from '../dataEntities/message' import { getTransactionReceipt, isDefined } from '../utils/lib' import { EventFetcher } from '../utils/eventFetcher' import { ErrorCode, Logger } from '@ethersproject/logger' +import { getArbitrumNetwork } from '../dataEntities/networks' export enum ParentToChildMessageStatus { /** diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index b9e8906bff..5d29e06ad9 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -65,13 +65,13 @@ describe('Custom ERC20', () => { childSigner: Signer adminErc20Bridger: AdminErc20Bridger childChain: ArbitrumNetwork - l1CustomToken: TestCustomTokenL1 | TestOrbitCustomTokenL1 + parentCustomToken: TestCustomTokenL1 | TestOrbitCustomTokenL1 } before('init', async () => { testState = { ...(await testSetup()), - l1CustomToken: {} as any, + parentCustomToken: {} as any, } await fundParentSigner(testState.parentSigner) await fundChildSigner(testState.childSigner) @@ -82,22 +82,22 @@ describe('Custom ERC20', () => { }) it('register custom token', async () => { - const { l1CustomToken: l1Token } = await registerCustomToken( + const { parentCustomToken: parentToken } = await registerCustomToken( testState.childChain, testState.parentSigner, testState.childSigner, testState.adminErc20Bridger ) - testState.l1CustomToken = l1Token + testState.parentCustomToken = parentToken }) it('deposit', async () => { await ( - await testState.l1CustomToken.connect(testState.parentSigner).mint() + await testState.parentCustomToken.connect(testState.parentSigner).mint() ).wait() await depositToken({ depositAmount, - parentTokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.parentCustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -116,7 +116,7 @@ describe('Custom ERC20', () => { gatewayType: GatewayType.CUSTOM, startBalance: depositAmount, parentToken: ERC20__factory.connect( - testState.l1CustomToken.address, + testState.parentCustomToken.address, testState.parentSigner.provider! ), }) @@ -126,7 +126,7 @@ describe('Custom ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - parentTokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.parentCustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -140,7 +140,7 @@ describe('Custom ERC20', () => { await depositToken({ depositAmount, ethDepositAmount: utils.parseEther('0.0005'), - parentTokenAddress: testState.l1CustomToken.address, + parentTokenAddress: testState.parentCustomToken.address, erc20Bridger: testState.adminErc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, @@ -159,22 +159,22 @@ const registerCustomToken = async ( ) => { assertArbitrumNetworkHasTokenBridge(childChain) - // create a custom token on L1 and L2 - const l1CustomTokenFactory = isArbitrumNetworkWithCustomFeeToken() + // create a custom token on Parent and Child + const parentCustomTokenFactory = isArbitrumNetworkWithCustomFeeToken() ? new TestOrbitCustomTokenL1__factory(parentSigner) : new TestCustomTokenL1__factory(parentSigner) - const l1CustomToken = await l1CustomTokenFactory.deploy( + const parentCustomToken = await parentCustomTokenFactory.deploy( childChain.tokenBridge.l1CustomGateway, childChain.tokenBridge.l1GatewayRouter ) - await l1CustomToken.deployed() + await parentCustomToken.deployed() - const l2CustomTokenFac = new TestArbCustomToken__factory(childSigner) - const l2CustomToken = await l2CustomTokenFac.deploy( + const childCustomTokenFac = new TestArbCustomToken__factory(childSigner) + const childCustomToken = await childCustomTokenFac.deploy( childChain.tokenBridge.l2CustomGateway, - l1CustomToken.address + parentCustomToken.address ) - await l2CustomToken.deployed() + await childCustomToken.deployed() // check starting conditions - should initially use the default gateway const l1GatewayRouter = new L1GatewayRouter__factory(parentSigner).attach( @@ -189,46 +189,46 @@ const registerCustomToken = async ( const l2CustomGateway = new L1CustomGateway__factory(childSigner).attach( childChain.tokenBridge.l2CustomGateway ) - const startL1GatewayAddress = await l1GatewayRouter.l1TokenToGateway( - l1CustomToken.address + const startParentGatewayAddress = await l1GatewayRouter.l1TokenToGateway( + parentCustomToken.address ) expect( - startL1GatewayAddress, - 'Start l1GatewayAddress not equal empty address' + startParentGatewayAddress, + 'Start parentGatewayAddress not equal empty address' ).to.eq(constants.AddressZero) - const startL2GatewayAddress = await l2GatewayRouter.l1TokenToGateway( - l2CustomToken.address + const startChildGatewayAddress = await l2GatewayRouter.l1TokenToGateway( + childCustomToken.address ) expect( - startL2GatewayAddress, - 'Start l2GatewayAddress not equal empty address' + startChildGatewayAddress, + 'Start childGatewayAddress not equal empty address' ).to.eq(constants.AddressZero) - const startL1Erc20Address = await l1CustomGateway.l1ToL2Token( - l1CustomToken.address + const startParentErc20Address = await l1CustomGateway.l1ToL2Token( + parentCustomToken.address ) expect( - startL1Erc20Address, - 'Start l1Erc20Address not equal empty address' + startParentErc20Address, + 'Start parentErc20Address not equal empty address' ).to.eq(constants.AddressZero) - const startL2Erc20Address = await l2CustomGateway.l1ToL2Token( - l1CustomToken.address + const startChildErc20Address = await l2CustomGateway.l1ToL2Token( + parentCustomToken.address ) expect( - startL2Erc20Address, - 'Start l2Erc20Address not equal empty address' + startChildErc20Address, + 'Start childErc20Address not equal empty address' ).to.eq(constants.AddressZero) // it should fail without the approval if (isArbitrumNetworkWithCustomFeeToken()) { try { const regTx = await adminErc20Bridger.registerCustomToken( - l1CustomToken.address, - l2CustomToken.address, + parentCustomToken.address, + childCustomToken.address, parentSigner, childSigner.provider! ) await regTx.wait() - throw new Error('L2 custom token is not approved but got deployed') + throw new Error('Child custom token is not approved but got deployed') } catch (err) { expect((err as Error).message).to.contain('Insufficient allowance') } @@ -237,70 +237,70 @@ const registerCustomToken = async ( if (isArbitrumNetworkWithCustomFeeToken()) { await adminErc20Bridger.approveGasTokenForCustomTokenRegistration({ parentSigner, - erc20ParentAddress: l1CustomToken.address, + erc20ParentAddress: parentCustomToken.address, }) } // send the messages const regTx = await adminErc20Bridger.registerCustomToken( - l1CustomToken.address, - l2CustomToken.address, + parentCustomToken.address, + childCustomToken.address, parentSigner, childSigner.provider! ) const regRec = await regTx.wait() // wait on messages - const l1ToL2Messages = await regRec.getParentToChildMessages( + const parentToChildMessages = await regRec.getParentToChildMessages( childSigner.provider! ) - expect(l1ToL2Messages.length, 'Should be 2 messages.').to.eq(2) + expect(parentToChildMessages.length, 'Should be 2 messages.').to.eq(2) - const setTokenTx = await l1ToL2Messages[0].waitForStatus() + const setTokenTx = await parentToChildMessages[0].waitForStatus() expect(setTokenTx.status, 'Set token not redeemed.').to.eq( ParentToChildMessageStatus.REDEEMED ) - const setGateways = await l1ToL2Messages[1].waitForStatus() + const setGateways = await parentToChildMessages[1].waitForStatus() expect(setGateways.status, 'Set gateways not redeemed.').to.eq( ParentToChildMessageStatus.REDEEMED ) // check end conditions - const endL1GatewayAddress = await l1GatewayRouter.l1TokenToGateway( - l1CustomToken.address + const endParentGatewayAddress = await l1GatewayRouter.l1TokenToGateway( + parentCustomToken.address ) expect( - endL1GatewayAddress, - 'End l1GatewayAddress not equal to l1 custom gateway' + endParentGatewayAddress, + 'End parentGatewayAddress not equal to parent custom gateway' ).to.eq(childChain.tokenBridge.l1CustomGateway) - const endL2GatewayAddress = await l2GatewayRouter.l1TokenToGateway( - l1CustomToken.address + const endChildGatewayAddress = await l2GatewayRouter.l1TokenToGateway( + parentCustomToken.address ) expect( - endL2GatewayAddress, - 'End l2GatewayAddress not equal to l2 custom gateway' + endChildGatewayAddress, + 'End childGatewayAddress not equal to child custom gateway' ).to.eq(childChain.tokenBridge.l2CustomGateway) - const endL1Erc20Address = await l1CustomGateway.l1ToL2Token( - l1CustomToken.address + const endParentErc20Address = await l1CustomGateway.l1ToL2Token( + parentCustomToken.address ) expect( - endL1Erc20Address, - 'End l1Erc20Address not equal l1CustomToken address' - ).to.eq(l2CustomToken.address) + endParentErc20Address, + 'End parentErc20Address not equal parentCustomToken address' + ).to.eq(childCustomToken.address) - const endL2Erc20Address = await l2CustomGateway.l1ToL2Token( - l1CustomToken.address + const endChildErc20Address = await l2CustomGateway.l1ToL2Token( + parentCustomToken.address ) expect( - endL2Erc20Address, - 'End l2Erc20Address not equal l2CustomToken address' - ).to.eq(l2CustomToken.address) + endChildErc20Address, + 'End childErc20Address not equal childCustomToken address' + ).to.eq(childCustomToken.address) return { - l1CustomToken, - l2CustomToken, + parentCustomToken, + childCustomToken, } } diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index d0158796f3..038e225ad0 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -114,7 +114,7 @@ describe('Ether', async () => { }) const rec = await res.wait() - expect(rec.status).to.equal(1, 'eth deposit L1 txn failed') + expect(rec.status).to.equal(1, 'eth deposit parent txn failed') const finalInboxBalance = await parentSigner.provider!.getBalance( inboxAddress ) @@ -125,15 +125,24 @@ describe('Ether', async () => { const waitResult = await rec.waitForChildTx(childSigner.provider!) - const l1ToL2Messages = await rec.getEthDeposits(childSigner.provider!) - expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') - const l1ToL2Message = l1ToL2Messages[0] + const parentToChildMessages = await rec.getEthDeposits( + childSigner.provider! + ) + expect(parentToChildMessages.length).to.eq( + 1, + 'failed to find 1 parent-to-child message' + ) + const parentToChildMessage = parentToChildMessages[0] const walletAddress = await parentSigner.getAddress() - expect(l1ToL2Message.to).to.eq(walletAddress, 'message inputs value error') - expect(l1ToL2Message.value.toString(), 'message inputs value error').to.eq( - ethToDeposit.toString() + expect(parentToChildMessage.to).to.eq( + walletAddress, + 'message inputs value error' ) + expect( + parentToChildMessage.value.toString(), + 'message inputs value error' + ).to.eq(ethToDeposit.toString()) prettyLog('childDepositTxHash: ' + waitResult.message.childDepositTxHash) prettyLog('chain transaction found!') @@ -141,13 +150,13 @@ describe('Ether', async () => { expect(waitResult.txReceipt).to.exist expect(waitResult.txReceipt).to.not.be.null - const testWalletL2EthBalance = await childSigner.getBalance() - expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( + const testWalletChildEthBalance = await childSigner.getBalance() + expect(testWalletChildEthBalance.toString(), 'final balance').to.eq( ethToDeposit.toString() ) }) - it('deposits ether to a specific L2 address', async () => { + it('deposits ether to a specific child address', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() await fundParentSigner(parentSigner) @@ -175,22 +184,25 @@ describe('Ether', async () => { 'balance failed to update after eth deposit' ) - const l1ToL2Messages = await rec.getParentToChildMessages( + const parentToChildMessages = await rec.getParentToChildMessages( childSigner.provider! ) - expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') - const l1ToL2Message = l1ToL2Messages[0] + expect(parentToChildMessages.length).to.eq( + 1, + 'failed to find 1 parent-to-child message' + ) + const parentToChildMessage = parentToChildMessages[0] - expect(l1ToL2Message.messageData.destAddress).to.eq( + expect(parentToChildMessage.messageData.destAddress).to.eq( destWallet.address, 'message inputs value error' ) expect( - l1ToL2Message.messageData.l2CallValue.toString(), + parentToChildMessage.messageData.l2CallValue.toString(), 'message inputs value error' ).to.eq(ethToDeposit.toString()) - const retryableTicketResult = await l1ToL2Message.waitForStatus() + const retryableTicketResult = await parentToChildMessage.waitForStatus() expect(retryableTicketResult.status).to.eq( ParentToChildMessageStatus.REDEEMED, 'Retryable ticket not redeemed' @@ -198,13 +210,16 @@ describe('Ether', async () => { const retryableTxReceipt = await childSigner.provider!.getTransactionReceipt( - l1ToL2Message.retryableCreationId + parentToChildMessage.retryableCreationId ) expect(retryableTxReceipt).to.exist expect(retryableTxReceipt).to.not.be.null - const l2RetryableTxReceipt = new ChildTransactionReceipt(retryableTxReceipt) - const ticketRedeemEvents = l2RetryableTxReceipt.getRedeemScheduledEvents() + const childRetryableTxReceipt = new ChildTransactionReceipt( + retryableTxReceipt + ) + const ticketRedeemEvents = + childRetryableTxReceipt.getRedeemScheduledEvents() expect(ticketRedeemEvents.length).to.eq( 1, 'failed finding the redeem event' @@ -212,15 +227,15 @@ describe('Ether', async () => { expect(ticketRedeemEvents[0].retryTxHash).to.exist expect(ticketRedeemEvents[0].retryTxHash).to.not.be.null - const testWalletL2EthBalance = await childSigner.provider!.getBalance( + const testWalletChildEthBalance = await childSigner.provider!.getBalance( destWallet.address ) - expect(testWalletL2EthBalance.toString(), 'final balance').to.eq( + expect(testWalletChildEthBalance.toString(), 'final balance').to.eq( ethToDeposit.toString() ) }) - it('deposit ether to a specific L2 address with manual redeem', async () => { + it('deposit ether to a specific child address with manual redeem', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() await fundParentSigner(parentSigner) @@ -240,47 +255,51 @@ describe('Ether', async () => { }, }) const rec = await res.wait() - const l1ToL2Messages = await rec.getParentToChildMessages( + const parentToChildMessages = await rec.getParentToChildMessages( childSigner.provider! ) - expect(l1ToL2Messages.length).to.eq(1, 'failed to find 1 l1 to l2 message') - const l1ToL2MessageReader = l1ToL2Messages[0] + expect(parentToChildMessages.length).to.eq( + 1, + 'failed to find 1 parent-to-child message' + ) + const parentToChildMessageReader = parentToChildMessages[0] - const retryableTicketResult = await l1ToL2MessageReader.waitForStatus() + const retryableTicketResult = + await parentToChildMessageReader.waitForStatus() expect(retryableTicketResult.status).to.eq( ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, 'unexpected status, expected auto-redeem to fail' ) - let testWalletL2EthBalance = await childSigner.provider!.getBalance( + let testWalletChildEthBalance = await childSigner.provider!.getBalance( destWallet.address ) expect( - testWalletL2EthBalance.eq(constants.Zero), + testWalletChildEthBalance.eq(constants.Zero), 'balance before auto-redeem' ).to.be.true await fundChildSigner(childSigner) - const l1TxHash = await parentSigner.provider!.getTransactionReceipt( + const parentTxHash = await parentSigner.provider!.getTransactionReceipt( res.hash ) - const l1Receipt = new ParentTransactionReceipt(l1TxHash) + const parentTxReceipt = new ParentTransactionReceipt(parentTxHash) - const l1ToL2MessageWriter = ( - await l1Receipt.getParentToChildMessages(childSigner) + const parentToChildMessageWriter = ( + await parentTxReceipt.getParentToChildMessages(childSigner) )[0] - await (await l1ToL2MessageWriter.redeem()).wait() + await (await parentToChildMessageWriter.redeem()).wait() - testWalletL2EthBalance = await childSigner.provider!.getBalance( + testWalletChildEthBalance = await childSigner.provider!.getBalance( destWallet.address ) expect( - testWalletL2EthBalance.toString(), + testWalletChildEthBalance.toString(), 'balance after manual redeem' ).to.eq(ethToDeposit.toString()) }) From 9ce5c5713bf50e9e388df843e882d4050068cc1a Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Fri, 14 Jun 2024 04:57:33 -0400 Subject: [PATCH 41/74] feat: update tokenBridge keys to parent/child (#479) Co-authored-by: spsjvc --- scripts/lib.ts | 4 +- scripts/testSetup.ts | 8 +- scripts/upgrade_weth.ts | 8 +- src/lib/assetBridger/erc20Bridger.ts | 32 ++-- src/lib/dataEntities/networks.ts | 224 +++++++++++++++--------- tests/integration/customerc20.test.ts | 42 ++--- tests/integration/sanity.test.ts | 56 +++--- tests/integration/standarderc20.test.ts | 2 +- tests/integration/testHelpers.ts | 12 +- tests/integration/weth.test.ts | 42 ++--- 10 files changed, 240 insertions(+), 190 deletions(-) diff --git a/scripts/lib.ts b/scripts/lib.ts index 6870536b1d..a0e0ca73fb 100644 --- a/scripts/lib.ts +++ b/scripts/lib.ts @@ -86,9 +86,9 @@ export const setGateWays = async ( if (overrideGateways.length > 0) { return overrideGateways } else if (type === 'standard') { - return tokens.map(() => childChain.tokenBridge.l1ERC20Gateway) + return tokens.map(() => childChain.tokenBridge.parentERC20Gateway) } else if (type === 'arbCustom') { - return tokens.map(() => childChain.tokenBridge.l1CustomGateway) + return tokens.map(() => childChain.tokenBridge.parentCustomGateway) } else { throw new Error('Unhandled else case') } diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 9edc17f58c..0b9f0820ee 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -23,9 +23,7 @@ import dotenv from 'dotenv' import { EthBridger, InboxTools, Erc20Bridger } from '../src' import { - L2Network, ArbitrumNetwork, - mapL2NetworkToArbitrumNetwork, getArbitrumNetwork, registerCustomArbitrumNetwork, TokenBridge, @@ -146,9 +144,7 @@ export function getLocalNetworksFromFile(): { throw new ArbSdkError('localNetwork.json not found, must gen:network first') } const localNetworksFile = fs.readFileSync(pathToLocalNetworkFile, 'utf8') - const localL2: L2Network = JSON.parse(localNetworksFile).l2Network + const localL2: ArbitrumNetwork = JSON.parse(localNetworksFile).l2Network - return { - l2Network: mapL2NetworkToArbitrumNetwork(localL2), - } + return { l2Network: localL2 } } diff --git a/scripts/upgrade_weth.ts b/scripts/upgrade_weth.ts index eb0e645cfd..efbb69c386 100644 --- a/scripts/upgrade_weth.ts +++ b/scripts/upgrade_weth.ts @@ -32,7 +32,7 @@ const main = async () => { console.log('aeWeth logic deployed to ', logicAddress) const connectedProxy = TransparentUpgradeableProxy__factory.connect( - l2Network.tokenBridge.l2Weth, + l2Network.tokenBridge.childWeth, l2Signer ) const upgradeRes = await connectedProxy.upgradeTo(logicAddress) @@ -45,13 +45,13 @@ const main = async () => { // const { bridge, l2Network } = await instantiateBridge() // const { l2Signer } = bridge.l2Bridge -// const aeWeth = AeWETH__factory.connect(l2Network.tokenBridge.l2Weth, l2Signer) +// const aeWeth = AeWETH__factory.connect(l2Network.tokenBridge.childWeth, l2Signer) // const res = await aeWeth.initialize( // 'Wrapped Ether', // 'WETH', // 18, -// l2Network.tokenBridge.l2WethGateway, -// l2Network.tokenBridge.l1Weth +// l2Network.tokenBridge.childWethGateway, +// l2Network.tokenBridge.parentWeth // ) // const rec = await res.wait() diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index b61a59a077..62f16eca6f 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -223,7 +223,7 @@ export class Erc20Bridger extends AssetBridger< await this.checkParentChain(parentProvider) return await L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.l1GatewayRouter, + this.childChain.tokenBridge.parentGatewayRouter, parentProvider ).getGateway(erc20ParentAddress) } @@ -241,7 +241,7 @@ export class Erc20Bridger extends AssetBridger< await this.checkChildChain(childProvider) return await L2GatewayRouter__factory.connect( - this.childChain.tokenBridge.l2GatewayRouter, + this.childChain.tokenBridge.childGatewayRouter, childProvider ).getGateway(erc20ParentAddress) } @@ -430,7 +430,7 @@ export class Erc20Bridger extends AssetBridger< gatewayAddress: string, parentProvider: Provider ): Promise { - const wethAddress = this.childChain.tokenBridge.l1WethGateway + const wethAddress = this.childChain.tokenBridge.parentWethGateway if (this.childChain.isCustom) { // For custom network, we do an ad-hoc check to see if it's a WETH gateway if (await this.looksLikeWethGateway(gatewayAddress, parentProvider)) { @@ -488,7 +488,7 @@ export class Erc20Bridger extends AssetBridger< await this.checkParentChain(parentProvider) const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.l1GatewayRouter, + this.childChain.tokenBridge.parentGatewayRouter, parentProvider ) @@ -513,9 +513,9 @@ export class Erc20Bridger extends AssetBridger< // child chain WETH contract doesn't have the parentAddress method on it if ( erc20ChildChainAddress.toLowerCase() === - this.childChain.tokenBridge.l2Weth.toLowerCase() + this.childChain.tokenBridge.childWeth.toLowerCase() ) { - return this.childChain.tokenBridge.l1Weth + return this.childChain.tokenBridge.parentWeth } const arbERC20 = L2GatewayToken__factory.connect( @@ -528,7 +528,7 @@ export class Erc20Bridger extends AssetBridger< // check that this l1 address is indeed registered to this child token const childGatewayRouter = L2GatewayRouter__factory.connect( - this.childChain.tokenBridge.l2GatewayRouter, + this.childChain.tokenBridge.childGatewayRouter, childProvider ) @@ -557,7 +557,7 @@ export class Erc20Bridger extends AssetBridger< await this.checkParentChain(parentProvider) const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.l1GatewayRouter, + this.childChain.tokenBridge.parentGatewayRouter, parentProvider ) @@ -662,7 +662,9 @@ export class Erc20Bridger extends AssetBridger< ) let tokenGasOverrides: GasOverrides | undefined = retryableGasOverrides // we also add a hardcoded minimum gas limit for custom gateway deposits - if (parentGatewayAddress === this.childChain.tokenBridge.l1CustomGateway) { + if ( + parentGatewayAddress === this.childChain.tokenBridge.parentCustomGateway + ) { if (!tokenGasOverrides) tokenGasOverrides = {} if (!tokenGasOverrides.gasLimit) tokenGasOverrides.gasLimit = {} if (!tokenGasOverrides.gasLimit.min) { @@ -703,7 +705,7 @@ export class Erc20Bridger extends AssetBridger< return { data: functionData, - to: this.childChain.tokenBridge.l1GatewayRouter, + to: this.childChain.tokenBridge.parentGatewayRouter, from: defaultedParams.from, value: this.getDepositRequestCallValue(depositParams), } @@ -718,7 +720,7 @@ export class Erc20Bridger extends AssetBridger< return { txRequest: { - to: this.childChain.tokenBridge.l1GatewayRouter, + to: this.childChain.tokenBridge.parentGatewayRouter, data: estimates.data, value: estimates.value, from: params.from, @@ -811,7 +813,7 @@ export class Erc20Bridger extends AssetBridger< return { txRequest: { data: functionData, - to: this.childChain.tokenBridge.l2GatewayRouter, + to: this.childChain.tokenBridge.childGatewayRouter, value: BigNumber.from(0), from: params.from, }, @@ -1110,7 +1112,7 @@ export class AdminErc20Bridger extends Erc20Bridger { await this.checkParentChain(parentProvider) const parentGatewayRouterAddress = - this.childChain.tokenBridge.l1GatewayRouter + this.childChain.tokenBridge.parentGatewayRouter const eventFetcher = new EventFetcher(parentProvider) return ( await eventFetcher.getEvents( @@ -1141,7 +1143,7 @@ export class AdminErc20Bridger extends Erc20Bridger { const childGatewayRouterAddress = customNetworkL2GatewayRouter || - this.childChain.tokenBridge.l2GatewayRouter + this.childChain.tokenBridge.childGatewayRouter const eventFetcher = new EventFetcher(childProvider) return ( @@ -1175,7 +1177,7 @@ export class AdminErc20Bridger extends Erc20Bridger { const from = await parentSigner.getAddress() const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.l1GatewayRouter, + this.childChain.tokenBridge.parentGatewayRouter, parentSigner ) diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 3d1f1a24fd..39170d43ee 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -76,13 +76,38 @@ export interface ArbitrumNetwork { * @deprecated since v4 */ export type L2Network = Prettify< - Omit & { + Omit & { chainID: number partnerChainID: number + tokenBridge: L2NetworkTokenBridge } > export interface TokenBridge { + parentGatewayRouter: string + childGatewayRouter: string + parentERC20Gateway: string + childERC20Gateway: string + parentCustomGateway: string + childCustomGateway: string + parentWethGateway: string + childWethGateway: string + parentWeth: string + childWeth: string + parentProxyAdmin: string + childProxyAdmin: string + parentMultiCall: string + childMulticall: string +} + +/** + * This type is only here for when you want to achieve backwards compatibility between SDK v3 and v4. + * + * Please see {@link TokenBridge} for the latest type. + * + * @deprecated since v4 + */ +export interface L2NetworkTokenBridge { l1GatewayRouter: string l2GatewayRouter: string l1ERC20Gateway: string @@ -115,20 +140,20 @@ export interface Networks { } const mainnetTokenBridge: TokenBridge = { - l1GatewayRouter: '0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef', - l2GatewayRouter: '0x5288c571Fd7aD117beA99bF60FE0846C4E84F933', - l1ERC20Gateway: '0xa3A7B6F88361F48403514059F1F16C8E78d60EeC', - l2ERC20Gateway: '0x09e9222E96E7B4AE2a407B98d48e330053351EEe', - l1CustomGateway: '0xcEe284F754E854890e311e3280b767F80797180d', - l2CustomGateway: '0x096760F208390250649E3e8763348E783AEF5562', - l1WethGateway: '0xd92023E9d9911199a6711321D1277285e6d4e2db', - l2WethGateway: '0x6c411aD3E74De3E7Bd422b94A27770f5B86C623B', - l2Weth: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', - l1Weth: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - l1ProxyAdmin: '0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa', - l2ProxyAdmin: '0xd570aCE65C43af47101fC6250FD6fC63D1c22a86', - l1MultiCall: '0x5ba1e12693dc8f9c48aad8770482f4739beed696', - l2Multicall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', + parentGatewayRouter: '0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef', + childGatewayRouter: '0x5288c571Fd7aD117beA99bF60FE0846C4E84F933', + parentERC20Gateway: '0xa3A7B6F88361F48403514059F1F16C8E78d60EeC', + childERC20Gateway: '0x09e9222E96E7B4AE2a407B98d48e330053351EEe', + parentCustomGateway: '0xcEe284F754E854890e311e3280b767F80797180d', + childCustomGateway: '0x096760F208390250649E3e8763348E783AEF5562', + parentWethGateway: '0xd92023E9d9911199a6711321D1277285e6d4e2db', + childWethGateway: '0x6c411aD3E74De3E7Bd422b94A27770f5B86C623B', + childWeth: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + parentWeth: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + parentProxyAdmin: '0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa', + childProxyAdmin: '0xd570aCE65C43af47101fC6250FD6fC63D1c22a86', + parentMultiCall: '0x5ba1e12693dc8f9c48aad8770482f4739beed696', + childMulticall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', } const mainnetETHBridge: EthBridge = { @@ -170,20 +195,20 @@ export const networks: Networks = { name: 'Arbitrum Nova', parentChainId: 1, tokenBridge: { - l1CustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', - l1ERC20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', - l1GatewayRouter: '0xC840838Bc438d73C16c2f8b22D2Ce3669963cD48', - l1MultiCall: '0x8896D23AfEA159a5e9b72C9Eb3DC4E2684A38EA3', - l1ProxyAdmin: '0xa8f7DdEd54a726eB873E98bFF2C95ABF2d03e560', - l1Weth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', - l1WethGateway: '0xE4E2121b479017955Be0b175305B35f312330BaE', - l2CustomGateway: '0xbf544970E6BD77b21C6492C281AB60d0770451F4', - l2ERC20Gateway: '0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257', - l2GatewayRouter: '0x21903d3F8176b1a0c17E953Cd896610Be9fFDFa8', - l2Multicall: '0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86', - l2ProxyAdmin: '0xada790b026097BfB36a5ed696859b97a96CEd92C', - l2Weth: '0x722E8BdD2ce80A4422E880164f2079488e115365', - l2WethGateway: '0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD', + parentCustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', + parentERC20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', + parentGatewayRouter: '0xC840838Bc438d73C16c2f8b22D2Ce3669963cD48', + parentMultiCall: '0x8896D23AfEA159a5e9b72C9Eb3DC4E2684A38EA3', + parentProxyAdmin: '0xa8f7DdEd54a726eB873E98bFF2C95ABF2d03e560', + parentWeth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + parentWethGateway: '0xE4E2121b479017955Be0b175305B35f312330BaE', + childCustomGateway: '0xbf544970E6BD77b21C6492C281AB60d0770451F4', + childERC20Gateway: '0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257', + childGatewayRouter: '0x21903d3F8176b1a0c17E953Cd896610Be9fFDFa8', + childMulticall: '0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86', + childProxyAdmin: '0xada790b026097BfB36a5ed696859b97a96CEd92C', + childWeth: '0x722E8BdD2ce80A4422E880164f2079488e115365', + childWethGateway: '0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD', }, }, 421614: { @@ -200,20 +225,20 @@ export const networks: Networks = { name: 'Arbitrum Rollup Sepolia Testnet', parentChainId: 11155111, tokenBridge: { - l1CustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', - l1ERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', - l1GatewayRouter: '0xcE18836b233C83325Cc8848CA4487e94C6288264', - l1MultiCall: '0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320', - l1ProxyAdmin: '0xDBFC2FfB44A5D841aB42b0882711ed6e5A9244b0', - l1Weth: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9', - l1WethGateway: '0xA8aD8d7e13cbf556eE75CB0324c13535d8100e1E', - l2CustomGateway: '0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5', - l2ERC20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502', - l2GatewayRouter: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7', - l2Multicall: '0xA115146782b7143fAdB3065D86eACB54c169d092', - l2ProxyAdmin: '0x715D99480b77A8d9D603638e593a539E21345FdF', - l2Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', - l2WethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D', + parentCustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', + parentERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', + parentGatewayRouter: '0xcE18836b233C83325Cc8848CA4487e94C6288264', + parentMultiCall: '0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320', + parentProxyAdmin: '0xDBFC2FfB44A5D841aB42b0882711ed6e5A9244b0', + parentWeth: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9', + parentWethGateway: '0xA8aD8d7e13cbf556eE75CB0324c13535d8100e1E', + childCustomGateway: '0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5', + childERC20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502', + childGatewayRouter: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7', + childMulticall: '0xA115146782b7143fAdB3065D86eACB54c169d092', + childProxyAdmin: '0x715D99480b77A8d9D603638e593a539E21345FdF', + childWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', + childWethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D', }, }, 23011913: { @@ -230,20 +255,20 @@ export const networks: Networks = { name: 'Stylus Testnet v1', parentChainId: 421614, tokenBridge: { - l1CustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', - l1ERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', - l1GatewayRouter: '0x0057892cb8bb5f1cE1B3C6f5adE899732249713f', - l1MultiCall: '0xBEbe3BfBF52FFEA965efdb3f14F2101c0264c940', - l1ProxyAdmin: '0xB9E77732f32831f09e2a50D6E71B2Cca227544bf', - l1Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', - l1WethGateway: '0x39845e4a230434D218b907459a305eBA61A790d4', - l2CustomGateway: '0xF6dbB0e312dF4652d59ce405F5E00CC3430f19c5', - l2ERC20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860', - l2GatewayRouter: '0x4c3a1f7011F02Fe4769fC704359c3696a6A60D89', - l2Multicall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3', - l2ProxyAdmin: '0xE914c0d417E8250d0237d2F4827ed3612e6A9C3B', - l2Weth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C', - l2WethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175', + parentCustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', + parentERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', + parentGatewayRouter: '0x0057892cb8bb5f1cE1B3C6f5adE899732249713f', + parentMultiCall: '0xBEbe3BfBF52FFEA965efdb3f14F2101c0264c940', + parentProxyAdmin: '0xB9E77732f32831f09e2a50D6E71B2Cca227544bf', + parentWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', + parentWethGateway: '0x39845e4a230434D218b907459a305eBA61A790d4', + childCustomGateway: '0xF6dbB0e312dF4652d59ce405F5E00CC3430f19c5', + childERC20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860', + childGatewayRouter: '0x4c3a1f7011F02Fe4769fC704359c3696a6A60D89', + childMulticall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3', + childProxyAdmin: '0xE914c0d417E8250d0237d2F4827ed3612e6A9C3B', + childWeth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C', + childWethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175', }, }, 13331371: { @@ -260,20 +285,20 @@ export const networks: Networks = { name: 'Stylus Testnet v2', parentChainId: 421614, tokenBridge: { - l1CustomGateway: '0x093353B9f723047abf37Ebe01cE48d7dDA8320F4', - l1ERC20Gateway: '0xD2C4693Dd8d44703af5CF9484fa8faAD6e33E392', - l1GatewayRouter: '0xAC4F454320A253267C6Ae95e4784b9A4f9F78359', - l1MultiCall: '0xce1CAd780c529e66e3aa6D952a1ED9A6447791c1', - l1ProxyAdmin: '0xBD76fd3fB5F3CD7165fB6e0DB895FFE1d81463e3', - l1Weth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', - l1WethGateway: '0x4FEbc93233aAc1523f36Abe297de9323f6C8ce79', - l2CustomGateway: '0xE102D94df0179082B39Ddcad58c9430dedc89aE3', - l2ERC20Gateway: '0xCf3a4aF3c48Ba19c5FccFB44FA3E3A0F2A6e60dA', - l2GatewayRouter: '0xD60FD4c5D335b00287202C93C5B4EE0478D92686', - l2Multicall: '0x39E068582873B2011F5a1e8E0F7D9D993c8111BC', - l2ProxyAdmin: '0x9DC4Da9a940AFEbBC8329aA6534aD767b60d968c', - l2Weth: '0xa3bD1fdeEb903142d16B3bd22f2aC9A82C714D62', - l2WethGateway: '0xec018E81eE818b04CFb1E013D91F1b779a2AC440', + parentCustomGateway: '0x093353B9f723047abf37Ebe01cE48d7dDA8320F4', + parentERC20Gateway: '0xD2C4693Dd8d44703af5CF9484fa8faAD6e33E392', + parentGatewayRouter: '0xAC4F454320A253267C6Ae95e4784b9A4f9F78359', + parentMultiCall: '0xce1CAd780c529e66e3aa6D952a1ED9A6447791c1', + parentProxyAdmin: '0xBD76fd3fB5F3CD7165fB6e0DB895FFE1d81463e3', + parentWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', + parentWethGateway: '0x4FEbc93233aAc1523f36Abe297de9323f6C8ce79', + childCustomGateway: '0xE102D94df0179082B39Ddcad58c9430dedc89aE3', + childERC20Gateway: '0xCf3a4aF3c48Ba19c5FccFB44FA3E3A0F2A6e60dA', + childGatewayRouter: '0xD60FD4c5D335b00287202C93C5B4EE0478D92686', + childMulticall: '0x39E068582873B2011F5a1e8E0F7D9D993c8111BC', + childProxyAdmin: '0x9DC4Da9a940AFEbBC8329aA6534aD767b60d968c', + childWeth: '0xa3bD1fdeEb903142d16B3bd22f2aC9A82C714D62', + childWethGateway: '0xec018E81eE818b04CFb1E013D91F1b779a2AC440', }, }, } @@ -446,20 +471,20 @@ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { name: 'ArbLocal', parentChainId: 1337, tokenBridge: { - l1CustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', - l1ERC20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', - l1GatewayRouter: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', - l1MultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', - l1ProxyAdmin: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', - l1Weth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', - l1WethGateway: '0xF5FfD11A55AFD39377411Ab9856474D2a7Cb697e', - l2CustomGateway: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', - l2ERC20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', - l2GatewayRouter: '0x1294b86822ff4976BfE136cB06CF43eC7FCF2574', - l2Multicall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', - l2ProxyAdmin: '0xda52b25ddB0e3B9CC393b0690Ac62245Ac772527', - l2Weth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', - l2WethGateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', + parentCustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', + parentERC20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', + parentGatewayRouter: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', + parentMultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', + parentProxyAdmin: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', + parentWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', + parentWethGateway: '0xF5FfD11A55AFD39377411Ab9856474D2a7Cb697e', + childCustomGateway: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', + childERC20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', + childGatewayRouter: '0x1294b86822ff4976BfE136cB06CF43eC7FCF2574', + childMulticall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', + childProxyAdmin: '0xda52b25ddB0e3B9CC393b0690Ac62245Ac772527', + childWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', + childWethGateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', }, } @@ -512,7 +537,7 @@ export async function getMulticallAddress( if (typeof chain !== 'undefined') { assertArbitrumNetworkHasTokenBridge(chain) // Return the address of Multicall on the chain - return chain.tokenBridge.l2Multicall + return chain.tokenBridge.childMulticall } // The provided chain is not found in the list @@ -528,7 +553,31 @@ export async function getMulticallAddress( assertArbitrumNetworkHasTokenBridge(childChain) // Return the address of Multicall on the parent chain - return childChain.tokenBridge.l1MultiCall + return childChain.tokenBridge.parentMultiCall +} + +/** + * Maps the old {@link L2Network.tokenBridge} (from SDK v3) to {@link ArbitrumNetwork.tokenBridge} (from SDK v4). + */ +export function mapL2NetworkTokenBridgeToTokenBridge( + input: L2NetworkTokenBridge +): TokenBridge { + return { + parentGatewayRouter: input.l1GatewayRouter, + childGatewayRouter: input.l2GatewayRouter, + parentERC20Gateway: input.l1ERC20Gateway, + childERC20Gateway: input.l2ERC20Gateway, + parentCustomGateway: input.l1CustomGateway, + childCustomGateway: input.l2CustomGateway, + parentWethGateway: input.l1WethGateway, + childWethGateway: input.l2WethGateway, + parentWeth: input.l1Weth, + childWeth: input.l2Weth, + parentProxyAdmin: input.l1ProxyAdmin, + childProxyAdmin: input.l2ProxyAdmin, + parentMultiCall: input.l1MultiCall, + childMulticall: input.l2Multicall, + } } /** @@ -543,6 +592,7 @@ export function mapL2NetworkToArbitrumNetwork( // Map properties that were changed chainId: l2Network.chainID, parentChainId: l2Network.partnerChainID, + tokenBridge: mapL2NetworkTokenBridgeToTokenBridge(l2Network.tokenBridge), } } diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 5d29e06ad9..a991ab51c1 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -164,53 +164,53 @@ const registerCustomToken = async ( ? new TestOrbitCustomTokenL1__factory(parentSigner) : new TestCustomTokenL1__factory(parentSigner) const parentCustomToken = await parentCustomTokenFactory.deploy( - childChain.tokenBridge.l1CustomGateway, - childChain.tokenBridge.l1GatewayRouter + childChain.tokenBridge.parentCustomGateway, + childChain.tokenBridge.parentGatewayRouter ) await parentCustomToken.deployed() const childCustomTokenFac = new TestArbCustomToken__factory(childSigner) const childCustomToken = await childCustomTokenFac.deploy( - childChain.tokenBridge.l2CustomGateway, + childChain.tokenBridge.childCustomGateway, parentCustomToken.address ) await childCustomToken.deployed() // check starting conditions - should initially use the default gateway - const l1GatewayRouter = new L1GatewayRouter__factory(parentSigner).attach( - childChain.tokenBridge.l1GatewayRouter + const parentGatewayRouter = new L1GatewayRouter__factory(parentSigner).attach( + childChain.tokenBridge.parentGatewayRouter ) - const l2GatewayRouter = new L2GatewayRouter__factory(childSigner).attach( - childChain.tokenBridge.l2GatewayRouter + const childGatewayRouter = new L2GatewayRouter__factory(childSigner).attach( + childChain.tokenBridge.childGatewayRouter ) - const l1CustomGateway = new L1CustomGateway__factory(parentSigner).attach( - childChain.tokenBridge.l1CustomGateway + const parentCustomGateway = new L1CustomGateway__factory(parentSigner).attach( + childChain.tokenBridge.parentCustomGateway ) - const l2CustomGateway = new L1CustomGateway__factory(childSigner).attach( - childChain.tokenBridge.l2CustomGateway + const childCustomGateway = new L1CustomGateway__factory(childSigner).attach( + childChain.tokenBridge.childCustomGateway ) - const startParentGatewayAddress = await l1GatewayRouter.l1TokenToGateway( + const startParentGatewayAddress = await parentGatewayRouter.l1TokenToGateway( parentCustomToken.address ) expect( startParentGatewayAddress, 'Start parentGatewayAddress not equal empty address' ).to.eq(constants.AddressZero) - const startChildGatewayAddress = await l2GatewayRouter.l1TokenToGateway( + const startChildGatewayAddress = await childGatewayRouter.l1TokenToGateway( childCustomToken.address ) expect( startChildGatewayAddress, 'Start childGatewayAddress not equal empty address' ).to.eq(constants.AddressZero) - const startParentErc20Address = await l1CustomGateway.l1ToL2Token( + const startParentErc20Address = await parentCustomGateway.l1ToL2Token( parentCustomToken.address ) expect( startParentErc20Address, 'Start parentErc20Address not equal empty address' ).to.eq(constants.AddressZero) - const startChildErc20Address = await l2CustomGateway.l1ToL2Token( + const startChildErc20Address = await childCustomGateway.l1ToL2Token( parentCustomToken.address ) expect( @@ -267,23 +267,23 @@ const registerCustomToken = async ( ) // check end conditions - const endParentGatewayAddress = await l1GatewayRouter.l1TokenToGateway( + const endParentGatewayAddress = await parentGatewayRouter.l1TokenToGateway( parentCustomToken.address ) expect( endParentGatewayAddress, 'End parentGatewayAddress not equal to parent custom gateway' - ).to.eq(childChain.tokenBridge.l1CustomGateway) + ).to.eq(childChain.tokenBridge.parentCustomGateway) - const endChildGatewayAddress = await l2GatewayRouter.l1TokenToGateway( + const endChildGatewayAddress = await childGatewayRouter.l1TokenToGateway( parentCustomToken.address ) expect( endChildGatewayAddress, 'End childGatewayAddress not equal to child custom gateway' - ).to.eq(childChain.tokenBridge.l2CustomGateway) + ).to.eq(childChain.tokenBridge.childCustomGateway) - const endParentErc20Address = await l1CustomGateway.l1ToL2Token( + const endParentErc20Address = await parentCustomGateway.l1ToL2Token( parentCustomToken.address ) expect( @@ -291,7 +291,7 @@ const registerCustomToken = async ( 'End parentErc20Address not equal parentCustomToken address' ).to.eq(childCustomToken.address) - const endChildErc20Address = await l2CustomGateway.l1ToL2Token( + const endChildErc20Address = await childCustomGateway.l1ToL2Token( parentCustomToken.address ) expect( diff --git a/tests/integration/sanity.test.ts b/tests/integration/sanity.test.ts index 43aba62d01..ad3f34c28b 100644 --- a/tests/integration/sanity.test.ts +++ b/tests/integration/sanity.test.ts @@ -39,11 +39,11 @@ describe('sanity checks (read-only)', async () => { it('standard gateways public storage vars properly set', async () => { const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1ERC20Gateway__factory.connect( - childChain.tokenBridge.l1ERC20Gateway, + childChain.tokenBridge.parentERC20Gateway, parentSigner ) const l2Gateway = await L2ERC20Gateway__factory.connect( - childChain.tokenBridge.l2ERC20Gateway, + childChain.tokenBridge.childERC20Gateway, childSigner ) @@ -57,46 +57,46 @@ describe('sanity checks (read-only)', async () => { const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expect(l1GatewayCounterParty).to.equal( - childChain.tokenBridge.l2ERC20Gateway + childChain.tokenBridge.childERC20Gateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expect(l2GatewayCounterParty).to.equal( - childChain.tokenBridge.l1ERC20Gateway + childChain.tokenBridge.parentERC20Gateway ) const l1Router = await l1Gateway.router() - expect(l1Router).to.equal(childChain.tokenBridge.l1GatewayRouter) + expect(l1Router).to.equal(childChain.tokenBridge.parentGatewayRouter) const l2Router = await l2Gateway.router() - expect(l2Router).to.equal(childChain.tokenBridge.l2GatewayRouter) + expect(l2Router).to.equal(childChain.tokenBridge.childGatewayRouter) }) it('custom gateways public storage vars properly set', async () => { const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1CustomGateway__factory.connect( - childChain.tokenBridge.l1CustomGateway, + childChain.tokenBridge.parentCustomGateway, parentSigner ) const l2Gateway = await L2CustomGateway__factory.connect( - childChain.tokenBridge.l2CustomGateway, + childChain.tokenBridge.childCustomGateway, childSigner ) const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expect(l1GatewayCounterParty).to.equal( - childChain.tokenBridge.l2CustomGateway + childChain.tokenBridge.childCustomGateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expect(l2GatewayCounterParty).to.equal( - childChain.tokenBridge.l1CustomGateway + childChain.tokenBridge.parentCustomGateway ) const l1Router = await l1Gateway.router() - expect(l1Router).to.equal(childChain.tokenBridge.l1GatewayRouter) + expect(l1Router).to.equal(childChain.tokenBridge.parentGatewayRouter) const l2Router = await l2Gateway.router() - expect(l2Router).to.equal(childChain.tokenBridge.l2GatewayRouter) + expect(l2Router).to.equal(childChain.tokenBridge.childGatewayRouter) }) itOnlyWhenEth( @@ -105,37 +105,37 @@ describe('sanity checks (read-only)', async () => { const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1WethGateway__factory.connect( - childChain.tokenBridge.l1WethGateway, + childChain.tokenBridge.parentWethGateway, parentSigner ) const l2Gateway = await L2WethGateway__factory.connect( - childChain.tokenBridge.l2WethGateway, + childChain.tokenBridge.childWethGateway, childSigner ) - const l1Weth = await l1Gateway.l1Weth() - expectIgnoreCase(l1Weth, childChain.tokenBridge.l1Weth) + const parentWeth = await l1Gateway.l1Weth() + expectIgnoreCase(parentWeth, childChain.tokenBridge.parentWeth) - const l2Weth = await l2Gateway.l2Weth() - expectIgnoreCase(l2Weth, childChain.tokenBridge.l2Weth) + const childWeth = await l2Gateway.l2Weth() + expectIgnoreCase(childWeth, childChain.tokenBridge.childWeth) const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expectIgnoreCase( l1GatewayCounterParty, - childChain.tokenBridge.l2WethGateway + childChain.tokenBridge.childWethGateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expectIgnoreCase( l2GatewayCounterParty, - childChain.tokenBridge.l1WethGateway + childChain.tokenBridge.parentWethGateway ) const l1Router = await l1Gateway.router() - expectIgnoreCase(l1Router, childChain.tokenBridge.l1GatewayRouter) + expectIgnoreCase(l1Router, childChain.tokenBridge.parentGatewayRouter) const l2Router = await l2Gateway.router() - expectIgnoreCase(l2Router, childChain.tokenBridge.l2GatewayRouter) + expectIgnoreCase(l2Router, childChain.tokenBridge.childGatewayRouter) } ) @@ -143,26 +143,26 @@ describe('sanity checks (read-only)', async () => { const { childSigner, childChain } = await testSetup() const aeWeth = AeWETH__factory.connect( - childChain.tokenBridge.l2Weth, + childChain.tokenBridge.childWeth, childSigner ) const l2GatewayOnAeWeth = await aeWeth.l2Gateway() - expectIgnoreCase(l2GatewayOnAeWeth, childChain.tokenBridge.l2WethGateway) + expectIgnoreCase(l2GatewayOnAeWeth, childChain.tokenBridge.childWethGateway) const l1AddressOnAeWeth = await aeWeth.l1Address() - expectIgnoreCase(l1AddressOnAeWeth, childChain.tokenBridge.l1Weth) + expectIgnoreCase(l1AddressOnAeWeth, childChain.tokenBridge.parentWeth) }) itOnlyWhenEth('l1 gateway router points to right weth gateways', async () => { const { adminErc20Bridger, parentSigner, childChain } = await testSetup() const gateway = await adminErc20Bridger.getParentGatewayAddress( - childChain.tokenBridge.l1Weth, + childChain.tokenBridge.parentWeth, parentSigner.provider! ) - expect(gateway).to.equal(childChain.tokenBridge.l1WethGateway) + expect(gateway).to.equal(childChain.tokenBridge.parentWethGateway) }) it('parent and child chain implementations of calculateL2ERC20Address match', async () => { @@ -174,7 +174,7 @@ describe('sanity checks (read-only)', async () => { const erc20ChildAddressAsPerParent = await erc20Bridger.getChildERC20Address(address, parentSigner.provider!) const childGatewayRouter = L2GatewayRouter__factory.connect( - childChain.tokenBridge.l2GatewayRouter, + childChain.tokenBridge.childGatewayRouter, childSigner.provider! ) const erc20ChildAddressAsPerChild = diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 03621e7f7a..4f6dc9e73f 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -145,7 +145,7 @@ describe('standard ERC20', () => { expect(retryRec.blockHash, 'redeemed in same block').to.eq(blockHash) expect(retryRec.to, 'redeemed in same block').to.eq( - testState.childChain.tokenBridge.l2ERC20Gateway + testState.childChain.tokenBridge.childERC20Gateway ) expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index bb17f568ae..a505cd072d 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -203,18 +203,18 @@ const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { switch (gatewayType) { case GatewayType.CUSTOM: return { - expectedL1Gateway: l2Network.tokenBridge.l1CustomGateway, - expectedL2Gateway: l2Network.tokenBridge.l2CustomGateway, + expectedL1Gateway: l2Network.tokenBridge.parentCustomGateway, + expectedL2Gateway: l2Network.tokenBridge.childCustomGateway, } case GatewayType.STANDARD: return { - expectedL1Gateway: l2Network.tokenBridge.l1ERC20Gateway, - expectedL2Gateway: l2Network.tokenBridge.l2ERC20Gateway, + expectedL1Gateway: l2Network.tokenBridge.parentERC20Gateway, + expectedL2Gateway: l2Network.tokenBridge.childERC20Gateway, } case GatewayType.WETH: return { - expectedL1Gateway: l2Network.tokenBridge.l1WethGateway, - expectedL2Gateway: l2Network.tokenBridge.l2WethGateway, + expectedL1Gateway: l2Network.tokenBridge.parentWethGateway, + expectedL2Gateway: l2Network.tokenBridge.childWethGateway, } default: throw new ArbSdkError(`Unexpected gateway type: ${gatewayType}`) diff --git a/tests/integration/weth.test.ts b/tests/integration/weth.test.ts index f72f2f360f..79c79e6cad 100644 --- a/tests/integration/weth.test.ts +++ b/tests/integration/weth.test.ts @@ -42,30 +42,30 @@ describeOnlyWhenEth('WETH', async () => { const { childChain, parentSigner, childSigner, erc20Bridger } = await testSetup() - const l1WethAddress = childChain.tokenBridge.l1Weth + const parentWethAddress = childChain.tokenBridge.parentWeth const wethToWrap = parseEther('0.00001') const wethToDeposit = parseEther('0.0000001') await fundParentSigner(parentSigner, parseEther('1')) - const l2WETH = AeWETH__factory.connect( - childChain.tokenBridge.l2Weth, + const childWETH = AeWETH__factory.connect( + childChain.tokenBridge.childWeth, childSigner.provider! ) expect( - (await l2WETH.balanceOf(await childSigner.getAddress())).toString(), + (await childWETH.balanceOf(await childSigner.getAddress())).toString(), 'start balance weth' ).to.eq('0') - const l1WETH = AeWETH__factory.connect(l1WethAddress, parentSigner) - const res = await l1WETH.deposit({ + const parentWETH = AeWETH__factory.connect(parentWethAddress, parentSigner) + const res = await parentWETH.deposit({ value: wethToWrap, }) await res.wait() await depositToken({ depositAmount: wethToDeposit, - parentTokenAddress: l1WethAddress, + parentTokenAddress: parentWethAddress, erc20Bridger, parentSigner, childSigner, @@ -73,25 +73,27 @@ describeOnlyWhenEth('WETH', async () => { expectedGatewayType: GatewayType.WETH, }) - const l2WethGateway = await erc20Bridger.getChildGatewayAddress( - l1WethAddress, + const childWethGateway = await erc20Bridger.getChildGatewayAddress( + parentWethAddress, childSigner.provider! ) - expect(l2WethGateway, 'l2 weth gateway').to.eq( - childChain.tokenBridge.l2WethGateway + expect(childWethGateway, 'child weth gateway').to.eq( + childChain.tokenBridge.childWethGateway ) - const l2Token = erc20Bridger.getChildTokenContract( + const childToken = erc20Bridger.getChildTokenContract( childSigner.provider!, - childChain.tokenBridge.l2Weth + childChain.tokenBridge.childWeth + ) + expect(childToken.address, 'child weth').to.eq( + childChain.tokenBridge.childWeth ) - expect(l2Token.address, 'l2 weth').to.eq(childChain.tokenBridge.l2Weth) // now try to withdraw the funds await fundChildSigner(childSigner) - const l2Weth = AeWETH__factory.connect(l2Token.address, childSigner) + const childWeth = AeWETH__factory.connect(childToken.address, childSigner) const randomAddr = Wallet.createRandom().address await ( - await l2Weth.connect(childSigner).withdrawTo(randomAddr, wethToDeposit) + await childWeth.connect(childSigner).withdrawTo(randomAddr, wethToDeposit) ).wait() const afterBalance = await childSigner.provider!.getBalance(randomAddr) @@ -109,11 +111,11 @@ describeOnlyWhenEth('WETH', async () => { await fundParentSigner(parentSigner) await fundChildSigner(childSigner) - const l2Weth = AeWETH__factory.connect( - childChain.tokenBridge.l2Weth, + const childWeth = AeWETH__factory.connect( + childChain.tokenBridge.childWeth, childSigner ) - const res = await l2Weth.deposit({ + const res = await childWeth.deposit({ value: wethToWrap, }) const rec = await res.wait() @@ -125,7 +127,7 @@ describeOnlyWhenEth('WETH', async () => { gatewayType: GatewayType.WETH, parentSigner: parentSigner, parentToken: ERC20__factory.connect( - childChain.tokenBridge.l1Weth, + childChain.tokenBridge.parentWeth, parentSigner.provider! ), childSigner: childSigner, From f4f281b41c0f437f9150f91bc3729ded5b7591f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragi=C5=A1a=20Spasojevi=C4=87?= Date: Fri, 14 Jun 2024 11:58:48 +0200 Subject: [PATCH 42/74] fix: use new method names --- src/lib/assetBridger/erc20Bridger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 119751ab96..6e735ec4a5 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -893,12 +893,12 @@ export class Erc20Bridger extends AssetBridger< l1Provider: Provider l2Provider: Provider }) { - const tokenL2AddressFromL1GatewayRouter = await this.getL2ERC20Address( + const tokenL2AddressFromL1GatewayRouter = await this.getChildERC20Address( erc20L1Address, l1Provider ) - const l2GatewayAddressFromL2Router = await this.getL2GatewayAddress( + const l2GatewayAddressFromL2Router = await this.getChildGatewayAddress( erc20L1Address, l2Provider ) From c66a65b8da34555361b022adc8c5a3dfb2320526 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 14 Jun 2024 14:24:00 +0200 Subject: [PATCH 43/74] feat: update ERC-20 casing (#489) * feat: update erc20 casing * missed a couple * update --- scripts/deployStandard.ts | 2 +- scripts/lib.ts | 2 +- src/lib/assetBridger/erc20Bridger.ts | 6 ++--- src/lib/dataEntities/networks.ts | 32 ++++++++++++------------- tests/integration/sanity.test.ts | 10 ++++---- tests/integration/standarderc20.test.ts | 4 ++-- tests/integration/testHelpers.ts | 10 ++++---- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/scripts/deployStandard.ts b/scripts/deployStandard.ts index 71beb2a26d..cea35a209e 100644 --- a/scripts/deployStandard.ts +++ b/scripts/deployStandard.ts @@ -102,7 +102,7 @@ const main = async () => { } /* check token not yet deployed */ - const l2TokenAddress = await erc20Bridger.getChildERC20Address( + const l2TokenAddress = await erc20Bridger.getChildErc20Address( l1TokenAddress, l1Provider ) diff --git a/scripts/lib.ts b/scripts/lib.ts index a0e0ca73fb..4b0191f90e 100644 --- a/scripts/lib.ts +++ b/scripts/lib.ts @@ -86,7 +86,7 @@ export const setGateWays = async ( if (overrideGateways.length > 0) { return overrideGateways } else if (type === 'standard') { - return tokens.map(() => childChain.tokenBridge.parentERC20Gateway) + return tokens.map(() => childChain.tokenBridge.parentErc20Gateway) } else if (type === 'arbCustom') { return tokens.map(() => childChain.tokenBridge.parentCustomGateway) } else { diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 6e735ec4a5..7ac6e622a5 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -482,7 +482,7 @@ export class Erc20Bridger extends AssetBridger< * @param parentProvider * @returns */ - public async getChildERC20Address( + public async getChildErc20Address( erc20ParentAddress: string, parentProvider: Provider ): Promise { @@ -505,7 +505,7 @@ export class Erc20Bridger extends AssetBridger< * @param childProvider * @returns */ - public async getParentERC20Address( + public async getParentErc20Address( erc20ChildChainAddress: string, childProvider: Provider ): Promise { @@ -893,7 +893,7 @@ export class Erc20Bridger extends AssetBridger< l1Provider: Provider l2Provider: Provider }) { - const tokenL2AddressFromL1GatewayRouter = await this.getChildERC20Address( + const tokenL2AddressFromL1GatewayRouter = await this.getChildErc20Address( erc20L1Address, l1Provider ) diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 39170d43ee..1293b2ae53 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -86,8 +86,8 @@ export type L2Network = Prettify< export interface TokenBridge { parentGatewayRouter: string childGatewayRouter: string - parentERC20Gateway: string - childERC20Gateway: string + parentErc20Gateway: string + childErc20Gateway: string parentCustomGateway: string childCustomGateway: string parentWethGateway: string @@ -142,8 +142,8 @@ export interface Networks { const mainnetTokenBridge: TokenBridge = { parentGatewayRouter: '0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef', childGatewayRouter: '0x5288c571Fd7aD117beA99bF60FE0846C4E84F933', - parentERC20Gateway: '0xa3A7B6F88361F48403514059F1F16C8E78d60EeC', - childERC20Gateway: '0x09e9222E96E7B4AE2a407B98d48e330053351EEe', + parentErc20Gateway: '0xa3A7B6F88361F48403514059F1F16C8E78d60EeC', + childErc20Gateway: '0x09e9222E96E7B4AE2a407B98d48e330053351EEe', parentCustomGateway: '0xcEe284F754E854890e311e3280b767F80797180d', childCustomGateway: '0x096760F208390250649E3e8763348E783AEF5562', parentWethGateway: '0xd92023E9d9911199a6711321D1277285e6d4e2db', @@ -196,14 +196,14 @@ export const networks: Networks = { parentChainId: 1, tokenBridge: { parentCustomGateway: '0x23122da8C581AA7E0d07A36Ff1f16F799650232f', - parentERC20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', + parentErc20Gateway: '0xB2535b988dcE19f9D71dfB22dB6da744aCac21bf', parentGatewayRouter: '0xC840838Bc438d73C16c2f8b22D2Ce3669963cD48', parentMultiCall: '0x8896D23AfEA159a5e9b72C9Eb3DC4E2684A38EA3', parentProxyAdmin: '0xa8f7DdEd54a726eB873E98bFF2C95ABF2d03e560', parentWeth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', parentWethGateway: '0xE4E2121b479017955Be0b175305B35f312330BaE', childCustomGateway: '0xbf544970E6BD77b21C6492C281AB60d0770451F4', - childERC20Gateway: '0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257', + childErc20Gateway: '0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257', childGatewayRouter: '0x21903d3F8176b1a0c17E953Cd896610Be9fFDFa8', childMulticall: '0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86', childProxyAdmin: '0xada790b026097BfB36a5ed696859b97a96CEd92C', @@ -226,14 +226,14 @@ export const networks: Networks = { parentChainId: 11155111, tokenBridge: { parentCustomGateway: '0xba2F7B6eAe1F9d174199C5E4867b563E0eaC40F3', - parentERC20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', + parentErc20Gateway: '0x902b3E5f8F19571859F4AB1003B960a5dF693aFF', parentGatewayRouter: '0xcE18836b233C83325Cc8848CA4487e94C6288264', parentMultiCall: '0xded9AD2E65F3c4315745dD915Dbe0A4Df61b2320', parentProxyAdmin: '0xDBFC2FfB44A5D841aB42b0882711ed6e5A9244b0', parentWeth: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9', parentWethGateway: '0xA8aD8d7e13cbf556eE75CB0324c13535d8100e1E', childCustomGateway: '0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5', - childERC20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502', + childErc20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502', childGatewayRouter: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7', childMulticall: '0xA115146782b7143fAdB3065D86eACB54c169d092', childProxyAdmin: '0x715D99480b77A8d9D603638e593a539E21345FdF', @@ -256,14 +256,14 @@ export const networks: Networks = { parentChainId: 421614, tokenBridge: { parentCustomGateway: '0xd624D491A5Bc32de52a2e1481846752213bF7415', - parentERC20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', + parentErc20Gateway: '0x7348Fdf6F3e090C635b23D970945093455214F3B', parentGatewayRouter: '0x0057892cb8bb5f1cE1B3C6f5adE899732249713f', parentMultiCall: '0xBEbe3BfBF52FFEA965efdb3f14F2101c0264c940', parentProxyAdmin: '0xB9E77732f32831f09e2a50D6E71B2Cca227544bf', parentWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', parentWethGateway: '0x39845e4a230434D218b907459a305eBA61A790d4', childCustomGateway: '0xF6dbB0e312dF4652d59ce405F5E00CC3430f19c5', - childERC20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860', + childErc20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860', childGatewayRouter: '0x4c3a1f7011F02Fe4769fC704359c3696a6A60D89', childMulticall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3', childProxyAdmin: '0xE914c0d417E8250d0237d2F4827ed3612e6A9C3B', @@ -286,14 +286,14 @@ export const networks: Networks = { parentChainId: 421614, tokenBridge: { parentCustomGateway: '0x093353B9f723047abf37Ebe01cE48d7dDA8320F4', - parentERC20Gateway: '0xD2C4693Dd8d44703af5CF9484fa8faAD6e33E392', + parentErc20Gateway: '0xD2C4693Dd8d44703af5CF9484fa8faAD6e33E392', parentGatewayRouter: '0xAC4F454320A253267C6Ae95e4784b9A4f9F78359', parentMultiCall: '0xce1CAd780c529e66e3aa6D952a1ED9A6447791c1', parentProxyAdmin: '0xBD76fd3fB5F3CD7165fB6e0DB895FFE1d81463e3', parentWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', parentWethGateway: '0x4FEbc93233aAc1523f36Abe297de9323f6C8ce79', childCustomGateway: '0xE102D94df0179082B39Ddcad58c9430dedc89aE3', - childERC20Gateway: '0xCf3a4aF3c48Ba19c5FccFB44FA3E3A0F2A6e60dA', + childErc20Gateway: '0xCf3a4aF3c48Ba19c5FccFB44FA3E3A0F2A6e60dA', childGatewayRouter: '0xD60FD4c5D335b00287202C93C5B4EE0478D92686', childMulticall: '0x39E068582873B2011F5a1e8E0F7D9D993c8111BC', childProxyAdmin: '0x9DC4Da9a940AFEbBC8329aA6534aD767b60d968c', @@ -472,14 +472,14 @@ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { parentChainId: 1337, tokenBridge: { parentCustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', - parentERC20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', + parentErc20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', parentGatewayRouter: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', parentMultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', parentProxyAdmin: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', parentWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', parentWethGateway: '0xF5FfD11A55AFD39377411Ab9856474D2a7Cb697e', childCustomGateway: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', - childERC20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', + childErc20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', childGatewayRouter: '0x1294b86822ff4976BfE136cB06CF43eC7FCF2574', childMulticall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', childProxyAdmin: '0xda52b25ddB0e3B9CC393b0690Ac62245Ac772527', @@ -565,8 +565,8 @@ export function mapL2NetworkTokenBridgeToTokenBridge( return { parentGatewayRouter: input.l1GatewayRouter, childGatewayRouter: input.l2GatewayRouter, - parentERC20Gateway: input.l1ERC20Gateway, - childERC20Gateway: input.l2ERC20Gateway, + parentErc20Gateway: input.l1ERC20Gateway, + childErc20Gateway: input.l2ERC20Gateway, parentCustomGateway: input.l1CustomGateway, childCustomGateway: input.l2CustomGateway, parentWethGateway: input.l1WethGateway, diff --git a/tests/integration/sanity.test.ts b/tests/integration/sanity.test.ts index ad3f34c28b..b1722e1c1d 100644 --- a/tests/integration/sanity.test.ts +++ b/tests/integration/sanity.test.ts @@ -39,11 +39,11 @@ describe('sanity checks (read-only)', async () => { it('standard gateways public storage vars properly set', async () => { const { parentSigner, childSigner, childChain } = await testSetup() const l1Gateway = await L1ERC20Gateway__factory.connect( - childChain.tokenBridge.parentERC20Gateway, + childChain.tokenBridge.parentErc20Gateway, parentSigner ) const l2Gateway = await L2ERC20Gateway__factory.connect( - childChain.tokenBridge.childERC20Gateway, + childChain.tokenBridge.childErc20Gateway, childSigner ) @@ -57,12 +57,12 @@ describe('sanity checks (read-only)', async () => { const l1GatewayCounterParty = await l1Gateway.counterpartGateway() expect(l1GatewayCounterParty).to.equal( - childChain.tokenBridge.childERC20Gateway + childChain.tokenBridge.childErc20Gateway ) const l2GatewayCounterParty = await l2Gateway.counterpartGateway() expect(l2GatewayCounterParty).to.equal( - childChain.tokenBridge.parentERC20Gateway + childChain.tokenBridge.parentErc20Gateway ) const l1Router = await l1Gateway.router() @@ -172,7 +172,7 @@ describe('sanity checks (read-only)', async () => { const address = hexlify(randomBytes(20)) const erc20ChildAddressAsPerParent = - await erc20Bridger.getChildERC20Address(address, parentSigner.provider!) + await erc20Bridger.getChildErc20Address(address, parentSigner.provider!) const childGatewayRouter = L2GatewayRouter__factory.connect( childChain.tokenBridge.childGatewayRouter, childSigner.provider! diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 4f6dc9e73f..847f63c2e6 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -145,7 +145,7 @@ describe('standard ERC20', () => { expect(retryRec.blockHash, 'redeemed in same block').to.eq(blockHash) expect(retryRec.to, 'redeemed in same block').to.eq( - testState.childChain.tokenBridge.childERC20Gateway + testState.childChain.tokenBridge.childErc20Gateway ) expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( @@ -262,7 +262,7 @@ describe('standard ERC20', () => { }) it('withdraws erc20', async function () { - const l2TokenAddr = await testState.erc20Bridger.getChildERC20Address( + const l2TokenAddr = await testState.erc20Bridger.getChildErc20Address( testState.parentToken.address, testState.parentSigner.provider! ) diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index a505cd072d..f0bd28a715 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -115,7 +115,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { ChildToParentMessageStatus.UNCONFIRMED ) - const childTokenAddr = await params.erc20Bridger.getChildERC20Address( + const childTokenAddr = await params.erc20Bridger.getChildErc20Address( params.parentToken.address, params.parentSigner.provider! ) @@ -208,8 +208,8 @@ const getGateways = (gatewayType: GatewayType, l2Network: ArbitrumNetwork) => { } case GatewayType.STANDARD: return { - expectedL1Gateway: l2Network.tokenBridge.parentERC20Gateway, - expectedL2Gateway: l2Network.tokenBridge.childERC20Gateway, + expectedL1Gateway: l2Network.tokenBridge.parentErc20Gateway, + expectedL2Gateway: l2Network.tokenBridge.childErc20Gateway, } case GatewayType.WETH: return { @@ -367,7 +367,7 @@ export const depositToken = async ({ expectedL2Gateway ) - const childErc20Addr = await erc20Bridger.getChildERC20Address( + const childErc20Addr = await erc20Bridger.getChildErc20Address( parentTokenAddress, parentSigner.provider! ) @@ -375,7 +375,7 @@ export const depositToken = async ({ childSigner.provider!, childErc20Addr ) - const parentErc20Addr = await erc20Bridger.getParentERC20Address( + const parentErc20Addr = await erc20Bridger.getParentErc20Address( childErc20Addr, childSigner.provider! ) From 90b3b63918eabb77cc844b0a1f4ae2018790b031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragi=C5=A1a=20Spasojevi=C4=87?= Date: Fri, 14 Jun 2024 14:27:31 +0200 Subject: [PATCH 44/74] chore: bump version to v4.0.0-alpha.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b72bf3ef7a..b47e239585 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.3", + "version": "4.0.0-alpha.4", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From cdccc97e891de963510f8b1eb2a52b946e87ddf4 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:24:48 -0400 Subject: [PATCH 45/74] chore: updates methods to waitForChildTransactionReceipt and isDepositDisabled (#480) --- scripts/deployStandard.ts | 2 +- src/lib/assetBridger/ethBridger.ts | 2 +- src/lib/message/ParentTransaction.ts | 4 ++-- tests/integration/eth.test.ts | 4 +++- tests/integration/testHelpers.ts | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/deployStandard.ts b/scripts/deployStandard.ts index cea35a209e..0fb68cdc5a 100644 --- a/scripts/deployStandard.ts +++ b/scripts/deployStandard.ts @@ -50,7 +50,7 @@ const main = async () => { } /** Check if disabled */ - const isDisabled = await erc20Bridger.l1TokenIsDisabled( + const isDisabled = await erc20Bridger.isDepositDisabled( l1TokenAddress, l1Provider ) diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index 9e74462fce..af8461209d 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -159,7 +159,7 @@ type EthDepositToRequestParams = OmitTyped< } /** - * Bridger for moving ETH back and forth between parent and child chain + * Bridger for moving either ETH or custom gas tokens back and forth between parent and child chains */ export class EthBridger extends AssetBridger< EthDepositParams | EthDepositToParams | ParentToChildTxReqAndSigner, diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 0f6b3a2dee..8709857a2a 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -366,7 +366,7 @@ export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt * If `complete` is true then this message is in the terminal state. * For eth deposits complete this is when the status is FUNDS_DEPOSITED, EXPIRED or REDEEMED. */ - public async waitForChildTx( + public async waitForChildTransactionReceipt( childProvider: Provider, confirmations?: number, timeout?: number @@ -404,7 +404,7 @@ export class ParentContractCallTransactionReceipt extends ParentTransactionRecei * If `complete` is true then this message is in the terminal state. * For contract calls this is true only if the status is REDEEMED. */ - public async waitForChildTx( + public async waitForChildTransactionReceipt( childSignerOrProvider: T, confirmations?: number, timeout?: number diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index 038e225ad0..d5f2efe478 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -123,7 +123,9 @@ describe('Ether', async () => { 'balance failed to update after eth deposit' ) - const waitResult = await rec.waitForChildTx(childSigner.provider!) + const waitResult = await rec.waitForChildTransactionReceipt( + childSigner.provider! + ) const parentToChildMessages = await rec.getEthDeposits( childSigner.provider! diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index f0bd28a715..68fedb1737 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -332,7 +332,7 @@ export const depositToken = async ({ parentTokenBalanceBefore.sub(depositAmount).toString() ) - const waitRes = await depositRec.waitForChildTx(childSigner) + const waitRes = await depositRec.waitForChildTransactionReceipt(childSigner) const childEthBalanceAfter = await childSigner.provider!.getBalance( destinationAddress || senderAddress From 03dc70afa761512c9ff4fd7c734250c794a8d915 Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 25 Jun 2024 20:24:15 +0200 Subject: [PATCH 46/74] feat: check if registered in deposit (#485) Co-authored-by: spsjvc Co-authored-by: Doug <4741454+douglance@users.noreply.github.com> --- src/lib/assetBridger/erc20Bridger.ts | 73 +++++++++++++++++---------- src/lib/utils/calldata.ts | 32 ++++++++++++ tests/integration/customerc20.test.ts | 12 ++--- tests/unit/calldata.test.ts | 64 +++++++++++++++++++++++ 4 files changed, 147 insertions(+), 34 deletions(-) create mode 100644 src/lib/utils/calldata.ts create mode 100644 tests/unit/calldata.test.ts diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 9fa2f7cbf3..c00a0d24c7 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -78,6 +78,7 @@ import { EventArgs } from '../dataEntities/event' import { ParentToChildMessageGasParams } from '../message/ParentToChildMessageCreator' import { isArbitrumChain } from '../utils/lib' import { L2ERC20Gateway__factory } from '../abi/factories/L2ERC20Gateway__factory' +import { getErc20ParentAddressFromParentToChildTxRequest } from '../utils/calldata' export interface TokenApproveParams { /** @@ -139,6 +140,7 @@ export interface Erc20WithdrawParams extends EthWithdrawParams { export type ParentToChildTxReqAndSignerProvider = ParentToChildTransactionRequest & { parentSigner: Signer + childProvider: Provider overrides?: Overrides } @@ -767,6 +769,24 @@ export class Erc20Bridger extends AssetBridger< params.parentSigner ) + const erc20ParentAddress = isParentToChildTransactionRequest(params) + ? getErc20ParentAddressFromParentToChildTxRequest(params) + : params.erc20ParentAddress + + const isRegistered = await this.isRegistered({ + erc20ParentAddress, + parentProvider, + childProvider: params.childProvider, + }) + + if (!isRegistered) { + const parentChainId = (await parentProvider.getNetwork()).chainId + + throw new Error( + `Token ${erc20ParentAddress} on chain ${parentChainId} is not registered on the gateways` + ) + } + const tokenDeposit = isParentToChildTransactionRequest(params) ? params : await this.getDepositRequest({ @@ -879,52 +899,49 @@ export class Erc20Bridger extends AssetBridger< /** * Checks if the token has been properly registered on both gateways. Mostly useful for tokens that use a custom gateway. - * @param erc20L1Address - * @param l1Provider - * @param l2Provider + * @param erc20ParentAddress + * @param parentProvider + * @param childProvider * @returns */ public async isRegistered({ - erc20L1Address, - l1Provider, - l2Provider, + erc20ParentAddress, + parentProvider, + childProvider, }: { - erc20L1Address: string - l1Provider: Provider - l2Provider: Provider + erc20ParentAddress: string + parentProvider: Provider + childProvider: Provider }) { - const l1StandardGatewayAddressFromChainConfig = + const parentStandardGatewayAddressFromChainConfig = this.childChain.tokenBridge.parentErc20Gateway - const l1GatewayAddressFromL1GatewayRouter = - await this.getParentGatewayAddress(erc20L1Address, l1Provider) + const parentGatewayAddressFromParentGatewayRouter = + await this.getParentGatewayAddress(erc20ParentAddress, parentProvider) // token uses standard gateway; no need to check further if ( - l1StandardGatewayAddressFromChainConfig.toLowerCase() === - l1GatewayAddressFromL1GatewayRouter.toLowerCase() + parentStandardGatewayAddressFromChainConfig.toLowerCase() === + parentGatewayAddressFromParentGatewayRouter.toLowerCase() ) { return true } - const tokenL2AddressFromL1GatewayRouter = await this.getChildErc20Address( - erc20L1Address, - l1Provider - ) + const childTokenAddressFromParentGatewayRouter = + await this.getChildErc20Address(erc20ParentAddress, parentProvider) - const l2GatewayAddressFromL2Router = await this.getChildGatewayAddress( - erc20L1Address, - l2Provider - ) + const childGatewayAddressFromChildRouter = + await this.getChildGatewayAddress(erc20ParentAddress, childProvider) - const l2AddressFromL2Gateway = await L2ERC20Gateway__factory.connect( - l2GatewayAddressFromL2Router, - l2Provider - ).calculateL2TokenAddress(erc20L1Address) + const childTokenAddressFromChildGateway = + await L2ERC20Gateway__factory.connect( + childGatewayAddressFromChildRouter, + childProvider + ).calculateL2TokenAddress(erc20ParentAddress) return ( - tokenL2AddressFromL1GatewayRouter.toLowerCase() === - l2AddressFromL2Gateway.toLowerCase() + childTokenAddressFromParentGatewayRouter.toLowerCase() === + childTokenAddressFromChildGateway.toLowerCase() ) } } diff --git a/src/lib/utils/calldata.ts b/src/lib/utils/calldata.ts new file mode 100644 index 0000000000..8f3cbc1a22 --- /dev/null +++ b/src/lib/utils/calldata.ts @@ -0,0 +1,32 @@ +import { L1GatewayRouter__factory } from '../abi/factories/L1GatewayRouter__factory' +import { ParentToChildTxReqAndSigner } from '../assetBridger/ethBridger' + +export const getErc20ParentAddressFromParentToChildTxRequest = ( + txReq: ParentToChildTxReqAndSigner +): string => { + const { + txRequest: { data }, + } = txReq + + const iGatewayRouter = L1GatewayRouter__factory.createInterface() + + try { + const decodedData = iGatewayRouter.decodeFunctionData( + 'outboundTransfer', + data + ) + + return decodedData['_token'] + } catch { + try { + const decodedData = iGatewayRouter.decodeFunctionData( + 'outboundTransferCustomRefund', + data + ) + + return decodedData['_token'] + } catch { + throw new Error('data signature not matching deposits methods') + } + } +} diff --git a/tests/integration/customerc20.test.ts b/tests/integration/customerc20.test.ts index 64171236ca..4834dae75a 100644 --- a/tests/integration/customerc20.test.ts +++ b/tests/integration/customerc20.test.ts @@ -171,9 +171,9 @@ const registerCustomToken = async ( adminErc20Bridger .isRegistered({ - erc20L1Address: parentCustomToken.address, - l1Provider: parentSigner.provider!, - l2Provider: childSigner.provider!, + erc20ParentAddress: parentCustomToken.address, + parentProvider: parentSigner.provider!, + childProvider: childSigner.provider!, }) .then(isRegistered => { expect(isRegistered, 'expected token not to be registered').to.be.false @@ -311,9 +311,9 @@ const registerCustomToken = async ( adminErc20Bridger .isRegistered({ - erc20L1Address: parentCustomToken.address, - l1Provider: parentSigner.provider!, - l2Provider: childSigner.provider!, + erc20ParentAddress: parentCustomToken.address, + parentProvider: parentSigner.provider!, + childProvider: childSigner.provider!, }) .then(isRegistered => { expect(isRegistered, 'expected token to be registered').to.be.true diff --git a/tests/unit/calldata.test.ts b/tests/unit/calldata.test.ts new file mode 100644 index 0000000000..a1897ddb5c --- /dev/null +++ b/tests/unit/calldata.test.ts @@ -0,0 +1,64 @@ +import { expect } from 'chai' +import { getErc20ParentAddressFromParentToChildTxRequest } from '../../src/lib/utils/calldata' +import { ParentToChildTxReqAndSigner } from '../../src/lib/assetBridger/ethBridger' + +describe('Calldata', () => { + describe('getErc20ParentAddressFromParentToChildTxRequest', () => { + it('decodes calldata to get token address from `outboundTransfer` method call on gateway router', async () => { + const calldata = + '0xd2ce7d65000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000df7fa906da092cc30f868c5730c944f4d5431e17000000000000000000000000000000000000000000000000dea56a0c808e9b6a0000000000000000000000000000000000000000000000000000000000026257000000000000000000000000000000000000000000000000000000000393870000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000580cedab294000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000' + const expectedAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + const output = getErc20ParentAddressFromParentToChildTxRequest({ + txRequest: { data: calldata }, + } as ParentToChildTxReqAndSigner) + expect(output).to.eq(expectedAddress) + }) + + it('decodes calldata to get token address from `outboundTransferCustomRefund` method call on gateway router', async () => { + const calldata = + '0x4fb1a07b000000000000000000000000429881672b9ae42b8eba0e26cd9c73711b891ca50000000000000000000000000f571d2625b503bb7c1d2b5655b483a2fa696fef0000000000000000000000007ecc7163469f37b777d7b8f45a667314030ace240000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000e35fa931a00000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000' + const expectedAddress = '0x429881672B9AE42b8EbA0E26cD9C73711b891Ca5' + const output = getErc20ParentAddressFromParentToChildTxRequest({ + txRequest: { data: calldata }, + } as ParentToChildTxReqAndSigner) + expect(output).to.eq(expectedAddress) + }) + + it('throws when handling bad calldata', async () => { + try { + const calldata = '0xInvalidCalldata' + getErc20ParentAddressFromParentToChildTxRequest({ + txRequest: { data: calldata }, + } as ParentToChildTxReqAndSigner) + } catch (err: any) { + expect(err.message).to.eq( + 'data signature not matching deposits methods' + ) + } + }) + + it('throws when handling an empty string', async () => { + try { + getErc20ParentAddressFromParentToChildTxRequest({ + txRequest: { data: '' }, + } as ParentToChildTxReqAndSigner) + } catch (err: any) { + expect(err.message).to.eq( + 'data signature not matching deposits methods' + ) + } + }) + + it('throws when handling `undefined` data ', async () => { + try { + getErc20ParentAddressFromParentToChildTxRequest({ + txRequest: { data: undefined }, + } as any as ParentToChildTxReqAndSigner) + } catch (err: any) { + expect(err.message).to.eq( + 'data signature not matching deposits methods' + ) + } + }) + }) +}) From e10de18e9116edc402074af42185ce29bcc63576 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:15:24 -0400 Subject: [PATCH 47/74] removes unused import --- src/lib/message/ChildToParentMessageNitro.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index 527e88e8c6..e71ab5fcb7 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -42,11 +42,7 @@ import { SignerOrProvider, } from '../dataEntities/signerOrProvider' import { getBlockRangesForL1Block, isArbitrumChain, wait } from '../utils/lib' -import { - ArbitrumNetwork, - getArbitrumNetwork, - L2Network, -} from '../dataEntities/networks' +import { ArbitrumNetwork, getArbitrumNetwork } from '../dataEntities/networks' import { NodeCreatedEvent, RollupUserLogic } from '../abi/RollupUserLogic' import { AssertionCreatedEvent, From 0a8512a881d5c0c5c67ea371accb8991f5b1c440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragi=C5=A1a=20Spasojevi=C4=87?= Date: Fri, 28 Jun 2024 15:22:06 +0200 Subject: [PATCH 48/74] chore: bump version to 4.0.0-alpha.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 173a89f813..27392ea144 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "3.6.0", + "version": "4.0.0-alpha.5", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 6bfede95a656cf8c6d15db8925d1c551c82095b4 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Tue, 9 Jul 2024 05:53:41 -0400 Subject: [PATCH 49/74] feat: enable teleporter to work with v4 (#502) --- scripts/genNetwork.ts | 5 +- scripts/testSetup.ts | 9 +- src/lib/assetBridger/l1l3Bridger.ts | 234 +++++++++--------- .../customFeeTokenTestHelpers.ts | 6 +- tests/integration/l1l3Bridger.test.ts | 114 +++++---- 5 files changed, 204 insertions(+), 164 deletions(-) diff --git a/scripts/genNetwork.ts b/scripts/genNetwork.ts index d0b7fdff45..f991bc2660 100644 --- a/scripts/genNetwork.ts +++ b/scripts/genNetwork.ts @@ -74,6 +74,7 @@ async function main() { let output = getLocalNetworksFromContainer('l1l2') if (isTestingOrbitChains) { + // When running with L3 active, the container calls the L3 network L2 so we rename it here const { l2Network: l3Network } = getLocalNetworksFromContainer('l2l3') const { patchedL2Network, patchedL3Network } = await patchNetworks( output.l2Network, @@ -82,8 +83,8 @@ async function main() { ) output = { - l1Network: patchedL2Network, - l2Network: patchedL3Network, + l2Network: patchedL2Network, + l3Network: patchedL3Network, } } else { const { patchedL2Network } = await patchNetworks( diff --git a/scripts/testSetup.ts b/scripts/testSetup.ts index 0b9f0820ee..10bc2c68ba 100644 --- a/scripts/testSetup.ts +++ b/scripts/testSetup.ts @@ -102,9 +102,12 @@ export const testSetup = async (): Promise<{ const l2Network = await getArbitrumNetwork(childDeployer) setChildChain = l2Network } catch (err) { + const localNetworks = getLocalNetworksFromFile() // the networks havent been added yet // check if theres an existing network available - const { l2Network: childChain } = getLocalNetworksFromFile() + const childChain = ( + isTestingOrbitChains ? localNetworks.l3Network : localNetworks.l2Network + ) as ArbitrumNetwork setChildChain = registerCustomArbitrumNetwork(childChain) } @@ -138,6 +141,7 @@ export const testSetup = async (): Promise<{ export function getLocalNetworksFromFile(): { l2Network: ArbitrumNetwork + l3Network?: ArbitrumNetwork } { const pathToLocalNetworkFile = path.join(__dirname, '..', 'localNetwork.json') if (!fs.existsSync(pathToLocalNetworkFile)) { @@ -145,6 +149,7 @@ export function getLocalNetworksFromFile(): { } const localNetworksFile = fs.readFileSync(pathToLocalNetworkFile, 'utf8') const localL2: ArbitrumNetwork = JSON.parse(localNetworksFile).l2Network + const localL3: ArbitrumNetwork = JSON.parse(localNetworksFile).l3Network - return { l2Network: localL2 } + return { l2Network: localL2, l3Network: localL3 } } diff --git a/src/lib/assetBridger/l1l3Bridger.ts b/src/lib/assetBridger/l1l3Bridger.ts index 3e2c28ae0f..0ffecbe05f 100644 --- a/src/lib/assetBridger/l1l3Bridger.ts +++ b/src/lib/assetBridger/l1l3Bridger.ts @@ -18,33 +18,32 @@ import { IL1Teleporter__factory } from '../abi/factories/IL1Teleporter__factory' import { Address } from '../dataEntities/address' import { ArbSdkError } from '../dataEntities/errors' import { - L1Network, - L2Network, + ArbitrumNetwork, Teleporter, - l1Networks, - l2Networks, + assertArbitrumNetworkHasTokenBridge, + networks, } from '../dataEntities/networks' import { SignerOrProvider, SignerProviderUtils, } from '../dataEntities/signerOrProvider' -import { L1ToL2TransactionRequest } from '../dataEntities/transactionRequest' +import { ParentToChildTransactionRequest } from '../dataEntities/transactionRequest' import { - L1ToL2MessageReader, - L1ToL2MessageStatus, -} from '../message/L1ToL2Message' -import { L1ToL2MessageCreator } from '../message/L1ToL2MessageCreator' + ParentToChildMessageReader, + ParentToChildMessageStatus, +} from '../message/ParentToChildMessage' +import { ParentToChildMessageCreator } from '../message/ParentToChildMessageCreator' import { GasOverrides, - L1ToL2MessageGasEstimator, + ParentToChildMessageGasEstimator, PercentIncrease, -} from '../message/L1ToL2MessageGasEstimator' +} from '../message/ParentToChildMessageGasEstimator' import { - L1ContractCallTransaction, - L1ContractCallTransactionReceipt, - L1EthDepositTransactionReceipt, - L1TransactionReceipt, -} from '../message/L1Transaction' + ParentContractCallTransaction, + ParentContractCallTransactionReceipt, + ParentEthDepositTransactionReceipt, + ParentTransactionReceipt, +} from '../message/ParentTransaction' import { Erc20Bridger } from './erc20Bridger' import { Inbox__factory } from '../abi/factories/Inbox__factory' import { OmitTyped } from '../utils/types' @@ -179,8 +178,8 @@ export type Erc20DepositRequestParams = { export type TxReference = | { txHash: string } - | { tx: L1ContractCallTransaction } - | { txReceipt: L1ContractCallTransactionReceipt } + | { tx: ParentContractCallTransaction } + | { txReceipt: ParentContractCallTransactionReceipt } export type GetDepositStatusParams = { l1Provider: Provider @@ -192,25 +191,25 @@ export type Erc20DepositStatus = { /** * L1 to L2 token bridge message */ - l1l2TokenBridgeRetryable: L1ToL2MessageReader + l1l2TokenBridgeRetryable: ParentToChildMessageReader /** * L1 to L2 fee token bridge message */ - l1l2GasTokenBridgeRetryable: L1ToL2MessageReader | undefined + l1l2GasTokenBridgeRetryable: ParentToChildMessageReader | undefined /** * L2ForwarderFactory message */ - l2ForwarderFactoryRetryable: L1ToL2MessageReader + l2ForwarderFactoryRetryable: ParentToChildMessageReader /** * L2 to L3 token bridge message */ - l2l3TokenBridgeRetryable: L1ToL2MessageReader | undefined + l2l3TokenBridgeRetryable: ParentToChildMessageReader | undefined /** * Indicates that the L2ForwarderFactory call was front ran by another teleportation. * * This is true if: * - l1l2TokenBridgeRetryable status is REDEEMED; AND - * - l2ForwarderFactoryRetryable status is FUNDS_DEPOSITED_ON_L2; AND + * - l2ForwarderFactoryRetryable status is FUNDS_DEPOSITED_ON_CHAIN; AND * - L2Forwarder token balance is 0 * * The first teleportation with l2ForwarderFactoryRetryable redemption *after* this teleportation's l1l2TokenBridgeRetryable redemption @@ -260,11 +259,11 @@ export type EthDepositStatus = { /** * L1 to L2 message */ - l2Retryable: L1ToL2MessageReader + l2Retryable: ParentToChildMessageReader /** * L2 to L3 message */ - l3Retryable: L1ToL2MessageReader | undefined + l3Retryable: ParentToChildMessageReader | undefined /** * Whether the teleportation has completed */ @@ -275,31 +274,24 @@ export type EthDepositStatus = { * Base functionality for L1 to L3 bridging. */ class BaseL1L3Bridger { - public readonly l1Network: L1Network - public readonly l2Network: L2Network - public readonly l3Network: L2Network + public readonly l1Network: { chainId: number } + public readonly l2Network: ArbitrumNetwork + public readonly l3Network: ArbitrumNetwork public readonly defaultGasPricePercentIncrease: BigNumber = BigNumber.from(500) public readonly defaultGasLimitPercentIncrease: BigNumber = BigNumber.from(100) - constructor(l3Network: L2Network) { - const l2Network = l2Networks[l3Network.partnerChainID] + constructor(l3Network: ArbitrumNetwork) { + const l2Network = networks[l3Network.parentChainId] if (!l2Network) { throw new ArbSdkError( - `Unknown l2 network chain id: ${l3Network.partnerChainID}` + `Unknown arbitrum network chain id: ${l3Network.parentChainId}` ) } - const l1Network = l1Networks[l2Network.partnerChainID] - if (!l1Network) { - throw new ArbSdkError( - `Unknown l1 network chain id: ${l2Network.partnerChainID}` - ) - } - - this.l1Network = l1Network + this.l1Network = { chainId: l2Network.parentChainId } this.l2Network = l2Network this.l3Network = l3Network } @@ -309,7 +301,7 @@ class BaseL1L3Bridger { * @param sop */ protected async _checkL1Network(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.l1Network.chainID) + await SignerProviderUtils.checkNetworkMatches(sop, this.l1Network.chainId) } /** @@ -317,7 +309,7 @@ class BaseL1L3Bridger { * @param sop */ protected async _checkL2Network(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.l2Network.chainID) + await SignerProviderUtils.checkNetworkMatches(sop, this.l2Network.chainId) } /** @@ -325,7 +317,7 @@ class BaseL1L3Bridger { * @param sop */ protected async _checkL3Network(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.l3Network.chainID) + await SignerProviderUtils.checkNetworkMatches(sop, this.l3Network.chainId) } protected _percentIncrease(num: BigNumber, increase: BigNumber): BigNumber { @@ -345,12 +337,12 @@ class BaseL1L3Bridger { protected async _getTxFromTxRef( txRef: TxReference, provider: Provider - ): Promise { + ): Promise { if ('tx' in txRef) { return txRef.tx } - return L1TransactionReceipt.monkeyPatchContractCallWait( + return ParentTransactionReceipt.monkeyPatchContractCallWait( await provider.getTransaction(this._getTxHashFromTxRef(txRef)) ) } @@ -358,12 +350,12 @@ class BaseL1L3Bridger { protected async _getTxReceiptFromTxRef( txRef: TxReference, provider: Provider - ): Promise { + ): Promise { if ('txReceipt' in txRef) { return txRef.txReceipt } - return new L1ContractCallTransactionReceipt( + return new ParentContractCallTransactionReceipt( await provider.getTransactionReceipt(this._getTxHashFromTxRef(txRef)) ) } @@ -410,7 +402,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { */ protected _l1FeeTokenAddress: string | undefined - public constructor(l3Network: L2Network) { + public constructor(l3Network: ArbitrumNetwork) { super(l3Network) if (!this.l2Network.teleporter) { @@ -449,7 +441,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { let l1FeeTokenAddress: string | undefined try { - l1FeeTokenAddress = await this.l2Erc20Bridger.getL1ERC20Address( + l1FeeTokenAddress = await this.l2Erc20Bridger.getParentErc20Address( this.l2GasTokenAddress, l2Provider ) @@ -514,7 +506,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { erc20L1Address: string, l1Provider: Provider ): Promise { - return this.l2Erc20Bridger.getL2ERC20Address(erc20L1Address, l1Provider) + return this.l2Erc20Bridger.getChildErc20Address(erc20L1Address, l1Provider) } /** @@ -525,7 +517,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l1Provider: Provider, l2Provider: Provider ): Promise { - return this.l3Erc20Bridger.getL2ERC20Address( + return this.l3Erc20Bridger.getChildErc20Address( await this.getL2ERC20Address(erc20L1Address, l1Provider), l2Provider ) @@ -538,7 +530,10 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { erc20L1Address: string, l1Provider: Provider ): Promise { - return this.l2Erc20Bridger.getL1GatewayAddress(erc20L1Address, l1Provider) + return this.l2Erc20Bridger.getParentGatewayAddress( + erc20L1Address, + l1Provider + ) } /** @@ -550,7 +545,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l2Provider: Provider ): Promise { const l2Token = await this.getL2ERC20Address(erc20L1Address, l1Provider) - return this.l3Erc20Bridger.getL1GatewayAddress(l2Token, l2Provider) + return this.l3Erc20Bridger.getParentGatewayAddress(l2Token, l2Provider) } /** @@ -596,7 +591,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l1TokenAddress: string, l1Provider: Provider ): Promise { - return this.l2Erc20Bridger.l1TokenIsDisabled(l1TokenAddress, l1Provider) + return this.l2Erc20Bridger.isDepositDisabled(l1TokenAddress, l1Provider) } /** @@ -606,7 +601,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l2TokenAddress: string, l2Provider: Provider ): Promise { - return this.l3Erc20Bridger.l1TokenIsDisabled(l2TokenAddress, l2Provider) + return this.l3Erc20Bridger.isDepositDisabled(l2TokenAddress, l2Provider) } /** @@ -621,9 +616,9 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { const chainId = (await l1OrL2Provider.getNetwork()).chainId let predictor - if (chainId === this.l1Network.chainID) { + if (chainId === this.l1Network.chainId) { predictor = this.teleporter.l1Teleporter - } else if (chainId === this.l2Network.chainID) { + } else if (chainId === this.l2Network.chainId) { predictor = this.teleporter.l2ForwarderFactory } else { throw new ArbSdkError(`Unknown chain id: ${chainId}`) @@ -741,6 +736,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { | { l1Signer: Signer } ) ): Promise { + assertArbitrumNetworkHasTokenBridge(this.l2Network) + assertArbitrumNetworkHasTokenBridge(this.l3Network) const l1Provider = 'l1Provider' in params ? params.l1Provider : params.l1Signer.provider! @@ -772,12 +769,12 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { > = { l1Token: params.erc20L1Address, l3FeeTokenL1Addr: l1FeeToken, - l1l2Router: this.l2Network.tokenBridge.l1GatewayRouter, + l1l2Router: this.l2Network.tokenBridge.parentGatewayRouter, l2l3RouterOrInbox: l1FeeToken && getAddress(params.erc20L1Address) === getAddress(l1FeeToken) ? this.l3Network.ethBridge.inbox - : this.l3Network.tokenBridge.l1GatewayRouter, + : this.l3Network.tokenBridge.parentGatewayRouter, to: params.destinationAddress || from, amount: params.amount, } @@ -815,7 +812,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { overrides?: PayableOverrides }) | TxRequestParams - ): Promise { + ): Promise { await this._checkL1Network(params.l1Signer) const depositRequest = @@ -828,7 +825,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentTransactionReceipt.monkeyPatchContractCallWait(tx) } /** @@ -896,11 +893,11 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { await partialResult.l2ForwarderFactoryRetryable.getSuccessfulRedeem() const l2l3Message = - factoryRedeem.status === L1ToL2MessageStatus.REDEEMED + factoryRedeem.status === ParentToChildMessageStatus.REDEEMED ? ( - await new L1TransactionReceipt( - factoryRedeem.l2TxReceipt - ).getL1ToL2Messages(params.l3Provider) + await new ParentTransactionReceipt( + factoryRedeem.txReceipt + ).getParentToChildMessages(params.l3Provider) )[0] : undefined @@ -912,8 +909,9 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { const l1l2TokenBridgeRetryableStatus = await partialResult.l1l2TokenBridgeRetryable.status() if ( - l1l2TokenBridgeRetryableStatus === L1ToL2MessageStatus.REDEEMED && - factoryRedeem.status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + l1l2TokenBridgeRetryableStatus === ParentToChildMessageStatus.REDEEMED && + factoryRedeem.status === + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN ) { // decoding the factory call is the most reliable way to get the owner and other parameters const decodedFactoryCall = this._decodeCallForwarderCalldata( @@ -941,7 +939,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { ...partialResult, l2l3TokenBridgeRetryable: l2l3Message, l2ForwarderFactoryRetryableFrontRan, - completed: (await l2l3Message?.status()) === L1ToL2MessageStatus.REDEEMED, + completed: + (await l2l3Message?.status()) === ParentToChildMessageStatus.REDEEMED, } } @@ -995,7 +994,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { '0x' ) - const estimates = await new L1ToL2MessageGasEstimator( + const estimates = await new ParentToChildMessageGasEstimator( params.childProvider ).estimateAll( { @@ -1027,6 +1026,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l1Provider: Provider l2Provider: Provider }): Promise { + assertArbitrumNetworkHasTokenBridge(this.l2Network) + const parentGatewayAddress = await this.getL1L2GatewayAddress( params.l1Token, params.l1Provider @@ -1042,7 +1043,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { amount: BigNumber.from(params.amount), isWeth: getAddress(parentGatewayAddress) === - getAddress(this.l2Network.tokenBridge.l1WethGateway), + getAddress(this.l2Network.tokenBridge.parentWethGateway), }) } @@ -1057,6 +1058,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l1Provider: Provider l2Provider: Provider }): Promise { + assertArbitrumNetworkHasTokenBridge(this.l2Network) + if (params.l3FeeTokenL1Addr === this.skipL1GasTokenMagic) { return { gasLimit: BigNumber.from(0), @@ -1078,7 +1081,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { amount: params.feeTokenAmount, isWeth: getAddress(parentGatewayAddress) === - getAddress(this.l2Network.tokenBridge.l1WethGateway), + getAddress(this.l2Network.tokenBridge.parentWethGateway), }) } @@ -1119,6 +1122,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l3Provider: Provider l2ForwarderAddress: string }): Promise { + assertArbitrumNetworkHasTokenBridge(this.l3Network) + const teleportationType = this.teleportationType( params.partialTeleportParams ) @@ -1133,7 +1138,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { } } else if (teleportationType === TeleportationType.OnlyGasToken) { // we are bridging the fee token to l3, this will not go through the l2l3 token bridge, instead it's just a regular retryable - const estimate = await new L1ToL2MessageGasEstimator( + const estimate = await new ParentToChildMessageGasEstimator( params.l3Provider ).estimateAll( { @@ -1174,7 +1179,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { amount: BigNumber.from(params.partialTeleportParams.amount), isWeth: getAddress(parentGatewayAddress) === - getAddress(this.l3Network.tokenBridge.l1WethGateway), + getAddress(this.l3Network.tokenBridge.parentWethGateway), }) } } @@ -1403,15 +1408,15 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { } protected async _getL1ToL2Messages( - l1TxReceipt: L1ContractCallTransactionReceipt, + l1TxReceipt: ParentContractCallTransactionReceipt, l2Provider: Provider ) { - const l1l2Messages = await l1TxReceipt.getL1ToL2Messages(l2Provider) + const l1l2Messages = await l1TxReceipt.getParentToChildMessages(l2Provider) let partialResult: { - l1l2TokenBridgeRetryable: L1ToL2MessageReader - l1l2GasTokenBridgeRetryable: L1ToL2MessageReader | undefined - l2ForwarderFactoryRetryable: L1ToL2MessageReader + l1l2TokenBridgeRetryable: ParentToChildMessageReader + l1l2GasTokenBridgeRetryable: ParentToChildMessageReader | undefined + l2ForwarderFactoryRetryable: ParentToChildMessageReader } if (l1l2Messages.length === 2) { @@ -1436,7 +1441,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { * Bridge ETH from L1 to L3 using a double retryable ticket */ export class EthL1L3Bridger extends BaseL1L3Bridger { - constructor(l3Network: L2Network) { + constructor(l3Network: ArbitrumNetwork) { super(l3Network) if ( @@ -1461,7 +1466,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { } | { l1Signer: Signer } ) - ): Promise { + ): Promise { const l1Provider = 'l1Provider' in params ? params.l1Provider : params.l1Signer.provider! await this._checkL1Network(l1Provider) @@ -1474,33 +1479,35 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { const l3DestinationAddress = params.destinationAddress || from const l2RefundAddress = params.l2RefundAddress || from - const l3TicketRequest = await L1ToL2MessageCreator.getTicketCreationRequest( - { - to: l3DestinationAddress, - data: '0x', - from: new Address(from).applyAlias().value, - l2CallValue: BigNumber.from(params.amount), - excessFeeRefundAddress: l3DestinationAddress, - callValueRefundAddress: l3DestinationAddress, - }, - params.l2Provider, - params.l3Provider, - params.l3TicketGasOverrides - ) + const l3TicketRequest = + await ParentToChildMessageCreator.getTicketCreationRequest( + { + to: l3DestinationAddress, + data: '0x', + from: new Address(from).applyAlias().value, + l2CallValue: BigNumber.from(params.amount), + excessFeeRefundAddress: l3DestinationAddress, + callValueRefundAddress: l3DestinationAddress, + }, + params.l2Provider, + params.l3Provider, + params.l3TicketGasOverrides + ) - const l2TicketRequest = await L1ToL2MessageCreator.getTicketCreationRequest( - { - from, - to: l3TicketRequest.txRequest.to, - l2CallValue: BigNumber.from(l3TicketRequest.txRequest.value), - data: ethers.utils.hexlify(l3TicketRequest.txRequest.data), - excessFeeRefundAddress: l2RefundAddress, - callValueRefundAddress: l2RefundAddress, - }, - l1Provider, - params.l2Provider, - params.l2TicketGasOverrides - ) + const l2TicketRequest = + await ParentToChildMessageCreator.getTicketCreationRequest( + { + from, + to: l3TicketRequest.txRequest.to, + l2CallValue: BigNumber.from(l3TicketRequest.txRequest.value), + data: ethers.utils.hexlify(l3TicketRequest.txRequest.data), + excessFeeRefundAddress: l2RefundAddress, + callValueRefundAddress: l2RefundAddress, + }, + l1Provider, + params.l2Provider, + params.l2TicketGasOverrides + ) return l2TicketRequest } @@ -1515,7 +1522,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { overrides?: PayableOverrides }) | TxRequestParams - ): Promise { + ): Promise { await this._checkL1Network(params.l1Signer) const depositRequest = @@ -1528,7 +1535,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { ...params.overrides, }) - return L1TransactionReceipt.monkeyPatchContractCallWait(tx) + return ParentTransactionReceipt.monkeyPatchContractCallWait(tx) } /** @@ -1577,11 +1584,11 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { ) const l1l2Message = ( - await l1TxReceipt.getL1ToL2Messages(params.l2Provider) + await l1TxReceipt.getParentToChildMessages(params.l2Provider) )[0] const l1l2Redeem = await l1l2Message.getSuccessfulRedeem() - if (l1l2Redeem.status != L1ToL2MessageStatus.REDEEMED) { + if (l1l2Redeem.status != ParentToChildMessageStatus.REDEEMED) { return { l2Retryable: l1l2Message, l3Retryable: undefined, @@ -1590,9 +1597,9 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { } const l2l3Message = ( - await new L1EthDepositTransactionReceipt( - l1l2Redeem.l2TxReceipt - ).getL1ToL2Messages(params.l3Provider) + await new ParentEthDepositTransactionReceipt( + l1l2Redeem.txReceipt + ).getParentToChildMessages(params.l3Provider) )[0] if (l2l3Message === undefined) { @@ -1602,7 +1609,8 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { return { l2Retryable: l1l2Message, l3Retryable: l2l3Message, - completed: (await l2l3Message.status()) === L1ToL2MessageStatus.REDEEMED, + completed: + (await l2l3Message.status()) === ParentToChildMessageStatus.REDEEMED, } } diff --git a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts index 89abe126fb..199b12eac2 100644 --- a/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts +++ b/tests/integration/custom-fee-token/customFeeTokenTestHelpers.ts @@ -15,7 +15,7 @@ const arbProvider = () => new StaticJsonRpcProvider(config.arbUrl) const localNetworks = () => getLocalNetworksFromFile() export function isArbitrumNetworkWithCustomFeeToken(): boolean { - const nt = localNetworks().l2Network.nativeToken + const nt = localNetworks().l3Network?.nativeToken return typeof nt !== 'undefined' && nt !== ethers.constants.AddressZero } @@ -35,7 +35,7 @@ export async function testSetup() { export async function fundParentCustomFeeToken( parentSignerOrAddress: Signer | string ) { - const nativeToken = localNetworks().l2Network.nativeToken + const nativeToken = localNetworks().l3Network?.nativeToken const address = typeof parentSignerOrAddress === 'string' ? parentSignerOrAddress @@ -69,7 +69,7 @@ export async function getParentCustomFeeTokenAllowance( owner: string, spender: string ) { - const nativeToken = localNetworks().l2Network.nativeToken + const nativeToken = localNetworks().l3Network?.nativeToken const nativeTokenContract = ERC20__factory.connect( nativeToken!, ethProvider() diff --git a/tests/integration/l1l3Bridger.test.ts b/tests/integration/l1l3Bridger.test.ts index 8ffe355296..f61cb37cfb 100644 --- a/tests/integration/l1l3Bridger.test.ts +++ b/tests/integration/l1l3Bridger.test.ts @@ -1,31 +1,40 @@ -import { getSigner, testSetup } from '../../scripts/testSetup' +import { + getLocalNetworksFromFile, + getSigner, + testSetup, +} from '../../scripts/testSetup' import { Address, Erc20Bridger, Erc20L1L3Bridger, - L1ToL2MessageStatus, - L1ToL2MessageWriter, - L2Network, + ParentToChildMessageStatus, + ParentToChildMessageWriter, + ArbitrumNetwork, } from '../../src' import { L2ForwarderContractsDeployer__factory } from '../../src/lib/abi/factories/L2ForwarderContractsDeployer__factory' import { TestERC20__factory } from '../../src/lib/abi/factories/TestERC20__factory' import { TestERC20 } from '../../src/lib/abi/TestERC20' import { AeWETH__factory } from '../../src/lib/abi/factories/AeWETH__factory' import { L1Teleporter__factory } from '../../src/lib/abi/factories/L1Teleporter__factory' -import { fundL1, fundL2, skipIfMainnet } from './testHelpers' +import { fundParentSigner, fundChildSigner, skipIfMainnet } from './testHelpers' import { BigNumber, Signer, Wallet, ethers, providers, utils } from 'ethers' import { Erc20DepositRequestParams, EthL1L3Bridger, } from '../../src/lib/assetBridger/l1l3Bridger' import { assert, expect } from 'chai' -import { isL2NetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' +import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' import { ERC20__factory } from '../../src/lib/abi/factories/ERC20__factory' import { Deferrable } from 'ethers/lib/utils' import { itOnlyWhenCustomGasToken, itOnlyWhenEth, } from './custom-fee-token/mochaExtensions' +import { + assertArbitrumNetworkHasTokenBridge, + getArbitrumNetwork, + registerCustomArbitrumNetwork, +} from '../../src/lib/dataEntities/networks' async function expectPromiseToReject( promise: Promise, @@ -120,10 +129,10 @@ async function deployTeleportContracts(l1Signer: Signer, l2Signer: Signer) { async function fundActualL1CustomFeeToken( l1Signer: Signer, l2FeeToken: string, - l2Network: L2Network, + l2Network: ArbitrumNetwork, l2Provider: providers.Provider ) { - const l1FeeToken = await new Erc20Bridger(l2Network).getL1ERC20Address( + const l1FeeToken = await new Erc20Bridger(l2Network).getParentErc20Address( l2FeeToken, l2Provider ) @@ -147,8 +156,8 @@ describe('L1 to L3 Bridging', () => { if (process.env.ORBIT_TEST !== '1') return // let setup: Unwrap> - let l2Network: L2Network - let l3Network: L2Network + let l2Network: ArbitrumNetwork + let l3Network: ArbitrumNetwork let l1Signer: ethers.Signer let l2Signer: ethers.Signer @@ -200,8 +209,14 @@ describe('L1 to L3 Bridging', () => { const setup = await testSetup() - l2Network = setup.l1Network as L2Network - l3Network = setup.l2Network + try { + l2Network = await getArbitrumNetwork(setup.parentDeployer) + } catch (err) { + const { l2Network: childChain } = getLocalNetworksFromFile() + l2Network = registerCustomArbitrumNetwork(childChain) + } + + l3Network = setup.childChain l1Signer = getSigner( new ethers.providers.JsonRpcProvider(process.env['ETH_URL']), @@ -218,11 +233,11 @@ describe('L1 to L3 Bridging', () => { ) // fund signers on L1 and L2 - await fundL1(l1Signer, ethers.utils.parseEther('10')) - await fundL2(l2Signer, ethers.utils.parseEther('10')) - await fundL2(l3Signer, ethers.utils.parseEther('10')) + await fundParentSigner(l1Signer, ethers.utils.parseEther('10')) + await fundChildSigner(l2Signer, ethers.utils.parseEther('10')) + await fundChildSigner(l3Signer, ethers.utils.parseEther('10')) - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { await fundActualL1CustomFeeToken( l1Signer, l3Network.nativeToken!, @@ -364,7 +379,7 @@ describe('L1 to L3 Bridging', () => { expect(l1l3Bridger.l2GasTokenAddress).to.eq(l3Network.nativeToken) // make sure l1 token maps to l2 token expect( - await new Erc20Bridger(l2Network).getL2ERC20Address( + await new Erc20Bridger(l2Network).getChildErc20Address( (await l1l3Bridger.getGasTokenOnL1( l1Signer.provider!, l2Signer.provider! @@ -378,7 +393,9 @@ describe('L1 to L3 Bridging', () => { itOnlyWhenCustomGasToken( 'should throw getting l1 gas token address when it is unavailable', async () => { - const networkCopy = JSON.parse(JSON.stringify(l3Network)) as L2Network + const networkCopy = JSON.parse( + JSON.stringify(l3Network) + ) as ArbitrumNetwork networkCopy.nativeToken = ethers.utils.hexlify( ethers.utils.randomBytes(20) ) @@ -456,30 +473,32 @@ describe('L1 to L3 Bridging', () => { }) it('getL2ERC20Address', async () => { + assertArbitrumNetworkHasTokenBridge(l2Network) // use weth to test, since we already know its addresses - const l1Weth = l2Network.tokenBridge.l1Weth - const l2Weth = l2Network.tokenBridge.l2Weth + const parentWeth = l2Network.tokenBridge.parentWeth + const childWeth = l2Network.tokenBridge.childWeth const ans = await l1l3Bridger.getL2ERC20Address( - l1Weth, + parentWeth, l1Signer.provider! ) - expect(ans).to.eq(l2Weth) + expect(ans).to.eq(childWeth) }) it('getL1L2GatewayAddress', async () => { + assertArbitrumNetworkHasTokenBridge(l2Network) // test weth and default gateway - const l1Weth = l2Network.tokenBridge.l1Weth - const l1l2WethGateway = l2Network.tokenBridge.l1WethGateway + const parentWeth = l2Network.tokenBridge.parentWeth + const l1l2WethGateway = l2Network.tokenBridge.parentWethGateway const wethAns = await l1l3Bridger.getL1L2GatewayAddress( - l1Weth, + parentWeth, l1Signer.provider! ) expect(wethAns).to.eq(l1l2WethGateway) // test default gateway - const l1l2Gateway = l2Network.tokenBridge.l1ERC20Gateway + const l1l2Gateway = l2Network.tokenBridge.parentErc20Gateway const defaultAns = await l1l3Bridger.getL1L2GatewayAddress( l1Token.address, l1Signer.provider! @@ -488,11 +507,14 @@ describe('L1 to L3 Bridging', () => { }) itOnlyWhenEth('getL3ERC20Address', async () => { + assertArbitrumNetworkHasTokenBridge(l2Network) + assertArbitrumNetworkHasTokenBridge(l3Network) + // use weth to test, since we already know its addresses - const l1Weth = l2Network.tokenBridge.l1Weth - const l3Weth = l3Network.tokenBridge.l2Weth + const parentWeth = l2Network.tokenBridge.parentWeth + const l3Weth = l3Network.tokenBridge.childWeth const ans = await l1l3Bridger.getL3ERC20Address( - l1Weth, + parentWeth, l1Signer.provider!, l2Signer.provider! ) @@ -500,12 +522,15 @@ describe('L1 to L3 Bridging', () => { }) itOnlyWhenEth('getL2L3GatewayAddress', async () => { + assertArbitrumNetworkHasTokenBridge(l2Network) + assertArbitrumNetworkHasTokenBridge(l3Network) + // test weth and default gateway - const l1Weth = l2Network.tokenBridge.l1Weth - const l2l3WethGateway = l3Network.tokenBridge.l1WethGateway + const parentWeth = l2Network.tokenBridge.parentWeth + const l2l3WethGateway = l3Network.tokenBridge.parentWethGateway const wethAns = await l1l3Bridger.getL2L3GatewayAddress( - l1Weth, + parentWeth, l1Signer.provider!, l2Signer.provider! ) @@ -513,7 +538,7 @@ describe('L1 to L3 Bridging', () => { expect(wethAns).to.eq(l2l3WethGateway) // test default gateway - const l2l3Gateway = l3Network.tokenBridge.l1ERC20Gateway + const l2l3Gateway = l3Network.tokenBridge.parentErc20Gateway const defaultAns = await l1l3Bridger.getL2L3GatewayAddress( l1Token.address, l1Signer.provider!, @@ -543,7 +568,7 @@ describe('L1 to L3 Bridging', () => { it('functions should be guarded by check*Network', async () => { // l1FeeTokenAddress - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { await checkNetworkGuards( true, true, @@ -654,8 +679,8 @@ describe('L1 to L3 Bridging', () => { } ) - // getApproveFeeTokenRequest - if (isL2NetworkWithCustomFeeToken()) { + // getApproveGasTokenRequest + if (isArbitrumNetworkWithCustomFeeToken()) { await checkNetworkGuards( true, true, @@ -670,7 +695,7 @@ describe('L1 to L3 Bridging', () => { ) } - // approveFeeToken + // approveGasToken await checkNetworkGuards( true, false, @@ -775,7 +800,7 @@ describe('L1 to L3 Bridging', () => { return ( (await status.l2l3TokenBridgeRetryable?.status()) === - L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2 + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN ) }, 1000) @@ -788,12 +813,12 @@ describe('L1 to L3 Bridging', () => { }) const ticket = status.l2l3TokenBridgeRetryable! - const messageWriter = new L1ToL2MessageWriter( + const messageWriter = new ParentToChildMessageWriter( l3Signer, - l3Network.chainID, + l3Network.chainId, ticket.sender, ticket.messageNumber, - ticket.l1BaseFee, + ticket.parentBaseFee, ticket.messageData ) await (await messageWriter.redeem({ gasLimit: 20_000_000 })).wait() @@ -819,7 +844,7 @@ describe('L1 to L3 Bridging', () => { l1Signer, }) - if (isL2NetworkWithCustomFeeToken()) { + if (isArbitrumNetworkWithCustomFeeToken()) { assert(depositTxRequest.gasTokenAmount.gt('0')) // approve fee token await ( @@ -889,9 +914,10 @@ describe('L1 to L3 Bridging', () => { }) it('happy path weth', async () => { + assertArbitrumNetworkHasTokenBridge(l2Network) const l3Recipient = ethers.utils.hexlify(ethers.utils.randomBytes(20)) const weth = AeWETH__factory.connect( - l2Network.tokenBridge.l1Weth, + l2Network.tokenBridge.parentWeth, l1Signer ) @@ -908,7 +934,7 @@ describe('L1 to L3 Bridging', () => { ).wait() const depositParams: Erc20DepositRequestParams = { - erc20L1Address: l2Network.tokenBridge.l1Weth, + erc20L1Address: l2Network.tokenBridge.parentWeth, destinationAddress: l3Recipient, amount, l2Provider: l2Signer.provider!, From 2eb6ad2e8afee3f266217a734c55c576f50b2e35 Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 9 Jul 2024 11:56:33 +0200 Subject: [PATCH 50/74] feat: rename getFirstBlockForL1Block properties (#486) --- src/lib/inbox/inbox.ts | 2 +- src/lib/message/ChildToParentMessageNitro.ts | 18 +++--- src/lib/utils/lib.ts | 58 +++++++++---------- ....test.ts => childBlocksForL1Block.test.ts} | 44 +++++++------- 4 files changed, 61 insertions(+), 61 deletions(-) rename tests/unit/{childBlocksForParentBlock.test.ts => childBlocksForL1Block.test.ts} (82%) diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index bfd66ed6b2..a2f4c88ac1 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -106,7 +106,7 @@ export class InboxTools { // alternatively we use binary search to get the nearest block const _blockNum = ( await getBlockRangesForL1Block({ - provider: this.parentProvider as JsonRpcProvider, + arbitrumProvider: this.parentProvider as JsonRpcProvider, forL1Block: blockNumber - 1, allowGreater: true, }) diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index e71ab5fcb7..8d8698dc07 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -77,12 +77,12 @@ const mutex = new Mutex() function getChildBlockRangeCacheKey({ childChainId, - parentBlockNumber, + l1BlockNumber, }: { childChainId: number - parentBlockNumber: number + l1BlockNumber: number }) { - return `${childChainId}-${parentBlockNumber}` + return `${childChainId}-${l1BlockNumber}` } function setChildBlockRangeCache(key: string, value: (number | undefined)[]) { @@ -92,16 +92,16 @@ function setChildBlockRangeCache(key: string, value: (number | undefined)[]) { async function getBlockRangesForL1BlockWithCache({ parentProvider, childProvider, - forParentBlock, + forL1Block, }: { parentProvider: JsonRpcProvider childProvider: JsonRpcProvider - forParentBlock: number + forL1Block: number }) { const childChainId = (await childProvider.getNetwork()).chainId const key = getChildBlockRangeCacheKey({ childChainId, - parentBlockNumber: forParentBlock, + l1BlockNumber: forL1Block, }) if (childBlockRangeCache[key]) { @@ -119,8 +119,8 @@ async function getBlockRangesForL1BlockWithCache({ try { const childBlockRange = await getBlockRangesForL1Block({ - forL1Block: forParentBlock, - provider: parentProvider, + forL1Block, + arbitrumProvider: parentProvider, }) setChildBlockRangeCache(key, childBlockRange) } finally { @@ -348,7 +348,7 @@ export class ChildToParentMessageReaderNitro extends ChildToParentMessageNitro { const l2BlockRange = await getBlockRangesForL1BlockWithCache({ parentProvider: this.parentProvider as JsonRpcProvider, childProvider: childProvider as JsonRpcProvider, - forParentBlock: createdAtBlock.toNumber(), + forL1Block: createdAtBlock.toNumber(), }) const startBlock = l2BlockRange[0] const endBlock = l2BlockRange[1] diff --git a/src/lib/utils/lib.ts b/src/lib/utils/lib.ts index a195ed23a2..baaab9a0af 100644 --- a/src/lib/utils/lib.ts +++ b/src/lib/utils/lib.ts @@ -68,37 +68,37 @@ export const isArbitrumChain = async (provider: Provider): Promise => { } type GetFirstBlockForL1BlockProps = { + arbitrumProvider: JsonRpcProvider forL1Block: number - provider: JsonRpcProvider allowGreater?: boolean - minL2Block?: number - maxL2Block?: number | 'latest' + minArbitrumBlock?: number + maxArbitrumBlock?: number | 'latest' } /** - * This function performs a binary search to find the first L2 block that corresponds to a given L1 block number. + * This function performs a binary search to find the first Arbitrum block that corresponds to a given L1 block number. * The function returns a Promise that resolves to a number if a block is found, or undefined otherwise. * - * @param {JsonRpcProvider} provider - The L2 provider to use for the search. + * @param {JsonRpcProvider} arbitrumProvider - The Arbitrum provider to use for the search. * @param {number} forL1Block - The L1 block number to search for. * @param {boolean} [allowGreater=false] - Whether to allow the search to go past the specified `forL1Block`. - * @param {number|string} minL2Block - The minimum L2 block number to start the search from. Cannot be below the network's Nitro genesis block. - * @param {number|string} [maxL2Block='latest'] - The maximum L2 block number to end the search at. Can be a `number` or `'latest'`. `'latest'` is the current block. + * @param {number|string} minArbitrumBlock - The minimum Arbitrum block number to start the search from. Cannot be below the network's Nitro genesis block. + * @param {number|string} [maxArbitrumBlock='latest'] - The maximum Arbitrum block number to end the search at. Can be a `number` or `'latest'`. `'latest'` is the current block. * @returns {Promise} - A Promise that resolves to a number if a block is found, or undefined otherwise. */ export async function getFirstBlockForL1Block({ - provider, + arbitrumProvider, forL1Block, allowGreater = false, - minL2Block, - maxL2Block = 'latest', + minArbitrumBlock, + maxArbitrumBlock = 'latest', }: GetFirstBlockForL1BlockProps): Promise { - if (!(await isArbitrumChain(provider))) { + if (!(await isArbitrumChain(arbitrumProvider))) { // Provider is L1. return forL1Block } - const arbProvider = new ArbitrumProvider(provider) + const arbProvider = new ArbitrumProvider(arbitrumProvider) const currentArbBlock = await arbProvider.getBlockNumber() const arbitrumChainId = (await arbProvider.getNetwork()).chainId const nitroGenesisBlock = getNitroGenesisBlock(arbitrumChainId) @@ -108,28 +108,28 @@ export async function getFirstBlockForL1Block({ return l1BlockNumber } - if (!minL2Block) { - minL2Block = nitroGenesisBlock + if (!minArbitrumBlock) { + minArbitrumBlock = nitroGenesisBlock } - if (maxL2Block === 'latest') { - maxL2Block = currentArbBlock + if (maxArbitrumBlock === 'latest') { + maxArbitrumBlock = currentArbBlock } - if (minL2Block >= maxL2Block) { + if (minArbitrumBlock >= maxArbitrumBlock) { throw new Error( - `'minL2Block' (${minL2Block}) must be lower than 'maxL2Block' (${maxL2Block}).` + `'minArbitrumBlock' (${minArbitrumBlock}) must be lower than 'maxArbitrumBlock' (${maxArbitrumBlock}).` ) } - if (minL2Block < nitroGenesisBlock) { + if (minArbitrumBlock < nitroGenesisBlock) { throw new Error( - `'minL2Block' (${minL2Block}) cannot be below the Nitro genesis block, which is ${nitroGenesisBlock} for the current network.` + `'minArbitrumBlock' (${minArbitrumBlock}) cannot be below the Nitro genesis block, which is ${nitroGenesisBlock} for the current network.` ) } - let start = minL2Block - let end = maxL2Block + let start = minArbitrumBlock + let end = maxArbitrumBlock let resultForTargetBlock let resultForGreaterBlock @@ -150,7 +150,7 @@ export async function getFirstBlockForL1Block({ end = mid - 1 } - // Stores last valid L2 block corresponding to the current, or greater, L1 block. + // Stores last valid Arbitrum block corresponding to the current, or greater, L1 block. if (l1Block) { if (l1Block === forL1Block) { resultForTargetBlock = mid @@ -167,11 +167,11 @@ export async function getFirstBlockForL1Block({ export const getBlockRangesForL1Block = async ( props: GetFirstBlockForL1BlockProps ) => { - const arbProvider = new ArbitrumProvider(props.provider) - const currentL2Block = await arbProvider.getBlockNumber() + const arbProvider = new ArbitrumProvider(props.arbitrumProvider) + const currentArbitrumBlock = await arbProvider.getBlockNumber() - if (!props.maxL2Block || props.maxL2Block === 'latest') { - props.maxL2Block = currentL2Block + if (!props.maxArbitrumBlock || props.maxArbitrumBlock === 'latest') { + props.maxArbitrumBlock = currentArbitrumBlock } const result = await Promise.all([ @@ -189,9 +189,9 @@ export const getBlockRangesForL1Block = async ( } if (result[0] && result[1]) { - // If both results are defined, we can assume that the previous L2 block for the end of the range will be for 'forL1Block'. + // If both results are defined, we can assume that the previous Arbitrum block for the end of the range will be for 'forL1Block'. return [result[0], result[1] - 1] } - return [result[0], props.maxL2Block] + return [result[0], props.maxArbitrumBlock] } diff --git a/tests/unit/childBlocksForParentBlock.test.ts b/tests/unit/childBlocksForL1Block.test.ts similarity index 82% rename from tests/unit/childBlocksForParentBlock.test.ts rename to tests/unit/childBlocksForL1Block.test.ts index 023e669cc1..f1004636c6 100644 --- a/tests/unit/childBlocksForParentBlock.test.ts +++ b/tests/unit/childBlocksForL1Block.test.ts @@ -2,8 +2,8 @@ import { BigNumber } from 'ethers' import { expect } from 'chai' import { JsonRpcProvider } from '@ethersproject/providers' import { - getBlockRangesForL1Block as getBlockRangesForParentBlock, - getFirstBlockForL1Block as getFirstBlockForParentBlock, + getBlockRangesForL1Block, + getFirstBlockForL1Block, } from '../../src/lib/utils/lib' import { ArbitrumProvider } from '../../src/lib/utils/arbProvider' import { ArbBlock } from '../../src/lib/dataEntities/rpc' @@ -74,22 +74,22 @@ describe('Child blocks lookup for a Parent block', () => { } it('successfully searches for an Child block range', async function () { - const childBlocks = await getBlockRangesForParentBlock({ - provider: arbProvider, + const childBlocks = await getBlockRangesForL1Block({ + arbitrumProvider: arbProvider, forL1Block: 17926532, // Expected result: 121907680. Narrows down the range to speed up the search. - minL2Block: 121800000, - maxL2Block: 122000000, + minArbitrumBlock: 121800000, + maxArbitrumBlock: 122000000, }) await validateChildBlocks({ childBlocks, childBlocksCount: 2 }) }) it('fails to search for an Child block range', async function () { - const childBlocks = await getBlockRangesForParentBlock({ - provider: arbProvider, + const childBlocks = await getBlockRangesForL1Block({ + arbitrumProvider: arbProvider, forL1Block: 17926533, - minL2Block: 121800000, - maxL2Block: 122000000, + minArbitrumBlock: 121800000, + maxArbitrumBlock: 122000000, }) await validateChildBlocks({ childBlocks, @@ -100,12 +100,12 @@ describe('Child blocks lookup for a Parent block', () => { it('successfully searches for the first Child block', async function () { const childBlocks = [ - await getFirstBlockForParentBlock({ - provider: arbProvider, + await getFirstBlockForL1Block({ + arbitrumProvider: arbProvider, forL1Block: 17926532, // Expected result: 121907680. Narrows down the range to speed up the search. - minL2Block: 121800000, - maxL2Block: 122000000, + minArbitrumBlock: 121800000, + maxArbitrumBlock: 122000000, }), ] await validateChildBlocks({ childBlocks, childBlocksCount: 1 }) @@ -113,12 +113,12 @@ describe('Child blocks lookup for a Parent block', () => { it('fails to search for the first Child block, while not using `allowGreater` flag', async function () { const childBlocks = [ - await getFirstBlockForParentBlock({ - provider: arbProvider, + await getFirstBlockForL1Block({ + arbitrumProvider: arbProvider, forL1Block: 17926533, allowGreater: false, - minL2Block: 121800000, - maxL2Block: 122000000, + minArbitrumBlock: 121800000, + maxArbitrumBlock: 122000000, }), ] await validateChildBlocks({ @@ -130,13 +130,13 @@ describe('Child blocks lookup for a Parent block', () => { it('successfully searches for the first Child block, while using `allowGreater` flag', async function () { const childBlocks = [ - await getFirstBlockForParentBlock({ - provider: arbProvider, + await getFirstBlockForL1Block({ + arbitrumProvider: arbProvider, forL1Block: 17926533, allowGreater: true, // Expected result: 121907740. Narrows down the range to speed up the search. - minL2Block: 121800000, - maxL2Block: 122000000, + minArbitrumBlock: 121800000, + maxArbitrumBlock: 122000000, }), ] await validateChildBlocks({ childBlocks, childBlocksCount: 1 }) From 0e8f94f447a5cea351e4ce0672e8a8988eb60f83 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 9 Jul 2024 12:00:22 +0200 Subject: [PATCH 51/74] chore: bump version to 4.0.0-alpha.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b5a808a5f..25e875f7f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.5", + "version": "4.0.0-alpha.6", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From c3c024e298a24a8c9121e756cbb7671189b48c63 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 9 Jul 2024 15:44:40 +0200 Subject: [PATCH 52/74] feat: export more stuff (#505) --- src/index.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4ff7ff2215..d4172ac5ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,6 +32,10 @@ export { ChildToParentMessageReader, } from './lib/message/ChildToParentMessage' export { + ParentEthDepositTransaction, + ParentEthDepositTransactionReceipt, + ParentContractCallTransaction, + ParentContractCallTransactionReceipt, ParentContractTransaction, ParentTransactionReceipt, } from './lib/message/ParentTransaction' @@ -62,10 +66,19 @@ export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' export { ArbitrumProvider } from './lib/utils/arbProvider' export * as constants from './lib/dataEntities/constants' -export { ChildToParentMessageStatus } from './lib/dataEntities/message' +export { + ChildToParentMessageStatus, + RetryableMessageParams, +} from './lib/dataEntities/message' export { RetryableData, RetryableDataTools, } from './lib/dataEntities/retryableData' - +export { EventArgs } from './lib/dataEntities/event' export { Address } from './lib/dataEntities/address' +export { + ParentToChildTransactionRequest, + isParentToChildTransactionRequest, + ChildToParentTransactionRequest, + isChildToParentTransactionRequest, +} from './lib/dataEntities/transactionRequest' From ab4d378e5244653849bcd237166a41c6f06f30d8 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 9 Jul 2024 15:54:55 +0200 Subject: [PATCH 53/74] feat: clean up names (#504) --- src/lib/assetBridger/l1l3Bridger.ts | 14 +++++++------- src/lib/dataEntities/networks.ts | 18 +++++++++--------- src/lib/message/ParentToChildMessage.ts | 24 ++++++++++++------------ tests/integration/eth.test.ts | 2 +- tests/integration/l1l3Bridger.test.ts | 22 +++++++++++----------- tests/integration/standarderc20.test.ts | 10 +++++----- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/lib/assetBridger/l1l3Bridger.ts b/src/lib/assetBridger/l1l3Bridger.ts index 0ffecbe05f..4063e06225 100644 --- a/src/lib/assetBridger/l1l3Bridger.ts +++ b/src/lib/assetBridger/l1l3Bridger.ts @@ -209,7 +209,7 @@ export type Erc20DepositStatus = { * * This is true if: * - l1l2TokenBridgeRetryable status is REDEEMED; AND - * - l2ForwarderFactoryRetryable status is FUNDS_DEPOSITED_ON_CHAIN; AND + * - l2ForwarderFactoryRetryable status is FUNDS_DEPOSITED_ON_CHILD; AND * - L2Forwarder token balance is 0 * * The first teleportation with l2ForwarderFactoryRetryable redemption *after* this teleportation's l1l2TokenBridgeRetryable redemption @@ -502,7 +502,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { /** * Get the corresponding L2 token address for the provided L1 token */ - public getL2ERC20Address( + public getL2Erc20Address( erc20L1Address: string, l1Provider: Provider ): Promise { @@ -512,13 +512,13 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { /** * Get the corresponding L3 token address for the provided L1 token */ - public async getL3ERC20Address( + public async getL3Erc20Address( erc20L1Address: string, l1Provider: Provider, l2Provider: Provider ): Promise { return this.l3Erc20Bridger.getChildErc20Address( - await this.getL2ERC20Address(erc20L1Address, l1Provider), + await this.getL2Erc20Address(erc20L1Address, l1Provider), l2Provider ) } @@ -544,7 +544,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { l1Provider: Provider, l2Provider: Provider ): Promise { - const l2Token = await this.getL2ERC20Address(erc20L1Address, l1Provider) + const l2Token = await this.getL2Erc20Address(erc20L1Address, l1Provider) return this.l3Erc20Bridger.getParentGatewayAddress(l2Token, l2Provider) } @@ -911,7 +911,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { if ( l1l2TokenBridgeRetryableStatus === ParentToChildMessageStatus.REDEEMED && factoryRedeem.status === - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD ) { // decoding the factory call is the most reliable way to get the owner and other parameters const decodedFactoryCall = this._decodeCallForwarderCalldata( @@ -1169,7 +1169,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { parentProvider: params.l2Provider, childProvider: params.l3Provider, parentGasPrice: params.l2GasPrice, - parentErc20Address: await this.getL2ERC20Address( + parentErc20Address: await this.getL2Erc20Address( params.partialTeleportParams.l1Token, params.l1Provider ), diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index c7048d1ccd..bd0abdd7df 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -112,7 +112,7 @@ export interface TokenBridge { parentProxyAdmin: string childProxyAdmin: string parentMultiCall: string - childMulticall: string + childMultiCall: string } /** @@ -168,7 +168,7 @@ const mainnetTokenBridge: TokenBridge = { parentProxyAdmin: '0x9aD46fac0Cf7f790E5be05A0F15223935A0c0aDa', childProxyAdmin: '0xd570aCE65C43af47101fC6250FD6fC63D1c22a86', parentMultiCall: '0x5ba1e12693dc8f9c48aad8770482f4739beed696', - childMulticall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', + childMultiCall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', } const mainnetETHBridge: EthBridge = { @@ -224,7 +224,7 @@ export const networks: Networks = { childCustomGateway: '0xbf544970E6BD77b21C6492C281AB60d0770451F4', childErc20Gateway: '0xcF9bAb7e53DDe48A6DC4f286CB14e05298799257', childGatewayRouter: '0x21903d3F8176b1a0c17E953Cd896610Be9fFDFa8', - childMulticall: '0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86', + childMultiCall: '0x5e1eE626420A354BbC9a95FeA1BAd4492e3bcB86', childProxyAdmin: '0xada790b026097BfB36a5ed696859b97a96CEd92C', childWeth: '0x722E8BdD2ce80A4422E880164f2079488e115365', childWethGateway: '0x7626841cB6113412F9c88D3ADC720C9FAC88D9eD', @@ -258,7 +258,7 @@ export const networks: Networks = { childCustomGateway: '0x8Ca1e1AC0f260BC4dA7Dd60aCA6CA66208E642C5', childErc20Gateway: '0x6e244cD02BBB8a6dbd7F626f05B2ef82151Ab502', childGatewayRouter: '0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7', - childMulticall: '0xA115146782b7143fAdB3065D86eACB54c169d092', + childMultiCall: '0xA115146782b7143fAdB3065D86eACB54c169d092', childProxyAdmin: '0x715D99480b77A8d9D603638e593a539E21345FdF', childWeth: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73', childWethGateway: '0xCFB1f08A4852699a979909e22c30263ca249556D', @@ -292,7 +292,7 @@ export const networks: Networks = { childCustomGateway: '0xF6dbB0e312dF4652d59ce405F5E00CC3430f19c5', childErc20Gateway: '0xe027f79CE40a1eF8e47B51d0D46Dc4ea658C5860', childGatewayRouter: '0x4c3a1f7011F02Fe4769fC704359c3696a6A60D89', - childMulticall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3', + childMultiCall: '0xEb4A260FD16aaf18c04B1aeaDFE20E622e549bd3', childProxyAdmin: '0xE914c0d417E8250d0237d2F4827ed3612e6A9C3B', childWeth: '0x61Dc4b961D2165623A25EB775260785fE78BD37C', childWethGateway: '0x7021B4Edd9f047772242fc948441d6e0b9121175', @@ -322,7 +322,7 @@ export const networks: Networks = { childCustomGateway: '0xE102D94df0179082B39Ddcad58c9430dedc89aE3', childErc20Gateway: '0xCf3a4aF3c48Ba19c5FccFB44FA3E3A0F2A6e60dA', childGatewayRouter: '0xD60FD4c5D335b00287202C93C5B4EE0478D92686', - childMulticall: '0x39E068582873B2011F5a1e8E0F7D9D993c8111BC', + childMultiCall: '0x39E068582873B2011F5a1e8E0F7D9D993c8111BC', childProxyAdmin: '0x9DC4Da9a940AFEbBC8329aA6534aD767b60d968c', childWeth: '0xa3bD1fdeEb903142d16B3bd22f2aC9A82C714D62', childWethGateway: '0xec018E81eE818b04CFb1E013D91F1b779a2AC440', @@ -508,7 +508,7 @@ export const addDefaultLocalNetwork = (): ArbitrumNetwork => { childCustomGateway: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', childErc20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', childGatewayRouter: '0x1294b86822ff4976BfE136cB06CF43eC7FCF2574', - childMulticall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', + childMultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', childProxyAdmin: '0xda52b25ddB0e3B9CC393b0690Ac62245Ac772527', childWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', childWethGateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', @@ -564,7 +564,7 @@ export async function getMulticallAddress( if (typeof chain !== 'undefined') { assertArbitrumNetworkHasTokenBridge(chain) // Return the address of Multicall on the chain - return chain.tokenBridge.childMulticall + return chain.tokenBridge.childMultiCall } // The provided chain is not found in the list @@ -603,7 +603,7 @@ export function mapL2NetworkTokenBridgeToTokenBridge( parentProxyAdmin: input.l1ProxyAdmin, childProxyAdmin: input.l2ProxyAdmin, parentMultiCall: input.l1MultiCall, - childMulticall: input.l2Multicall, + childMultiCall: input.l2Multicall, } } diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index c37f1e866e..0a0ec9d3ce 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -60,7 +60,7 @@ export enum ParentToChildMessageStatus { * redeem tx is ever issued. An auto redeem is also never issued for ETH deposits. * A manual redeem is now required. */ - FUNDS_DEPOSITED_ON_CHAIN = 3, + FUNDS_DEPOSITED_ON_CHILD = 3, /** * The retryable ticket has been redeemed (either by auto, or manually) and the * chain transaction has been executed @@ -346,7 +346,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { // the retryable was created and still exists // therefore it cant have been redeemed or be expired return { - status: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + status: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, } } @@ -479,7 +479,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { /** * Wait for the retryable ticket to be created, for it to be redeemed, and for the chainTx to be executed. - * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_CHAIN as + * Note: The terminal status of a transaction that only does an eth deposit is FUNDS_DEPOSITED_ON_CHILD as * no Chain transaction needs to be executed, however the terminal state of any other transaction is REDEEMED * which represents that the retryable ticket has been redeemed and the Chain tx has been executed. * @param confirmations Amount of confirmations the retryable ticket and the auto redeem receipt should have @@ -672,11 +672,11 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { /** * Manually redeem the retryable ticket. - * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD */ public async redeem(overrides?: Overrides): Promise { const status = await this.status() - if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, this.chainSigner @@ -696,7 +696,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { ParentToChildMessageStatus[status] } must be: ${ ParentToChildMessageStatus[ - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD ] }.` ) @@ -705,11 +705,11 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { /** * Cancel the retryable ticket. - * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD */ public async cancel(overrides?: Overrides): Promise { const status = await this.status() - if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, this.chainSigner @@ -721,7 +721,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { ParentToChildMessageStatus[status] } must be: ${ ParentToChildMessageStatus[ - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD ] }.` ) @@ -730,11 +730,11 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { /** * Increase the timeout of a retryable ticket. - * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + * Throws if message status is not ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD */ public async keepAlive(overrides?: Overrides): Promise { const status = await this.status() - if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN) { + if (status === ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD) { const arbRetryableTx = ArbRetryableTx__factory.connect( ARB_RETRYABLE_TX_ADDRESS, this.chainSigner @@ -746,7 +746,7 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { ParentToChildMessageStatus[status] } must be: ${ ParentToChildMessageStatus[ - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD ] }.` ) diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index d5f2efe478..f5a553ae17 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -270,7 +270,7 @@ describe('Ether', async () => { await parentToChildMessageReader.waitForStatus() expect(retryableTicketResult.status).to.eq( - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, 'unexpected status, expected auto-redeem to fail' ) diff --git a/tests/integration/l1l3Bridger.test.ts b/tests/integration/l1l3Bridger.test.ts index f61cb37cfb..84302a0eab 100644 --- a/tests/integration/l1l3Bridger.test.ts +++ b/tests/integration/l1l3Bridger.test.ts @@ -472,12 +472,12 @@ describe('L1 to L3 Bridging', () => { ) }) - it('getL2ERC20Address', async () => { + it('getL2Erc20Address', async () => { assertArbitrumNetworkHasTokenBridge(l2Network) // use weth to test, since we already know its addresses const parentWeth = l2Network.tokenBridge.parentWeth const childWeth = l2Network.tokenBridge.childWeth - const ans = await l1l3Bridger.getL2ERC20Address( + const ans = await l1l3Bridger.getL2Erc20Address( parentWeth, l1Signer.provider! ) @@ -506,14 +506,14 @@ describe('L1 to L3 Bridging', () => { expect(defaultAns).to.eq(l1l2Gateway) }) - itOnlyWhenEth('getL3ERC20Address', async () => { + itOnlyWhenEth('getL3Erc20Address', async () => { assertArbitrumNetworkHasTokenBridge(l2Network) assertArbitrumNetworkHasTokenBridge(l3Network) // use weth to test, since we already know its addresses const parentWeth = l2Network.tokenBridge.parentWeth const l3Weth = l3Network.tokenBridge.childWeth - const ans = await l1l3Bridger.getL3ERC20Address( + const ans = await l1l3Bridger.getL3Erc20Address( parentWeth, l1Signer.provider!, l2Signer.provider! @@ -582,26 +582,26 @@ describe('L1 to L3 Bridging', () => { ) } - // getL2ERC20Address + // getL2Erc20Address await checkNetworkGuards( true, false, false, async (l1Signer, _l2Signer, _l3Signer) => { - return new Erc20L1L3Bridger(l3Network).getL2ERC20Address( + return new Erc20L1L3Bridger(l3Network).getL2Erc20Address( l1Token.address, l1Signer.provider! ) } ) - // getL3ERC20Address + // getL3Erc20Address await checkNetworkGuards( true, true, false, async (l1Signer, l2Signer, _l3Signer) => { - return new Erc20L1L3Bridger(l3Network).getL3ERC20Address( + return new Erc20L1L3Bridger(l3Network).getL3Erc20Address( l1Token.address, l1Signer.provider!, l2Signer.provider! @@ -800,7 +800,7 @@ describe('L1 to L3 Bridging', () => { return ( (await status.l2l3TokenBridgeRetryable?.status()) === - ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD ) }, 1000) @@ -824,7 +824,7 @@ describe('L1 to L3 Bridging', () => { await (await messageWriter.redeem({ gasLimit: 20_000_000 })).wait() // make sure the tokens have landed in the right place - const l3TokenAddr = await l1l3Bridger.getL3ERC20Address( + const l3TokenAddr = await l1l3Bridger.getL3Erc20Address( l1Token.address, l1Signer.provider!, l2Signer.provider! @@ -877,7 +877,7 @@ describe('L1 to L3 Bridging', () => { }, 1000) // make sure the tokens have landed in the right place - const l3TokenAddr = await l1l3Bridger.getL3ERC20Address( + const l3TokenAddr = await l1l3Bridger.getL3Erc20Address( depositParams.erc20L1Address, l1Signer.provider!, l2Signer.provider! diff --git a/tests/integration/standarderc20.test.ts b/tests/integration/standarderc20.test.ts index 847f63c2e6..f32f91c91e 100644 --- a/tests/integration/standarderc20.test.ts +++ b/tests/integration/standarderc20.test.ts @@ -150,7 +150,7 @@ describe('standard ERC20', () => { expect(retryRec.status, 'tx didnt fail').to.eq(expectedStatus) expect(await message.status(), 'message status').to.eq( expectedStatus === 0 - ? ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN + ? ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD : ParentToChildMessageStatus.REDEEMED ) } @@ -162,7 +162,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(0) }, @@ -180,7 +180,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(5) }, @@ -200,7 +200,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(21000) }, @@ -232,7 +232,7 @@ describe('standard ERC20', () => { erc20Bridger: testState.erc20Bridger, parentSigner: testState.parentSigner, childSigner: testState.childSigner, - expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHAIN, + expectedStatus: ParentToChildMessageStatus.FUNDS_DEPOSITED_ON_CHILD, expectedGatewayType: GatewayType.STANDARD, retryableOverrides: { gasLimit: { base: BigNumber.from(5) }, From 40ac5ba17c9daaf887f1bd23dc017b25bbf7c176 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 9 Jul 2024 17:06:20 +0200 Subject: [PATCH 54/74] feat: clean up networks (#506) --- src/index.ts | 1 + src/lib/assetBridger/l1l3Bridger.ts | 7 ++++-- src/lib/dataEntities/networks.ts | 36 ++++++++++++----------------- tests/unit/network.test.ts | 12 ++++------ 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/index.ts b/src/index.ts index d4172ac5ac..ef4ee931e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -56,6 +56,7 @@ export { CallInput, MultiCaller } from './lib/utils/multicall' export { ArbitrumNetwork, getArbitrumNetwork, + getArbitrumNetworks, ArbitrumNetworkInformationFromRollup, getArbitrumNetworkInformationFromRollup, getChildrenForNetwork, diff --git a/src/lib/assetBridger/l1l3Bridger.ts b/src/lib/assetBridger/l1l3Bridger.ts index 4063e06225..5173e543ab 100644 --- a/src/lib/assetBridger/l1l3Bridger.ts +++ b/src/lib/assetBridger/l1l3Bridger.ts @@ -21,7 +21,7 @@ import { ArbitrumNetwork, Teleporter, assertArbitrumNetworkHasTokenBridge, - networks, + getArbitrumNetworks, } from '../dataEntities/networks' import { SignerOrProvider, @@ -284,7 +284,10 @@ class BaseL1L3Bridger { BigNumber.from(100) constructor(l3Network: ArbitrumNetwork) { - const l2Network = networks[l3Network.parentChainId] + const l2Network = getArbitrumNetworks().find( + network => network.chainId === l3Network.parentChainId + ) + if (!l2Network) { throw new ArbSdkError( `Unknown arbitrum network chain id: ${l3Network.parentChainId}` diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index bd0abdd7df..4177495037 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -150,10 +150,6 @@ export interface EthBridge { } } -export interface Networks { - [id: string]: ArbitrumNetwork -} - const mainnetTokenBridge: TokenBridge = { parentGatewayRouter: '0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef', childGatewayRouter: '0x5288c571Fd7aD117beA99bF60FE0846C4E84F933', @@ -184,9 +180,11 @@ const mainnetETHBridge: EthBridge = { } /** - * Storage for all networks, either L1, L2 or L3. + * Storage for all Arbitrum networks, either L2 or L3. */ -export const networks: Networks = { +const networks: { + [id: string]: ArbitrumNetwork +} = { 42161: { chainId: 42161, name: 'Arbitrum One', @@ -342,13 +340,9 @@ export const isParentNetwork = ( : parentChainOrChainId.chainId // Check if there are any chains that have this chain as its parent chain - return [...Object.values(l2Networks)].some( - c => c.parentChainId === parentChainId - ) + return getArbitrumNetworks().some(c => c.parentChainId === parentChainId) } -const getArbitrumChains = () => networks - /** * Returns a list of children chains for the given chain or chain id. */ @@ -360,16 +354,11 @@ export const getChildrenForNetwork = ( ? parentChainOrChainId : parentChainOrChainId.chainId - return Object.values(getArbitrumChains()).filter( + return getArbitrumNetworks().filter( arbitrumChain => arbitrumChain.parentChainId === parentChainId ) } -/** - * Index of all Arbitrum chains that have been added. - */ -export let l2Networks = getArbitrumChains() - /** * Returns the Arbitrum chain associated with the given signer, provider or chain id. * @@ -389,7 +378,7 @@ export const getArbitrumNetwork = async ( return (await provider.getNetwork()).chainId })() - const network: ArbitrumNetwork | undefined = getArbitrumChains()[chainId] + const network = getArbitrumNetworks().find(n => n.chainId === chainId) if (!network) { throw new ArbSdkError(`Unrecognized network ${chainId}.`) @@ -398,6 +387,13 @@ export const getArbitrumNetwork = async ( return network } +/** + * Returns all Arbitrum networks registered in the SDK, both default and custom. + */ +export function getArbitrumNetworks(): ArbitrumNetwork[] { + return Object.values(networks) +} + export type ArbitrumNetworkInformationFromRollup = Pick< ArbitrumNetwork, 'parentChainId' | 'confirmPeriodBlocks' | 'ethBridge' @@ -473,7 +469,6 @@ export function registerCustomArbitrumNetwork( // store the network with the rest of the networks networks[network.chainId] = network - l2Networks = getArbitrumChains() return network } @@ -528,7 +523,6 @@ const createNetworkStateHandler = () => { resetNetworksToDefault: () => { Object.keys(networks).forEach(key => delete networks[key]) Object.assign(networks, JSON.parse(JSON.stringify(initialState))) - l2Networks = getArbitrumChains() }, } } @@ -552,7 +546,7 @@ export function getNitroGenesisBlock( export async function getMulticallAddress( providerOrChainId: Provider | number ): Promise { - const chains = [...Object.values(l2Networks)] + const chains = getArbitrumNetworks() const chainId = typeof providerOrChainId === 'number' diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 212fc522e9..373dec5e28 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -3,7 +3,7 @@ import { resetNetworksToDefault, registerCustomArbitrumNetwork, getArbitrumNetwork, - l2Networks as arbitrumNetworks, + getArbitrumNetworks, getChildrenForNetwork, isParentNetwork, getMulticallAddress, @@ -118,15 +118,11 @@ describe('Networks', async () => { describe('returns correct networks', () => { // todo: this could be a snapshot test it('returns correct Arbitrum networks', () => { - const arbitrumNetworksEntries = Object.entries(arbitrumNetworks) - const arbitrumNetworksKeys = arbitrumNetworksEntries.map(([key]) => key) - + const arbitrumNetworksIds = getArbitrumNetworks().map(n => n.chainId) const expected = [42161, 42170, 421614, 23011913, 13331371] - // - .map(id => id.toString()) - expect(arbitrumNetworksKeys).to.have.length(expected.length) - expect(arbitrumNetworksKeys).to.have.members(expected) + expect(arbitrumNetworksIds).to.have.length(expected.length) + expect(arbitrumNetworksIds).to.have.members(expected) }) }) From 18a750deaca8ec392ef8b6703f9ac584135539b0 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 9 Jul 2024 17:52:09 +0200 Subject: [PATCH 55/74] chore: bump version to 4.0.0-alpha.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25e875f7f2..790b353160 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.6", + "version": "4.0.0-alpha.7", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 210ac840203becf9cdbb4fec55edc4fea4915ad7 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 10 Jul 2024 05:42:49 -0400 Subject: [PATCH 56/74] feat: add synchronous getArbitrumNetwork (#508) --- src/lib/dataEntities/networks.ts | 34 +++++++++++++++++++------------- tests/unit/network.test.ts | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 4177495037..1e56d748f8 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -364,29 +364,35 @@ export const getChildrenForNetwork = ( * * @note Throws if the chain is not an Arbitrum chain. */ -export const getArbitrumNetwork = async ( +export function getArbitrumNetwork(chainId: number): ArbitrumNetwork +export function getArbitrumNetwork( + signerOrProvider: SignerOrProvider +): Promise +export function getArbitrumNetwork( signerOrProviderOrChainId: SignerOrProvider | number -): Promise => { - const chainId = await (async () => { - if (typeof signerOrProviderOrChainId === 'number') { - return signerOrProviderOrChainId - } - const provider = SignerProviderUtils.getProviderOrThrow( - signerOrProviderOrChainId - ) - - return (await provider.getNetwork()).chainId - })() +): ArbitrumNetwork | Promise { + if (typeof signerOrProviderOrChainId === 'number') { + return getArbitrumNetworkByChainId(signerOrProviderOrChainId) + } + return getArbitrumNetworkBySignerOrProvider(signerOrProviderOrChainId) +} +function getArbitrumNetworkByChainId(chainId: number): ArbitrumNetwork { const network = getArbitrumNetworks().find(n => n.chainId === chainId) - if (!network) { throw new ArbSdkError(`Unrecognized network ${chainId}.`) } - return network } +async function getArbitrumNetworkBySignerOrProvider( + signerOrProvider: SignerOrProvider +): Promise { + const provider = SignerProviderUtils.getProviderOrThrow(signerOrProvider) + const { chainId } = await provider.getNetwork() + return getArbitrumNetworkByChainId(chainId) +} + /** * Returns all Arbitrum networks registered in the SDK, both default and custom. */ diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 373dec5e28..16ee673cb2 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -8,6 +8,7 @@ import { isParentNetwork, getMulticallAddress, } from '../../src/lib/dataEntities/networks' +import { SignerOrProvider } from '../../src/lib/dataEntities/signerOrProvider' const ethereumMainnetChainId = 1 const arbitrumOneChainId = 42161 @@ -201,4 +202,22 @@ describe('Networks', async () => { expect(multicall).to.equal('0xA115146782b7143fAdB3065D86eACB54c169d092') }) }) + + describe('async/sync usage of the getArbitrumNetwork function', () => { + it('returns ArbitrumNetwork for chain ID', () => { + const network = getArbitrumNetwork(arbitrumOneChainId) + // TypeScript should infer this as ArbitrumNetwork, not Promise + expect(network.chainId).to.equal(arbitrumOneChainId) + }) + + it('returns Promise for SignerOrProvider input', async () => { + const networkPromise = getArbitrumNetwork({ + getNetwork: async () => ({ chainId: arbitrumOneChainId }), + } as unknown as SignerOrProvider) + // TypeScript should infer this as Promise + expect(networkPromise).to.be.an.instanceOf(Promise) + const network = await networkPromise + expect(network.chainId).to.equal(arbitrumOneChainId) + }) + }) }) From 49ed39cce8764b52348fa173c6c7c733fc9e282b Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 13:00:13 +0200 Subject: [PATCH 57/74] feat: rename and export L1-L3 utils (#509) --- src/index.ts | 10 +++++++- src/lib/assetBridger/l1l3Bridger.ts | 34 +++++++++++++-------------- tests/integration/l1l3Bridger.test.ts | 12 +++++----- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index ef4ee931e8..112f038d8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,8 +17,14 @@ 'use strict' export { - Erc20L1L3Bridger, EthL1L3Bridger, + EthL1L3DepositStatus, + EthL1L3DepositRequestParams, + Erc20L1L3Bridger, + Erc20L1L3DepositStatus, + Erc20L1L3DepositRequestParams, + Erc20L1L3DepositRequestRetryableOverrides, + GetL1L3DepositStatusParams, } from './lib/assetBridger/l1l3Bridger' export { EthBridger } from './lib/assetBridger/ethBridger' export { Erc20Bridger } from './lib/assetBridger/erc20Bridger' @@ -30,6 +36,8 @@ export { ChildToParentMessage, ChildToParentMessageWriter, ChildToParentMessageReader, + ChildToParentMessageReaderOrWriter, + ChildToParentTransactionEvent, } from './lib/message/ChildToParentMessage' export { ParentEthDepositTransaction, diff --git a/src/lib/assetBridger/l1l3Bridger.ts b/src/lib/assetBridger/l1l3Bridger.ts index 5173e543ab..e488d49612 100644 --- a/src/lib/assetBridger/l1l3Bridger.ts +++ b/src/lib/assetBridger/l1l3Bridger.ts @@ -110,7 +110,7 @@ export type TokenApproveParams = { amount?: BigNumber } -export type Erc20DepositRequestRetryableOverrides = { +export type Erc20L1L3DepositRequestRetryableOverrides = { /** * Optional L1 gas price override. Used to estimate submission fees. */ @@ -141,7 +141,7 @@ export type Erc20DepositRequestRetryableOverrides = { l2l3TokenBridgeRetryableGas?: TeleporterRetryableGasOverride } -export type Erc20DepositRequestParams = { +export type Erc20L1L3DepositRequestParams = { /** * Address of L1 token */ @@ -173,7 +173,7 @@ export type Erc20DepositRequestParams = { /** * Optional overrides for retryable gas parameters */ - retryableOverrides?: Erc20DepositRequestRetryableOverrides + retryableOverrides?: Erc20L1L3DepositRequestRetryableOverrides } export type TxReference = @@ -181,13 +181,13 @@ export type TxReference = | { tx: ParentContractCallTransaction } | { txReceipt: ParentContractCallTransactionReceipt } -export type GetDepositStatusParams = { +export type GetL1L3DepositStatusParams = { l1Provider: Provider l2Provider: Provider l3Provider: Provider } & TxReference -export type Erc20DepositStatus = { +export type Erc20L1L3DepositStatus = { /** * L1 to L2 token bridge message */ @@ -224,7 +224,7 @@ export type Erc20DepositStatus = { completed: boolean } -export type EthDepositRequestParams = { +export type EthL1L3DepositRequestParams = { /** * Amount of ETH to send to L3 */ @@ -255,7 +255,7 @@ export type EthDepositRequestParams = { l3TicketGasOverrides?: Omit } -export type EthDepositStatus = { +export type EthL1L3DepositStatus = { /** * L1 to L2 message */ @@ -730,7 +730,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { * Also returns the amount of fee tokens required for teleportation. */ public async getDepositRequest( - params: Erc20DepositRequestParams & + params: Erc20L1L3DepositRequestParams & ( | { from: string @@ -810,7 +810,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { */ public async deposit( params: - | (Erc20DepositRequestParams & { + | (Erc20L1L3DepositRequestParams & { l1Signer: Signer overrides?: PayableOverrides }) @@ -876,8 +876,8 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { * Can provide either the txHash, the tx, or the txReceipt */ public async getDepositStatus( - params: GetDepositStatusParams - ): Promise { + params: GetL1L3DepositStatusParams + ): Promise { await this._checkL1Network(params.l1Provider) await this._checkL2Network(params.l2Provider) await this._checkL3Network(params.l3Provider) @@ -1196,7 +1196,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { IL1Teleporter.TeleportParamsStruct, 'gasParams' >, - retryableOverrides: Erc20DepositRequestRetryableOverrides, + retryableOverrides: Erc20L1L3DepositRequestRetryableOverrides, l1Provider: Provider, l2Provider: Provider, l3Provider: Provider @@ -1461,7 +1461,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { * Get a tx request to deposit ETH to L3 via a double retryable ticket */ public async getDepositRequest( - params: EthDepositRequestParams & + params: EthL1L3DepositRequestParams & ( | { from: string @@ -1520,7 +1520,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { */ public async deposit( params: - | (EthDepositRequestParams & { + | (EthL1L3DepositRequestParams & { l1Signer: Signer overrides?: PayableOverrides }) @@ -1572,11 +1572,11 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { * Get the status of a deposit given an L1 tx receipt. Does not check if the tx is actually a deposit tx. * * @return Information regarding each step of the deposit - * and `EthDepositStatus.completed` which indicates whether the deposit has fully completed. + * and `EthL1L3DepositStatus.completed` which indicates whether the deposit has fully completed. */ public async getDepositStatus( - params: GetDepositStatusParams - ): Promise { + params: GetL1L3DepositStatusParams + ): Promise { await this._checkL1Network(params.l1Provider) await this._checkL2Network(params.l2Provider) await this._checkL3Network(params.l3Provider) diff --git a/tests/integration/l1l3Bridger.test.ts b/tests/integration/l1l3Bridger.test.ts index 84302a0eab..c669eeb8df 100644 --- a/tests/integration/l1l3Bridger.test.ts +++ b/tests/integration/l1l3Bridger.test.ts @@ -19,8 +19,8 @@ import { L1Teleporter__factory } from '../../src/lib/abi/factories/L1Teleporter_ import { fundParentSigner, fundChildSigner, skipIfMainnet } from './testHelpers' import { BigNumber, Signer, Wallet, ethers, providers, utils } from 'ethers' import { - Erc20DepositRequestParams, EthL1L3Bridger, + Erc20L1L3DepositRequestParams, } from '../../src/lib/assetBridger/l1l3Bridger' import { assert, expect } from 'chai' import { isArbitrumNetworkWithCustomFeeToken } from './custom-fee-token/customFeeTokenTestHelpers' @@ -766,7 +766,7 @@ describe('L1 to L3 Bridging', () => { itOnlyWhenCustomGasToken('happy path skip fee token', async () => { const l3Recipient = ethers.utils.hexlify(ethers.utils.randomBytes(20)) - const depositParams: Erc20DepositRequestParams = { + const depositParams: Erc20L1L3DepositRequestParams = { erc20L1Address: l1Token.address, destinationAddress: l3Recipient, amount, @@ -837,7 +837,7 @@ describe('L1 to L3 Bridging', () => { }) async function testHappyPathNonFeeOrStandard( - depositParams: Erc20DepositRequestParams + depositParams: Erc20L1L3DepositRequestParams ) { const depositTxRequest = await l1l3Bridger.getDepositRequest({ ...depositParams, @@ -902,7 +902,7 @@ describe('L1 to L3 Bridging', () => { it('happy path non fee token or standard', async () => { const l3Recipient = ethers.utils.hexlify(ethers.utils.randomBytes(20)) - const depositParams: Erc20DepositRequestParams = { + const depositParams: Erc20L1L3DepositRequestParams = { erc20L1Address: l1Token.address, destinationAddress: l3Recipient, amount, @@ -933,7 +933,7 @@ describe('L1 to L3 Bridging', () => { await weth.approve(l1l3Bridger.teleporter.l1Teleporter, amount) ).wait() - const depositParams: Erc20DepositRequestParams = { + const depositParams: Erc20L1L3DepositRequestParams = { erc20L1Address: l2Network.tokenBridge.parentWeth, destinationAddress: l3Recipient, amount, @@ -951,7 +951,7 @@ describe('L1 to L3 Bridging', () => { l2Signer.provider! ))! - const depositParams: Erc20DepositRequestParams = { + const depositParams: Erc20L1L3DepositRequestParams = { erc20L1Address: l1FeeToken, destinationAddress: l3Recipient, amount: ethers.utils.parseEther('0.1'), From 578d056a8c4cb943d7bb54125407a16dff3bfc3d Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 13:34:17 +0200 Subject: [PATCH 58/74] chore: bump version to 4.0.0-alpha.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 790b353160..2bce040e23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.7", + "version": "4.0.0-alpha.8", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 6684914553ffb6578ebc4743fd550d1dd93fe132 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 17:28:02 +0200 Subject: [PATCH 59/74] test: update assertion for arb sepolia --- tests/unit/network.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/network.test.ts b/tests/unit/network.test.ts index 056c0bfd35..a78d5be91c 100644 --- a/tests/unit/network.test.ts +++ b/tests/unit/network.test.ts @@ -172,7 +172,7 @@ describe('Networks', async () => { }) it('returns correct value for arbitrum sepolia', () => { - expect(isParentNetwork(421614)).to.equal(true) + expect(isParentNetwork(421614)).to.equal(false) }) }) From 60f6a019c4fdc066e380a2d1bb48880727e9ae92 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 18:18:36 +0200 Subject: [PATCH 60/74] feat: remove addDefaultLocalNetwork (#512) --- src/index.ts | 1 - src/lib/dataEntities/networks.ts | 40 -------------------------------- 2 files changed, 41 deletions(-) diff --git a/src/index.ts b/src/index.ts index 112f038d8c..d39e305548 100644 --- a/src/index.ts +++ b/src/index.ts @@ -69,7 +69,6 @@ export { getArbitrumNetworkInformationFromRollup, getChildrenForNetwork, registerCustomArbitrumNetwork, - addDefaultLocalNetwork, } from './lib/dataEntities/networks' export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index 7f776a83ad..abea1cddda 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -419,46 +419,6 @@ export function registerCustomArbitrumNetwork( return network } -/** - * Registers a custom network that matches the one created by a Nitro local node. Useful in development. - * - * @see {@link https://github.com/OffchainLabs/nitro} - */ -export const addDefaultLocalNetwork = (): ArbitrumNetwork => { - const defaultLocalL2Network: ArbitrumNetwork = { - chainId: 412346, - confirmPeriodBlocks: 20, - ethBridge: { - bridge: '0x2b360A9881F21c3d7aa0Ea6cA0De2a3341d4eF3C', - inbox: '0xfF4a24b22F94979E9ba5f3eb35838AA814bAD6F1', - outbox: '0x49940929c7cA9b50Ff57a01d3a92817A414E6B9B', - rollup: '0x65a59D67Da8e710Ef9A01eCa37f83f84AEdeC416', - sequencerInbox: '0xE7362D0787b51d8C72D504803E5B1d6DcdA89540', - }, - isCustom: true, - name: 'ArbLocal', - parentChainId: 1337, - tokenBridge: { - parentCustomGateway: '0x3DF948c956e14175f43670407d5796b95Bb219D8', - parentErc20Gateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', - parentGatewayRouter: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', - parentMultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', - parentProxyAdmin: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', - parentWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', - parentWethGateway: '0xF5FfD11A55AFD39377411Ab9856474D2a7Cb697e', - childCustomGateway: '0x525c2aBA45F66987217323E8a05EA400C65D06DC', - childErc20Gateway: '0xe1080224B632A93951A7CFA33EeEa9Fd81558b5e', - childGatewayRouter: '0x1294b86822ff4976BfE136cB06CF43eC7FCF2574', - childMultiCall: '0xDB2D15a3EB70C347E0D2C2c7861cAFb946baAb48', - childProxyAdmin: '0xda52b25ddB0e3B9CC393b0690Ac62245Ac772527', - childWeth: '0x408Da76E87511429485C32E4Ad647DD14823Fdc4', - childWethGateway: '0x4A2bA922052bA54e29c5417bC979Daaf7D5Fe4f4', - }, - } - - return registerCustomArbitrumNetwork(defaultLocalL2Network) -} - /** * Creates a function that resets the networks index to default. Useful in development. */ From da6d81aafa91486970732428b0c04a975cd84c3f Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 10 Jul 2024 13:05:51 -0400 Subject: [PATCH 61/74] chore: rename chain to network on bridgers (#513) --- src/lib/assetBridger/assetBridger.ts | 21 ++-- src/lib/assetBridger/erc20Bridger.ts | 112 +++++++++--------- src/lib/assetBridger/ethBridger.ts | 38 +++--- .../customFeeTokenEthBridger.test.ts | 8 +- tests/integration/eth.test.ts | 4 +- tests/integration/testHelpers.ts | 4 +- 6 files changed, 95 insertions(+), 92 deletions(-) diff --git a/src/lib/assetBridger/assetBridger.ts b/src/lib/assetBridger/assetBridger.ts index 75c2962611..6ef1d549d1 100644 --- a/src/lib/assetBridger/assetBridger.ts +++ b/src/lib/assetBridger/assetBridger.ts @@ -34,31 +34,34 @@ export abstract class AssetBridger { /** * In case of a chain that uses ETH as its native/gas token, this is either `undefined` or the zero address * - * In case of a chain that uses an ERC-20 token from the parent chain as its native/gas token, this is the address of said token on the parent chain + * In case of a chain that uses an ERC-20 token from the parent network as its native/gas token, this is the address of said token on the parent network */ public readonly nativeToken?: string - public constructor(public readonly childChain: ArbitrumNetwork) { - this.nativeToken = childChain.nativeToken + public constructor(public readonly childNetwork: ArbitrumNetwork) { + this.nativeToken = childNetwork.nativeToken } /** - * Check the signer/provider matches the parentChain, throws if not + * Check the signer/provider matches the parent network, throws if not * @param sop */ - protected async checkParentChain(sop: SignerOrProvider): Promise { + protected async checkParentNetwork(sop: SignerOrProvider): Promise { await SignerProviderUtils.checkNetworkMatches( sop, - this.childChain.parentChainId + this.childNetwork.parentChainId ) } /** - * Check the signer/provider matches the childChain, throws if not + * Check the signer/provider matches the child network, throws if not * @param sop */ - protected async checkChildChain(sop: SignerOrProvider): Promise { - await SignerProviderUtils.checkNetworkMatches(sop, this.childChain.chainId) + protected async checkChildNetwork(sop: SignerOrProvider): Promise { + await SignerProviderUtils.checkNetworkMatches( + sop, + this.childNetwork.chainId + ) } /** diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index c00a0d24c7..84ceed3b0b 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -82,7 +82,7 @@ import { getErc20ParentAddressFromParentToChildTxRequest } from '../utils/callda export interface TokenApproveParams { /** - * Parent chain address of the ERC20 token contract + * Parent network address of the ERC20 token contract */ erc20ParentAddress: string /** @@ -101,11 +101,11 @@ export interface Erc20DepositParams extends EthDepositParams { */ childProvider: Provider /** - * Parent chain address of the token ERC20 contract + * Parent network address of the token ERC20 contract */ erc20ParentAddress: string /** - * Child chain address of the entity receiving the funds. Defaults to the l1FromAddress + * Child network address of the entity receiving the funds. Defaults to the l1FromAddress */ destinationAddress?: string /** @@ -132,7 +132,7 @@ export interface Erc20DepositParams extends EthDepositParams { export interface Erc20WithdrawParams extends EthWithdrawParams { /** - * Parent chain address of the token ERC20 contract + * Parent network address of the token ERC20 contract */ erc20ParentAddress: string } @@ -191,17 +191,17 @@ export class Erc20Bridger extends AssetBridger< public static MAX_APPROVAL: BigNumber = MaxUint256 public static MIN_CUSTOM_DEPOSIT_GAS_LIMIT = BigNumber.from(275000) - public readonly childChain: ArbitrumNetwork & { + public readonly childNetwork: ArbitrumNetwork & { tokenBridge: TokenBridge } /** * Bridger for moving ERC20 tokens back and forth between parent-to-child */ - public constructor(childChain: ArbitrumNetwork) { - super(childChain) - assertArbitrumNetworkHasTokenBridge(childChain) - this.childChain = childChain + public constructor(childNetwork: ArbitrumNetwork) { + super(childNetwork) + assertArbitrumNetworkHasTokenBridge(childNetwork) + this.childNetwork = childNetwork } /** @@ -223,10 +223,10 @@ export class Erc20Bridger extends AssetBridger< erc20ParentAddress: string, parentProvider: Provider ): Promise { - await this.checkParentChain(parentProvider) + await this.checkParentNetwork(parentProvider) return await L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.parentGatewayRouter, + this.childNetwork.tokenBridge.parentGatewayRouter, parentProvider ).getGateway(erc20ParentAddress) } @@ -241,16 +241,16 @@ export class Erc20Bridger extends AssetBridger< erc20ParentAddress: string, childProvider: Provider ): Promise { - await this.checkChildChain(childProvider) + await this.checkChildNetwork(childProvider) return await L2GatewayRouter__factory.connect( - this.childChain.tokenBridge.childGatewayRouter, + this.childNetwork.tokenBridge.childGatewayRouter, childProvider ).getGateway(erc20ParentAddress) } /** - * Creates a transaction request for approving the custom gas token to be spent by the relevant gateway on the parent chain + * Creates a transaction request for approving the custom gas token to be spent by the relevant gateway on the parent network * @param params */ public async getApproveGasTokenRequest( @@ -266,7 +266,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Approves the custom gas token to be spent by the relevant gateway on the parent chain + * Approves the custom gas token to be spent by the relevant gateway on the parent network * @param params */ public async approveGasToken( @@ -276,7 +276,7 @@ export class Erc20Bridger extends AssetBridger< throw new Error('chain uses ETH as its native/gas token') } - await this.checkParentChain(params.parentSigner) + await this.checkParentNetwork(params.parentSigner) const approveGasTokenRequest = this.isApproveParams(params) ? await this.getApproveGasTokenRequest({ @@ -335,7 +335,7 @@ export class Erc20Bridger extends AssetBridger< public async approveToken( params: ApproveParamsOrTxRequest ): Promise { - await this.checkParentChain(params.parentSigner) + await this.checkParentNetwork(params.parentSigner) const approveRequest = this.isApproveParams(params) ? await this.getApproveTokenRequest({ @@ -352,7 +352,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the child chain events created by a withdrawal + * Get the child network events created by a withdrawal * @param childProvider * @param gatewayAddress * @param parentTokenAddress @@ -368,7 +368,7 @@ export class Erc20Bridger extends AssetBridger< fromAddress?: string, toAddress?: string ): Promise<(EventArgs & { txHash: string })[]> { - await this.checkChildChain(childProvider) + await this.checkChildNetwork(childProvider) const eventFetcher = new EventFetcher(childProvider) const events = ( @@ -433,8 +433,8 @@ export class Erc20Bridger extends AssetBridger< gatewayAddress: string, parentProvider: Provider ): Promise { - const wethAddress = this.childChain.tokenBridge.parentWethGateway - if (this.childChain.isCustom) { + const wethAddress = this.childNetwork.tokenBridge.parentWethGateway + if (this.childNetwork.isCustom) { // For custom network, we do an ad-hoc check to see if it's a WETH gateway if (await this.looksLikeWethGateway(gatewayAddress, parentProvider)) { return true @@ -447,7 +447,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the child chain token contract at the provided address + * Get the child network token contract at the provided address * Note: This function just returns a typed ethers object for the provided address, it doesn't * check the underlying form of the contract bytecode to see if it's an erc20, and doesn't ensure the validity * of any of the underlying functions on that contract. @@ -479,7 +479,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the corresponding child chain token address for the provided parent chain token + * Get the corresponding child network token address for the provided parent network token * @param erc20ParentAddress * @param parentProvider * @returns @@ -488,10 +488,10 @@ export class Erc20Bridger extends AssetBridger< erc20ParentAddress: string, parentProvider: Provider ): Promise { - await this.checkParentChain(parentProvider) + await this.checkParentNetwork(parentProvider) const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.parentGatewayRouter, + this.childNetwork.tokenBridge.parentGatewayRouter, parentProvider ) @@ -501,8 +501,8 @@ export class Erc20Bridger extends AssetBridger< } /** - * Get the corresponding parent chain address for the provided child chain token - * Validates the returned address against the child chain router to ensure it is correctly mapped to the provided erc20ChildChainAddress + * Get the corresponding parent network address for the provided child network token + * Validates the returned address against the child network router to ensure it is correctly mapped to the provided erc20ChildChainAddress * @param erc20ChildChainAddress * @param childProvider * @returns @@ -511,14 +511,14 @@ export class Erc20Bridger extends AssetBridger< erc20ChildChainAddress: string, childProvider: Provider ): Promise { - await this.checkChildChain(childProvider) + await this.checkChildNetwork(childProvider) - // child chain WETH contract doesn't have the parentAddress method on it + // child network WETH contract doesn't have the parentAddress method on it if ( erc20ChildChainAddress.toLowerCase() === - this.childChain.tokenBridge.childWeth.toLowerCase() + this.childNetwork.tokenBridge.childWeth.toLowerCase() ) { - return this.childChain.tokenBridge.parentWeth + return this.childNetwork.tokenBridge.parentWeth } const arbERC20 = L2GatewayToken__factory.connect( @@ -531,7 +531,7 @@ export class Erc20Bridger extends AssetBridger< // check that this l1 address is indeed registered to this child token const childGatewayRouter = L2GatewayRouter__factory.connect( - this.childChain.tokenBridge.childGatewayRouter, + this.childNetwork.tokenBridge.childGatewayRouter, childProvider ) @@ -557,10 +557,10 @@ export class Erc20Bridger extends AssetBridger< parentTokenAddress: string, parentProvider: Provider ): Promise { - await this.checkParentChain(parentProvider) + await this.checkParentNetwork(parentProvider) const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.parentGatewayRouter, + this.childNetwork.tokenBridge.parentGatewayRouter, parentProvider ) @@ -647,8 +647,8 @@ export class Erc20Bridger extends AssetBridger< public async getDepositRequest( params: DepositRequest ): Promise { - await this.checkParentChain(params.parentProvider) - await this.checkChildChain(params.childProvider) + await this.checkParentNetwork(params.parentProvider) + await this.checkChildNetwork(params.childProvider) const defaultedParams = this.applyDefaults(params) const { amount, @@ -666,7 +666,7 @@ export class Erc20Bridger extends AssetBridger< let tokenGasOverrides: GasOverrides | undefined = retryableGasOverrides // we also add a hardcoded minimum gas limit for custom gateway deposits if ( - parentGatewayAddress === this.childChain.tokenBridge.parentCustomGateway + parentGatewayAddress === this.childNetwork.tokenBridge.parentCustomGateway ) { if (!tokenGasOverrides) tokenGasOverrides = {} if (!tokenGasOverrides.gasLimit) tokenGasOverrides.gasLimit = {} @@ -708,7 +708,7 @@ export class Erc20Bridger extends AssetBridger< return { data: functionData, - to: this.childChain.tokenBridge.parentGatewayRouter, + to: this.childNetwork.tokenBridge.parentGatewayRouter, from: defaultedParams.from, value: this.getDepositRequestCallValue(depositParams), } @@ -723,7 +723,7 @@ export class Erc20Bridger extends AssetBridger< return { txRequest: { - to: this.childChain.tokenBridge.parentGatewayRouter, + to: this.childNetwork.tokenBridge.parentGatewayRouter, data: estimates.data, value: estimates.value, from: params.from, @@ -747,14 +747,14 @@ export class Erc20Bridger extends AssetBridger< } /** - * Execute a token deposit from parent to child chain + * Execute a token deposit from parent to child network * @param params * @returns */ public async deposit( params: Erc20DepositParams | ParentToChildTxReqAndSignerProvider ): Promise { - await this.checkParentChain(params.parentSigner) + await this.checkParentNetwork(params.parentSigner) // Although the types prevent should alert callers that value is not // a valid override, it is possible that they pass it in anyway as it's a common override @@ -834,7 +834,7 @@ export class Erc20Bridger extends AssetBridger< return { txRequest: { data: functionData, - to: this.childChain.tokenBridge.childGatewayRouter, + to: this.childNetwork.tokenBridge.childGatewayRouter, value: BigNumber.from(0), from: params.from, }, @@ -867,7 +867,7 @@ export class Erc20Bridger extends AssetBridger< } /** - * Withdraw tokens from child to parent chain + * Withdraw tokens from child to parent network * @param params * @returns */ @@ -879,7 +879,7 @@ export class Erc20Bridger extends AssetBridger< if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { throw new MissingProviderArbSdkError('childSigner') } - await this.checkChildChain(params.childSigner) + await this.checkChildNetwork(params.childSigner) const withdrawalRequest = isChildToParentTransactionRequest< OmitTyped & { childSigner: Signer } @@ -914,7 +914,7 @@ export class Erc20Bridger extends AssetBridger< childProvider: Provider }) { const parentStandardGatewayAddressFromChainConfig = - this.childChain.tokenBridge.parentErc20Gateway + this.childNetwork.tokenBridge.parentErc20Gateway const parentGatewayAddressFromParentGatewayRouter = await this.getParentGatewayAddress(erc20ParentAddress, parentProvider) @@ -989,7 +989,7 @@ export class AdminErc20Bridger extends Erc20Bridger { throw new Error('chain uses ETH as its native/gas token') } - await this.checkParentChain(params.parentSigner) + await this.checkParentNetwork(params.parentSigner) const approveGasTokenRequest = this.isApproveParams(params) ? this.getApproveGasTokenForCustomTokenRegistrationRequest({ @@ -1024,8 +1024,8 @@ export class AdminErc20Bridger extends Erc20Bridger { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } - await this.checkParentChain(parentSigner) - await this.checkChildChain(childProvider) + await this.checkParentNetwork(parentSigner) + await this.checkChildNetwork(childProvider) const parentProvider = parentSigner.provider! const parentSenderAddress = await parentSigner.getAddress() @@ -1178,10 +1178,10 @@ export class AdminErc20Bridger extends Erc20Bridger { parentProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag } ): Promise[]> { - await this.checkParentChain(parentProvider) + await this.checkParentNetwork(parentProvider) const parentGatewayRouterAddress = - this.childChain.tokenBridge.parentGatewayRouter + this.childNetwork.tokenBridge.parentGatewayRouter const eventFetcher = new EventFetcher(parentProvider) return ( await eventFetcher.getEvents( @@ -1203,16 +1203,16 @@ export class AdminErc20Bridger extends Erc20Bridger { filter: { fromBlock: BlockTag; toBlock: BlockTag }, customNetworkL2GatewayRouter?: string ): Promise[]> { - if (this.childChain.isCustom && !customNetworkL2GatewayRouter) { + if (this.childNetwork.isCustom && !customNetworkL2GatewayRouter) { throw new ArbSdkError( 'Must supply customNetworkL2GatewayRouter for custom network ' ) } - await this.checkChildChain(childProvider) + await this.checkChildNetwork(childProvider) const childGatewayRouterAddress = customNetworkL2GatewayRouter || - this.childChain.tokenBridge.childGatewayRouter + this.childNetwork.tokenBridge.childGatewayRouter const eventFetcher = new EventFetcher(childProvider) return ( @@ -1240,13 +1240,13 @@ export class AdminErc20Bridger extends Erc20Bridger { if (!SignerProviderUtils.signerHasProvider(parentSigner)) { throw new MissingProviderArbSdkError('parentSigner') } - await this.checkParentChain(parentSigner) - await this.checkChildChain(childProvider) + await this.checkParentNetwork(parentSigner) + await this.checkChildNetwork(childProvider) const from = await parentSigner.getAddress() const parentGatewayRouter = L1GatewayRouter__factory.connect( - this.childChain.tokenBridge.parentGatewayRouter, + this.childNetwork.tokenBridge.parentGatewayRouter, parentSigner ) diff --git a/src/lib/assetBridger/ethBridger.ts b/src/lib/assetBridger/ethBridger.ts index af8461209d..61dd02bc12 100644 --- a/src/lib/assetBridger/ethBridger.ts +++ b/src/lib/assetBridger/ethBridger.ts @@ -86,7 +86,7 @@ export interface EthWithdrawParams { */ amount: BigNumber /** - * The parent chain address to receive the value. + * The parent network address to receive the value. */ destinationAddress: string /** @@ -101,7 +101,7 @@ export interface EthWithdrawParams { export type EthDepositParams = { /** - * Parent chain provider or signer + * Parent network provider or signer */ parentSigner: Signer /** @@ -116,11 +116,11 @@ export type EthDepositParams = { export type EthDepositToParams = EthDepositParams & { /** - * Child chain provider + * Child network provider */ childProvider: Provider /** - * Child chain address of the entity receiving the funds + * Child network address of the entity receiving the funds */ destinationAddress: string /** @@ -149,7 +149,7 @@ type EthDepositToRequestParams = OmitTyped< 'overrides' | 'parentSigner' > & { /** - * Parent chain provider + * Parent network provider */ parentProvider: Provider /** @@ -159,14 +159,14 @@ type EthDepositToRequestParams = OmitTyped< } /** - * Bridger for moving either ETH or custom gas tokens back and forth between parent and child chains + * Bridger for moving either ETH or custom gas tokens back and forth between parent and child networks */ export class EthBridger extends AssetBridger< EthDepositParams | EthDepositToParams | ParentToChildTxReqAndSigner, EthWithdrawParams | ChildToParentTxReqAndSigner > { /** - * Instantiates a new EthBridger from a child chain Provider + * Instantiates a new EthBridger from a child network Provider * @param childProvider * @returns */ @@ -185,7 +185,7 @@ export class EthBridger extends AssetBridger< } /** - * Creates a transaction request for approving the custom gas token to be spent by the inbox on the parent chain + * Creates a transaction request for approving the custom gas token to be spent by the inbox on the parent network * @param params */ public getApproveGasTokenRequest( @@ -199,7 +199,7 @@ export class EthBridger extends AssetBridger< 'approve', [ // spender - this.childChain.ethBridge.inbox, + this.childNetwork.ethBridge.inbox, // value params?.amount ?? constants.MaxUint256, ] @@ -213,7 +213,7 @@ export class EthBridger extends AssetBridger< } /** - * Approves the custom gas token to be spent by the Inbox on the parent chain. + * Approves the custom gas token to be spent by the Inbox on the parent network. * @param params */ public async approveGasToken( @@ -270,7 +270,7 @@ export class EthBridger extends AssetBridger< ): Promise> { return { txRequest: { - to: this.childChain.ethBridge.inbox, + to: this.childNetwork.ethBridge.inbox, value: this.nativeTokenIsEth ? params.amount : 0, data: this.getDepositRequestData(params), from: params.from, @@ -280,14 +280,14 @@ export class EthBridger extends AssetBridger< } /** - * Deposit ETH from Parent onto Child chain + * Deposit ETH from Parent onto Child network * @param params * @returns */ public async deposit( params: EthDepositParams | ParentToChildTxReqAndSigner ): Promise { - await this.checkParentChain(params.parentSigner) + await this.checkParentNetwork(params.parentSigner) const ethDeposit = isParentToChildTransactionRequest(params) ? params @@ -305,7 +305,7 @@ export class EthBridger extends AssetBridger< } /** - * Get a transaction request for an ETH deposit to a different child chain address using Retryables + * Get a transaction request for an ETH deposit to a different child network address using Retryables * @param params * @returns */ @@ -332,7 +332,7 @@ export class EthBridger extends AssetBridger< } /** - * Deposit ETH from parent chain onto a different child chain address + * Deposit ETH from parent network onto a different child network address * @param params * @returns */ @@ -341,8 +341,8 @@ export class EthBridger extends AssetBridger< | EthDepositToParams | (ParentToChildTxReqAndSigner & { childProvider: Provider }) ): Promise { - await this.checkParentChain(params.parentSigner) - await this.checkChildChain(params.childProvider) + await this.checkParentNetwork(params.parentSigner) + await this.checkChildNetwork(params.childProvider) const retryableTicketRequest = isParentToChildTransactionRequest(params) ? params @@ -401,7 +401,7 @@ export class EthBridger extends AssetBridger< } /** - * Withdraw ETH from child chain onto parent chain + * Withdraw ETH from child network onto parent network * @param params * @returns */ @@ -413,7 +413,7 @@ export class EthBridger extends AssetBridger< if (!SignerProviderUtils.signerHasProvider(params.childSigner)) { throw new MissingProviderArbSdkError('childSigner') } - await this.checkChildChain(params.childSigner) + await this.checkChildNetwork(params.childSigner) const request = isChildToParentTransactionRequest< EthWithdrawParams & { childSigner: Signer } diff --git a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts index 4ce32939ad..5964b017d5 100644 --- a/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts +++ b/tests/integration/custom-fee-token/customFeeTokenEthBridger.test.ts @@ -65,7 +65,7 @@ describeOnlyWhenCustomGasToken( const allowance = await nativeTokenContract.allowance( await parentSigner.getAddress(), - ethBridger.childChain.ethBridge.inbox + ethBridger.childNetwork.ethBridge.inbox ) expect(allowance.toString()).to.equal( @@ -89,7 +89,7 @@ describeOnlyWhenCustomGasToken( const allowance = await nativeTokenContract.allowance( await parentSigner.getAddress(), - ethBridger.childChain.ethBridge.inbox + ethBridger.childNetwork.ethBridge.inbox ) expect(allowance.toString()).to.equal( @@ -106,7 +106,7 @@ describeOnlyWhenCustomGasToken( childSigner, childProvider, } = await testSetup() - const bridge = ethBridger.childChain.ethBridge.bridge + const bridge = ethBridger.childNetwork.ethBridge.bridge const amount = parseEther('2') await fundParentSignerEther(parentSigner) @@ -167,7 +167,7 @@ describeOnlyWhenCustomGasToken( ethBridger, nativeTokenContract, } = await testSetup() - const bridge = ethBridger.childChain.ethBridge.bridge + const bridge = ethBridger.childNetwork.ethBridge.bridge const amount = parseEther('0.2') await fundParentSignerEther(parentSigner) diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index f5a553ae17..d69dcf5912 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -102,7 +102,7 @@ describe('Ether', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() await fundParentSigner(parentSigner) - const inboxAddress = ethBridger.childChain.ethBridge.inbox + const inboxAddress = ethBridger.childNetwork.ethBridge.inbox const initialInboxBalance = await parentSigner.provider!.getBalance( inboxAddress @@ -162,7 +162,7 @@ describe('Ether', async () => { const { ethBridger, parentSigner, childSigner } = await testSetup() await fundParentSigner(parentSigner) - const inboxAddress = ethBridger.childChain.ethBridge.inbox + const inboxAddress = ethBridger.childNetwork.ethBridge.inbox const destWallet = Wallet.createRandom() const initialInboxBalance = await parentSigner.provider!.getBalance( diff --git a/tests/integration/testHelpers.ts b/tests/integration/testHelpers.ts index 68fedb1737..2106c009c6 100644 --- a/tests/integration/testHelpers.ts +++ b/tests/integration/testHelpers.ts @@ -139,7 +139,7 @@ export const withdrawToken = async (params: WithdrawalParams) => { const { expectedL2Gateway } = getGateways( params.gatewayType, - params.erc20Bridger.childChain + params.erc20Bridger.childNetwork ) expect(gatewayAddress, 'Gateway is not custom gateway').to.eq( expectedL2Gateway @@ -348,7 +348,7 @@ export const depositToken = async ({ const { expectedL1Gateway, expectedL2Gateway } = getGateways( expectedGatewayType, - erc20Bridger.childChain + erc20Bridger.childNetwork ) const parentGateway = await erc20Bridger.getParentGatewayAddress( From 0e0a0827e10d3ac8c3612cc489daa04ef7e75ee8 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 19:22:28 +0200 Subject: [PATCH 62/74] feat: make naming consistent for child tx (#514) --- src/lib/assetBridger/l1l3Bridger.ts | 4 ++-- src/lib/message/ParentToChildMessage.ts | 28 ++++++++++++------------- src/lib/message/ParentTransaction.ts | 2 +- tests/integration/eth.test.ts | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/lib/assetBridger/l1l3Bridger.ts b/src/lib/assetBridger/l1l3Bridger.ts index e488d49612..b71912c312 100644 --- a/src/lib/assetBridger/l1l3Bridger.ts +++ b/src/lib/assetBridger/l1l3Bridger.ts @@ -899,7 +899,7 @@ export class Erc20L1L3Bridger extends BaseL1L3Bridger { factoryRedeem.status === ParentToChildMessageStatus.REDEEMED ? ( await new ParentTransactionReceipt( - factoryRedeem.txReceipt + factoryRedeem.childTxReceipt ).getParentToChildMessages(params.l3Provider) )[0] : undefined @@ -1601,7 +1601,7 @@ export class EthL1L3Bridger extends BaseL1L3Bridger { const l2l3Message = ( await new ParentEthDepositTransactionReceipt( - l1l2Redeem.txReceipt + l1l2Redeem.childTxReceipt ).getParentToChildMessages(params.l3Provider) )[0] diff --git a/src/lib/message/ParentToChildMessage.ts b/src/lib/message/ParentToChildMessage.ts index 0a0ec9d3ce..df0d4ab125 100644 --- a/src/lib/message/ParentToChildMessage.ts +++ b/src/lib/message/ParentToChildMessage.ts @@ -234,13 +234,13 @@ export abstract class ParentToChildMessage { } /** - * If the status is redeemed an chainTxReceipt is populated. - * For all other statuses chainTxReceipt is not populated + * If the status is redeemed, childTxReceipt is populated. + * For all other statuses childTxReceipt is not populated */ export type ParentToChildMessageWaitForStatusResult = | { status: ParentToChildMessageStatus.REDEEMED - txReceipt: TransactionReceipt + childTxReceipt: TransactionReceipt } | { status: Exclude< @@ -250,7 +250,7 @@ export type ParentToChildMessageWaitForStatusResult = } export type EthDepositMessageWaitForStatusResult = { - txReceipt: TransactionReceipt | null + childTxReceipt: TransactionReceipt | null } export class ParentToChildMessageReader extends ParentToChildMessage { @@ -337,7 +337,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { const autoRedeem = await this.getAutoRedeemAttempt() if (autoRedeem && autoRedeem.status === 1) { return { - txReceipt: autoRedeem, + childTxReceipt: autoRedeem, status: ParentToChildMessageStatus.REDEEMED, } } @@ -395,7 +395,7 @@ export class ParentToChildMessageReader extends ParentToChildMessage { ) if (successfulRedeem.length == 1) return { - txReceipt: successfulRedeem[0], + childTxReceipt: successfulRedeem[0], status: ParentToChildMessageStatus.REDEEMED, } @@ -758,8 +758,8 @@ export class ParentToChildMessageWriter extends ParentToChildMessageReader { * A message for Eth deposits from Parent to Child */ export class EthDepositMessage { - public readonly childDepositTxHash: string - private childDepositTxReceipt: TransactionReceipt | undefined | null + public readonly childTxHash: string + private childTxReceipt: TransactionReceipt | undefined | null public static calculateDepositTxId( childChainId: number, @@ -857,7 +857,7 @@ export class EthDepositMessage { public readonly to: string, public readonly value: BigNumber ) { - this.childDepositTxHash = EthDepositMessage.calculateDepositTxId( + this.childTxHash = EthDepositMessage.calculateDepositTxId( childChainId, messageNumber, from, @@ -868,7 +868,7 @@ export class EthDepositMessage { public async status(): Promise { const receipt = await this.childProvider.getTransactionReceipt( - this.childDepositTxHash + this.childTxHash ) if (receipt === null) return EthDepositMessageStatus.PENDING else return EthDepositMessageStatus.DEPOSITED @@ -877,15 +877,15 @@ export class EthDepositMessage { public async wait(confirmations?: number, timeout?: number) { const chosenTimeout = isDefined(timeout) ? timeout : DEFAULT_DEPOSIT_TIMEOUT - if (!this.childDepositTxReceipt) { - this.childDepositTxReceipt = await getTransactionReceipt( + if (!this.childTxReceipt) { + this.childTxReceipt = await getTransactionReceipt( this.childProvider, - this.childDepositTxHash, + this.childTxHash, confirmations, chosenTimeout ) } - return this.childDepositTxReceipt || null + return this.childTxReceipt || null } } diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 8709857a2a..4d54189b7a 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -383,7 +383,7 @@ export class ParentEthDepositTransactionReceipt extends ParentTransactionReceipt return { complete: isDefined(res), - txReceipt: res, + childTxReceipt: res, message, } } diff --git a/tests/integration/eth.test.ts b/tests/integration/eth.test.ts index d69dcf5912..bbea2bc690 100644 --- a/tests/integration/eth.test.ts +++ b/tests/integration/eth.test.ts @@ -146,11 +146,11 @@ describe('Ether', async () => { 'message inputs value error' ).to.eq(ethToDeposit.toString()) - prettyLog('childDepositTxHash: ' + waitResult.message.childDepositTxHash) + prettyLog('childDepositTxHash: ' + waitResult.message.childTxHash) prettyLog('chain transaction found!') expect(waitResult.complete).to.eq(true, 'eth deposit not complete') - expect(waitResult.txReceipt).to.exist - expect(waitResult.txReceipt).to.not.be.null + expect(waitResult.childTxReceipt).to.exist + expect(waitResult.childTxReceipt).to.not.be.null const testWalletChildEthBalance = await childSigner.getBalance() expect(testWalletChildEthBalance.toString(), 'final balance').to.eq( From 1ff83a833f195f961f48e18d01f5a32db5702df4 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Wed, 10 Jul 2024 19:23:00 +0200 Subject: [PATCH 63/74] chore: bump version to 4.0.0-alpha.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bce040e23..da2b20f199 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.8", + "version": "4.0.0-alpha.9", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From a06007463bec458b587a0a1ac0be41811b4e92f2 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 16 Jul 2024 18:05:56 +0200 Subject: [PATCH 64/74] feat: export compat utils --- src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/index.ts b/src/index.ts index d39e305548..fc75ca783a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -69,6 +69,11 @@ export { getArbitrumNetworkInformationFromRollup, getChildrenForNetwork, registerCustomArbitrumNetwork, + // deprecated, but here for backwards compatibility + L2Network, + L2NetworkTokenBridge, + mapL2NetworkToArbitrumNetwork, + mapL2NetworkTokenBridgeToTokenBridge, } from './lib/dataEntities/networks' export { InboxTools } from './lib/inbox/inbox' export { EventFetcher } from './lib/utils/eventFetcher' From b7a7873eae053bed1e0cdb98162a4da70e2e1f75 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Tue, 16 Jul 2024 18:06:27 +0200 Subject: [PATCH 65/74] chore: bump version to 4.0.0-alpha.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da2b20f199..b783fd5d60 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.9", + "version": "4.0.0-alpha.10", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 4fa580ffe73d5d5e54916c61c8cccc5d51c955d4 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 17 Jul 2024 07:10:24 -0400 Subject: [PATCH 66/74] docs: update for v4 (#494) Co-authored-by: spsjvc --- .gitignore | 4 - README.md | 173 +++++++++------------ docs/1-introduction.mdx | 198 +++++++++++++++++++++++++ docs/2-migrate.mdx | 198 +++++++++++++++++++++++++ package.json | 4 - src/lib/utils/byte_serialize_params.ts | 3 +- theme/style.css | 4 - yarn.lock | 113 +------------- 8 files changed, 472 insertions(+), 225 deletions(-) create mode 100644 docs/1-introduction.mdx create mode 100644 docs/2-migrate.mdx delete mode 100644 theme/style.css diff --git a/.gitignore b/.gitignore index 037426b618..5182036e87 100644 --- a/.gitignore +++ b/.gitignore @@ -244,9 +244,6 @@ instance/ # Scrapy stuff: .scrapy -# Sphinx documentation -docs/_build/ - # PyBuilder target/ @@ -312,6 +309,5 @@ packages/arb-bridge-eth/password.txt packages/issues packages/**/issues -docs json_data abi diff --git a/README.md b/README.md index a787f212a5..0a342a8f1c 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,110 @@ # Arbitrum SDK -TypeScript library for client-side interactions with Arbitrum. Arbitrum SDK provides common helper functionality as well as access to the underlying smart contract interfaces. +[![npm version](https://badge.fury.io/js/%40arbitrum%2Fsdk.svg)](https://badge.fury.io/js/@arbitrum%2Fsdk.svg) +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -Below is an overview of the Arbitrum SDK functionality. See the [tutorials](https://github.com/OffchainLabs/arbitrum-tutorials) for further examples of how to use these classes. +A TypeScript library for client-side interactions with Arbitrum. The Arbitrum SDK provides essential helper functionality and direct access to underlying smart contract interfaces, enabling developers to build powerful applications on the Arbitrum network. -### Quickstart Recipes +> [!IMPORTANT] +> +> This is the code and documentation for `@arbitrum/sdk` v4. +> +> If you're looking for v3, check out [this branch](https://github.com/OffchainLabs/arbitrum-sdk/tree/v3). +> +> If you're looking to migrate from v3 to v4, check out [this guide](./docs/2-migrate.mdx). -- ##### Deposit Ether Into Arbitrum +## Table of Contents -```ts -import { getArbitrumNetwork, EthBridger } from '@arbitrum/sdk' - -const l2Network = await getArbitrumNetwork( - l2ChainID /** <-- chain id of target Arbitrum chain */ -) -const ethBridger = new EthBridger(l2Network) - -const ethDepositTxResponse = await ethBridger.deposit({ - amount: utils.parseEther('23'), - l1Signer: l1Signer /** <-- connected ethers-js Wallet */, - l2Provider: l2Provider /** <--- ethers-js Provider */, -}) +- [Arbitrum SDK](#arbitrum-sdk) + - [Table of Contents](#table-of-contents) + - [Overview](#overview) + - [Installation](#installation) + - [Key Features](#key-features) + - [Bridging Assets](#bridging-assets) + - [Cross-Chain Messages](#cross-chain-messages) + - [Network Configuration](#network-configuration) + - [Usage](#usage) + - [Running Integration Tests](#running-integration-tests) + - [Documentation](#documentation) + - [License](#license) -const ethDepositTxReceipt = await ethDepositTxResponse.wait() - -/** check ethDepositTxReceipt.status */ -``` - -- ##### Redeem an L1 to L2 Message - -```ts -import { L1TransactionReceipt, L1ToL2MessageStatus } from '@arbitrum/sdk' - -const l1TxnReceipt = new L1TransactionReceipt( - txnReceipt /** <-- ethers-js TransactionReceipt of an ethereum tx that triggered an L1 to L2 message (say depositting a token via a bridge) */ -) - -const l1ToL2Message = ( - await l1TxnReceipt.getL1ToL2Messages( - l2Signer /** <-- connected ethers-js Wallet */ - ) -)[0] - -const res = await l1ToL2Message.waitForStatus() - -if (res.status === L1ToL2MessageStatus.FUNDS_DEPOSITED_ON_L2) { - /** Message wasn't auto-redeemed; redeem it now: */ - const response = await l1ToL2Message.redeem() - const receipt = await response.wait() -} else if (res.status === L1ToL2MessageStatus.REDEEMED) { - /** Message succesfully redeeemed */ -} -``` +## Overview -- ##### Check if sequencer has included a transaction in L1 data +Arbitrum SDK simplifies the process of interacting with Arbitrum chains, offering a robust set of tools for asset bridging and cross-chain messaging. -```ts -import { L2TransactionReceipt } from '@arbitrum/sdk' +## Installation -const l2TxnReceipt = new L2TransactionReceipt( - txnReceipt /** <-- ethers-js TransactionReceipt of an arbitrum tx */ -) +```bash +npm install @arbitrum/sdk -/** Wait 3 minutes: */ -await new Promise(resolve => setTimeout(resolve, 1000 * 60 * 3000)) +# or -// if dataIsOnL1, sequencer has posted it and it inherits full rollup/L1 security -const dataIsOnL1 = await l2TxnReceipt.isDataAvailable(l2Provider, l1Provider) +yarn add @arbitrum/sdk ``` -### Bridging assets - -Arbitrum SDK can be used to bridge assets to/from the rollup chain. The following asset bridgers are currently available: - -- EthBridger -- Erc20Bridger - -All asset bridgers have the following methods: +## Key Features -- **deposit** - moves assets from the L1 to the L2 -- **depositEstimateGas** - estimates the gas required to do the deposit -- **withdraw** - moves assets from the L2 to the L1 -- **withdrawEstimateGas** - estimates the gas required to do the withdrawal - Which accept different parameters depending on the asset bridger type +### Bridging Assets -### Cross chain messages +Arbitrum SDK facilitates the bridging of assets between an Arbitrum chain and its parent chain. Currently supported asset bridgers: -When assets are moved by the L1 and L2 cross chain messages are sent. The lifecycles of these messages are encapsulated in the classes `L1ToL2Message` and `L2ToL1Message`. These objects are commonly created from the receipts of transactions that send cross chain messages. A cross chain message will eventually result in a transaction being executed on the destination chain, and these message classes provide the ability to wait for that finalizing transaction to occur. +- `EthBridger`: For bridging ETH to and from an Arbitrum chain (L2 or L3) +- `Erc20Bridger`: For bridging ERC-20 tokens to and from an Arbitrum chain (L2 or L3) +- `EthL1L3Bridger`: For bridging ETH to an L3 directly from L1 +- `Erc20L1L3Bridger`: For bridging ERC-20 tokens to an L3 directly from L1 -### Networks +### Cross-Chain Messages -Arbitrum SDK comes pre-configured for Mainnet and Sepolia, and their Arbitrum counterparts. However, the networks functionality can be used to register networks for custom Arbitrum instances. Most of the classes in Arbitrum SDK depend on network objects so this must be configured before using other Arbitrum SDK functionality. +Cross-chain communication is handled through `ParentToChildMessage` and `ChildToParentMessage` classes. These encapsulate the lifecycle of messages sent between chains, typically created from transaction receipts that initiate cross-chain messages. -### Inbox tools +### Network Configuration -As part of normal operation the Arbitrum sequencer will send messages into the rollup chain. However, if the sequencer is unavailable and not posting batches, the inbox tools can be used to force the inclusion of transactions into the rollup chain. +The SDK comes preconfigured for Arbitrum One, Arbitrum Nova and Arbitrum Sepolia. Custom Arbitrum networks can be registered using `registerCustomArbitrumNetwork`, which is required before utilizing other SDK features. -### Utils +## Usage -- **EventFetcher** - A utility to provide typing for the fetching of events -- **MultiCaller** - A utility for executing multiple calls as part of a single RPC request. This can be useful for reducing round trips. -- **constants** - A list of useful Arbitrum related constants +Here's a basic example of using the SDK to bridge ETH: -### Run Integration tests - -1. First, make sure you have a Nitro test node running. Follow the instructions [here](https://docs.arbitrum.io/node-running/how-tos/local-dev-node). +```ts +import { ethers } from 'ethers' +import { EthBridger, getArbitrumNetwork } from '@arbitrum/sdk' -2. After the node has started up (that could take up to 20-30 mins), run `yarn gen:network`. +async function bridgeEth(parentSigner: ethers.Signer, childChainId: number) { + const childNetwork = await getArbitrumNetwork(childChainId) + const ethBridger = new EthBridger(childNetwork) -3. Once done, finally run `yarn test:integration` to run the integration tests. + const deposit = await ethBridger.deposit({ + amount: ethers.utils.parseEther('0.1'), + parentSigner, + }) -Defaults to `Arbitrum Sepolia`, for custom network use `--network` flag. + const txReceipt = await deposit.wait() + console.log(`Deposit initiated: ${txReceipt.transactionHash}`) +} +``` -`Arbitrum Sepolia` expects env var `ARB_KEY` to be prefunded with at least 0.02 ETH, and env var `INFURA_KEY` to be set. -(see `integration_test/config.ts`) +For more detailed usage examples and API references, please refer to the [Arbitrum SDK documentation](https://docs.arbitrum.io/sdk). -### Bridge A Standard Token +## Running Integration Tests -Bridging a new token to L2 (i.e., deploying a new token contract) through the standard gateway is done by simply depositing a token that hasn't yet been bridged. This repo includes a script to trigger this initial deposit/deployment: +1. Set up a Nitro test node by following the instructions [here](https://docs.arbitrum.io/node-running/how-tos/local-dev-node). +2. Copy `.env.example` to `.env` and update relevant environment variables. +3. Generate the network configuration against your active Nitro test node: -1. Clone `arbitrum-sdk` + ```sh + yarn gen:network + ``` -2. `yarn install` (from root) +4. Execute the integration tests: -3. Set `PRIVKEY` environment variable (you can use .env) to the key of the account from which you'll be deploying (account should have some balance of the token you're bridging). + ```sh + yarn test:integration + ``` -4. Set MAINNET_RPC environment variable to L1 RPC endpoint (i.e., https://mainnet.infura.io/v3/my-infura-key) +## Documentation -5. `yarn bridgeStandardToken` +For comprehensive guides and API documentation, visit the [Arbitrum SDK Documentation](https://docs.arbitrum.io/sdk). -Required CL params: -`networkID`:number — Chain ID of L2 network -`l1TokenAddress`:string — address of L1 token to be bridged +## License -Ex: -`yarn bridgeStandardToken --networkID 421614 --l1TokenAddress 0xdf032bc4b9dc2782bb09352007d4c57b75160b15 --amount 3` +Arbitrum SDK is released under the [Apache 2.0 License](LICENSE). diff --git a/docs/1-introduction.mdx b/docs/1-introduction.mdx new file mode 100644 index 0000000000..7b53656af6 --- /dev/null +++ b/docs/1-introduction.mdx @@ -0,0 +1,198 @@ +# Introduction + +The Arbitrum SDK is a powerful TypeScript library that streamlines interactions with Arbitrum networks. It offers robust tools for bridging tokens and passing messages between networks through an intuitive interface to the underlying smart contracts. + +**Key Features** + +- Token Bridging: Effortlessly bridge tokens between Ethereum and Arbitrum. +- Message Passing: Seamlessly pass messages across networks. +- Contracts Interface: Leverage a strongly-typed interface for interacting with smart contracts. + +Below is an overview of the Arbitrum SDK functionality. See the [tutorials](https://github.com/OffchainLabs/arbitrum-tutorials) for more examples. + +## Getting Started + +Install dependencies + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +```sh +npm install @arbitrum/sdk +``` + + + + +```sh +yarn add @arbitrum/sdk +``` + + + + +```sh +pnpm install @arbitrum/sdk +``` + + + + +## Using the Arbitrum SDK + +### Bridging assets + +Arbitrum SDK can be used to bridge assets to or from an Arbitrum Network. The following asset bridgers are currently available: + +- [`EthBridger`](./reference/assetBridger/ethBridger.md) +- [`Erc20Bridger`](./reference/assetBridger/erc20Bridger.md) + +All asset bridgers have the following methods which accept different parameters depending on the asset bridger type: + +- [`deposit`](./reference/assetBridger/assetBridger.md#deposit) - moves assets from the Parent to the Child chain +- [`withdraw`](./reference/assetBridger/assetBridger.md#withdraw) - moves assets from the Child to the Parent chain + +#### Example ETH Deposit to Arbitrum One + +```ts +import { getArbitrumNetwork, EthBridger } from '@arbitrum/sdk' + +// get the `@arbitrum/sdk` ArbitrumNetwork object using the chain id of the Arbitrum One chain +const childNetwork = await getArbitrumNetwork(42161) +const ethBridger = new EthBridger(childNetwork) + +const ethDepositTxResponse = await ethBridger.deposit({ + amount: utils.parseEther('23'), + parentSigner, // an ethers v5 signer connected to mainnet ethereum + childProvider, // an ethers v5 provider connected to Arbitrum One +}) + +const ethDepositTxReceipt = await ethDepositTxResponse.wait() +``` + +[Learn more in the Eth Deposit tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/eth-deposit) + +#### Example ETH Withdrawal from Arbitrum One + +```ts +import { getArbitrumNetwork, EthBridger } from '@arbitrum/sdk' + +// get the `@arbitrum/sdk` ArbitrumNetwork object using the chain id of the Arbitrum One chain +const childNetwork = await getArbitrumNetwork(42161) +const ethBridger = new EthBridger(childNetwork) + +const withdrawTx = await ethBridger.withdraw({ + amount: utils.parseEther('23'), + childSigner, // an ethers v5 signer connected to Arbitrum One + destinationAddress: childWallet.address, +}) +const withdrawRec = await withdrawTx.wait() +``` + +[Learn more in the Eth Withdraw tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/eth-withdraw) + +### Networks + +Arbitrum SDK comes pre-configured for Mainnet and Sepolia, and their Arbitrum counterparts. Any other networks that are not pre-configured **must** be registered before being used. + +#### Configuring Network + +To interact with a custom [`ArbitrumNetwork`](./reference/dataEntities/networks), you can register it using the [`registerCustomArbitrumNetwork`](./reference/dataEntities/networks.md#registerCustomArbitrumNetwork) function. + +```ts +import { registerCustomArbitrumNetwork } from '@arbitrum/sdk' + +registerCustomArbitrumNetwork({ + chainID: 123456, + name: 'Custom Arbitrum Network', +}) +``` + +### Cross chain messages + +When assets are moved by the Parent and Child cross chain messages are sent. The lifecycles of these messages are encapsulated in the classes [`ParentToChildMessage`](./reference/message/ParentToChildMessage) and [`ChildToParentMessage`](./reference/message/ParentToChildMessage). These objects are commonly created from the receipts of transactions that send cross chain messages. A cross chain message will eventually result in a transaction being executed on the destination chain, and these message classes provide the ability to wait for that finalizing transaction to occur. + +#### Redeem a Parent-to-Child Message + +```ts +import { + ParentTransactionReceipt, + ParentToChildMessageStatus, +} from '@arbitrum/sdk' + +const parentTxnReceipt = new ParentTransactionReceipt( + txnReceipt // ethers-js TransactionReceipt of an ethereum tx that triggered a Parent-to-Child message (say depositing a token via a bridge) +) + +const parentToChildMessage = ( + await parentTxnReceipt.getParentToChildMessages( + childSigner // connected ethers-js Wallet + ) +)[0] + +const res = await parentToChildMessage.waitForStatus() + +if (res.status === ParentToChildMessageStatus.Child) { + // Message wasn't auto-redeemed; redeem it now: + const response = await parentToChildMessage.redeem() + const receipt = await response.wait() +} else if (res.status === ParentToChildMessageStatus.REDEEMED) { + // Message successfully redeemed +} +``` + +[Learn more in the Redeem Failed Retryable Tickets tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/redeem-failed-retryable) + +### Inbox Tools + +As part of normal operation, the Arbitrum sequencer will send messages into the rollup chain. However, if the sequencer is unavailable and not posting batches, the inbox tools can be used to force the inclusion of transactions into the Arbitrum network. + +Here's how you can use the inbox tools to withdraw ether from Arbitrum One without waiting for the sequencer: + +```ts +const childNetwork = await getArbitrumNetwork(await childWallet.getChainId()) + +const inboxSdk = new InboxTools(parentWallet, childNetwork) +const arbSys = ArbSys__factory.connect(ARB_SYS_ADDRESS, childProvider) +const arbSysIface = arbSys.interface +const childCalldata = arbSysIface.encodeFunctionData('withdrawEth', [ + parentWallet.address, +]) + +const txChildRequest = { + data: childCalldata, + to: ARB_SYS_ADDRESS, + value: 1, +} + +const childSignedTx = await inboxSdk.signChildTx(txChildRequest, childWallet) +const childTxhash = ethers.utils.parseTransaction(childSignedTx).hash +const resultsParent = await inboxSdk.sendChildSignedTx(childSignedTx) + +const inboxRec = await resultsParent.wait() +``` + +[Learn more in the Delayed Inbox tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/delayedInbox-l2msg). + +### Utils + +- [`EventFetcher`](./reference/utils/eventFetcher) - A utility to provide typing for the fetching of events +- [`MultiCaller`](./reference/utils/multicall#multicaller) - A utility for executing multiple calls as part of a single RPC request. This can be useful for reducing round trips. +- [`constants`](./reference/dataEntities/constants) - A list of useful Arbitrum related constants + +## Development + +### Run Integration tests + +1. Copy the `.env-sample` file to `.env` and update the values with your own. +1. First, make sure you have a [Nitro test node](https://github.com/Offchainlabs/nitro-testnode) running. Follow the instructions [here](https://docs.arbitrum.io/node-running/how-tos/local-dev-node). +1. After the node has started up (that could take up to 20-30 mins), run `yarn gen:network`. +1. Once done, finally run `yarn test:integration` to run the integration tests. + +Defaults to `Arbitrum Sepolia`, for custom network use `--network` flag. + +`Arbitrum Sepolia` expects env var `ARB_KEY` to be prefunded with at least 0.02 ETH, and env var `INFURA_KEY` to be set. +(see `integration_test/config.ts`) diff --git a/docs/2-migrate.mdx b/docs/2-migrate.mdx new file mode 100644 index 0000000000..f45d5f3550 --- /dev/null +++ b/docs/2-migrate.mdx @@ -0,0 +1,198 @@ +# Migrating from v3 to v4 + +## Introduction + +`@arbitrum/sdk` v4 introduces significant changes to improve support Orbit chains from Offchain Labs. This guide outlines the breaking changes to know before migrating your existing v3 code to v4. + +## Major Changes Overview + +1. Terminology change from L1/L2 to parent/child +2. Network types and functions updated +3. Updates to `AssetBridger` and `Erc20Bridger` classes +4. Changes to Message classes + +## Detailed Changes + +### 1. Terminology change from L1/L2 to parent/child + +Most instances of "L1" and "L2" have been replaced with "parent" and "child" respectively. This change reflects the more general parent-child relationship between chains in the Arbitrum ecosystem. + +- In most circumstances, when referring to a parent-child relationship between chains, the terms "parent" and "child" are used. +- Though, when referring explicitly to "L1", "L2", or "L3", those specific terms are still used. + +### 2. Network types and functions updated + +- The `L1Network` is no longer required to be registered before bridging. +- Only Arbitrum networks need to be registered. +- Arbitrum networks are defined as Arbitrum One, Arbitrum testnets, and any Orbit chain. +- If you need a full list of Arbitrum networks, you can use the new [`getArbitrumNetworks`](./reference/dataEntities/networks#getArbitrumNetworks) function. +- To list all of the children of a network, use the new [`getChildrenForNetwork`](./reference/dataEntities/networks#getChildrenForNetwork) function. + +| v3 Name | v4 Name | +| --------------------- | -------------------------------------------------------------------------------------------------- | +| `L2Network` | [`ArbitrumNetwork`](./reference/dataEntities/networks#arbitrumnetwork) | +| `getL2Network` | [`getArbitrumNetwork`](./reference/dataEntities/networks#getArbitrumNetwork) | +| `l2Networks` | [`getArbitrumNetworks`](./reference/dataEntities/networks#getArbitrumNetworks) | +| `addCustomNetwork` | [`registerCustomArbitrumNetwork`](./reference/dataEntities/networks#registerCustomArbitrumNetwork) | +| `Network` | *removed* | +| `L1Network` | *removed* | +| `getL1Network` | *removed* | +| `getParentForNetwork` | *removed* | + +#### `ArbitrumNetwork` type + +`Network` type has been replaced with the [`ArbitrumNetwork`](./reference/dataEntities/networks#arbitrumnetwork) type and some properties have been removed or renamed. + +| v3 Name | v4 Name | +| --------------------- | --------------- | +| `chainID` | `chainId` | +| `partnerChainID` | `parentChainId` | +| `explorerUrl` | *removed* | +| `isArbitrum` | *removed* | +| `partnerChainIDs` | *removed* | +| `nitroGenesisBlock` | *removed* | +| `nitroGenesisL1Block` | *removed* | +| `depositTimeout` | *removed* | +| `blockTime` | *removed* | + +#### `TokenBridge` type + +The `TokenBridge` type within the[`ArbitrumNetwork`](./reference/dataEntities/networks#arbitrumnetwork) object has been updated. + +| v3 Name | v4 Name | +| ----------------- | --------------------- | +| `l1CustomGateway` | `parentCustomGateway` | +| `l1ERC20Gateway` | `parentErc20Gateway` | +| `l1GatewayRouter` | `parentGatewayRouter` | +| `l1MultiCall` | `parentMultiCall` | +| `l1ProxyAdmin` | `parentProxyAdmin` | +| `l1Weth` | `parentWeth` | +| `l1WethGateway` | `parentWethGateway` | +| `l2CustomGateway` | `childCustomGateway` | +| `l2ERC20Gateway` | `childErc20Gateway` | +| `l2GatewayRouter` | `childGatewayRouter` | +| `l2Multicall` | `childMultiCall` | +| `l2ProxyAdmin` | `childProxyAdmin` | +| `l2Weth` | `childWeth` | +| `l2WethGateway` | `childWethGateway` | + +### 3. Updates to `AssetBridger` and `Erc20Bridger` classes + +#### [`AssetBridger`](./reference/assetBridger/assetBridger.md) Class Methods + +The [`AssetBridger`](./reference/assetBridger/assetBridger.md) class methods and properties have been renamed to reflect the new parent-child terminology. + +| v3 Name | v4 Name | +| ---------------- | -------------------- | +| `l2Network` | `childNetwork` | +| `checkL1Network` | `checkParentNetwork` | +| `checkL2Network` | `checkChildNetwork` | + +#### [`AssetBridger`](./reference/assetBridger/assetBridger.md) Class Method Parameters + +The objects passed to the class methods of classes that inherit from [`AssetBridger`](./reference/assetBridger/assetBridger.md) ([`EthBridger`](./reference/assetBridger/ethBridger.md) and [`Erc20Bridger`](./reference/assetBridger/erc20Bridger.md)) have been renamed. + +| v3 Name | v4 Name | +| ---------------- | -------------------- | +| `erc20L1Address` | `erc20ParentAddress` | +| `l1Provider` | `parentProvider` | +| `l2Provider` | `childProvider` | +| `l1Signer` | `parentSigner` | +| `l2Signer` | `childSigner` | + +#### [`Erc20Bridger`](./reference/assetBridger/erc20Bridger.md) Class Methods + +| v3 Name | v4 Name | +| ----------------------- | --------------------------- | +| `getL1GatewayAddress` | `getParentGatewayAddress` | +| `getL2GatewayAddress` | `getChildGatewayAddress` | +| `getL2WithdrawalEvents` | `getWithdrawalEvents` | +| `getL1TokenContract` | `getParentTokenContract` | +| `getL1ERC20Address` | `getParentErc20Address` | +| `getL2TokenContract` | `getChildTokenContract` | +| `getL2ERC20Address` | `getChildErc20Address` | +| `l1TokenIsDisabled` | `isDepositDisabled` | +| `l1Provider` | `parentProvider` | +| `getL1GatewaySetEvents` | `getParentGatewaySetEvents` | +| `getL2GatewaySetEvents` | `getChildGatewaySetEvents` | + +#### [`Erc20L1L3Bridger`](./reference/assetBridger/L1L3Bridger.md) Class Methods + +| v3 Name | v4 Name | +| ------------------- | ------------------- | +| `getL2ERC20Address` | `getL2Erc20Address` | +| `getL3ERC20Address` | `getL3Erc20Address` | + +### 4. Changes to Message classes + +Message classes have been renamed and their methods updated: + +| v3 Name | v4 Name | +| ----------------------------- | ----------------------------------------- | +| `L1TransactionReceipt` | `ParentTransactionReceipt` | +| `L1ContractTransaction` | `ParentContractTransaction` | +| `L1ToL2Message` | `ParentToChildMessage` | +| `L1ToL2MessageWriter` | `ParentToChildMessageWriter` | +| `L1ToL2MessageReader` | `ParentToChildMessageReader` | +| `L1ToL2MessageReaderClassic` | `ParentToChildMessageReaderClassic` | +| `L1ToL2MessageStatus` | `ParentToChildMessageStatus` | +| `L1ToL2MessageGasEstimator` | `ParentToChildMessageGasEstimator` | +| `L2TransactionReceipt` | `ChildTransactionReceipt` | +| `L2ContractTransaction` | `ChildContractTransaction` | +| `L2ToL1Message` | `ChildToParentMessage` | +| `L2ToL1MessageWriter` | `ChildToParentMessageWriter` | +| `L2ToL1MessageReader` | `ChildToParentMessageReader` | +| `L2ToL1MessageStatus` | `ChildToParentMessageStatus` | +| `EthDepositStatus` | `EthDepositMessageStatus` | +| `EthDepositMessageWaitResult` | `EthDepositMessageWaitForStatusResult` | +| `L1ToL2MessageWaitResult` | `ParentToChildMessageWaitForStatusResult` | + +#### `ChildToParentMessageClassic` + +| v3 Name | v4 Name | +| ----------------- | ------------------------ | +| `getL2ToL1Events` | `getChildToParentEvents` | + +#### `ChildToParentChainMessageNitro` + +| v3 Name | v4 Name | +| ----------------- | ------------------------ | +| `getL2ToL1Events` | `getChildToParentEvents` | + +#### `ChildTransactionReceipt` + +| v3 Name | v4 Name | +| ------------------- | -------------------------- | +| `getL2ToL1Events` | `getChildToParentEvents` | +| `getL2ToL1Messages` | `getChildToParentMessages` | + +#### `ParentToChildMessage` + +| v3 Name | v4 Name | +| ------------------ | ------------------------- | +| `EthDepositStatus` | `EthDepositMessageStatus` | + +#### `ParentToChildMessageStatus` + +| v3 Name | v4 Name | +| ----------------------- | -------------------------- | +| `FUNDS_DEPOSITED_ON_L2` | `FUNDS_DEPOSITED_ON_CHILD` | + +#### `ParentTransactionReceipt` + +| v3 Name | v4 Name | +| -------------------------- | --------------------------------- | +| `getL1ToL2MessagesClassic` | `getParentToChildMessagesClassic` | +| `getL1ToL2Messages` | `getParentToChildMessages` | + +#### `ParentEthDepositTransactionReceipt` + +| v3 Name | v4 Name | +| ----------- | -------------------------------- | +| `waitForL2` | `waitForChildTransactionReceipt` | + +#### `ParentContractCallTransactionReceipt` + +| v3 Name | v4 Name | +| ----------- | -------------------------------- | +| `waitForL2` | `waitForChildTransactionReceipt` | diff --git a/package.json b/package.json index b783fd5d60..b7e8f409e3 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,6 @@ "lint": "eslint .", "format": "prettier './**/*.{js,json,md,ts,yml}' '!./src/lib/abi' --write && yarn run lint --fix", "clean:compile": "ts-node scripts/cleanCompileContracts.ts", - "generate_docs": "typedoc --options typedoc_md.js && node scripts/postProcessDocs.js", - "generate_docs_site": "typedoc", "checkRetryable": "ts-node scripts/checkRetryableStatus.ts", "redeemRetryable": "ts-node scripts/redeemRetryable.ts", "setStandard": "ts-node scripts/setStandardGateways.ts", @@ -86,8 +84,6 @@ "ts-node": "^10.2.1", "tslint": "^6.1.3", "typechain": "7.0.0", - "typedoc": "^0.25.7", - "typedoc-plugin-markdown": "^3.17.1", "typescript": "^4.9.5", "yargs": "^17.3.1" }, diff --git a/src/lib/utils/byte_serialize_params.ts b/src/lib/utils/byte_serialize_params.ts index 577a3515c9..f3afa1e1c1 100644 --- a/src/lib/utils/byte_serialize_params.ts +++ b/src/lib/utils/byte_serialize_params.ts @@ -92,7 +92,8 @@ export const getAddressIndex = (() => { })() /** - // to use: + to use: + ```js const mySerializeParamsFunction = argSerializerConstructor("rpcurl") mySerializeParamsFunction(["4","5", "6"]) diff --git a/theme/style.css b/theme/style.css deleted file mode 100644 index a53d604b27..0000000000 --- a/theme/style.css +++ /dev/null @@ -1,4 +0,0 @@ -:root { - /* we can override CSS variables */ - /* --light-color-background: #ffffff; */ -} diff --git a/yarn.lock b/yarn.lock index b297791c83..6193b395ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1866,11 +1866,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-sequence-parser@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz#4d790f31236ac20366b23b3916b789e1bde39aed" - integrity sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -3627,18 +3622,6 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - hardhat@^2.18.3: version "2.18.3" resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.18.3.tgz#8fd01348795c77086fff417a4d13c521dce28fcf" @@ -4206,11 +4189,6 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -4391,11 +4369,6 @@ lru_map@^0.3.3: resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -4420,11 +4393,6 @@ map-stream@0.0.7: resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" integrity sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ== -marked@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - mcl-wasm@^0.7.1: version "0.7.9" resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" @@ -4509,21 +4477,7 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -4649,11 +4603,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -5405,16 +5354,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shiki@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" - integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== - dependencies: - ansi-sequence-parser "^1.1.0" - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" - side-channel@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.5.tgz#9a84546599b48909fb6af1211708d23b1946221b" @@ -5941,23 +5880,6 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedoc-plugin-markdown@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.17.1.tgz#c33f42363c185adf842f4699166015f7fe0ed02b" - integrity sha512-QzdU3fj0Kzw2XSdoL15ExLASt2WPqD7FbLeaqwT70+XjKyTshBnUlQA5nNREO1C2P8Uen0CDjsBLMsCQ+zd0lw== - dependencies: - handlebars "^4.7.7" - -typedoc@^0.25.7: - version "0.25.7" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.7.tgz#11e3f527ca80ca3c029cb8e15f362e6d9f715e25" - integrity sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow== - dependencies: - lunr "^2.3.9" - marked "^4.3.0" - minimatch "^9.0.3" - shiki "^0.14.7" - typescript@^4.9.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" @@ -5973,11 +5895,6 @@ typical@^5.2.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== -uglify-js@^3.1.4: - version "3.15.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.4.tgz#fa95c257e88f85614915b906204b9623d4fa340d" - integrity sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -6058,29 +5975,6 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -6127,11 +6021,6 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - wordwrapjs@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" From 98b08b2457c9118f6361d4913e0352feb486c8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragi=C5=A1a=20Spasojevi=C4=87?= Date: Wed, 17 Jul 2024 13:14:46 +0200 Subject: [PATCH 67/74] chore: update yarn.lock --- yarn.lock | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/yarn.lock b/yarn.lock index 6193b395ef..92a334607c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4477,6 +4477,13 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" @@ -5975,6 +5982,19 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" From 6357832c01383135eb25e1b4b5909905e4b28e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dragi=C5=A1a=20Spasojevi=C4=87?= Date: Wed, 17 Jul 2024 13:14:56 +0200 Subject: [PATCH 68/74] chore: bump version to 4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7e8f409e3..bfd602db7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0-alpha.10", + "version": "4.0.0", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From f5b3d04baf62356032f5475057637d989da5b6c1 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Wed, 17 Jul 2024 12:47:14 -0400 Subject: [PATCH 69/74] docs: fix casing of markdown link (#517) --- docs/2-migrate.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2-migrate.mdx b/docs/2-migrate.mdx index f45d5f3550..6c65870c31 100644 --- a/docs/2-migrate.mdx +++ b/docs/2-migrate.mdx @@ -116,7 +116,7 @@ The objects passed to the class methods of classes that inherit from [`AssetBrid | `getL1GatewaySetEvents` | `getParentGatewaySetEvents` | | `getL2GatewaySetEvents` | `getChildGatewaySetEvents` | -#### [`Erc20L1L3Bridger`](./reference/assetBridger/L1L3Bridger.md) Class Methods +#### [`Erc20L1L3Bridger`](./reference/assetBridger/l1l3Bridger.md) Class Methods | v3 Name | v4 Name | | ------------------- | ------------------- | From 116c15d1459e3cb2fe9bba726de1f38ebfca79fd Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:39:02 -0400 Subject: [PATCH 70/74] docs: fix warnings for jsdoc comments (#518) --- src/lib/assetBridger/erc20Bridger.ts | 32 +++++++++++-------- src/lib/inbox/inbox.ts | 2 +- src/lib/message/ChildToParentMessage.ts | 8 ++--- .../message/ChildToParentMessageClassic.ts | 2 +- src/lib/message/ChildToParentMessageNitro.ts | 4 +-- src/lib/message/ChildTransaction.ts | 2 +- src/lib/message/ParentTransaction.ts | 2 +- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/lib/assetBridger/erc20Bridger.ts b/src/lib/assetBridger/erc20Bridger.ts index 84ceed3b0b..d7feb62119 100644 --- a/src/lib/assetBridger/erc20Bridger.ts +++ b/src/lib/assetBridger/erc20Bridger.ts @@ -899,9 +899,11 @@ export class Erc20Bridger extends AssetBridger< /** * Checks if the token has been properly registered on both gateways. Mostly useful for tokens that use a custom gateway. - * @param erc20ParentAddress - * @param parentProvider - * @param childProvider + * + * @param {Object} params + * @param {string} params.erc20ParentAddress + * @param {Provider} params.parentProvider + * @param {Provider} params.childProvider * @returns */ public async isRegistered({ @@ -1170,9 +1172,9 @@ export class AdminErc20Bridger extends Erc20Bridger { /** * Get all the gateway set events on the Parent gateway router - * @param parentProvider - * @param customNetworkParentGatewayRouter - * @returns + * @param parentProvider The provider for the parent network + * @param filter An object containing fromBlock and toBlock to filter events + * @returns An array of GatewaySetEvent event arguments */ public async getParentGatewaySetEvents( parentProvider: Provider, @@ -1193,25 +1195,27 @@ export class AdminErc20Bridger extends Erc20Bridger { } /** - * Get all the gateway set events on the L2 gateway router - * @param parentProvider - * @param customNetworkParentGatewayRouter - * @returns + * Get all the gateway set events on the child gateway router + * @param childProvider The provider for the child network + * @param filter An object containing fromBlock and toBlock to filter events + * @param customNetworkChildGatewayRouter Optional address of the custom network child gateway router + * @returns An array of GatewaySetEvent event arguments + * @throws {ArbSdkError} If the network is custom and customNetworkChildGatewayRouter is not provided */ public async getChildGatewaySetEvents( childProvider: Provider, filter: { fromBlock: BlockTag; toBlock: BlockTag }, - customNetworkL2GatewayRouter?: string + customNetworkChildGatewayRouter?: string ): Promise[]> { - if (this.childNetwork.isCustom && !customNetworkL2GatewayRouter) { + if (this.childNetwork.isCustom && !customNetworkChildGatewayRouter) { throw new ArbSdkError( - 'Must supply customNetworkL2GatewayRouter for custom network ' + 'Must supply customNetworkChildGatewayRouter for custom network ' ) } await this.checkChildNetwork(childProvider) const childGatewayRouterAddress = - customNetworkL2GatewayRouter || + customNetworkChildGatewayRouter || this.childNetwork.tokenBridge.childGatewayRouter const eventFetcher = new EventFetcher(childProvider) diff --git a/src/lib/inbox/inbox.ts b/src/lib/inbox/inbox.ts index a2f4c88ac1..7e6f6a4259 100644 --- a/src/lib/inbox/inbox.ts +++ b/src/lib/inbox/inbox.ts @@ -418,7 +418,7 @@ export class InboxTools { * Sign a transaction with msg.to, msg.value and msg.data. * You can use this as a helper to call inboxTools.sendChainSignedMessage * above. - * @param message A signed transaction which can be sent directly to chain, + * @param txRequest A signed transaction which can be sent directly to chain, * tx.to, tx.data, tx.value must be provided when not contract creation, if * contractCreation is true, no need provide tx.to. tx.gasPrice and tx.nonce * can be overrided. (You can also send contract creation transaction by set tx.to diff --git a/src/lib/message/ChildToParentMessage.ts b/src/lib/message/ChildToParentMessage.ts index 37a5057470..7ac988d74e 100644 --- a/src/lib/message/ChildToParentMessage.ts +++ b/src/lib/message/ChildToParentMessage.ts @@ -69,9 +69,9 @@ export class ChildToParentMessage { /** * Instantiates a new `ChildToParentMessageWriter` or `ChildToParentMessageReader` object. * - * @param {SignerOrProvider} ParentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. + * @param {SignerOrProvider} parentSignerOrProvider Signer or provider to be used for executing or reading the Child-to-Parent message. * @param {ChildToParentTransactionEvent} event The event containing the data of the Child-to-Parent message. - * @param {Provider} [ParentProvider] Optional. Used to override the Provider which is attached to `ParentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `ParentSignerOrProvider` in case you need more control. This will be a required parameter in a future major version update. */ public static fromEvent( parentSignerOrProvider: T, @@ -289,9 +289,9 @@ export class ChildToParentMessageWriter extends ChildToParentMessageReader { /** * Instantiates a new `ChildToParentMessageWriter` object. * - * @param {Signer} ParentSigner The signer to be used for executing the Child-to-Parent message. + * @param {Signer} parentSigner The signer to be used for executing the Child-to-Parent message. * @param {ChildToParentTransactionEvent} event The event containing the data of the Child-to-Parent message. - * @param {Provider} [ParentProvider] Optional. Used to override the Provider which is attached to `ParentSigner` in case you need more control. This will be a required parameter in a future major version update. + * @param {Provider} [parentProvider] Optional. Used to override the Provider which is attached to `parentSigner` in case you need more control. This will be a required parameter in a future major version update. */ constructor( parentSigner: Signer, diff --git a/src/lib/message/ChildToParentMessageClassic.ts b/src/lib/message/ChildToParentMessageClassic.ts index e646083a7d..368cba35ca 100644 --- a/src/lib/message/ChildToParentMessageClassic.ts +++ b/src/lib/message/ChildToParentMessageClassic.ts @@ -333,7 +333,7 @@ export class ChildToParentMessageReaderClassic extends ChildToParentMessageClass /** * Get the status of this message * In order to check if the message has been executed proof info must be provided. - * @param proofInfo + * @param childProvider * @returns */ public async status( diff --git a/src/lib/message/ChildToParentMessageNitro.ts b/src/lib/message/ChildToParentMessageNitro.ts index 8d8698dc07..e9f25f155b 100644 --- a/src/lib/message/ChildToParentMessageNitro.ts +++ b/src/lib/message/ChildToParentMessageNitro.ts @@ -524,8 +524,8 @@ export class ChildToParentMessageReaderNitro extends ChildToParentMessageNitro { /** * Check whether the provided network has a BoLD rollup - * @param l2Network - * @param l1Provider + * @param arbitrumNetwork + * @param parentProvider * @returns */ private async isBold( diff --git a/src/lib/message/ChildTransaction.ts b/src/lib/message/ChildTransaction.ts index 1f29c13854..7c86ba2e75 100644 --- a/src/lib/message/ChildTransaction.ts +++ b/src/lib/message/ChildTransaction.ts @@ -114,7 +114,7 @@ export class ChildTransactionReceipt implements TransactionReceipt { /** * Get any child-to-parent-messages created by this transaction - * @param l2SignerOrProvider + * @param parentSignerOrProvider */ public async getChildToParentMessages( parentSignerOrProvider: T diff --git a/src/lib/message/ParentTransaction.ts b/src/lib/message/ParentTransaction.ts index 4d54189b7a..0818b25576 100644 --- a/src/lib/message/ParentTransaction.ts +++ b/src/lib/message/ParentTransaction.ts @@ -186,7 +186,7 @@ export class ParentTransactionReceipt implements TransactionReceipt { /** * Get any eth deposit messages created by this transaction - * @param childSignerOrProvider + * @param childProvider */ public async getEthDeposits( childProvider: Provider From 480ad7176b18573b9fe9e65122b7910464a98acd Mon Sep 17 00:00:00 2001 From: Fionna Chan <13184582+fionnachan@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:45:26 +0100 Subject: [PATCH 71/74] ci: replace restore action with install action (#524) --- .github/workflows/build-test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index b8b1acd692..2a675fc22c 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -46,8 +46,8 @@ jobs: with: node-version: ${{ matrix.node-version }} - - name: Restore node_modules - uses: OffchainLabs/actions/node-modules/restore@main + - name: Install node_modules + uses: OffchainLabs/actions/node-modules/install@main - name: Lint sdk run: | @@ -91,8 +91,8 @@ jobs: with: node-version: ${{ matrix.node-version }} - - name: Restore node_modules - uses: OffchainLabs/actions/node-modules/restore@main + - name: Install node_modules + uses: OffchainLabs/actions/node-modules/install@main - run: yarn audit:ci @@ -112,8 +112,8 @@ jobs: with: node-version: ${{ matrix.node-version }} - - name: Restore node_modules - uses: OffchainLabs/actions/node-modules/restore@main + - name: Install node_modules + uses: OffchainLabs/actions/node-modules/install@main - name: Build run: | @@ -152,8 +152,8 @@ jobs: with: node-version: ${{ matrix.node-version }} - - name: Restore node_modules - uses: OffchainLabs/actions/node-modules/restore@main + - name: Install node_modules + uses: OffchainLabs/actions/node-modules/install@main - name: Set up the local node uses: OffchainLabs/actions/run-nitro-test-node@main From ae1a33de0df4382b5ee4494bf368504be5add0b3 Mon Sep 17 00:00:00 2001 From: Bartek Date: Fri, 2 Aug 2024 12:01:56 +0200 Subject: [PATCH 72/74] feat: add isTestnet to ArbitrumNetwork (#522) --- src/lib/dataEntities/networks.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/dataEntities/networks.ts b/src/lib/dataEntities/networks.ts index abea1cddda..1b3744f27e 100644 --- a/src/lib/dataEntities/networks.ts +++ b/src/lib/dataEntities/networks.ts @@ -66,6 +66,10 @@ export interface ArbitrumNetwork { * In case of a chain that uses an ERC-20 token from the parent chain as its native/gas token, this is the address of said token on the parent chain */ nativeToken?: string + /** + * Whether or not it is a testnet chain. + */ + isTestnet: boolean /** * Whether or not the chain was registered by the user. */ @@ -197,6 +201,7 @@ const networks: { }, confirmPeriodBlocks: 45818, isCustom: false, + isTestnet: false, }, 42170: { chainId: 42170, @@ -209,6 +214,7 @@ const networks: { sequencerInbox: '0x211E1c4c7f1bF5351Ac850Ed10FD68CFfCF6c21b', }, isCustom: false, + isTestnet: false, name: 'Arbitrum Nova', parentChainId: 1, tokenBridge: { @@ -243,6 +249,7 @@ const networks: { sequencerInbox: '0x6c97864CE4bEf387dE0b3310A44230f7E3F1be0D', }, isCustom: false, + isTestnet: true, name: 'Arbitrum Rollup Sepolia Testnet', parentChainId: 11155111, tokenBridge: { From fd66cee17d36838e8d1771d137f78c1d2c07b862 Mon Sep 17 00:00:00 2001 From: spsjvc Date: Fri, 2 Aug 2024 12:17:39 +0200 Subject: [PATCH 73/74] chore: bump version to 4.0.1 (#525) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfd602db7f..6153ca94b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/sdk", - "version": "4.0.0", + "version": "4.0.1", "description": "Typescript library client-side interactions with Arbitrum", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", From 792a7ee3ccf09842653bc49b771671706894cbb4 Mon Sep 17 00:00:00 2001 From: Fionna Chan <13184582+fionnachan@users.noreply.github.com> Date: Tue, 6 Aug 2024 12:10:40 +0100 Subject: [PATCH 74/74] ci: ignore elliptic advisories (#527) --- audit-ci.jsonc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/audit-ci.jsonc b/audit-ci.jsonc index 3b1ff26409..7a87fa4a75 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -104,6 +104,15 @@ // Issue with sol2uml library that generates UML diagrams from Solidity code. Only used at build time. // from: @offchainlabs/l1-l3-teleport-contracts>@arbitrum/nitro-contracts>sol2uml>axios // from: @offchainlabs/l1-l3-teleport-contracts>@arbitrum/token-bridge-contracts>@arbitrum/nitro-contracts>sol2uml>axios - "GHSA-wf5p-g6vw-rhxx" + "GHSA-wf5p-g6vw-rhxx", + // elliptic + // waiting for it to release a fix but low severity so we can ignore it + // from: @ethersproject/signing-key>elliptic + // https://github.com/advisories/GHSA-49q7-c7j4-3p7m + "GHSA-49q7-c7j4-3p7m", + // https://github.com/advisories/GHSA-977x-g7h5-7qgw + "GHSA-977x-g7h5-7qgw", + // https://github.com/advisories/GHSA-f7q4-pwc6-w24p + "GHSA-f7q4-pwc6-w24p" ] }