fix: a V4 SETTLE of ETH paid from the router reads as moved from the sender (closes #682) #686

Merged
clawbot merged 1 commits from issue-682-settle-router-payer into next 2026-10-27 06:49:38 +01:00
Collaborator

A V4 SETTLE of ETH that names the router as payer now counts as ETH the user pays. V4Router pays a SETTLE of ETH from the router's own ETH, whichever payer it names. The router holds the transaction's value.

  • With no ETH from an earlier step in the router, such a SETTLE reads as one the user pays.
  • When an earlier step left ETH in the router, such a SETTLE gets lines of its own. Its Moved from the sender line reads Up to and the amount.
  • When the decoder does not know the amount, as for CONTRACT_BALANCE, the Moved from the sender line reads Unknown (could not be decoded). A SETTLE on the step that sets the input side gets that line too.

With ETH as Token In, that Unknown line comes with no Amount line, as for any take of an unknown amount. On next, the Amount line showed the swap's own amount instead.

Deviation: one existing row in tests/uniswapRecipient.test.js now expects the ETH lines. Its SETTLE spends all the router's ETH, the transaction's value included.

Judgement call: ETH that reads Up to never joins the Amount total.

Unverified: how V4Router pays ETH comes from reading its code, not from a run on a chain.

Model: opus-5-5

A V4 `SETTLE` of ETH that names the router as payer now counts as ETH the user pays. V4Router pays a `SETTLE` of ETH from the router's own ETH, whichever payer it names. The router holds the transaction's value. - With no ETH from an earlier step in the router, such a `SETTLE` reads as one the user pays. - When an earlier step left ETH in the router, such a `SETTLE` gets lines of its own. Its `Moved from the sender` line reads `Up to` and the amount. - When the decoder does not know the amount, as for `CONTRACT_BALANCE`, the `Moved from the sender` line reads `Unknown (could not be decoded)`. A `SETTLE` on the step that sets the input side gets that line too. With ETH as `Token In`, that `Unknown` line comes with no `Amount` line, as for any take of an unknown amount. On `next`, the `Amount` line showed the swap's own amount instead. Deviation: one existing row in `tests/uniswapRecipient.test.js` now expects the ETH lines. Its `SETTLE` spends all the router's ETH, the transaction's value included. Judgement call: ETH that reads `Up to` never joins the `Amount` total. Unverified: how V4Router pays ETH comes from reading its code, not from a run on a chain. Model: opus-5-5
clawbot added the needs-review label 2026-10-27 05:35:00 +01:00
clawbot self-assigned this 2026-10-27 05:35:00 +01:00
Author
Collaborator

Review: FAIL (needs-rework)

  1. src/shared/uniswap.js, the V4_SWAP branch of decode(). The step that sets the input side may settle ETH from the router at an amount the decoder does not know. With no other figure on screen, that ETH now reads as nothing. Example: one V4 step with a SETTLE of CONTRACT_BALANCE of ETH from the router, a swap of ETH for USDC, and a TAKE_ALL. It shows Token In ETH with no Amount line and no Moved from the sender line, where next gave an Amount line. This breaks "never nothing" in the plan (#682 (comment)) and makes the PR body's "Its amount reads Unknown (could not be decoded)" false. Acceptable: such a SETTLE always gives a Moved from the sender line reading Unknown (could not be decoded), as it does after a V3 step, with a test for this one-step route.

  2. README.md, in the paragraph this change edits, and three comments in src/shared/uniswap.js: this change makes these sentences false.

    • "A later step paid from the router spends what the router holds and takes nothing": earlier in the same paragraph, the new text says a SETTLE of ETH paid from the router takes from the wallet.
    • "A later take of Token In is added to the total while both are quantities": an Up to ETH take is a quantity, and it is not added.
    • "A step that sets the input side and is paid from the router takes nothing from the user's wallet and gets none.", and "as when the router pays it" in the next sentence: a V4 step that pays ETH from the router now counts as paid by the user and gets lines.
    • The comments above inputPaidByUser ("A step paid from the router takes nothing from the sender."), above inTotal ("... is paid from the router counts in total but is not among them.") and above hasFirstTake ("paid from the router, it takes nothing from the sender.").

    Acceptable: each one is rewritten as a short, correct sentence that holds for ETH paid from the router, not patched with an added qualifier.

  3. tests/uniswap.test.js: no test has an Up to take of Token In, so no test covers the rule that Up to ETH never joins the Amount total (the !t.atMost check in decode()). Acceptable: a test where Token In is ETH, and an earlier step left ETH in the router before a later SETTLE of ETH from the router. That SETTLE reads Up to on its own lines, and the Amount line is unchanged.

Judgement call: the PR's choice stands. An Up to ETH take always keeps its own lines, so leaving it out of the total hides nothing.

Model: opus-5-5

**Review: FAIL (needs-rework)** 1. `src/shared/uniswap.js`, the `V4_SWAP` branch of `decode()`. The step that sets the input side may settle ETH from the router at an amount the decoder does not know. With no other figure on screen, that ETH now reads as nothing. Example: one V4 step with a `SETTLE` of `CONTRACT_BALANCE` of ETH from the router, a swap of ETH for USDC, and a `TAKE_ALL`. It shows `Token In` ETH with no `Amount` line and no `Moved from the sender` line, where `next` gave an `Amount` line. This breaks "never nothing" in the plan (https://git.eeqj.de/sneak/AutistMask/issues/682#issuecomment-157899) and makes the PR body's "Its amount reads `Unknown (could not be decoded)`" false. Acceptable: such a `SETTLE` always gives a `Moved from the sender` line reading `Unknown (could not be decoded)`, as it does after a V3 step, with a test for this one-step route. 2. `README.md`, in the paragraph this change edits, and three comments in `src/shared/uniswap.js`: this change makes these sentences false. - "A later step paid from the router spends what the router holds and takes nothing": earlier in the same paragraph, the new text says a `SETTLE` of ETH paid from the router takes from the wallet. - "A later take of `Token In` is added to the total while both are quantities": an `Up to` ETH take is a quantity, and it is not added. - "A step that sets the input side and is paid from the router takes nothing from the user's wallet and gets none.", and "as when the router pays it" in the next sentence: a V4 step that pays ETH from the router now counts as paid by the user and gets lines. - The comments above `inputPaidByUser` ("A step paid from the router takes nothing from the sender."), above `inTotal` ("... is paid from the router counts in `total` but is not among them.") and above `hasFirstTake` ("paid from the router, it takes nothing from the sender."). Acceptable: each one is rewritten as a short, correct sentence that holds for ETH paid from the router, not patched with an added qualifier. 3. `tests/uniswap.test.js`: no test has an `Up to` take of `Token In`, so no test covers the rule that `Up to` ETH never joins the `Amount` total (the `!t.atMost` check in `decode()`). Acceptable: a test where `Token In` is ETH, and an earlier step left ETH in the router before a later `SETTLE` of ETH from the router. That `SETTLE` reads `Up to` on its own lines, and the `Amount` line is unchanged. Judgement call: the PR's choice stands. An `Up to` ETH take always keeps its own lines, so leaving it out of the total hides nothing. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-27 06:00:51 +01:00
clawbot force-pushed issue-682-settle-router-payer from 182742152d to 628bc07c27 2026-10-27 06:21:27 +01:00 Compare
Author
Collaborator

Rework for #686 (comment):

  1. Fixed: ETH settled from the router at an amount the decoder does not know is now always a take of its own, also on the step that sets the input side. A new test covers the one-step route. The PR body now says so.
  2. Fixed: rewrote the listed README sentences and the three comments. Also fixed the README list of takes the total does not count, which lacked the Up to take. The ETH sentences now follow the ERC-20 one.
  3. Fixed: new test with WRAP_ETH, UNWRAP_WETH into the router, then a SETTLE of 1 ETH from the router. It reads Up to 1.0000 ETH on its own lines, and Amount stays 0.5000 ETH.

Model: opus-5-5

Rework for https://git.eeqj.de/sneak/AutistMask/pulls/686#issuecomment-157985: 1. Fixed: ETH settled from the router at an amount the decoder does not know is now always a take of its own, also on the step that sets the input side. A new test covers the one-step route. The PR body now says so. 2. Fixed: rewrote the listed README sentences and the three comments. Also fixed the README list of takes the total does not count, which lacked the `Up to` take. The ETH sentences now follow the ERC-20 one. 3. Fixed: new test with `WRAP_ETH`, `UNWRAP_WETH` into the router, then a `SETTLE` of 1 ETH from the router. It reads `Up to 1.0000 ETH` on its own lines, and `Amount` stays `0.5000 ETH`. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-27 06:21:36 +01:00
Author
Collaborator

Review: FAIL (needs-rework)

  1. README.md, the item this change adds to the list of takes the total does not count: "one of Token In that ETH an earlier step left in the router may pay part of" has to be read twice. Acceptable: a short item such as "an ETH take whose line reads Up to (see above);".

Follow-up note: in the PR body, "That line appears on the step that sets the input side too" could read "A SETTLE on the step that sets the input side gets that line too."

Judgement call: the PR's choice stands. An Up to ETH take always gets its own lines beside the Amount line.

Model: opus-5-5

**Review: FAIL (needs-rework)** 1. `README.md`, the item this change adds to the list of takes the total does not count: "one of `Token In` that ETH an earlier step left in the router may pay part of" has to be read twice. Acceptable: a short item such as "an ETH take whose line reads `Up to` (see above);". Follow-up note: in the PR body, "That line appears on the step that sets the input side too" could read "A `SETTLE` on the step that sets the input side gets that line too." Judgement call: the PR's choice stands. An `Up to` ETH take always gets its own lines beside the `Amount` line. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-27 06:35:18 +01:00
clawbot added 1 commit 2026-10-27 06:47:13 +01:00
fix: a V4 SETTLE of ETH paid from the router reads as moved from the sender (closes #682)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
060042f923
V4Router pays a SETTLE of ETH from the router's own ETH, whichever payer
it names. The router holds the transaction's value. So a SETTLE of ETH
that names the router as payer now counts as paid by the user.

When an earlier step left ETH in the router, such a SETTLE gets lines of
its own. Its line reads "Up to" and its amount, and that amount never
joins the Amount total. When the decoder does not know the SETTLE's
amount, as for CONTRACT_BALANCE, its line reads "Unknown (could not be
decoded)", also on the step that sets the input side.

One existing row in tests/uniswapRecipient.test.js now expects the ETH
lines. Its SETTLE spends all the router's ETH, the transaction's value
included.

Model: opus-5-5
clawbot force-pushed issue-682-settle-router-payer from 628bc07c27 to 060042f923 2026-10-27 06:47:13 +01:00 Compare
Author
Collaborator

Rewrote the README list item and the PR body sentence as the review suggested.

Model: opus-5-5

Rewrote the README list item and the PR body sentence as the review suggested. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-27 06:47:19 +01:00
Author
Collaborator

Review: PASS

The README list item and the PR body sentence now read clearly and are true to the code.

Model: opus-5-5

**Review: PASS** The README list item and the PR body sentence now read clearly and are true to the code. Model: opus-5-5
clawbot merged commit ec6b6b57a3 into next 2026-10-27 06:49:38 +01:00
clawbot deleted branch issue-682-settle-router-payer 2026-10-27 06:49:39 +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#686