A PERMIT2_TRANSFER_FROM before a standing permit can move more than the Amount shows #655

Closed
opened 2026-10-21 00:13:07 +02:00 by clawbot · 2 comments
Collaborator

Seen by the review of #651.

Where

The swap decoder, decode() in src/shared/uniswap.js: the Amount figure when a PERMIT2_PERMIT stands (the plain shape of Uniswap's own routes) and a PERMIT2_TRANSFER_FROM of the same token also runs.

What happens

A PERMIT2_TRANSFER_FROM that runs before the standing permit uses whatever allowance the router already had, so it can move more of the token than the permit's amount. The Amount figure is the permit's amount; the transfer's figure appears only on its own lines. The Amount line can then read lower than what leaves the wallet.

What should happen

The approval screen never shows a figure for what leaves the wallet that may be too low: a permit's amount stands as the Amount figure only when no other step can take that token from the sender under an allowance the permit does not set; otherwise the figure is the total of the takes, or none.

Severity: major

Definition of done

  • A PERMIT2_TRANSFER_FROM of the permit's token before the permit ends the permit's standing, so the Amount figure is not lower than what may leave.
  • A test with that route, failing on next.

Model: opus-5-5

Seen by the review of https://git.eeqj.de/sneak/AutistMask/pulls/651. ## Where The swap decoder, `decode()` in `src/shared/uniswap.js`: the `Amount` figure when a `PERMIT2_PERMIT` stands (the plain shape of Uniswap's own routes) and a `PERMIT2_TRANSFER_FROM` of the same token also runs. ## What happens A `PERMIT2_TRANSFER_FROM` that runs before the standing permit uses whatever allowance the router already had, so it can move more of the token than the permit's amount. The `Amount` figure is the permit's amount; the transfer's figure appears only on its own lines. The `Amount` line can then read lower than what leaves the wallet. ## What should happen The approval screen never shows a figure for what leaves the wallet that may be too low: a permit's amount stands as the `Amount` figure only when no other step can take that token from the sender under an allowance the permit does not set; otherwise the figure is the total of the takes, or none. Severity: major ## Definition of done - [ ] A `PERMIT2_TRANSFER_FROM` of the permit's token before the permit ends the permit's standing, so the `Amount` figure is not lower than what may leave. - [ ] A test with that route, failing on `next`. Model: opus-5-5
clawbot self-assigned this 2026-10-21 00:13:07 +02:00
Author
Collaborator

Plan: one PR to next, in permitStands in decode() (src/shared/uniswap.js). Any step before the permit that may take the permit's token from the sender (a PERMIT2_TRANSFER_FROM of that token, a swap step the user pays in it, or a step the decoder does not read) ends the permit's standing, as a later one already does; the Amount figure is then the total of the takes, or none. Tests with a PERMIT2_TRANSFER_FROM and with a user-paid swap step before the permit, each failing on next; Uniswap's own routes read as on next.

Model: opus-5-5

Plan: one PR to `next`, in `permitStands` in `decode()` (`src/shared/uniswap.js`). Any step before the permit that may take the permit's token from the sender (a `PERMIT2_TRANSFER_FROM` of that token, a swap step the user pays in it, or a step the decoder does not read) ends the permit's standing, as a later one already does; the `Amount` figure is then the total of the takes, or none. Tests with a `PERMIT2_TRANSFER_FROM` and with a user-paid swap step before the permit, each failing on `next`; Uniswap's own routes read as on `next`. Model: opus-5-5
Author
Collaborator

Built in #661: a PERMIT2_TRANSFER_FROM of the permit's token before the permit now keeps the permit's amount from standing as the Amount figure. The plan's second test, a user-paid swap step before the permit, was not added: that route already reads as the total on next (reason on the PR).

Model: opus-5-5

Built in https://git.eeqj.de/sneak/AutistMask/pulls/661: a `PERMIT2_TRANSFER_FROM` of the permit's token before the permit now keeps the permit's amount from standing as the `Amount` figure. The plan's second test, a user-paid swap step before the permit, was not added: that route already reads as the total on `next` (reason on the PR). 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#655