diff --git a/src/adapter/BaseChainAdapter.ts b/src/adapter/BaseChainAdapter.ts index bf63567804..ee168dfdb3 100644 --- a/src/adapter/BaseChainAdapter.ts +++ b/src/adapter/BaseChainAdapter.ts @@ -48,7 +48,7 @@ import { setL2TokenAllowanceInCache, TransferTokenParams, } from "./utils"; -import { BaseBridgeAdapter, BridgeTransactionDetails } from "./bridges/BaseBridgeAdapter"; +import { BridgeEvents, BaseBridgeAdapter, BridgeTransactionDetails } from "./bridges/BaseBridgeAdapter"; import { OutstandingTransfers } from "../interfaces"; import WETH_ABI from "../common/abi/Weth.json"; import { BaseL2BridgeAdapter } from "./l2Bridges/BaseL2BridgeAdapter"; @@ -57,7 +57,7 @@ import { ExpandedERC20 } from "@across-protocol/contracts"; export type SupportedL1Token = EvmAddress; export type SupportedTokenSymbol = string; -export class BaseChainAdapter { +export class BaseChainAdapter { protected baseL1SearchConfig: MakeOptional; protected baseL2SearchConfig: MakeOptional; protected readonly spokePoolManager: SpokePoolManager; @@ -70,7 +70,7 @@ export class BaseChainAdapter { protected readonly monitoredAddresses: Address[], protected readonly logger: winston.Logger, public readonly supportedTokens: SupportedTokenSymbol[], - protected readonly bridges: { [l1Token: string]: BaseBridgeAdapter }, + protected readonly bridges: { [l1Token: string]: BaseBridgeAdapter }, protected readonly l2Bridges: { [l1Token: string]: BaseL2BridgeAdapter }, protected readonly gasMultiplier: number ) { @@ -513,7 +513,7 @@ export class BaseChainAdapter { await forEachAsync(this.monitoredAddresses, async (monitoredAddress) => { await forEachAsync(availableL1Tokens, async (l1Token) => { const bridge = this.bridges[l1Token.toNative()]; - const [depositInitiatedResults, depositFinalizedResults] = await Promise.all([ + const [depositInitiatedResults, depositFinalizedResults]: [BridgeEvents, BridgeEvents] = await Promise.all([ bridge.queryL1BridgeInitiationEvents(l1Token, monitoredAddress, monitoredAddress, l1SearchConfig), bridge.queryL2BridgeFinalizationEvents(l1Token, monitoredAddress, monitoredAddress, l2SearchConfig), ]); diff --git a/src/adapter/bridges/ArbitrumOrbitBridge.ts b/src/adapter/bridges/ArbitrumOrbitBridge.ts index 87aa451e4e..e074a20ca5 100644 --- a/src/adapter/bridges/ArbitrumOrbitBridge.ts +++ b/src/adapter/bridges/ArbitrumOrbitBridge.ts @@ -33,7 +33,7 @@ const maxFeePerGas: { [chainId: number]: BigNumber } = { [CHAIN_IDs.ARBITRUM_SEPOLIA]: toBN(20e9), }; -export class ArbitrumOrbitBridge extends BaseBridgeAdapter { +export class ArbitrumOrbitBridge extends BaseBridgeAdapter { protected l1GatewayRouter: Contract; private readonly transactionSubmissionData = @@ -58,7 +58,7 @@ export class ArbitrumOrbitBridge extends BaseBridgeAdapter { const l1Abi = CONTRACT_ADDRESSES[hubChainId][`orbitErc20Gateway_${l2chainId}`].abi; const l2Abi = ARBITRUM_ERC20_GATEWAY_L2_ABI; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); const nativeToken = PUBLIC_NETWORKS[l2chainId].nativeToken; // Only set nonstandard gas tokens. diff --git a/src/adapter/bridges/BaseBridgeAdapter.ts b/src/adapter/bridges/BaseBridgeAdapter.ts index 0d5edc8d7f..f29cda5b06 100644 --- a/src/adapter/bridges/BaseBridgeAdapter.ts +++ b/src/adapter/bridges/BaseBridgeAdapter.ts @@ -2,7 +2,6 @@ import { Contract, BigNumber, EventSearchConfig, - Signer, getTranslatedTokenAddress, assert, isDefined, @@ -27,7 +26,7 @@ export type BridgeEvent = SortableEvent & { export type BridgeEvents = { [l2Token: string]: BridgeEvent[] }; -export abstract class BaseBridgeAdapter { +export abstract class BaseBridgeAdapter { protected l1Bridge: Contract; protected l2Bridge: Contract; public gasToken: EvmAddress | undefined; @@ -37,7 +36,8 @@ export abstract class BaseBridgeAdapter { constructor( protected l2chainId: number, protected hubChainId: number, - protected l1Signer: Signer, + protected l1Signer: O, + protected l2SignerOrProvider: D, public l1Gateways: EvmAddress[] ) { this.hubPoolAddress = getHubPoolAddress(hubChainId); diff --git a/src/adapter/bridges/BinanceCEXBridge.ts b/src/adapter/bridges/BinanceCEXBridge.ts index b1f6da181b..77b01071c2 100644 --- a/src/adapter/bridges/BinanceCEXBridge.ts +++ b/src/adapter/bridges/BinanceCEXBridge.ts @@ -24,7 +24,7 @@ import { import { BaseBridgeAdapter, BridgeTransactionDetails, BridgeEvents, BridgeEvent } from "./BaseBridgeAdapter"; import ERC20_ABI from "../../common/abi/MinimalERC20.json"; -export class BinanceCEXBridge extends BaseBridgeAdapter { +export class BinanceCEXBridge extends BaseBridgeAdapter { // Only store the promise in the constructor and evaluate the promise in async blocks. protected readonly binanceApiClientPromise; protected binanceApiClient; @@ -44,7 +44,7 @@ export class BinanceCEXBridge extends BaseBridgeAdapter { throw new Error("Cannot define a binance CEX bridge on a non-production network"); } // No L1 gateways needed since no L1 bridge transfers tokens from the EOA. - super(l2chainId, hubChainId, l1Signer, []); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, []); // Pull the binance API key from environment and throw if we cannot instantiate this bridge. this.binanceApiClientPromise = getBinanceApiClient(process.env["BINANCE_API_BASE"]); diff --git a/src/adapter/bridges/BlastBridge.ts b/src/adapter/bridges/BlastBridge.ts index a26827fd20..4b0d6b4533 100644 --- a/src/adapter/bridges/BlastBridge.ts +++ b/src/adapter/bridges/BlastBridge.ts @@ -12,7 +12,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BaseBridgeAdapter, BridgeTransactionDetails, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class BlastBridge extends BaseBridgeAdapter { +export class BlastBridge extends BaseBridgeAdapter { private readonly l2Gas = 200000; constructor( @@ -27,7 +27,7 @@ export class BlastBridge extends BaseBridgeAdapter { ) { const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].blastBridge; const { address: l2Address, abi: l2Abi } = CONTRACT_ADDRESSES[l2chainId].blastBridge; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); this.l2Bridge = new Contract(l2Address, l2Abi, l2SignerOrProvider); diff --git a/src/adapter/bridges/HyperlaneXERC20Bridge.ts b/src/adapter/bridges/HyperlaneXERC20Bridge.ts index c284197320..0d11acec7b 100644 --- a/src/adapter/bridges/HyperlaneXERC20Bridge.ts +++ b/src/adapter/bridges/HyperlaneXERC20Bridge.ts @@ -18,7 +18,7 @@ import { PUBLIC_NETWORKS, HYPERLANE_NO_DOMAIN_ID } from "@across-protocol/consta import HYPERLANE_ROUTER_ABI from "../../common/abi/IHypXERC20Router.json"; import { HYPERLANE_DEFAULT_FEE_CAP, HYPERLANE_FEE_CAP_OVERRIDES, HYPERLANE_ROUTERS } from "../../common"; -export class HyperlaneXERC20Bridge extends BaseBridgeAdapter { +export class HyperlaneXERC20Bridge extends BaseBridgeAdapter { readonly hubToken: EvmAddress; readonly dstToken: EvmAddress; private readonly hubDomainId: number; @@ -40,7 +40,7 @@ export class HyperlaneXERC20Bridge extends BaseBridgeAdapter { ); const l1RouterEvmAddress = EvmAddress.from(l1RouterAddressStr); - super(l2chainId, hubChainId, l1Signer, [l1RouterEvmAddress]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [l1RouterEvmAddress]); this.hubToken = l1Token; this.hubDomainId = PUBLIC_NETWORKS[hubChainId].hypDomainId; diff --git a/src/adapter/bridges/LineaBridge.ts b/src/adapter/bridges/LineaBridge.ts index c88169be42..92cc63be7e 100644 --- a/src/adapter/bridges/LineaBridge.ts +++ b/src/adapter/bridges/LineaBridge.ts @@ -12,7 +12,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class LineaBridge extends BaseBridgeAdapter { +export class LineaBridge extends BaseBridgeAdapter { constructor( l2chainId: number, hubChainId: number, @@ -25,7 +25,7 @@ export class LineaBridge extends BaseBridgeAdapter { ) { const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].lineaL1TokenBridge; const { address: l2Address, abi: l2Abi } = CONTRACT_ADDRESSES[l2chainId].lineaL2TokenBridge; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); this.l2Bridge = new Contract(l2Address, l2Abi, l2SignerOrProvider); diff --git a/src/adapter/bridges/LineaWethBridge.ts b/src/adapter/bridges/LineaWethBridge.ts index b509862d71..a63413dd74 100644 --- a/src/adapter/bridges/LineaWethBridge.ts +++ b/src/adapter/bridges/LineaWethBridge.ts @@ -16,7 +16,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class LineaWethBridge extends BaseBridgeAdapter { +export class LineaWethBridge extends BaseBridgeAdapter { protected atomicDepositor: Contract; protected blockFinder: EVMBlockFinder; @@ -34,7 +34,7 @@ export class LineaWethBridge extends BaseBridgeAdapter { const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].lineaMessageService; const { address: l2Address, abi: l2Abi } = CONTRACT_ADDRESSES[l2chainId].l2MessageService; const { address: atomicDepositorAddress, abi: atomicDepositorAbi } = CONTRACT_ADDRESSES[hubChainId].atomicDepositor; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(atomicDepositorAddress)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(atomicDepositorAddress)]); this.atomicDepositor = new Contract(atomicDepositorAddress, atomicDepositorAbi, l1Signer); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); diff --git a/src/adapter/bridges/OFTBridge.ts b/src/adapter/bridges/OFTBridge.ts index b828faeec0..0bfb2e306f 100644 --- a/src/adapter/bridges/OFTBridge.ts +++ b/src/adapter/bridges/OFTBridge.ts @@ -24,7 +24,7 @@ type OFTBridgeArguments = { refundAddress: string; }; -export class OFTBridge extends BaseBridgeAdapter { +export class OFTBridge extends BaseBridgeAdapter { public readonly l2TokenAddress: string; private readonly l1ChainEid: number; private readonly l2ChainEid: number; @@ -51,7 +51,7 @@ export class OFTBridge extends BaseBridgeAdapter { const l1OftMessenger = OFT.getMessengerEvm(l1TokenAddress, l1ChainId); const l2OftMessenger = OFT.getMessengerEvm(l1TokenAddress, l2ChainId); - super(l2ChainId, l1ChainId, l1Signer, [l1OftMessenger]); + super(l2ChainId, l1ChainId, l1Signer, l2SignerOrProvider, [l1OftMessenger]); this.l2TokenAddress = this.resolveL2TokenAddress(l1TokenAddress); this.l1ChainEid = OFT.getEndpointId(l1ChainId); diff --git a/src/adapter/bridges/OpStackDefaultErc20Bridge.ts b/src/adapter/bridges/OpStackDefaultErc20Bridge.ts index 5c3c6cee01..91224f52ce 100644 --- a/src/adapter/bridges/OpStackDefaultErc20Bridge.ts +++ b/src/adapter/bridges/OpStackDefaultErc20Bridge.ts @@ -12,7 +12,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class OpStackDefaultERC20Bridge extends BaseBridgeAdapter { +export class OpStackDefaultERC20Bridge extends BaseBridgeAdapter { private readonly l2Gas = 200000; constructor( @@ -25,7 +25,7 @@ export class OpStackDefaultERC20Bridge extends BaseBridgeAdapter { // eslint-disable-next-line @typescript-eslint/no-unused-vars _logger: winston.Logger ) { - super(l2chainId, hubChainId, l1Signer, [ + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [ EvmAddress.from(CONTRACT_ADDRESSES[hubChainId][`ovmStandardBridge_${l2chainId}`].address), ]); diff --git a/src/adapter/bridges/OpStackUSDCBridge.ts b/src/adapter/bridges/OpStackUSDCBridge.ts index dce065521b..e6bce4c41b 100644 --- a/src/adapter/bridges/OpStackUSDCBridge.ts +++ b/src/adapter/bridges/OpStackUSDCBridge.ts @@ -12,7 +12,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BaseBridgeAdapter, BridgeTransactionDetails, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class OpStackUSDCBridge extends BaseBridgeAdapter { +export class OpStackUSDCBridge extends BaseBridgeAdapter { private readonly l2Gas = 200000; constructor( @@ -27,7 +27,7 @@ export class OpStackUSDCBridge extends BaseBridgeAdapter { ) { const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId][`opUSDCBridge_${l2chainId}`]; const { address: l2Address, abi: l2Abi } = CONTRACT_ADDRESSES[l2chainId].opUSDCBridge; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); this.l2Bridge = new Contract(l2Address, l2Abi, l2SignerOrProvider); diff --git a/src/adapter/bridges/OpStackWethBridge.ts b/src/adapter/bridges/OpStackWethBridge.ts index 3a6717171d..8ec55534c9 100644 --- a/src/adapter/bridges/OpStackWethBridge.ts +++ b/src/adapter/bridges/OpStackWethBridge.ts @@ -18,7 +18,7 @@ import { utils } from "@across-protocol/sdk"; import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter"; import WETH_ABI from "../../common/abi/Weth.json"; -export class OpStackWethBridge extends BaseBridgeAdapter { +export class OpStackWethBridge extends BaseBridgeAdapter { protected atomicDepositor: Contract; protected l2Weth: Contract; protected l1Weth: EvmAddress; @@ -39,6 +39,7 @@ export class OpStackWethBridge extends BaseBridgeAdapter { l2chainId, hubChainId, l1Signer, + l2SignerOrProvider, // To keep existing logic, we should use atomic depositor as the l1 bridge [EvmAddress.from(CONTRACT_ADDRESSES[hubChainId].atomicDepositor.address)] ); diff --git a/src/adapter/bridges/PolygonERC20Bridge.ts b/src/adapter/bridges/PolygonERC20Bridge.ts index 7539a41359..4b99ba1f39 100644 --- a/src/adapter/bridges/PolygonERC20Bridge.ts +++ b/src/adapter/bridges/PolygonERC20Bridge.ts @@ -18,7 +18,7 @@ import { processEvent } from "../utils"; * and a token gateway which is the address used to initiate a * deposit */ -export class PolygonERC20Bridge extends BaseBridgeAdapter { +export class PolygonERC20Bridge extends BaseBridgeAdapter { protected l1Gateway: Contract; constructor( @@ -36,7 +36,7 @@ export class PolygonERC20Bridge extends BaseBridgeAdapter { // up-to-date. const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].polygonBridge; const { address: l1GatewayAddress, abi: l1GatewayAbi } = CONTRACT_ADDRESSES[hubChainId].polygonRootChainManager; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); this.l1Gateway = new Contract(l1GatewayAddress, l1GatewayAbi, l1Signer); diff --git a/src/adapter/bridges/PolygonWethBridge.ts b/src/adapter/bridges/PolygonWethBridge.ts index bd11908a20..5302e4a02d 100644 --- a/src/adapter/bridges/PolygonWethBridge.ts +++ b/src/adapter/bridges/PolygonWethBridge.ts @@ -19,7 +19,7 @@ import { processEvent } from "../utils"; * and a token gateway which is the address used to initiate a * deposit */ -export class PolygonWethBridge extends BaseBridgeAdapter { +export class PolygonWethBridge extends BaseBridgeAdapter { protected atomicDepositor: Contract; protected rootChainManager: Contract; @@ -41,7 +41,7 @@ export class PolygonWethBridge extends BaseBridgeAdapter { const { address: atomicDepositorAddress, abi: atomicDepositorAbi } = CONTRACT_ADDRESSES[hubChainId].atomicDepositor; const { address: rootChainManagerAddress, abi: rootChainManagerAbi } = CONTRACT_ADDRESSES[hubChainId].polygonRootChainManager; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(atomicDepositorAddress)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(atomicDepositorAddress)]); this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); this.atomicDepositor = new Contract(atomicDepositorAddress, atomicDepositorAbi, l1Signer); diff --git a/src/adapter/bridges/ScrollERC20Bridge.ts b/src/adapter/bridges/ScrollERC20Bridge.ts index 8ce3eeccb9..021a810ddd 100644 --- a/src/adapter/bridges/ScrollERC20Bridge.ts +++ b/src/adapter/bridges/ScrollERC20Bridge.ts @@ -23,7 +23,7 @@ const SCROLL_STANDARD_GATEWAY: { l1: string; l2: string } = { l2: "0xE2b4795039517653c5Ae8C2A9BFdd783b48f447A", }; -export class ScrollERC20Bridge extends BaseBridgeAdapter { +export class ScrollERC20Bridge extends BaseBridgeAdapter { // Gas limit obtained here: https://docs.scroll.io/en/developers/l1-and-l2-bridging/eth-and-erc20-token-bridge protected l2Gas = 200000; protected feeMultiplier = toWei(1.5); @@ -46,7 +46,7 @@ export class ScrollERC20Bridge extends BaseBridgeAdapter { const { address: gasPriceOracleAddress, abi: gasPriceOracleAbi } = CONTRACT_ADDRESSES[hubChainId].scrollGasPriceOracle; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); this.l1Bridge = new Contract(l1BridgeAddress, l1Abi, l1Signer); this.l2Bridge = new Contract(l2BridgeAddress, l2Abi, l2SignerOrProvider); diff --git a/src/adapter/bridges/SnxOptimismBridge.ts b/src/adapter/bridges/SnxOptimismBridge.ts index 67a4748a23..a773329e94 100644 --- a/src/adapter/bridges/SnxOptimismBridge.ts +++ b/src/adapter/bridges/SnxOptimismBridge.ts @@ -13,7 +13,7 @@ import { CONTRACT_ADDRESSES } from "../../common"; import { BaseBridgeAdapter, BridgeTransactionDetails, BridgeEvents } from "./BaseBridgeAdapter"; import { processEvent } from "../utils"; -export class SnxOptimismBridge extends BaseBridgeAdapter { +export class SnxOptimismBridge extends BaseBridgeAdapter { constructor( l2chainId: number, hubChainId: number, @@ -24,7 +24,9 @@ export class SnxOptimismBridge extends BaseBridgeAdapter { // eslint-disable-next-line @typescript-eslint/no-unused-vars _logger: winston.Logger ) { - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(CONTRACT_ADDRESSES[hubChainId].snxOptimismBridge.address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [ + EvmAddress.from(CONTRACT_ADDRESSES[hubChainId].snxOptimismBridge.address), + ]); const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].snxOptimismBridge; this.l1Bridge = new Contract(l1Address, l1Abi, l1Signer); diff --git a/src/adapter/bridges/SolanaUsdcCCTPBridge.ts b/src/adapter/bridges/SolanaUsdcCCTPBridge.ts index 3891328477..6109eabbd5 100644 --- a/src/adapter/bridges/SolanaUsdcCCTPBridge.ts +++ b/src/adapter/bridges/SolanaUsdcCCTPBridge.ts @@ -30,7 +30,7 @@ type MintAndWithdrawData = { amount: bigint; }; -export class SolanaUsdcCCTPBridge extends BaseBridgeAdapter { +export class SolanaUsdcCCTPBridge extends BaseBridgeAdapter { private readonly l1UsdcTokenAddress: EvmAddress; private readonly l2UsdcTokenAddress: SvmAddress; private readonly solanaMessageTransmitter: SvmAddress; @@ -53,7 +53,7 @@ export class SolanaUsdcCCTPBridge extends BaseBridgeAdapter { // This adapter currently only supports CCTP V1. const { address: l1Address, abi: l1Abi } = getCctpV1TokenMessenger(hubChainId); - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2Provider, [EvmAddress.from(l1Address)]); assert( getCctpDomainForChainId(l2chainId) !== CCTP_NO_DOMAIN && getCctpDomainForChainId(hubChainId) !== CCTP_NO_DOMAIN, "Unknown CCTP domain ID" diff --git a/src/adapter/bridges/UsdcCCTPBridge.ts b/src/adapter/bridges/UsdcCCTPBridge.ts index fe9a788410..3516e77cbc 100644 --- a/src/adapter/bridges/UsdcCCTPBridge.ts +++ b/src/adapter/bridges/UsdcCCTPBridge.ts @@ -27,7 +27,7 @@ import { CCTP_NO_DOMAIN } from "@across-protocol/constants"; import { CCTP_MAX_SEND_AMOUNT } from "../../common"; import { SortableEvent } from "../../interfaces"; -export class UsdcCCTPBridge extends BaseBridgeAdapter { +export class UsdcCCTPBridge extends BaseBridgeAdapter { private IS_CCTP_V2 = false; private readonly l1UsdcTokenAddress: EvmAddress; @@ -42,7 +42,7 @@ export class UsdcCCTPBridge extends BaseBridgeAdapter { _logger: winston.Logger ) { const { address: l1Address, abi: l1Abi } = getCctpV2TokenMessenger(hubChainId); - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(l1Address)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(l1Address)]); assert( getCctpDomainForChainId(l2chainId) !== CCTP_NO_DOMAIN && getCctpDomainForChainId(hubChainId) !== CCTP_NO_DOMAIN, "Unknown CCTP domain ID" diff --git a/src/adapter/bridges/UsdcTokenSplitterBridge.ts b/src/adapter/bridges/UsdcTokenSplitterBridge.ts index bce1d63fd0..d1f051ca50 100644 --- a/src/adapter/bridges/UsdcTokenSplitterBridge.ts +++ b/src/adapter/bridges/UsdcTokenSplitterBridge.ts @@ -1,5 +1,5 @@ import { Signer } from "ethers"; -import { CONTRACT_ADDRESSES, CANONICAL_BRIDGE } from "../../common"; +import { CONTRACT_ADDRESSES, EVM_CANONICAL_BRIDGE } from "../../common"; import { UsdcCCTPBridge } from "./UsdcCCTPBridge"; import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter"; import { @@ -15,9 +15,9 @@ import { } from "../../utils"; import { TransferTokenParams } from "../utils"; -export class UsdcTokenSplitterBridge extends BaseBridgeAdapter { - protected cctpBridge: BaseBridgeAdapter; - protected canonicalBridge: BaseBridgeAdapter; +export class UsdcTokenSplitterBridge extends BaseBridgeAdapter { + protected cctpBridge: BaseBridgeAdapter; + protected canonicalBridge: BaseBridgeAdapter; constructor( l2chainId: number, @@ -28,7 +28,7 @@ export class UsdcTokenSplitterBridge extends BaseBridgeAdapter { // eslint-disable-next-line @typescript-eslint/no-unused-vars logger: winston.Logger ) { - const canonicalBridge = new CANONICAL_BRIDGE[l2chainId]( + const canonicalBridge = new EVM_CANONICAL_BRIDGE[l2chainId]( l2chainId, hubChainId, l1Signer, @@ -37,7 +37,7 @@ export class UsdcTokenSplitterBridge extends BaseBridgeAdapter { logger ); - super(l2chainId, hubChainId, l1Signer, [ + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [ EvmAddress.from(CONTRACT_ADDRESSES[hubChainId].cctpTokenMessenger.address), canonicalBridge.l1Gateways[0], // Canonical Bridge should have a single L1 Gateway. ]); @@ -46,7 +46,7 @@ export class UsdcTokenSplitterBridge extends BaseBridgeAdapter { this.canonicalBridge = canonicalBridge; } - private getRouteForL2Token(l2Token: Address): BaseBridgeAdapter { + private getRouteForL2Token(l2Token: Address): BaseBridgeAdapter { return compareAddressesSimple(l2Token.toNative(), TOKEN_SYMBOLS_MAP.USDC.addresses[this.l2chainId]) ? this.cctpBridge : this.canonicalBridge; diff --git a/src/adapter/bridges/ZKStackBridge.ts b/src/adapter/bridges/ZKStackBridge.ts index c4bef04829..35a2fde7c0 100644 --- a/src/adapter/bridges/ZKStackBridge.ts +++ b/src/adapter/bridges/ZKStackBridge.ts @@ -33,7 +33,7 @@ const FEE_SCALER_DENOMINATOR = 10; * addresses and gas prices (this is also why `constructL1toL2Txn` * is an async fn). */ -export class ZKStackBridge extends BaseBridgeAdapter { +export class ZKStackBridge extends BaseBridgeAdapter { readonly gasPerPubdataLimit = zksync.utils.REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; readonly l2GasLimit = BigNumber.from(2_000_000); readonly sharedBridge: Contract; @@ -54,7 +54,7 @@ export class ZKStackBridge extends BaseBridgeAdapter { _logger: winston.Logger ) { const { address: sharedBridgeAddress, abi: sharedBridgeAbi } = CONTRACT_ADDRESSES[hubChainId].zkStackSharedBridge; - super(l2chainId, hubChainId, l1Signer, [EvmAddress.from(sharedBridgeAddress)]); + super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [EvmAddress.from(sharedBridgeAddress)]); this.sharedBridge = new Contract(sharedBridgeAddress, sharedBridgeAbi, l1Signer); const nativeToken = PUBLIC_NETWORKS[l2chainId].nativeToken; diff --git a/src/clients/bridges/AdapterManager.ts b/src/clients/bridges/AdapterManager.ts index 8e1ea61739..2cc05bc8a7 100644 --- a/src/clients/bridges/AdapterManager.ts +++ b/src/clients/bridges/AdapterManager.ts @@ -24,6 +24,9 @@ import { Address, isSVMSpokePoolClient, bnZero, + chainIsEvm, + Provider, + SVMProvider, } from "../../utils"; import { SpokePoolClient, HubPoolClient, SpokePoolManager } from "../"; import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "@across-protocol/constants"; @@ -31,7 +34,7 @@ import { BaseChainAdapter } from "../../adapter"; import { TransferTokenParams } from "../../adapter/utils"; export class AdapterManager { - public adapters: { [chainId: number]: BaseChainAdapter } = {}; + public adapters: { [chainId: number]: BaseChainAdapter } = {}; // Some L2's canonical bridges send ETH, not WETH, over the canonical bridges, resulting in recipient addresses // receiving ETH that needs to be wrapped on the L2. This array contains the chainIds of the chains that this @@ -127,17 +130,31 @@ export class AdapterManager { }; Object.values(this.spokePoolManager.getSpokePoolClients()).map(({ chainId }) => { // Instantiate a generic adapter and supply all network-specific configurations. - this.adapters[chainId] = new BaseChainAdapter( - this.spokePoolManager.getSpokePoolClients(), - chainId, - hubChainId, - filterMonitoredAddresses(chainId), - logger, - SUPPORTED_TOKENS[chainId] ?? [], - constructBridges(chainId), - constructL2Bridges(chainId), - DEFAULT_GAS_MULTIPLIER[chainId] ?? 1 - ); + if (chainIsEvm(chainId)) { + this.adapters[chainId] = new BaseChainAdapter( + this.spokePoolManager.getSpokePoolClients(), + chainId, + hubChainId, + filterMonitoredAddresses(chainId), + logger, + SUPPORTED_TOKENS[chainId] ?? [], + constructBridges(chainId), + constructL2Bridges(chainId), + DEFAULT_GAS_MULTIPLIER[chainId] ?? 1 + ); + } else { + this.adapters[chainId] = new BaseChainAdapter( + this.spokePoolManager.getSpokePoolClients(), + chainId, + hubChainId, + filterMonitoredAddresses(chainId), + logger, + SUPPORTED_TOKENS[chainId] ?? [], + constructBridges(chainId), + constructL2Bridges(chainId), + DEFAULT_GAS_MULTIPLIER[chainId] ?? 1 + ); + } }); logger.debug({ at: "AdapterManager#constructor", diff --git a/src/common/Constants.ts b/src/common/Constants.ts index dc25cfd7b9..cf2bfc89cd 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -14,6 +14,7 @@ import { BigNumber, winston, toBN, + Provider, } from "../utils"; import { BaseBridgeAdapter, @@ -398,15 +399,17 @@ export const TOKEN_APPROVALS_TO_FIRST_ZERO: Record = { ], }; -// Type alias for a function which takes in arbitrary arguments and outputs a BaseBridgeAdapter class. -type L1BridgeConstructor = new ( - l2chainId: number, - hubChainId: number, - l1Signer: Signer, - l2SignerOrProvider: any, - l1Token: EvmAddress, - logger: winston.Logger -) => T; +// Connection for same token network -> network transfer. Not necessarily a two-way transfer method. +export interface BridgeEdge { + new ( + l2chainId: number, + hubChainId: number, + l1Signer: O, + l2SignerOrProvider: D, + l1Token: EvmAddress, + logger: winston.Logger + ): BaseBridgeAdapter; +} type L2BridgeConstructor = new ( l2chainId: number, @@ -418,14 +421,13 @@ type L2BridgeConstructor = new ( // Map of chain IDs to all "canonical bridges" for the given chain. Canonical is loosely defined -- in this // case, it is the default bridge for the given chain. -const resolveCanonicalBridges = (): Record> => { +const resolveEvmCanonicalBridges = (): Record> => { const bridges = { [CHAIN_IDs.ARBITRUM]: ArbitrumOrbitBridge, [CHAIN_IDs.BSC]: BinanceCEXBridge, [CHAIN_IDs.LINEA]: LineaBridge, [CHAIN_IDs.POLYGON]: PolygonERC20Bridge, [CHAIN_IDs.SCROLL]: ScrollERC20Bridge, - [CHAIN_IDs.SOLANA]: SolanaUsdcCCTPBridge, [CHAIN_IDs.ZK_SYNC]: ZKStackBridge, // Testnets: [CHAIN_IDs.ARBITRUM_SEPOLIA]: ArbitrumOrbitBridge, @@ -450,7 +452,13 @@ const resolveCanonicalBridges = (): Record isDefined(bridge)) ); }; -export const CANONICAL_BRIDGE = resolveCanonicalBridges(); + +export const EVM_CANONICAL_BRIDGE = resolveEvmCanonicalBridges(); + +export const CANONICAL_BRIDGE = { + ...EVM_CANONICAL_BRIDGE, + [CHAIN_IDs.SOLANA]: SolanaUsdcCCTPBridge, +}; export const CANONICAL_L2_BRIDGE: Record> = { [CHAIN_IDs.BSC]: L2BinanceCEXBridge, @@ -461,7 +469,7 @@ export const CANONICAL_L2_BRIDGE: Record>> = { +export const CUSTOM_BRIDGE: Record>> = { [CHAIN_IDs.ARBITRUM]: { [TOKEN_SYMBOLS_MAP.USDC.addresses[CHAIN_IDs.MAINNET]]: UsdcTokenSplitterBridge, [TOKEN_SYMBOLS_MAP.USDT.addresses[CHAIN_IDs.MAINNET]]: OFTBridge, diff --git a/src/refiller/Refiller.ts b/src/refiller/Refiller.ts index 78dbef4e07..01ed570231 100644 --- a/src/refiller/Refiller.ts +++ b/src/refiller/Refiller.ts @@ -34,7 +34,7 @@ import { bnZero, getL1TokenAddress, } from "../utils"; -import { SWAP_ROUTES, SwapRoute, CUSTOM_BRIDGE, CANONICAL_BRIDGE } from "../common"; +import { SWAP_ROUTES, SwapRoute, CUSTOM_BRIDGE, EVM_CANONICAL_BRIDGE } from "../common"; import { arch } from "@across-protocol/sdk"; import { AcrossSwapApiClient, BalanceAllocator, MultiCallerClient } from "../clients"; import { RedisCache } from "../caching/RedisCache"; @@ -312,7 +312,7 @@ export class Refiller { // Construct a token bridge for the target token and build a transaction to send the l1 token to l2. const l1Token = getL1TokenAddress(token, chainId); const l2TokenInfo = getTokenInfo(token, chainId); - const tokenBridgeConstructor = CUSTOM_BRIDGE[chainId]?.[l1Token.toNative()] ?? CANONICAL_BRIDGE[chainId]; + const tokenBridgeConstructor = CUSTOM_BRIDGE[chainId]?.[l1Token.toNative()] ?? EVM_CANONICAL_BRIDGE[chainId]; const tokenBridge = new tokenBridgeConstructor( chainId, this.clients.hubPoolClient.chainId,