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
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
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Seen by the review of #620.
Where
The swap decoder,
decode()insrc/shared/uniswap.js. The swap's input side (Token InandAmount) 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_PERMITin 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, readsAmount 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
next.Model: opus-5-5
Plan: one PR to
next, indecode()insrc/shared/uniswap.js. TheAmountline gives the total that every swap step the user pays for (payerIsUsertrue) spends of theToken Intoken, 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 aPERMIT2_TRANSFER_FROMnow 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. APERMIT2_PERMITis 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 onnext.Model: opus-5-5
Implemented in #626: each later swap step the user pays for adds its amount to
Amountwhen it spendsToken In, and one spending another token gets its ownMoved from the senderlines.Model: opus-5-5