fix: WETH paid to the user before an UNWRAP_WETH reads as WETH (closes #607)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

An UNWRAP_WETH made Token Out ETH whenever the output side was WETH,
though the router unwraps only the WETH it holds. decode() now records
where the step that set the output side paid its output, and an
UNWRAP_WETH makes the output ETH only when that step paid WETH to the
router and the router still holds WETH. When that step paid only part
of its WETH to the router, or made a payout the decoder cannot read,
the output reads 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 BALANCE_CHECK_ERC20 pays nobody, so it is
never read as unwrapped. README Display Consistency says the same.

Model: opus-5-5
This commit is contained in:
2026-10-20 13:03:40 +00:00
parent 070ad82338
commit edfd01014d
4 changed files with 261 additions and 30 deletions
+2 -2
View File
@@ -875,7 +875,7 @@ describe("uniswap decoder", () => {
const data = buildExecute(
solidityPacked(["uint8", "uint8"], [0x08, 0x0c]),
[
encodeV2SwapExactIn(USER_ADDR, 1000000n, 500000000000000n, [
encodeV2SwapExactIn(ROUTER_ADDR, 1000000n, 500000000000000n, [
USDC_ADDR,
SEPOLIA_WETH_ADDR,
]),
@@ -958,7 +958,7 @@ describe("uniswap decoder", () => {
const data = buildExecute(
solidityPacked(["uint8", "uint8"], [0x08, 0x0c]),
[
encodeV2SwapExactIn(USER_ADDR, 1000000n, 500000000000000n, [
encodeV2SwapExactIn(ROUTER_ADDR, 1000000n, 500000000000000n, [
USDT_ADDR,
WETH_ADDR,
]),