Skip to content

Commit

Permalink
Merge branch 'master' into pxrl/relayerRefactorEvaluate
Browse files Browse the repository at this point in the history
  • Loading branch information
pxrl authored Mar 21, 2024
2 parents 0b3ccf8 + efcc47c commit 89cf27b
Show file tree
Hide file tree
Showing 8 changed files with 649 additions and 182 deletions.
4 changes: 4 additions & 0 deletions src/clients/bridges/AdapterManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { utils } from "@across-protocol/sdk-v2";
import { CHAIN_IDs } from "@across-protocol/constants-v2";
import { BaseChainAdapter } from "./op-stack/base/BaseChainAdapter";
import { spokesThatHoldEthAndWeth } from "../../common/Constants";
import { LineaAdapter } from "./LineaAdapter";
export class AdapterManager {
public adapters: { [chainId: number]: BaseAdapter } = {};

Expand Down Expand Up @@ -39,6 +40,9 @@ export class AdapterManager {
if (this.spokePoolClients[8453] !== undefined) {
this.adapters[8453] = new BaseChainAdapter(logger, spokePoolClients, monitoredAddresses);
}
if (this.spokePoolClients[59144] !== undefined) {
this.adapters[59144] = new LineaAdapter(logger, spokePoolClients, monitoredAddresses);
}

logger.debug({
at: "AdapterManager#constructor",
Expand Down
146 changes: 139 additions & 7 deletions src/clients/bridges/LineaAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import * as sdk from "@across-protocol/sdk-v2";
import { CONTRACT_ADDRESSES } from "../../common";
import { OutstandingTransfers } from "../../interfaces";
import {
BigNumber,
CHAIN_IDs,
Expand All @@ -8,12 +11,11 @@ import {
bnZero,
compareAddressesSimple,
isDefined,
paginatedEventQuery,
winston,
} from "../../utils";
import { SpokePoolClient } from "../SpokePoolClient";
import { BaseAdapter } from "./BaseAdapter";
import { CONTRACT_ADDRESSES } from "../../common";
import * as sdk from "@across-protocol/sdk-v2";

export class LineaAdapter extends BaseAdapter {
readonly l1TokenBridge = CONTRACT_ADDRESSES[this.hubChainId].lineaL1TokenBridge.address;
Expand Down Expand Up @@ -65,6 +67,24 @@ export class LineaAdapter extends BaseAdapter {
return null;
}

getL2MessageService(): Contract {
const chainId = this.chainId;
return new Contract(
CONTRACT_ADDRESSES[chainId].l2MessageService.address,
CONTRACT_ADDRESSES[chainId].l2MessageService.abi,
this.getSigner(chainId)
);
}

getL1MessageService(): Contract {
const { hubChainId } = this;
return new Contract(
CONTRACT_ADDRESSES[hubChainId].lineaMessageService.address,
CONTRACT_ADDRESSES[hubChainId].lineaMessageService.abi,
this.getSigner(hubChainId)
);
}

getL1TokenBridge(): Contract {
const { hubChainId } = this;
return new Contract(
Expand All @@ -83,6 +103,28 @@ export class LineaAdapter extends BaseAdapter {
);
}

getL2TokenBridge(): Contract {
const chainId = this.chainId;
return new Contract(
CONTRACT_ADDRESSES[chainId].lineaL2TokenBridge.address,
CONTRACT_ADDRESSES[chainId].lineaL2TokenBridge.abi,
this.getSigner(chainId)
);
}

getL2UsdcBridge(): Contract {
const chainId = this.chainId;
return new Contract(
CONTRACT_ADDRESSES[chainId].lineaL2UsdcBridge.address,
CONTRACT_ADDRESSES[chainId].lineaL2UsdcBridge.abi,
this.getSigner(chainId)
);
}

getL2Bridge(l1Token: string): Contract {
return this.isUsdc(l1Token) ? this.getL2UsdcBridge() : this.getL2TokenBridge();
}

/**
* Get L1 Atomic WETH depositor contract
* @returns L1 Atomic WETH depositor contract
Expand All @@ -108,10 +150,94 @@ export class LineaAdapter extends BaseAdapter {
: this.getL1TokenBridge();
}

// FIXME: NO-OP
getOutstandingCrossChainTransfers(l1Tokens: string[]): Promise<sdk.interfaces.OutstandingTransfers> {
l1Tokens;
return Promise.resolve({});
async getOutstandingCrossChainTransfers(l1Tokens: string[]): Promise<sdk.interfaces.OutstandingTransfers> {
const outstandingTransfers: OutstandingTransfers = {};
const { l1SearchConfig, l2SearchConfig } = this.getUpdatedSearchConfigs();
const supportedL1Tokens = l1Tokens.filter(this.isSupportedToken.bind(this));
await sdk.utils.mapAsync(this.monitoredAddresses, async (address) => {
await sdk.utils.mapAsync(supportedL1Tokens, async (l1Token) => {
if (this.isWeth(l1Token)) {
const atomicDepositor = this.getAtomicDepositor();
const l1MessageService = this.getL1MessageService();
const l2MessageService = this.getL2MessageService();

// We need to do the following sequential steps.
// 1. Get all initiated MessageSent events from the L1MessageService where the 'from' address is
// the AtomicDepositor and the 'to' address is the user's address.
// 2. Pipe the resulting _messageHash argument from step 1 into the MessageClaimed event filter
// 3. For each MessageSent, match the _messageHash to the _messageHash in the MessageClaimed event
// any unmatched MessageSent events are considered outstanding transfers.
const initiatedQueryResult = await paginatedEventQuery(
l1MessageService,
l1MessageService.filters.MessageSent(atomicDepositor.address, address),
l1SearchConfig
);
const internalMessageHashes = initiatedQueryResult.map(({ args }) => args._messageHash);
const finalizedQueryResult = await paginatedEventQuery(
l2MessageService,
// Passing in an array of message hashes results in an OR filter
l2MessageService.filters.MessageClaimed(internalMessageHashes),
l2SearchConfig
);
initiatedQueryResult
.filter(
({ args }) =>
!finalizedQueryResult.some(
(finalizedEvent) => args._messageHash.toLowerCase() === finalizedEvent.args._messageHash.toLowerCase()
)
)
.forEach((event) => {
const txHash = event.transactionHash;
const amount = event.args._value;
outstandingTransfers[address] ??= {};
outstandingTransfers[address][l1Token] ??= { totalAmount: bnZero, depositTxHashes: [] };
outstandingTransfers[address][l1Token] = {
totalAmount: outstandingTransfers[address][l1Token].totalAmount.add(amount),
depositTxHashes: [...outstandingTransfers[address][l1Token].depositTxHashes, txHash],
};
});
} else {
const isUsdc = this.isUsdc(l1Token);
const l1Bridge = this.getL1Bridge(l1Token);
const l2Bridge = this.getL2Bridge(l1Token);

// Define the initialized and finalized event filters for the L1 and L2 bridges
const [filterL1, filterL2] = isUsdc
? [l1Bridge.filters.Deposited(address, null, address), l2Bridge.filters.ReceivedFromOtherLayer(address)]
: [l1Bridge.filters.BridgingInitiated(address, null, l1Token), l2Bridge.filters.BridgingFinalized(l1Token)];

const [initiatedQueryResult, finalizedQueryResult] = await Promise.all([
paginatedEventQuery(l1Bridge, filterL1, l1SearchConfig),
paginatedEventQuery(l2Bridge, filterL2, l2SearchConfig),
]);
initiatedQueryResult
.filter(
(initialEvent) =>
!isDefined(
finalizedQueryResult.find((finalEvent) =>
isUsdc
? finalEvent.args.amount.eq(initialEvent.args.amount) &&
compareAddressesSimple(initialEvent.args.to, finalEvent.args.recipient)
: finalEvent.args.amount.eq(initialEvent.args.amount) &&
compareAddressesSimple(initialEvent.args.recipient, finalEvent.args.recipient) &&
compareAddressesSimple(finalEvent.args.nativeToken, initialEvent.args.token)
)
)
)
.forEach((initialEvent) => {
const txHash = initialEvent.transactionHash;
const amount = initialEvent.args.amount;
outstandingTransfers[address] ??= {};
outstandingTransfers[address][l1Token] ??= { totalAmount: bnZero, depositTxHashes: [] };
outstandingTransfers[address][l1Token] = {
totalAmount: outstandingTransfers[address][l1Token].totalAmount.add(amount),
depositTxHashes: [...outstandingTransfers[address][l1Token].depositTxHashes, txHash],
};
});
}
});
});
return outstandingTransfers;
}

sendTokenToTargetChain(
Expand All @@ -125,7 +251,13 @@ export class LineaAdapter extends BaseAdapter {
const isUsdc = this.isUsdc(l1Token);
const l1Bridge = this.getL1Bridge(l1Token);
const l1BridgeMethod = isWeth ? "bridgeWethToLinea" : isUsdc ? "depositTo" : "bridgeToken";
const l1BridgeArgs = isUsdc || isWeth ? [amount, address] : [l1Token, amount, address];
// prettier-ignore
const l1BridgeArgs = isUsdc
? [amount, address]
: isWeth
? [address, amount]
: [l1Token, amount, address];

return this._sendTokenToTargetChain(
l1Token,
l2Token,
Expand Down
2 changes: 1 addition & 1 deletion src/common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export type Multicall2Call = {

// These are the spokes that can hold both ETH and WETH, so they should be added together when caclulating whether
// a bundle execution is possible with the funds in the pool.
export const spokesThatHoldEthAndWeth = [10, 324, 8453];
export const spokesThatHoldEthAndWeth = [10, 324, 8453, 59144];

/**
* An official mapping of chain IDs to CCTP domains. This mapping is separate from chain identifiers
Expand Down
Loading

0 comments on commit 89cf27b

Please sign in to comment.