From 1d659a6f01db14f409f6f8f117189d06809e1b4f Mon Sep 17 00:00:00 2001 From: hzhu Date: Wed, 10 Jul 2024 00:59:01 -0700 Subject: [PATCH] fix: native transfers with SettlerMetaTxn --- src/parseSwapV2.ts | 33 +++++++++++++++++++++++++++++++++ src/tests/parseSwapV2.test.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/parseSwapV2.ts b/src/parseSwapV2.ts index 1bde04f..84180d6 100644 --- a/src/parseSwapV2.ts +++ b/src/parseSwapV2.ts @@ -63,6 +63,16 @@ export const NATIVE_SYMBOL_BY_CHAIN_ID: { [key in SupportedChainId]: string } = 43114: "AVAX", // Avalanche }; +const SETTLER_META_TXN_BY_CHAIN_ID: { [key in SupportedChainId]: string } = { + 1: "0x7C39a136EA20B3483e402EA031c1f3C019bAb24b", + 10: "0x4069560a180EbD76bB1aF947f5119Fe555BB4eA0", + 56: "0x73C25Ef091Ce3F2451946Be3f982549776bFED31", + 137: "0xF9332450385291b6dcE301917aF6905e28E8f35f", + 8453: "0x5CE929DDB01804bfF35B2F5c77b735bdB094AAc8", + 42161: "0x1aa84EB5cb62f686FC0D908AFd85864f4A05d5Ee", + 43114: "0x2adb2cE26848B94E13d2f7fE0fF7E945050D741c", +}; + const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11"; export function isChainIdSupported( @@ -280,6 +290,26 @@ export async function parseSwapV2({ } } + const isSettlerMetaTxn = + to?.toLowerCase() === SETTLER_META_TXN_BY_CHAIN_ID[chainId].toLowerCase(); + + if (isSettlerMetaTxn) { + const { args } = decodeFunctionData({ + abi: settlerAbi, + data: transaction.input, + }); + + const taker = args[0].recipient.toLowerCase() as Address; + + const nativeTransferAmount = extractNativeTransfer(trace, taker); + + output = { + symbol: NATIVE_SYMBOL_BY_CHAIN_ID[chainId], + amount: nativeTransferAmount, + address: NATIVE_TOKEN_ADDRESS, + }; + } + if (isNativeSell) { const nativeSellAmount = formatEther(value); const tokenOut = logs @@ -307,6 +337,9 @@ export async function parseSwapV2({ } if (!output) { + console.error( + "An error has occurred. File a bug report here: https://github.com/0xProject/0x-parser/issues/new/choose" + ); return null; } diff --git a/src/tests/parseSwapV2.test.ts b/src/tests/parseSwapV2.test.ts index 76868a4..9736d9d 100644 --- a/src/tests/parseSwapV2.test.ts +++ b/src/tests/parseSwapV2.test.ts @@ -414,6 +414,37 @@ test("parse a gasless swap on Base (USDC for DEGEN)", async () => { }); }); +// https://basescan.org/tx/0x14416958953850c5c5a572d6e8cb832c032d0678b3ce9da6cdce891a20864b99 +test("parse a gasless swap on Base (USDC for ETH) for SettlerMetaTxn", async () => { + const publicClient = createPublicClient({ + chain: base, + transport: http( + `https://base-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}` + ), + }) as PublicClient; + + const transactionHash = + "0x14416958953850c5c5a572d6e8cb832c032d0678b3ce9da6cdce891a20864b99"; + + const result = await parseSwapV2({ + publicClient, + transactionHash, + }); + + expect(result).toEqual({ + tokenIn: { + symbol: "USDC", + amount: "21.27865", + address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + }, + tokenOut: { + symbol: "ETH", + amount: "0.006847116541535933", + address: NATIVE_ASSET.address, + }, + }); +}); + // https://arbiscan.io/tx/0xb2c05194e4ec9ae0f82098ec82a606df544e87c8d6b7726bbb4b1dcc023cb9d7 test("parse a gasless swap on on Arbitrum (ARB for ETH)", async () => { const publicClient = createPublicClient({