A swap split across two steps the user pays for shows only the first step's amount #625

Open
opened 2026-10-20 00:24:31 +02:00 by clawbot · 2 comments
Collaborator

Seen by the review of #620.

Where

The swap decoder, decode() in src/shared/uniswap.js. The swap's input side (Token In and Amount) is set by the first swap step that states it (setInputOnce()), and later swap steps never add to it.

What happens

A route split across two swap steps that the user pays for, with no PERMIT2_PERMIT in the transaction (the user already gave Permit2 an allowance), such as a V3 exact-in of 600 USDT and a V2 exact-in of 400 USDT, both paid by the user, reads Amount 600.0000 USDT. 1,000 USDT leave the wallet. The approval screen shows less than the user is authorizing.

What should happen

The approval screen states what the user is authorizing: every amount of the user's tokens the swap steps spend is shown, so the amount read is what leaves the wallet.

Severity: major

Definition of done

  • A swap whose steps the user pays for, split across two or more steps, shows the total the user pays, or each step's amount, so no amount of the user's tokens that leaves the wallet goes unshown.
  • Tests for a two-step split paid by the user (V3 and V2, and a V4 step), each failing on next.

Model: opus-5-5

Seen by the review of https://git.eeqj.de/sneak/AutistMask/pulls/620. ## Where The swap decoder, `decode()` in `src/shared/uniswap.js`. The swap's input side (`Token In` and `Amount`) is set by the first swap step that states it (`setInputOnce()`), and later swap steps never add to it. ## What happens A route split across two swap steps that the user pays for, with no `PERMIT2_PERMIT` in the transaction (the user already gave Permit2 an allowance), such as a V3 exact-in of 600 USDT and a V2 exact-in of 400 USDT, both paid by the user, reads `Amount 600.0000 USDT`. 1,000 USDT leave the wallet. The approval screen shows less than the user is authorizing. ## What should happen The approval screen states what the user is authorizing: every amount of the user's tokens the swap steps spend is shown, so the amount read is what leaves the wallet. Severity: major ## Definition of done - [ ] A swap whose steps the user pays for, split across two or more steps, shows the total the user pays, or each step's amount, so no amount of the user's tokens that leaves the wallet goes unshown. - [ ] Tests for a two-step split paid by the user (V3 and V2, and a V4 step), each failing on `next`. Model: opus-5-5
clawbot self-assigned this 2026-10-20 00:24:31 +02:00
Author
Collaborator

Plan: one PR to next, in decode() in src/shared/uniswap.js. The Amount line gives the total that every swap step the user pays for (payerIsUser true) spends of the Token In token, not the first such step's amount. A swap step the user pays for that spends a different token gets its own line with its amount and token, in the shape of the lines a PERMIT2_TRANSFER_FROM now gets. Steps paid from the router spend what is already there and add nothing. Where a step states a maximum rather than an exact amount, the line says the total is at most that, as the line already does for such a step. A PERMIT2_PERMIT is left as it is (that is #370). Tests for a split paid by the user across V3 and V2, and across a V4 step, each failing on next.

Model: opus-5-5

Plan: one PR to `next`, in `decode()` in `src/shared/uniswap.js`. The `Amount` line gives the total that every swap step the user pays for (`payerIsUser` true) spends of the `Token In` token, not the first such step's amount. A swap step the user pays for that spends a different token gets its own line with its amount and token, in the shape of the lines a `PERMIT2_TRANSFER_FROM` now gets. Steps paid from the router spend what is already there and add nothing. Where a step states a maximum rather than an exact amount, the line says the total is at most that, as the line already does for such a step. A `PERMIT2_PERMIT` is left as it is (that is https://git.eeqj.de/sneak/AutistMask/issues/370). Tests for a split paid by the user across V3 and V2, and across a V4 step, each failing on `next`. Model: opus-5-5
Author
Collaborator

Implemented in #626: each later swap step the user pays for adds its amount to Amount when it spends Token In, and one spending another token gets its own Moved from the sender lines.

Model: opus-5-5

Implemented in https://git.eeqj.de/sneak/AutistMask/pulls/626: each later swap step the user pays for adds its amount to `Amount` when it spends `Token In`, and one spending another token gets its own `Moved from the sender` lines. 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#625