fix: the swap decoder shows the ETH of a WRAP_ETH that does not set the input side (closes #721) #725

Merged
clawbot merged 1 commits from issue-721-wrap-eth-moved-from-sender into next 2026-11-03 06:51:15 +01:00
Collaborator

A WRAP_ETH that did not set the input side took ETH from the sender with no line saying so, as #721 describes.

A WRAP_ETH of a stated amount after that step now counts as a take from the sender:

  • Paid to anyone but the router, it gets Moved from the sender, Token moved and Moved to. Moved to names the recipient or reads The sender.
  • Paid into the router, it joins the Amount line when Token In is ETH. With any other Token In, it gets the same lines, and Moved to reads The swap step that spends it.
  • When the router may already hold ETH, the amount reads Up to and never joins the Amount line.

A WRAP_ETH this decoder cannot read gets Moved from the sender reading Unknown (could not be decoded).

A WRAP_ETH of CONTRACT_BALANCE reads as before. Uniswap's SDK states an amount only on the wrap that comes first and uses CONTRACT_BALANCE on every later one, so its routes do not change.

Disclosures:

  • Deviation: the plan names tests/uniswap.test.js, but three rows of tests/uniswapRecipient.test.js pinned the missing lines, so they changed too.
  • Judgement call: a later WRAP_ETH of zero gets no line, because it wraps nothing.
  • Judgement call: with a V2 or V3 exact-out step in the transaction, these lines read Up to, as every other take's lines do there.
  • Unverified: nothing was run on a chain, and the SDK was read from its main branch.

Model: opus-5-5

A `WRAP_ETH` that did not set the input side took ETH from the sender with no line saying so, as https://git.eeqj.de/sneak/AutistMask/issues/721 describes. A `WRAP_ETH` of a stated amount after that step now counts as a take from the sender: - Paid to anyone but the router, it gets `Moved from the sender`, `Token moved` and `Moved to`. `Moved to` names the recipient or reads `The sender`. - Paid into the router, it joins the `Amount` line when `Token In` is ETH. With any other `Token In`, it gets the same lines, and `Moved to` reads `The swap step that spends it`. - When the router may already hold ETH, the amount reads `Up to` and never joins the `Amount` line. A `WRAP_ETH` this decoder cannot read gets `Moved from the sender` reading `Unknown (could not be decoded)`. A `WRAP_ETH` of `CONTRACT_BALANCE` reads as before. Uniswap's SDK states an amount only on the wrap that comes first and uses `CONTRACT_BALANCE` on every later one, so its routes do not change. Disclosures: - Deviation: the plan names `tests/uniswap.test.js`, but three rows of `tests/uniswapRecipient.test.js` pinned the missing lines, so they changed too. - Judgement call: a later `WRAP_ETH` of zero gets no line, because it wraps nothing. - Judgement call: with a V2 or V3 exact-out step in the transaction, these lines read `Up to`, as every other take's lines do there. - Unverified: nothing was run on a chain, and the SDK was read from its `main` branch. Model: opus-5-5
clawbot added the needs-review label 2026-11-03 05:06:22 +01:00
clawbot self-assigned this 2026-11-03 05:06:22 +01:00
Author
Collaborator

FAIL, needs-rework.

1. src/shared/uniswap.js, the else of the WRAP_ETH branch: a WRAP_ETH this decoder cannot read takes ETH with no line. The router reads this input with no length check and ignores the upper bytes of the address word, so a step decodeWrapEth() rejects can still run. A V3 exact-in of 600 USDT, then a WRAP_ETH of 1 ETH whose recipient word has non-zero upper bytes, reads Amount 600 USDT and gives no ETH figure. After a first WRAP_ETH of 1 ETH, the same step leaves Amount at 1 ETH. #721 asks for a line for every amount the calldata takes from the sender.

Acceptable:

  • Call spentUnread() in that else, as the V2, V3 and PERMIT2_TRANSFER_FROM branches do.
  • Add a WRAP_ETH whose input it cannot read to the list in the comment above spentUnread.
  • Add a row to the new table in tests/uniswap.test.js: commands: [0x00, 0x0b], inputs: [V3_600, "0x1234"], lines: [...USDT_600_GROUP, ["Moved from the sender", UNDECODED]].

2. README.md, the Moved from the sender bullet: a sentence that is false as read. "A WRAP_ETH of CONTRACT_BALANCE states no amount, so it gets none. ETH that the sender pays a V4 step or such a WRAP_ETH can get these three lines when the router may hold ETH from an earlier step." Here "such a WRAP_ETH" points at the CONTRACT_BALANCE wrap, which never gets these lines, and "gets none" does not say none of what.

Acceptable: "A WRAP_ETH of CONTRACT_BALANCE states no amount, so it gets no lines. ETH that the sender pays a V4 step or a WRAP_ETH of a stated amount can get these three lines when the router may hold ETH from an earlier step."

Follow-up note, not failing: Moved to reads The swap step that spends it when no swap step does, as with a WRAP_ETH into the router followed by a SWEEP of that WETH to another address, though Paid to names that address.

Judgement call: finding 1 reads the same on next, and the plan names only a stated amount; I took the issue's "every amount" sentence as covering it.

Unverified: nothing was run on a chain, and finding 1 rests on the router's source on its main branch.

Unverified: the SDK's encodeSwaps accepts steps from Uniswap's routing service, including a later WRAP_ETH of any amount. Its tests use CONTRACT_BALANCE there, but what the service sends was not checked.

Model: opus-5-5

FAIL, `needs-rework`. **1. `src/shared/uniswap.js`, the `else` of the `WRAP_ETH` branch: a `WRAP_ETH` this decoder cannot read takes ETH with no line.** The router reads this input with no length check and ignores the upper bytes of the address word, so a step `decodeWrapEth()` rejects can still run. A V3 exact-in of 600 USDT, then a `WRAP_ETH` of 1 ETH whose recipient word has non-zero upper bytes, reads `Amount` 600 USDT and gives no ETH figure. After a first `WRAP_ETH` of 1 ETH, the same step leaves `Amount` at 1 ETH. https://git.eeqj.de/sneak/AutistMask/issues/721 asks for a line for every amount the calldata takes from the sender. Acceptable: - Call `spentUnread()` in that `else`, as the V2, V3 and `PERMIT2_TRANSFER_FROM` branches do. - Add a `WRAP_ETH` whose input it cannot read to the list in the comment above `spentUnread`. - Add a row to the new table in `tests/uniswap.test.js`: `commands: [0x00, 0x0b]`, `inputs: [V3_600, "0x1234"]`, `lines: [...USDT_600_GROUP, ["Moved from the sender", UNDECODED]]`. **2. `README.md`, the `Moved from the sender` bullet: a sentence that is false as read.** "A `WRAP_ETH` of `CONTRACT_BALANCE` states no amount, so it gets none. ETH that the sender pays a V4 step or such a `WRAP_ETH` can get these three lines when the router may hold ETH from an earlier step." Here "such a `WRAP_ETH`" points at the `CONTRACT_BALANCE` wrap, which never gets these lines, and "gets none" does not say none of what. Acceptable: "A `WRAP_ETH` of `CONTRACT_BALANCE` states no amount, so it gets no lines. ETH that the sender pays a V4 step or a `WRAP_ETH` of a stated amount can get these three lines when the router may hold ETH from an earlier step." Follow-up note, not failing: `Moved to` reads `The swap step that spends it` when no swap step does, as with a `WRAP_ETH` into the router followed by a `SWEEP` of that WETH to another address, though `Paid to` names that address. Judgement call: finding 1 reads the same on `next`, and the plan names only a stated amount; I took the issue's "every amount" sentence as covering it. Unverified: nothing was run on a chain, and finding 1 rests on the router's source on its `main` branch. Unverified: the SDK's `encodeSwaps` accepts steps from Uniswap's routing service, including a later `WRAP_ETH` of any amount. Its tests use `CONTRACT_BALANCE` there, but what the service sends was not checked. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-11-03 05:28:58 +01:00
clawbot force-pushed issue-721-wrap-eth-moved-from-sender from f6af4ca1bd to 894d972caa 2026-11-03 05:39:23 +01:00 Compare
Author
Collaborator
  1. Done: a WRAP_ETH this decoder cannot read now gets the line saying the amount could not be decoded, with the code comment's list and a new table row in tests/uniswap.test.js.
  2. Done: the README.md sentences now read as the review gave them.

Model: opus-5-5

1. Done: a `WRAP_ETH` this decoder cannot read now gets the line saying the amount could not be decoded, with the code comment's list and a new table row in `tests/uniswap.test.js`. 2. Done: the `README.md` sentences now read as the review gave them. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-11-03 05:39:31 +01:00
Author
Collaborator

FAIL, needs-rework.

1. README.md, the Moved from the sender bullet: a false sentence. "A WRAP_ETH of CONTRACT_BALANCE states no amount, so it gets no lines." One that sets the input side does get these lines when there is no Amount line, or when a permit's amount stands as the Amount figure. A PERMIT2_PERMIT of 5,000 USDT to the router, then that WRAP_ETH, then a V3 exact-in, reads Moved from the sender Unlimited.

Acceptable: replace the sentence with "A later WRAP_ETH of CONTRACT_BALANCE states no amount, so it gets no lines." and run make fmt.

2. tests/uniswap.test.js, the comment above the new table: a false sentence. "The rows marked "reads as on next" take nothing from the sender." A WRAP_ETH of CONTRACT_BALANCE wraps all the router's ETH, including any ETH the transaction carries, so the sender can pay for it.

Acceptable: replace the sentence with The rows marked "reads as on next" state no amount to take from the sender.

Follow-up note, not failing: a WRAP_ETH of CONTRACT_BALANCE to another address pays that address all the ETH the transaction carries with no Moved from the sender line, though the approval screen's Value line gives that ETH.

Follow-up note, not failing: the PR body does not mention the line for a WRAP_ETH this decoder cannot read; the commit message does.

Judgement call: finding 1 corrects wording the first review supplied.

Unverified: nothing was run on a chain, and the SDK was read from its main branch.

Model: opus-5-5

FAIL, `needs-rework`. **1. `README.md`, the `Moved from the sender` bullet: a false sentence.** "A `WRAP_ETH` of `CONTRACT_BALANCE` states no amount, so it gets no lines." One that sets the input side does get these lines when there is no `Amount` line, or when a permit's amount stands as the `Amount` figure. A `PERMIT2_PERMIT` of 5,000 USDT to the router, then that `WRAP_ETH`, then a V3 exact-in, reads `Moved from the sender` `Unlimited`. Acceptable: replace the sentence with "A later `WRAP_ETH` of `CONTRACT_BALANCE` states no amount, so it gets no lines." and run `make fmt`. **2. `tests/uniswap.test.js`, the comment above the new table: a false sentence.** "The rows marked "reads as on next" take nothing from the sender." A `WRAP_ETH` of `CONTRACT_BALANCE` wraps all the router's ETH, including any ETH the transaction carries, so the sender can pay for it. Acceptable: replace the sentence with `The rows marked "reads as on next" state no amount to take from the sender.` Follow-up note, not failing: a `WRAP_ETH` of `CONTRACT_BALANCE` to another address pays that address all the ETH the transaction carries with no `Moved from the sender` line, though the approval screen's `Value` line gives that ETH. Follow-up note, not failing: the PR body does not mention the line for a `WRAP_ETH` this decoder cannot read; the commit message does. Judgement call: finding 1 corrects wording the first review supplied. Unverified: nothing was run on a chain, and the SDK was read from its `main` branch. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-11-03 05:55:35 +01:00
clawbot added 1 commit 2026-11-03 06:10:28 +01:00
fix: the swap decoder shows the ETH of a WRAP_ETH that does not set the input side (closes #721)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
1a3fefde4a
A later WRAP_ETH of a stated amount now counts as a take from the sender.
When it pays anyone but the router, it gets its own Moved from the sender
lines, with the recipient on Moved to. When it pays the router, it joins
the Amount line if Token In is ETH, and otherwise gets those lines too.
When the router may already hold ETH, the amount reads Up to.

A WRAP_ETH whose input this decoder cannot read gets a line saying the
amount could not be decoded.

A WRAP_ETH of CONTRACT_BALANCE states no amount and reads as before, so
Uniswap's own routes do not change.

Model: opus-5-5
clawbot force-pushed issue-721-wrap-eth-moved-from-sender from 894d972caa to 1a3fefde4a 2026-11-03 06:10:28 +01:00 Compare
Author
Collaborator
  1. Done: the README.md sentence now reads as the review gave it.
  2. Done: the comment above the new table in tests/uniswap.test.js now reads as the review gave it.
  3. Done: the PR body now has a line about a WRAP_ETH this decoder cannot read.

Model: opus-5-5

1. Done: the `README.md` sentence now reads as the review gave it. 2. Done: the comment above the new table in `tests/uniswap.test.js` now reads as the review gave it. 3. Done: the PR body now has a line about a `WRAP_ETH` this decoder cannot read. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-11-03 06:10:45 +01:00
Author
Collaborator

PASS: this change does what #721 asks, and the two corrected sentences and the PR body line are as they say and true.

Judgement call: I read "later" in the README.md sentence as after the swap step, so a WRAP_ETH of CONTRACT_BALANCE between a PERMIT2_PERMIT and the swap step, which does get these lines, falls outside it.

Unverified: nothing was run on a chain, and the SDK was not re-read; what the sentences say about its routes rests on the earlier reviews.

Model: opus-5-5

PASS: this change does what https://git.eeqj.de/sneak/AutistMask/issues/721 asks, and the two corrected sentences and the PR body line are as they say and true. Judgement call: I read "later" in the `README.md` sentence as after the swap step, so a `WRAP_ETH` of `CONTRACT_BALANCE` between a `PERMIT2_PERMIT` and the swap step, which does get these lines, falls outside it. Unverified: nothing was run on a chain, and the SDK was not re-read; what the sentences say about its routes rests on the earlier reviews. Model: opus-5-5
clawbot merged commit 42a5d94b49 into next 2026-11-03 06:51:15 +01:00
clawbot deleted branch issue-721-wrap-eth-moved-from-sender 2026-11-03 06:51:15 +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#725