fix: a V4 swap action not in the deployed shape is shown as not decoded #537

Open
clawbot wants to merge 1 commits from issue-358-v4-undecoded-step into next
Collaborator

Fixes #358, as settled there: the V4 swap actions stay pinned to the parameter structs deployed on mainnet and Sepolia.

The issue expected the newer v4-periphery structs, which add minHopPriceX36, to fail to decode. They did not: ethers ignores leftover bytes and holds back an error in a field until that field is used, so it read all four as the deployed structs. The newer multi-hop exact-in struct then showed the offset of its hop-price array as Amount and its real amountIn as Min. received.

So the four swap-action decodes in src/shared/uniswap.js now go through decodeExactly(), which accepts a decode only when encoding the result again gives back the same bytes. A swap action that fails that lists its step as V4 Swap (could not be decoded), and its amounts are not shown. SETTLE and TAKE still name the tokens where present. A side the step leaves unnamed reads Unknown (could not be decoded), not Unknown (not named in the calldata), and no V2 or V3 step beside it, nor an UNWRAP_WETH, fills it in. The comment above decodeExactly() and the README record the pinned shape and both wordings.

The tests encode each swap action in both shapes; the newer one also with SETTLE_ALL and TAKE_ALL, and beside a V3 step on either side. Two existing tests with an unreadable V4 action now expect the new wordings.

Judgement call: the strict decode goes beyond marking the fallthrough, because without it the marker never fires for the shape the issue is about.

Not done: an unreadable V4_SWAP input as a whole, and failed V2, V3, SETTLE or TAKE decodes, are still skipped silently.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/AutistMask/issues/358, as settled there: the V4 swap actions stay pinned to the parameter structs deployed on mainnet and Sepolia. The issue expected the newer `v4-periphery` structs, which add `minHopPriceX36`, to fail to decode. They did not: ethers ignores leftover bytes and holds back an error in a field until that field is used, so it read all four as the deployed structs. The newer multi-hop exact-in struct then showed the offset of its hop-price array as `Amount` and its real `amountIn` as `Min. received`. So the four swap-action decodes in `src/shared/uniswap.js` now go through `decodeExactly()`, which accepts a decode only when encoding the result again gives back the same bytes. A swap action that fails that lists its step as `V4 Swap (could not be decoded)`, and its amounts are not shown. `SETTLE` and `TAKE` still name the tokens where present. A side the step leaves unnamed reads `Unknown (could not be decoded)`, not `Unknown (not named in the calldata)`, and no V2 or V3 step beside it, nor an `UNWRAP_WETH`, fills it in. The comment above `decodeExactly()` and the README record the pinned shape and both wordings. The tests encode each swap action in both shapes; the newer one also with `SETTLE_ALL` and `TAKE_ALL`, and beside a V3 step on either side. Two existing tests with an unreadable V4 action now expect the new wordings. Judgement call: the strict decode goes beyond marking the fallthrough, because without it the marker never fires for the shape the issue is about. Not done: an unreadable `V4_SWAP` input as a whole, and failed V2, V3, `SETTLE` or `TAKE` decodes, are still skipped silently. Model: opus-5-5
clawbot added the needs-review label 2026-10-14 05:52:27 +02:00
clawbot self-assigned this 2026-10-14 05:52:27 +02:00
clawbot force-pushed issue-358-v4-undecoded-step from 6e00d52f89 to 0c88dcbda9 2026-10-14 06:27:51 +02:00 Compare
Author
Collaborator

FAIL (needs-rework)

  1. src/shared/uniswap.js, the Token In and Token Out fallbacks in decode() (lines 671 and 734), next to the new step marker (line 596). When a V4 swap action is not in the deployed shape and no SETTLE/TAKE names the currencies, for example a swap action followed by SETTLE_ALL and TAKE_ALL, the screen shows V4 Swap (could not be decoded) and also says both tokens are "Unknown (not named in the calldata)". The calldata did name them, in the action that was not read, so those two lines present "could not decode" as "nothing there", which #358 rules out. For the newer single-pool structs this is new: on next they showed the right tokens. Acceptable: when a swap action went unread and a side is left without a token, that line says the currency could not be read, not that the calldata did not name it, with a test for a newer-shape swap action followed by SETTLE_ALL and TAKE_ALL.

Judgement call: the cases the PR lists as not done (an unreadable V4_SWAP input as a whole; failed V2, V3, SETTLE or TAKE decodes) are outside the issue's definition of done, since none of them is a V4 swap struct whose shape changed upstream.
Judgement call: a deployed-shape swap action with extra bytes appended is now shown as not decoded, although the router would run it; taken as the intended effect of pinning the shape.

Model: opus-5-5

**FAIL** (`needs-rework`) 1. `src/shared/uniswap.js`, the Token In and Token Out fallbacks in `decode()` (lines 671 and 734), next to the new step marker (line 596). When a V4 swap action is not in the deployed shape and no `SETTLE`/`TAKE` names the currencies, for example a swap action followed by `SETTLE_ALL` and `TAKE_ALL`, the screen shows `V4 Swap (could not be decoded)` and also says both tokens are "Unknown (not named in the calldata)". The calldata did name them, in the action that was not read, so those two lines present "could not decode" as "nothing there", which https://git.eeqj.de/sneak/AutistMask/issues/358 rules out. For the newer single-pool structs this is new: on `next` they showed the right tokens. Acceptable: when a swap action went unread and a side is left without a token, that line says the currency could not be read, not that the calldata did not name it, with a test for a newer-shape swap action followed by `SETTLE_ALL` and `TAKE_ALL`. Judgement call: the cases the PR lists as not done (an unreadable `V4_SWAP` input as a whole; failed V2, V3, `SETTLE` or `TAKE` decodes) are outside the issue's definition of done, since none of them is a V4 swap struct whose shape changed upstream. Judgement call: a deployed-shape swap action with extra bytes appended is now shown as not decoded, although the router would run it; taken as the intended effect of pinning the shape. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-14 09:14:51 +02:00
clawbot force-pushed issue-358-v4-undecoded-step from 0c88dcbda9 to ec1254204c 2026-10-14 11:27:27 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-14 11:27:33 +02:00
Author
Collaborator
  1. A token line left without a currency after a swap action went unread now reads Unknown (could not be decoded), not Unknown (not named in the calldata). A new test runs each newer-shape swap action followed by SETTLE_ALL and TAKE_ALL, and the existing unreadable-action test in tests/uniswapUndeterminedTokenIn.test.js now expects the new wording.

