Skip to content

SyntaxError: Cannot convert decimal string to BigInt in reduce accumulator #102

@mwelche

Description

@mwelche

Bug Description

When a swap produces 2+ ERC-20 transfer logs to the same recipient (e.g., partial fills, rebates, or multi-hop output tokens), parseSwap throws:

SyntaxError: Cannot convert 1044719.296572006383948274 to a BigInt
    at BigInt (<anonymous>)
    at t (dist/index.esm.js:1:7714)
    at Array.reduce (<anonymous>)

Root Cause

In the native token output branch, the reduce accumulator stores amount as a formatted decimal string (output of formatUnits), then on the next iteration attempts BigInt(acc.amount) on that decimal string — which throws because BigInt() cannot parse decimal values.

Deminified from index.esm.js:

const outputToken = logs
  .filter(u => u.to.toLowerCase() === senderAddress)
  .reduce((acc, log) => ({
    symbol: log.symbol,
    amount: formatUnits(BigInt(acc.amount) + parseUnits(log.amount, log.decimals), log.decimals),
    //                   ^^^^^^^^^^^^^^^^^^^
    //                   BUG: on 2nd+ iteration, acc.amount is a decimal string
    //                   like "1044719.296572006383948274" from the previous
    //                   formatUnits() call — BigInt() can't parse decimals
    address: log.address,
  }), { symbol: "", amount: "", address: "" });

What happens step by step:

  1. 1st iteration: acc.amount is ""BigInt("") returns 0n (or throws depending on engine). formatUnits(...) produces a decimal string like "1044719.296572006383948274".
  2. 2nd iteration: acc.amount is now "1044719.296572006383948274"BigInt("1044719.296572006383948274") throws SyntaxError.

Suggested Fix

Track the raw bigint value through the accumulator instead of round-tripping through formatUnits:

.reduce((acc, log) => {
  const newRaw = acc.amountRaw + parseUnits(log.amount, log.decimals);
  return {
    symbol: log.symbol,
    amountRaw: newRaw,
    amount: formatUnits(newRaw, log.decimals),
    address: log.address,
  };
}, { symbol: "", amount: "", amountRaw: 0n, address: "" });

Reproduction

This triggers when a swap transaction has multiple ERC-20 transfer logs directed to the sender address — for example partial fills or multi-hop swaps with rebates.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions