harden: a V4 swap with an undetermined output token is asserted to the user as ETH at 18 decimals #353

Closed
opened 2026-08-23 16:31:15 +02:00 by clawbot · 0 comments
Collaborator

Raised by the review of #352 (#352 (comment)). Pre-existing and latent; not introduced there.

src/shared/uniswap.js:426-435 — a V4 swap can set minOutput while leaving outputToken null, because the assignment is gated on if (v4.tokenOut). tokenInfo(null) then returns {symbol: "ETH", decimals: 18}, so an undetermined output token is stated to the user as ETH, with its Min. received formatted at 18 decimals.

This is the same class as #340 and #306: the approval screen asserting a fact it has not established. Here it is worse than a wrong scale — it names the wrong asset.

It may be deliberate, which is why this needs determining rather than patching: Uniswap V4 represents native ETH as the zero address, so collapsing a null tokenOut to ETH could be correct protocol semantics. The reviewer declined to call it a defect for that reason. Establish which it is before changing anything.

Definition of done

  • Determine whether a null V4 tokenOut genuinely means native ETH in the V4 encoding, or whether it means undetermined. Cite the encoding, do not infer from the current code.
  • If it means undetermined: the screen must say so rather than naming ETH, using the refusal vocabulary already established by #340 — never substitute a guess.
  • If it genuinely means native ETH: leave the behaviour and record why at the call site, so the next reader does not file this again.
  • Test covering whichever branch is correct. If a fix is warranted, it fails against current head — state the mutation and observed result.
  • make check green.
Raised by the review of https://git.eeqj.de/sneak/AutistMask/pulls/352 (https://git.eeqj.de/sneak/AutistMask/pulls/352#issuecomment-69133). Pre-existing and latent; not introduced there. `src/shared/uniswap.js:426-435` — a V4 swap can set `minOutput` while leaving `outputToken` null, because the assignment is gated on `if (v4.tokenOut)`. `tokenInfo(null)` then returns `{symbol: "ETH", decimals: 18}`, so an **undetermined** output token is stated to the user as **ETH**, with its `Min. received` formatted at 18 decimals. This is the same class as https://git.eeqj.de/sneak/AutistMask/issues/340 and https://git.eeqj.de/sneak/AutistMask/issues/306: the approval screen asserting a fact it has not established. Here it is worse than a wrong scale — it names the wrong asset. **It may be deliberate**, which is why this needs determining rather than patching: Uniswap V4 represents native ETH as the zero address, so collapsing a null `tokenOut` to ETH could be correct protocol semantics. The reviewer declined to call it a defect for that reason. Establish which it is before changing anything. ## Definition of done - [ ] Determine whether a null V4 `tokenOut` genuinely means native ETH in the V4 encoding, or whether it means undetermined. Cite the encoding, do not infer from the current code. - [ ] If it means undetermined: the screen must say so rather than naming ETH, using the refusal vocabulary already established by https://git.eeqj.de/sneak/AutistMask/issues/340 — never substitute a guess. - [ ] If it genuinely means native ETH: leave the behaviour and record why at the call site, so the next reader does not file this again. - [ ] Test covering whichever branch is correct. If a fix is warranted, it fails against current head — state the mutation and observed result. - [ ] `make check` green.
clawbot added this to the 1.0.0 milestone 2026-08-23 16:31:15 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#353