fix: a swap's WETH minimum reads as ETH only when all its WETH reaches the UNWRAP_WETH (closes #642)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

Between the step that set the output side and the UNWRAP_WETH, only a
step the decoder read that is a PERMIT2_PERMIT, a BALANCE_CHECK_ERC20,
or a SWEEP, TRANSFER, PAY_PORTION or PAY_PORTION_FULL_PRECISION of a
token other than WETH, and not of ETH to a WETH contract, keeps the
swap's WETH minimum as an ETH minimum; any other step leaves ETH with no
minimum. After an UNWRAP_WETH whose recipient is the router or cannot be
read, any later step but those makes the swap read WETH with no minimum.
A WETH fee paid by PAY_PORTION before the UNWRAP_WETH now shows no
minimum. README Display Consistency states the same rule.

Model: opus-5-5
This commit is contained in:
2026-10-20 17:13:34 +00:00
committed by sneak
parent 4472746b89
commit 3d5c5e0e6b
3 changed files with 323 additions and 36 deletions
+21 -11
View File
@@ -1260,17 +1260,27 @@ runs (Transaction Decoding below gives what the router holds). The router
unwraps only the WETH it holds, so WETH that step paid to the user, or to anyone
else, stays WETH: a swap that pays the router WETH, then a swap that pays the
user WETH, then an unwrap, shows WETH with the second swap's minimum. The
minimum reads in ETH when that step paid all its WETH to the router. When it
paid only part of it to the router, as a V4 step does that `TAKE`s some of its
WETH to the user and the rest to the router, or paid the router WETH beside a
payout the decoder cannot read, the swap shows ETH with no minimum: the decoder
does not count how much of that step's minimum reaches the router, nor read the
`UNWRAP_WETH`'s own minimum. A later step that sets the output side sets it
anew. Otherwise `Token Out` and `Min. received` keep the output side's own token
and figure, whether the swap was paid in ETH or in a token: a V2 exact-out swap
that buys USDC and then unwraps the WETH it did not spend shows USDC. The token
permission warning on the signature screen has its own amount wording, including
`Unknown`; the SignApproval section below describes it.
minimum reads in ETH only when that step paid all its WETH to the router and
every step between it and the `UNWRAP_WETH` is one the decoder read of these: a
`PERMIT2_PERMIT`, a `BALANCE_CHECK_ERC20`, or a `SWEEP`, `TRANSFER`,
`PAY_PORTION` or `PAY_PORTION_FULL_PRECISION` of a token other than WETH, but
not of ETH to a WETH contract, which pays the router WETH. None of these can
take WETH out of the router or pay anyone WETH; the decoder treats every other
step as one that may. Otherwise the swap shows ETH with no minimum, as it does
after a V4 step that `TAKE`s some of its WETH to the user and the rest to the
router, or that pays the router WETH beside a payout the decoder cannot read,
and with a WETH interface fee paid by `PAY_PORTION` before the `UNWRAP_WETH`:
the decoder does not count how much of that step's minimum reaches the
`UNWRAP_WETH`, nor read the `UNWRAP_WETH`'s own minimum. When that `UNWRAP_WETH`
pays the router, or its recipient cannot be read, the router may hold the ETH,
and a later step may pay it out as WETH, as a `WRAP_ETH` of it to the user does:
after any later step but those listed, the swap shows WETH with no minimum. A
later step that sets the output side sets it anew. Otherwise `Token Out` and
`Min. received` keep the output side's own token and figure, whether the swap
was paid in ETH or in a token: a V2 exact-out swap that buys USDC and then
unwraps the WETH it did not spend shows USDC. The token permission warning on
the signature screen has its own amount wording, including `Unknown`; the
SignApproval section below describes it.
The swap's `Deadline` line is the router's deadline as a UTC date and time, e.g.
`2026-02-27 08:25:51`. A JavaScript date reaches only to 275760-09-13 00:00:00