From d64f1e27a2fd289eb049e8cde85f9749143645e5 Mon Sep 17 00:00:00 2001 From: hzhu Date: Mon, 20 Jan 2025 20:53:00 -0800 Subject: [PATCH] fix: sum total amount leaving the taker's account Some trades involve a sell tax, which needs to be accounted for. By including both the output amount and the sell tax, we can calculate the total amount leaving the user's wallet. Otherwise, only the tax is shown as the amount leaving the wallet. resolves #72 --- src/index.ts | 8 +++++++- src/tests/index.test.ts | 31 +++++++++++++++++++++++++++++++ src/types.ts | 1 + src/utils/index.ts | 3 ++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 20e7111..3df59c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -86,7 +86,13 @@ export async function parseSwap({ (log) => log.from.toLowerCase() === taker.toLowerCase() ); - let input = fromTaker.length ? fromTaker[0] : logs[0]; + let input = fromTaker.length + ? fromTaker.reduce((acc, curr) => ({ + ...acc, + amount: formatUnits(acc.amountRaw + curr.amountRaw, curr.decimals), + amountRaw: acc.amountRaw + curr.amountRaw, + })) + : logs[0]; let output = nativeAmountToTaker === "0" diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts index f189a2d..edf007f 100644 --- a/src/tests/index.test.ts +++ b/src/tests/index.test.ts @@ -550,6 +550,37 @@ test("parse a gasless swap on Base (DEGEN for USDC) for SettlerMetaTxn", async ( }); }); +// https://basescan.org/tx/0x3d032fdd216315c3dce7bcafeac0805ec18d27c7c9fdf43836cab7fb61332a6d +test("parse a swap on Base (KEIRA for ETH) for Settler", async () => { + const publicClient = createPublicClient({ + chain: base, + transport: http( + `https://base-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}` + ), + }) as PublicClient; + + const transactionHash = + "0x3d032fdd216315c3dce7bcafeac0805ec18d27c7c9fdf43836cab7fb61332a6d"; + + const result = await parseSwap({ + publicClient, + transactionHash, + }); + + expect(result).toEqual({ + tokenIn: { + symbol: "KEIRA", + amount: "27538.512122127777968652", + address: "0x710eEc215b3bB653d42fC6e70E0531eA13F51A7A", + }, + tokenOut: { + symbol: "ETH", + amount: "0.035509880980229712", + address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + }, + }); +}); + // https://arbiscan.io/tx/0xb2c05194e4ec9ae0f82098ec82a606df544e87c8d6b7726bbb4b1dcc023cb9d7 test("parse a gasless swap on on Arbitrum (ARB for ETH)", async () => { const publicClient = createPublicClient({ diff --git a/src/types.ts b/src/types.ts index 775f46f..6e5234c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -50,6 +50,7 @@ export interface EnrichedLog { amount: string; address: Address; decimals: number; + amountRaw: bigint; } export interface Trace { diff --git a/src/utils/index.ts b/src/utils/index.ts index a787244..dfd21d2 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -107,12 +107,13 @@ export async function transferLogs({ const decimals = results[midpoint + index].result as number; const amount = log.data === "0x" ? "0" : formatUnits(BigInt(log.data), decimals); + const amountRaw = log.data === "0x" ? 0n : BigInt(log.data); const { address, topics } = log; const { 1: fromHex, 2: toHex } = topics; const from = getAddress(convertHexToAddress(fromHex)); const to = getAddress(convertHexToAddress(toHex)); - return { to, from, symbol, amount, address, decimals }; + return { to, from, symbol, amount, amountRaw, address, decimals }; }) .filter((log) => log.amount !== "0");