Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream - 16-09-2024 #63

Merged
merged 22 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2225c03
improve: Support slow fill requests in SpokePool script (#1802)
pxrl Sep 6, 2024
6be5b42
refactor(relayer): Squash updateRelayerClients() (#1803)
pxrl Sep 6, 2024
eac5983
refactor(relayer): Add one-time init on startup (#1807)
pxrl Sep 6, 2024
bd101fc
fix(relayer): Skip logging contract object on eth wrap (#1810)
pxrl Sep 9, 2024
5be2609
refactor(relayer): Reduce inventory log spam in looping mode (#1808)
pxrl Sep 9, 2024
dd53999
improve(adapters): swap polygon adapter with generic adapter (#1756)
bmzig Sep 9, 2024
0fb1af7
improve: use bundle data client migrations (#1778)
james-a-morris Sep 9, 2024
b557ef6
improve(providers): Enable RPC error passthrough (#1804)
pxrl Sep 10, 2024
58115d5
fix(providers): pass logger to provider (#1812)
james-a-morris Sep 10, 2024
8240eb6
refactor(relayer): Rate-limit maintenance in looping mode (#1814)
pxrl Sep 11, 2024
7508b76
improve(relayer): Support dynamic handover in production (#1781)
pxrl Sep 11, 2024
e59a5ca
improve(adapters): swap Linea adapter with generic adapter (#1714)
bmzig Sep 11, 2024
865f4b9
fix(relayer): Don't prematurely mark deposits as filled (#1817)
pxrl Sep 11, 2024
d1fbae4
fix(relayer): Require at least one relayer loop (#1818)
pxrl Sep 12, 2024
88cbaf3
chore(deps): bump express from 4.19.2 to 4.20.0 (#1815)
dependabot[bot] Sep 12, 2024
4a814ad
chore(deps): bump body-parser from 1.20.0 to 1.20.3 (#1819)
dependabot[bot] Sep 12, 2024
1bdf527
chore(deps): bump micromatch from 4.0.5 to 4.0.8 (#1799)
dependabot[bot] Sep 12, 2024
6512bd3
chore(deps): bump axios from 1.6.1 to 1.7.4 (#1748)
dependabot[bot] Sep 12, 2024
0567acf
chore: Drop V3 type shims (#1821)
pxrl Sep 16, 2024
de345c5
Merge remote-tracking branch 'upstream/master' into LISK-1099-Merge-u…
sameersubudhi Sep 16, 2024
577dfcc
Start the API server
sameersubudhi Sep 16, 2024
1bd2da4
:bug: Fix docker GHA workflow
sameersubudhi Sep 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,4 @@ jobs:
context: ./
file: ./Dockerfile
push: true
tags:
- latest
- ${{ steps.docker-image.outputs.image }}
tags: latest,${{ steps.docker-image.outputs.image }}
5 changes: 4 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ dist/
*.txt

# env example files
*.env.example
*.env.example

# local files
.secret
31 changes: 31 additions & 0 deletions contracts/MockPolygonEvents.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// This file contains contracts that can be used to unit test the src/clients/bridges/ZkSyncAdapter.ts
// code which reads events from zkSync contracts facilitating cross chain transfers.

pragma solidity ^0.8.0;

contract Polygon_L1Bridge {
event LockedERC20(
address indexed depositor,
address indexed depositReceiver,
address indexed rootToken,
uint256 amount
);

event LockedEther(address indexed depositor, address indexed depositReceiver, uint256 amount);

function depositFor(address depositor, address depositReceiver, address rootToken, uint256 amount) external {
emit LockedERC20(depositor, depositReceiver, rootToken, amount);
}

function depositEtherFor(address depositor, address depositReceiver, uint256 amount) external {
emit LockedEther(depositor, depositReceiver, amount);
}
}

contract Polygon_L2Bridge {
event Transfer(address indexed from, address indexed to, uint256 value);

function transfer(address from, address to, uint256 value) external {
emit Transfer(from, to, value);
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@across-protocol/constants": "^3.1.14",
"@across-protocol/contracts": "^3.0.10",
"@across-protocol/sdk": "^3.1.31",
"@across-protocol/sdk": "^3.1.34",
"@arbitrum/sdk": "^3.1.3",
"@aws-sdk/client-kms": "^3.592.0",
"@aws-sdk/client-s3": "^3.592.0",
Expand All @@ -30,7 +30,7 @@
"@types/express": "^4.17.21",
"@uma/common": "2.33.0",
"@uma/logger": "^1.3.0",
"axios": "^1.6.1",
"axios": "^1.7.4",
"dotenv": "^16.3.1",
"ethers": "^5.7.2",
"express": "^4.19.2",
Expand Down
10 changes: 6 additions & 4 deletions scripts/spokepool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ async function deposit(args: Record<string, number | string>, signer: Signer): P
}

async function fillDeposit(args: Record<string, number | string | boolean>, signer: Signer): Promise<boolean> {
const { txnHash, depositId: depositIdArg, execute } = args;
const { txnHash, depositId: depositIdArg, execute, slow } = args;
const originChainId = Number(args.chainId);

if (txnHash === undefined || typeof txnHash !== "string" || txnHash.length != 66 || !txnHash.startsWith("0x")) {
Expand Down Expand Up @@ -295,7 +295,9 @@ async function fillDeposit(args: Record<string, number | string | boolean>, sign
fromLiteChain: false, // Not relevant
toLiteChain: false, // Not relevant
};
const fill = await sdkUtils.populateV3Relay(destSpokePool, deposit, relayer);
const fill = isDefined(slow)
? await destSpokePool.populateTransaction.requestV3SlowFill(deposit)
: await sdkUtils.populateV3Relay(destSpokePool, deposit, relayer);

console.group("Fill Txn Info");
console.log(`to: ${fill.to}`);
Expand Down Expand Up @@ -459,7 +461,7 @@ function usage(badInput?: string): boolean {

const dumpConfigArgs = "--chainId";
const fetchArgs = "--chainId <chainId> [--depositId <depositId> | --txnHash <txnHash>]";
const fillArgs = "--chainId <originChainId> --txnHash <depositHash> [--depositId <depositId>] [--execute]";
const fillArgs = "--chainId <originChainId> --txnHash <depositHash> [--depositId <depositId>] [--slow] [--execute]";

const pad = "deposit".length;
usageStr += `
Expand Down Expand Up @@ -491,7 +493,7 @@ async function run(argv: string[]): Promise<number> {
const fetchDepositOpts = ["chainId", "depositId"];
const opts = {
string: ["wallet", ...configOpts, ...depositOpts, ...fetchOpts, ...fillOpts, ...fetchDepositOpts],
boolean: ["decimals", "execute"], // @dev tbd whether this is good UX or not...may need to change.
boolean: ["decimals", "execute", "slow"], // @dev tbd whether this is good UX or not...may need to change.
default: {
wallet: "secret",
decimals: false,
Expand Down
7 changes: 6 additions & 1 deletion src/adapter/BaseChainAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,12 @@ export class BaseChainAdapter {
const augmentedTxn = { contract, chainId: this.chainId, method, args: [], value, mrkdwn, message };
if (simMode) {
const { succeed, reason } = (await this.transactionClient.simulate([augmentedTxn]))[0];
this.log("Simulation result", { succeed, reason, contract, value }, "debug", "wrapEthIfAboveThreshold");
this.log(
"Simulation result",
{ succeed, reason, contract: contract.address, value },
"debug",
"wrapEthIfAboveThreshold"
);
return { hash: ZERO_ADDRESS } as TransactionResponse;
} else {
(await this.transactionClient.submit(this.chainId, [augmentedTxn]))[0];
Expand Down
4 changes: 2 additions & 2 deletions src/adapter/bridges/LineaBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class LineaBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.BridgingInitiatedV2(undefined, fromAddress, l1Token),
this.getL1Bridge().filters.BridgingInitiatedV2(undefined, toAddress, l1Token),
eventConfig
);
return {
Expand All @@ -60,7 +60,7 @@ export class LineaBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL2Bridge(),
this.getL2Bridge().filters.BridgingFinalizedV2(l1Token, undefined, undefined, fromAddress),
this.getL2Bridge().filters.BridgingFinalizedV2(l1Token, undefined, undefined, toAddress),
eventConfig
);
// There is no "from" field in this event, so we set it to the L2 token received.
Expand Down
4 changes: 2 additions & 2 deletions src/adapter/bridges/LineaUSDCBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class LineaUSDCBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.Deposited(undefined, undefined, fromAddress),
this.getL1Bridge().filters.Deposited(undefined, undefined, toAddress),
eventConfig
);
return {
Expand All @@ -58,7 +58,7 @@ export class LineaUSDCBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL2Bridge(),
this.getL2Bridge().filters.ReceivedFromOtherLayer(fromAddress),
this.getL2Bridge().filters.ReceivedFromOtherLayer(toAddress),
eventConfig
);
// There is no "from" address in this event.
Expand Down
71 changes: 59 additions & 12 deletions src/adapter/bridges/LineaWethBridge.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { Contract, BigNumber, paginatedEventQuery, bnZero, Signer, EventSearchConfig, Provider } from "../../utils";
import {
Contract,
BigNumber,
paginatedEventQuery,
bnZero,
Signer,
EventSearchConfig,
Provider,
getBlockForTimestamp,
BlockFinder,
isDefined,
} from "../../utils";
import { CONTRACT_ADDRESSES } from "../../common";
import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter";
import { processEvent } from "../utils";

export class LineaWethBridge extends BaseBridgeAdapter {
protected atomicDepositor: Contract;
protected blockFinder: BlockFinder;

constructor(
l2chainId: number,
Expand Down Expand Up @@ -46,9 +58,12 @@ export class LineaWethBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.MessageSent(undefined, fromAddress),
this.getL1Bridge().filters.MessageSent(undefined, toAddress),
eventConfig
);

// @dev There will be a MessageSent to the SpokePool address for each RelayedRootBundle so remove
// those with 0 value.
return {
[this.resolveL2TokenAddress(l1Token)]: events
.map((event) => processEvent(event, "_value", "_to", "_from"))
Expand All @@ -62,16 +77,33 @@ export class LineaWethBridge extends BaseBridgeAdapter {
toAddress: string,
eventConfig: EventSearchConfig
): Promise<BridgeEvents> {
// TODO: This can probably be refactored to save an RPC call since this is called in parallel with
// queryL1BridgeInitiationEvents in the BaseChainAdapter class.
const l2Provider = this.getL2Bridge().provider;

const [fromBlock, toBlock] = await Promise.all([
l2Provider.getBlock(eventConfig.fromBlock),
l2Provider.getBlock(eventConfig.toBlock),
]);

const [l1FromBlock, l1ToBlock] = [
await getBlockForTimestamp(this.hubChainId, fromBlock.timestamp, this.blockFinder),
await getBlockForTimestamp(this.hubChainId, toBlock.timestamp, this.blockFinder),
];
const l1SearchConfig = {
fromBlock: l1FromBlock,
toBlock: l1ToBlock,
};
const initiatedQueryResult = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.MessageSent(undefined, fromAddress),
eventConfig
this.getL1Bridge().filters.MessageSent(undefined, toAddress),
l1SearchConfig
);

// @dev There will be a MessageSent to the SpokePool address for each RelayedRootBundle so remove
// those with 0 value.
// If there are no initiations, then exit early, since there will be no finalized events to match.
// This can happen if the from/toAddress is the hub pool.
if (initiatedQueryResult.length === 0) {
return Promise.resolve({});
}

const internalMessageHashes = initiatedQueryResult
.filter(({ args }) => args._value.gt(0))
.map(({ args }) => args._messageHash);
Expand All @@ -80,11 +112,26 @@ export class LineaWethBridge extends BaseBridgeAdapter {
this.getL2Bridge().filters.MessageClaimed(internalMessageHashes),
eventConfig
);
const finalizedHashes = events.map(({ args }) => args._messageHash);
const matchedEvents = events
.map((finalized) => {
const queryEvent = initiatedQueryResult.find(
(initiated) => initiated.args._messageHash === finalized.args._messageHash
);
// It is possible for a finalized event to be observed without the corresponding initiation event
// when the finalization event approaches the max look back value. In this case, we filter those out.
return isDefined(queryEvent)
? {
...processEvent(queryEvent, "_value", "_to", "_from"),
blockNumber: finalized.blockNumber,
transactionIndex: finalized.transactionIndex,
logIndex: finalized.logIndex,
transactionHash: finalized.transactionHash,
}
: undefined;
})
.filter(isDefined);
return {
[this.resolveL2TokenAddress(l1Token)]: initiatedQueryResult
.filter(({ args }) => finalizedHashes.includes(args._messageHash))
.map((event) => processEvent(event, "_value", "_to", "_from")),
[this.resolveL2TokenAddress(l1Token)]: matchedEvents,
};
}
}
11 changes: 5 additions & 6 deletions src/adapter/bridges/PolygonERC20Bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Provider,
bnToHex,
ZERO_ADDRESS,
getL2TokenAddresses,
} from "../../utils";
import { CONTRACT_ADDRESSES } from "../../common";
import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter";
Expand All @@ -31,7 +30,6 @@ export class PolygonERC20Bridge extends BaseBridgeAdapter {
// TOKEN_SYMBOLS_MAP. This constructor will therefore break if
// either the SDK, or the constants dependency in the SDK, is not
// up-to-date.
const l2TokenAddresses = getL2TokenAddresses(l1Token);
const { address: l1Address, abi: l1Abi } = CONTRACT_ADDRESSES[hubChainId].polygonBridge;
const { address: l1GatewayAddress, abi: l1GatewayAbi } = CONTRACT_ADDRESSES[hubChainId].polygonRootChainManager;
super(l2chainId, hubChainId, l1Signer, l2SignerOrProvider, [l1Address]);
Expand All @@ -41,7 +39,8 @@ export class PolygonERC20Bridge extends BaseBridgeAdapter {

// For Polygon, we look for mint events triggered by the L2 token, not the L2 Bridge.
const l2Abi = CONTRACT_ADDRESSES[l2chainId].withdrawableErc20.abi;
this.l2Bridge = new Contract(l2TokenAddresses[l2chainId], l2Abi, l2SignerOrProvider);
const l2TokenAddress = this.resolveL2TokenAddress(l1Token);
this.l2Bridge = new Contract(l2TokenAddress, l2Abi, l2SignerOrProvider);
}

async constructL1ToL2Txn(
Expand All @@ -65,12 +64,12 @@ export class PolygonERC20Bridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.LockedERC20(undefined, fromAddress, l1Token),
this.getL1Bridge().filters.LockedERC20(undefined, toAddress, l1Token),
eventConfig
);
return {
[this.resolveL2TokenAddress(l1Token)]: events.map((event) =>
processEvent(event, "amount", "depositorReceiver", "depositor")
processEvent(event, "amount", "depositReceiver", "depositor")
),
};
}
Expand All @@ -83,7 +82,7 @@ export class PolygonERC20Bridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL2Bridge(),
this.getL2Bridge().filters.Transfer(ZERO_ADDRESS, fromAddress),
this.getL2Bridge().filters.Transfer(ZERO_ADDRESS, toAddress),
eventConfig
);
return {
Expand Down
4 changes: 2 additions & 2 deletions src/adapter/bridges/PolygonWethBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class PolygonWethBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL1Bridge(),
this.getL1Bridge().filters.LockedEther(undefined, fromAddress),
this.getL1Bridge().filters.LockedEther(undefined, toAddress),
eventConfig
);
return {
Expand All @@ -82,7 +82,7 @@ export class PolygonWethBridge extends BaseBridgeAdapter {
): Promise<BridgeEvents> {
const events = await paginatedEventQuery(
this.getL2Bridge(),
this.getL2Bridge().filters.Transfer(ZERO_ADDRESS, fromAddress),
this.getL2Bridge().filters.Transfer(ZERO_ADDRESS, toAddress),
eventConfig
);
return {
Expand Down
Loading
Loading