Skip to content

Fix: use swapExactETHForTokens instead of swapETHForExactTokens - #5

Open
draevik wants to merge 1 commit into
lightchain-protocol:mainfrom
draevik:fix/swap-eth-for-exact-tokens
Open

Fix: use swapExactETHForTokens instead of swapETHForExactTokens#5
draevik wants to merge 1 commit into
lightchain-protocol:mainfrom
draevik:fix/swap-eth-for-exact-tokens

Conversation

@draevik

@draevik draevik commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What this fixes

The native-in swap branch in swap() (hooks/useWeb3Functions.ts) called swapETHForExactTokens — an exact-output router function — while passing it amountOutMin, a slippage floor, not an exact target. The call still succeeds (the user's input amount is normally enough to cover the floor amount), so it never reverts — it just silently pins the received tokens to the worst-case slippage amount every time, refunding the unused ETH, instead of delivering the real market-rate output.

Before (hooks/useWeb3Functions.ts):

if (fromAddress === zeroAddress) {
  path = [weth, toAddress];
  methods = [
    "swapETHForExactTokens",
    "swapExactETHForTokensSupportingFeeOnTransferTokens",
  ];
}

After (matches config.governor-style consistency — i.e. matches the swapExact... pattern already used correctly by the other two trade directions a few lines below):

if (fromAddress === zeroAddress) {
  path = [weth, toAddress];
}
// ...
const methods = getSwapMethods(
  fromAddress === zeroAddress,
  toAddress === zeroAddress
);

What this adds

Extracted the trade-type → router-function mapping into a small, dependency-free helper, lib/swap-method.ts, so this logic is unit-testable without a wallet or RPC connection. Repo previously had zero test infrastructure (package.json had no test script), so this also adds vitest as a devDependency and a test script.

lib/swap-method.test.ts covers all three trade directions and explicitly asserts the native-in case returns swapExactETHForTokens, not swapETHForExactTokens.

Verification

  • Reverted the helper to the original buggy string locally and confirmed pnpm test fails (2 of 4 assertions), then restored the fix and confirmed all 4 pass — the test genuinely catches this regression, not just a green checkmark by coincidence.
  • Ran pnpm test on the final diff: 4/4 passing.
  • Ran pnpm lint and pnpm build: both clean (aside from a pre-existing, unrelated @metamask/sdk React Native resolution warning present on main too).
  • Confirmed the fix doesn't touch the token→ETH or token→token branches, which already used the correct swapExact... pattern.
  • Manual on-chain verification on testnet was attempted but blocked — see note below.

Note on manual testnet verification

Wanted to confirm real quoted-vs-received amounts on-chain before/after this fix, but hit a blocker unrelated to this change: the app's testnet network isn't currently selectable in the UI at all (config/index.ts only lists lcai in chains, so config/wagmi.ts never offers testnet as a connectable network). Separately, the router address the explorer associates with real swap activity on testnet doesn't match what's committed to config/index.ts for lcaiTestnet — worth a maintainer sanity check, but it's a config/deployment question, not something this PR should guess at. Flagging both as follow-ups rather than blocking this fix on them, since neither affects mainnet or the correctness of the change itself.

The native-in swap branch called swapETHForExactTokens (an exact-OUTPUT
function) while passing amountOutMin - a minimum floor, not an exact
target. This silently capped output at the slippage floor instead of
the actual market rate, without ever reverting.

Extracted method selection into lib/swap-method.ts so it's unit-testable
without a wallet/RPC connection, and added a regression test.
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

@draevik is attempting to deploy a commit to the Lightchain AI Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant