fix: a permit on the zero address never reads as ETH (closes #660) #683

Merged
clawbot merged 1 commits from issue-660-permit-zero-address into next 2026-10-27 05:12:40 +01:00
Collaborator

Permit2 has no allowance of ETH. The swap decoder still read the zero address in a PERMIT2_PERMIT or a batch entry as ETH (#660).

  • Its Allowance token line read ETH. It now names the zero address, as for a token nothing knows. Permit2 allowance gives the amount in base units.
  • A permit of 1 wei of the zero address, then a V4 step of 5 ETH the user settles, read Amount 0.000000000000000001 ETH. A permit on the zero address now never stands as the Amount figure, so that route reads Amount 5.0000 ETH.
  • The same permit or batch entry to a spender other than the router left no Amount line. When the router paid the V4 SETTLE, no line gave the 5 ETH. An allowance of the zero address now never counts as one of Token In, so that route also reads Amount 5.0000 ETH.

Most of the README diff is prettier reflowing one long bullet. git diff --word-diff shows the two added sentences.

Model: opus-5-5

Permit2 has no allowance of ETH. The swap decoder still read the zero address in a `PERMIT2_PERMIT` or a batch entry as ETH (https://git.eeqj.de/sneak/AutistMask/issues/660). - Its `Allowance token` line read `ETH`. It now names the zero address, as for a token nothing knows. `Permit2 allowance` gives the amount in base units. - A permit of 1 wei of the zero address, then a V4 step of 5 ETH the user settles, read `Amount 0.000000000000000001 ETH`. A permit on the zero address now never stands as the `Amount` figure, so that route reads `Amount 5.0000 ETH`. - The same permit or batch entry to a spender other than the router left no `Amount` line. When the router paid the V4 `SETTLE`, no line gave the 5 ETH. An allowance of the zero address now never counts as one of `Token In`, so that route also reads `Amount 5.0000 ETH`. Most of the README diff is prettier reflowing one long bullet. `git diff --word-diff` shows the two added sentences. Model: opus-5-5
clawbot added the needs-review label 2026-10-27 04:03:11 +01:00
clawbot self-assigned this 2026-10-27 04:03:11 +01:00
Author
Collaborator

Review: FAIL (needs-rework)

  1. src/shared/uniswap.js, the toAnotherSpender check that decides the Amount line: an allowance of the zero address to a spender other than the router still counts as an allowance of Token In when Token In is ETH.

    • Route: a PERMIT2_PERMIT of 1 wei of the zero address to another address, then a V4 swap of 5 ETH whose SETTLE the router pays from the transaction's value.
    • It reads Token In ETH (native) with no Amount line, and no line gives the 5 ETH. A PERMIT2_PERMIT_BATCH entry reads the same.
    • The same route with no permit, or with a USDT permit to that address, reads Amount 5.0000 ETH.

    Permit2 cannot move ETH, so this allowance must not change the Amount line. Acceptable: that check never counts an allowance of the zero address as one of Token In, so the route reads Amount 5.0000 ETH. Add a test for the permit and one for the batch entry, and drop the PR body's judgement call.

  2. README.md, Transaction Decoding, and the comment above permitStands in src/shared/uniswap.js: the PR adds "its token is not the zero address" to a sentence that already runs about 110 words and chains its conditions with commas: "A PERMIT2_PERMIT names Token In only when its amount, Unlimited included, stands as the Amount figure [...] and the decoder reads every step after it in full." Acceptable: leave that sentence as on next in both places. Replace the sentence the PR adds after it with a short one, for example: "A permit on the zero address never stands as the Amount figure, because Permit2 has no allowance of ETH."

  3. PR body: "git diff --word-diff shows the three added sentences" is false. The README diff adds two sentences and one clause. Acceptable: say what the reworked diff adds, or drop the line.

Unverified: that Permit2 moves nothing under an allowance of the zero address comes from reading Permit2's code, not from a run on a chain.

Model: opus-5-5

**Review: FAIL (needs-rework)** 1. `src/shared/uniswap.js`, the `toAnotherSpender` check that decides the `Amount` line: an allowance of the zero address to a spender other than the router still counts as an allowance of `Token In` when `Token In` is ETH. - Route: a `PERMIT2_PERMIT` of 1 wei of the zero address to another address, then a V4 swap of 5 ETH whose `SETTLE` the router pays from the transaction's value. - It reads `Token In ETH (native)` with no `Amount` line, and no line gives the 5 ETH. A `PERMIT2_PERMIT_BATCH` entry reads the same. - The same route with no permit, or with a USDT permit to that address, reads `Amount 5.0000 ETH`. Permit2 cannot move ETH, so this allowance must not change the `Amount` line. Acceptable: that check never counts an allowance of the zero address as one of `Token In`, so the route reads `Amount 5.0000 ETH`. Add a test for the permit and one for the batch entry, and drop the PR body's judgement call. 2. `README.md`, Transaction Decoding, and the comment above `permitStands` in `src/shared/uniswap.js`: the PR adds "its token is not the zero address" to a sentence that already runs about 110 words and chains its conditions with commas: "A `PERMIT2_PERMIT` names `Token In` only when its amount, `Unlimited` included, stands as the `Amount` figure [...] and the decoder reads every step after it in full." Acceptable: leave that sentence as on `next` in both places. Replace the sentence the PR adds after it with a short one, for example: "A permit on the zero address never stands as the `Amount` figure, because Permit2 has no allowance of ETH." 3. PR body: "`git diff --word-diff` shows the three added sentences" is false. The README diff adds two sentences and one clause. Acceptable: say what the reworked diff adds, or drop the line. Unverified: that Permit2 moves nothing under an allowance of the zero address comes from reading Permit2's code, not from a run on a chain. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-27 04:14:43 +01:00
clawbot force-pushed issue-660-permit-zero-address from 427d99e0a0 to 9d97fa9d66 2026-10-27 04:38:55 +01:00 Compare
Author
Collaborator
  1. Fixed: an allowance of the zero address never counts as one of Token In. New tests cover the permit and the batch entry to another spender, with the router paying the SETTLE. Judgement call dropped.
  2. Done in both places. The short sentence comes right before "Every other PERMIT2_PERMIT", so the comment's "A step before it" still points at the permit that stands.
  3. Fixed: that line now names the two sentences the README diff adds.

Model: opus-5-5

1. Fixed: an allowance of the zero address never counts as one of `Token In`. New tests cover the permit and the batch entry to another spender, with the router paying the `SETTLE`. Judgement call dropped. 2. Done in both places. The short sentence comes right before "Every other `PERMIT2_PERMIT`", so the comment's "A step before it" still points at the permit that stands. 3. Fixed: that line now names the two sentences the README diff adds. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-27 04:39:09 +01:00
Author
Collaborator

Review: FAIL (needs-rework)

  1. README.md, Transaction Decoding, and the comment above permitStands in src/shared/uniswap.js: the added sentence "A permit on the zero address never stands as the Amount figure, because Permit2 has no allowance of ETH." comes right before "Every other PERMIT2_PERMIT [...] leaves Token In and the Amount line as they read with no permit".

    • "Every other" now first reads as "every permit not on the zero address".
    • That reading takes in the permit whose amount stands, and contradicts the sentences before it. A newcomer has to read it twice.

    Acceptable: put the added sentence right after the "Every other" sentence. In the README that is after "and so do that exact-in and then a permit of 5,000 DAI to the router."; in the comment, after "and gets lines of its own below." Starting that sentence with "Every PERMIT2_PERMIT whose amount does not stand" also works.

Out of scope, for its own issue: a PERMIT2_TRANSFER_FROM of the zero address still reads as ETH (Token moved: ETH, with an ETH figure on Moved from the sender or Paid to), though Permit2 moves no ETH. That line overstates what leaves the wallet; it hides nothing.

Unverified: that Permit2 moves nothing under an allowance of the zero address comes from reading Permit2's code, not from a run on a chain.

Model: opus-5-5

**Review: FAIL (needs-rework)** 1. `README.md`, Transaction Decoding, and the comment above `permitStands` in `src/shared/uniswap.js`: the added sentence "A permit on the zero address never stands as the `Amount` figure, because Permit2 has no allowance of ETH." comes right before "Every other `PERMIT2_PERMIT` [...] leaves `Token In` and the `Amount` line as they read with no permit". - "Every other" now first reads as "every permit not on the zero address". - That reading takes in the permit whose amount stands, and contradicts the sentences before it. A newcomer has to read it twice. Acceptable: put the added sentence right after the "Every other" sentence. In the README that is after "and so do that exact-in and then a permit of 5,000 DAI to the router."; in the comment, after "and gets lines of its own below." Starting that sentence with "Every `PERMIT2_PERMIT` whose amount does not stand" also works. Out of scope, for its own issue: a `PERMIT2_TRANSFER_FROM` of the zero address still reads as ETH (`Token moved: ETH`, with an ETH figure on `Moved from the sender` or `Paid to`), though Permit2 moves no ETH. That line overstates what leaves the wallet; it hides nothing. Unverified: that Permit2 moves nothing under an allowance of the zero address comes from reading Permit2's code, not from a run on a chain. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-27 04:51:13 +01:00
clawbot added 1 commit 2026-10-27 05:08:57 +01:00
fix: a permit on the zero address never reads as ETH (closes #660)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
f30b77e1d4
Permit2 has no allowance of ETH, but the swap decoder read a permit's
zero-address token as ETH. Its Allowance token line read ETH. A permit of
1 wei of the zero address before a V4 step of 5 ETH stood as the Amount
figure, which then read 0.000000000000000001 ETH. With that permit to
another spender, there was no Amount line.

Such a permit now never stands as the Amount figure. To another spender,
it no longer removes the Amount line either. Its lines give the amount in
base units and name the zero address, as for a token nothing knows.

Model: opus-5-5
clawbot force-pushed issue-660-permit-zero-address from 9d97fa9d66 to f30b77e1d4 2026-10-27 05:08:57 +01:00 Compare
Author
Collaborator

Rework: the zero-address sentence now comes right after the "Every other PERMIT2_PERMIT" sentence, in README.md and in the comment above permitStands; nothing else changed.

Model: opus-5-5

Rework: the zero-address sentence now comes right after the "Every other `PERMIT2_PERMIT`" sentence, in `README.md` and in the comment above `permitStands`; nothing else changed. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-27 05:09:02 +01:00
Author
Collaborator

Review: PASS

The zero-address sentence now follows the "Every other PERMIT2_PERMIT" sentence in README.md and in the comment above permitStands, so "Every other" points only at the permit whose amount stands.

Model: opus-5-5

**Review: PASS** The zero-address sentence now follows the "Every other `PERMIT2_PERMIT`" sentence in `README.md` and in the comment above `permitStands`, so "Every other" points only at the permit whose amount stands. Model: opus-5-5
clawbot merged commit 36b200247a into next 2026-10-27 05:12:40 +01:00
clawbot deleted branch issue-660-permit-zero-address 2026-10-27 05:12:41 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#683