Uniswap V2_SWAP_EXACT_OUT (command 0x09) is decoded by a function nothing calls #283

Closed
opened 2026-08-14 06:08:15 +02:00 by clawbot · 2 comments
Collaborator

Found while adding ESLint in #152 — no-unused-vars flagged it.

src/shared/uniswap.js defines decodeV2SwapExactOut() (line 105), the decoder for Universal Router command 0x09. The command dispatch in decode() handles 0x00 (decodeV3SwapExactIn), 0x08 (decodeV2SwapExactIn), 0x0b, 0x0e and 0x10, but there is no cmdId === 0x09 arm, so decodeV2SwapExactOut is never called.

0x09 is listed in the command-name table at line 23 as "V2 Swap (Exact Out)", so the name is shown but the swap's input token, output token and amounts are not extracted. The approval preview for a Uniswap V2 exact-out swap therefore shows no token or amount detail, which is exactly the detail the preview exists to show.

Not fixed there: wiring a new command arm changes what the approval screen tells the user about a transaction, which is outside a lint-adoption change. The function was left in place with a scoped eslint-disable-next-line no-unused-vars pointing at this issue, so the code the fix needs is still there.

Done when decode() handles 0x09 the way it handles 0x08, a test covers a V2 exact-out calldata sample, and the eslint-disable comment in src/shared/uniswap.js is removed.

Found while adding ESLint in https://git.eeqj.de/sneak/AutistMask/issues/152 — `no-unused-vars` flagged it. `src/shared/uniswap.js` defines `decodeV2SwapExactOut()` (line 105), the decoder for Universal Router command `0x09`. The command dispatch in `decode()` handles `0x00` (`decodeV3SwapExactIn`), `0x08` (`decodeV2SwapExactIn`), `0x0b`, `0x0e` and `0x10`, but there is no `cmdId === 0x09` arm, so `decodeV2SwapExactOut` is never called. `0x09` is listed in the command-name table at line 23 as `"V2 Swap (Exact Out)"`, so the name is shown but the swap's input token, output token and amounts are not extracted. The approval preview for a Uniswap V2 exact-out swap therefore shows no token or amount detail, which is exactly the detail the preview exists to show. Not fixed there: wiring a new command arm changes what the approval screen tells the user about a transaction, which is outside a lint-adoption change. The function was left in place with a scoped `eslint-disable-next-line no-unused-vars` pointing at this issue, so the code the fix needs is still there. Done when `decode()` handles `0x09` the way it handles `0x08`, a test covers a V2 exact-out calldata sample, and the `eslint-disable` comment in `src/shared/uniswap.js` is removed.
clawbot added this to the 1.0.0 milestone 2026-09-21 09:20:00 +02:00
Author
Collaborator

Plan. One PR on a branch cut from next, base next.

  • decode() in src/shared/uniswap.js gets a 0x09 arm next to 0x08: the input side is the path's first token with amountInMax, the output side the last token with amountOut, set through the same setInputOnce() / setOutput() pair.
  • Unlike 0x08, the input figure of an exact-out swap is a ceiling, not the amount spent, so the Amount line must say it is a maximum in plain words; it is never shown as if it were the exact amount.
  • A unit test decodes a V2 exact-out calldata sample and checks both lines; it fails against current next. The eslint-disable comment goes.
  • README.md's Display Consistency text that names which step sets the Amount line is updated to include this one.
  • Out of scope: V3 exact-out (0x01), and #415, which follows this unit because it changes the same function.

Model: opus-5-5

Plan. One PR on a branch cut from `next`, base `next`. - `decode()` in `src/shared/uniswap.js` gets a `0x09` arm next to `0x08`: the input side is the path's first token with `amountInMax`, the output side the last token with `amountOut`, set through the same `setInputOnce()` / `setOutput()` pair. - Unlike `0x08`, the input figure of an exact-out swap is a ceiling, not the amount spent, so the `Amount` line must say it is a maximum in plain words; it is never shown as if it were the exact amount. - A unit test decodes a V2 exact-out calldata sample and checks both lines; it fails against current `next`. The `eslint-disable` comment goes. - `README.md`'s Display Consistency text that names which step sets the `Amount` line is updated to include this one. - Out of scope: V3 exact-out (`0x01`), and https://git.eeqj.de/sneak/AutistMask/issues/415, which follows this unit because it changes the same function. Model: opus-5-5
Author
Collaborator

Built as planned in #423. A V2 exact-out swap now shows both tokens; its Amount line reads Up to followed by amountInMax, and Min. received shows amountOut.

Model: opus-5-5

Built as planned in https://git.eeqj.de/sneak/AutistMask/pulls/423. A V2 exact-out swap now shows both tokens; its `Amount` line reads `Up to` followed by `amountInMax`, and `Min. received` shows `amountOut`. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#283