Model: opus-5-5

1. A token line left without a currency after a swap action went unread now reads `Unknown (could not be decoded)`, not `Unknown (not named in the calldata)`. A new test runs each newer-shape swap action followed by `SETTLE_ALL` and `TAKE_ALL`, and the existing unreadable-action test in `tests/uniswapUndeterminedTokenIn.test.js` now expects the new wording. Model: opus-5-5
Author
Collaborator

FAIL (needs-rework)

The earlier finding is resolved.

  1. src/shared/uniswap.js, the V4 swap branch of decode() (lines 606 and 617). A V4 step whose swap action could not be read, and which has no TAKE (or no SETTLE), sets nothing on that side, so a neighbouring step's token and figure take its place. A V3 swap of USDT to WETH followed by a newer-shape V4 swap of WETH to USDC that ends in TAKE_ALL is titled Swap USDT → WETH, with Token Out WETH and the V3 step's Min. received, although the user receives USDC. The mirror case, a newer-shape V4 step with SETTLE_ALL and then a V3 step, names the V3 step's input token and amount as what is paid. On next both transactions showed the right tokens. The screen now names a wrong asset in the very shape #358 is about. Acceptable: a V4 step with an unread swap action leaves a side it did not name undetermined, so that line reads Unknown (could not be decoded) and no other step's figure is shown beside it, with tests for a V3 step before and after such a V4 step.

Judgement call: this is in scope although the PR lists an unreadable V4_SWAP input as not done, because here only the swap action, in the changed upstream shape, is unread.

Model: opus-5-5

**FAIL** (`needs-rework`) The earlier finding is resolved. 1. `src/shared/uniswap.js`, the V4 swap branch of `decode()` (lines 606 and 617). A V4 step whose swap action could not be read, and which has no `TAKE` (or no `SETTLE`), sets nothing on that side, so a neighbouring step's token and figure take its place. A V3 swap of USDT to WETH followed by a newer-shape V4 swap of WETH to USDC that ends in `TAKE_ALL` is titled `Swap USDT → WETH`, with `Token Out` WETH and the V3 step's `Min. received`, although the user receives USDC. The mirror case, a newer-shape V4 step with `SETTLE_ALL` and then a V3 step, names the V3 step's input token and amount as what is paid. On `next` both transactions showed the right tokens. The screen now names a wrong asset in the very shape https://git.eeqj.de/sneak/AutistMask/issues/358 is about. Acceptable: a V4 step with an unread swap action leaves a side it did not name undetermined, so that line reads `Unknown (could not be decoded)` and no other step's figure is shown beside it, with tests for a V3 step before and after such a V4 step. Judgement call: this is in scope although the PR lists an unreadable `V4_SWAP` input as not done, because here only the swap action, in the changed upstream shape, is unread. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-14 17:49:06 +02:00
clawbot added 1 commit 2026-10-14 20:42:12 +02:00
fix: a V4 swap action not in the deployed shape is shown as not decoded (closes #358)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
f938950161
The four V4 swap actions are read only as the parameter structs deployed
on mainnet and Sepolia. ethers decoded the newer v4-periphery structs,
which add minHopPriceX36, as the deployed ones without an error, and the
newer multi-hop exact-in struct showed the offset of its hop-price array
as the swap amount. A decode now counts only when encoding it again gives
back the same bytes. A swap action that fails that marks its step "V4
Swap (could not be decoded)", and a side of the swap that its SETTLE or
TAKE did not name reads "Unknown (could not be decoded)" instead of
another step's token and figure. The README records both.

Model: opus-5-5
clawbot force-pushed issue-358-v4-undecoded-step from ec1254204c to f938950161 2026-10-14 20:42:12 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-14 20:42:35 +02:00
Author
Collaborator
  1. A V4 step whose swap action could not be read now sets both sides itself: a side its SETTLE or TAKE did not name reads Unknown (could not be decoded), and no other step's token or figure is shown for it. Tests run each newer-shape swap action after a V3 step (ending in TAKE_ALL) and before one (with SETTLE_ALL).

Judgement call: an UNWRAP_WETH after such a step no longer turns its unknown Token Out into ETH, with a test.

Model: opus-5-5

1. A V4 step whose swap action could not be read now sets both sides itself: a side its `SETTLE` or `TAKE` did not name reads `Unknown (could not be decoded)`, and no other step's token or figure is shown for it. Tests run each newer-shape swap action after a V3 step (ending in `TAKE_ALL`) and before one (with `SETTLE_ALL`). Judgement call: an `UNWRAP_WETH` after such a step no longer turns its unknown `Token Out` into ETH, with a test. Model: opus-5-5
Some checks are pending
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-358-v4-undecoded-step:issue-358-v4-undecoded-step
git checkout issue-358-v4-undecoded-step
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#537