The swap decoder checked only the swap's output for being left in the router; it now checks every token a step pays the router, the WETH of a WRAP_ETH included. Each such token still there after the last step gets a Paid to line, The router, where it stays (no later step pays it out), and a Token moved into the router line naming it, so the minimum reads Min. paid out.
Not visible in the diff:
For Uniswap's own routes to read as before, more steps now count as spending all the router holds of a token: a V2 or V3 exact-in swap or a V4 SETTLE paid from the router with CONTRACT_BALANCE, a WRAP_ETH of CONTRACT_BALANCE, and an UNWRAP_WETH into the router.
A swap paid in ETH wraps an exact amount that its swap steps then spend from the router by exact amounts, so the WETH of a WRAP_ETH keeps its stated amount and those steps count against it. No other amount is followed.
That WETH is the one each network's routers were deployed with.
Judgement call: an existing test whose second swap is paid by the user, leaving the first swap's USDC in the router, now expects Min. paid out.
Not covered: a pool that runs out of liquidity fills an exact-in swap paid from the router only in part, leaving the rest there; the calldata cannot show that.
Unverified: router behaviour was read from its source at pinned commits, not run against deployed contracts.
Model: opus-5-5
Closes https://git.eeqj.de/sneak/AutistMask/issues/606.
The swap decoder checked only the swap's output for being left in the router; it now checks every token a step pays the router, the WETH of a `WRAP_ETH` included. Each such token still there after the last step gets a `Paid to` line, `The router, where it stays (no later step pays it out)`, and a `Token moved into the router` line naming it, so the minimum reads `Min. paid out`.
Not visible in the diff:
- For Uniswap's own routes to read as before, more steps now count as spending all the router holds of a token: a V2 or V3 exact-in swap or a V4 `SETTLE` paid from the router with `CONTRACT_BALANCE`, a `WRAP_ETH` of `CONTRACT_BALANCE`, and an `UNWRAP_WETH` into the router.
- A swap paid in ETH wraps an exact amount that its swap steps then spend from the router by exact amounts, so the WETH of a `WRAP_ETH` keeps its stated amount and those steps count against it. No other amount is followed.
- That WETH is the one each network's routers were deployed with.
Judgement call: an existing test whose second swap is paid by the user, leaving the first swap's USDC in the router, now expects `Min. paid out`.
Not covered: a pool that runs out of liquidity fills an exact-in swap paid from the router only in part, leaving the rest there; the calldata cannot show that.
Unverified: router behaviour was read from its source at pinned commits, not run against deployed contracts.
Model: opus-5-5
src/shared/uniswap.js, decode(), the loop over v4.settledFromRouter in the V4_SWAP branch, and the README sentence on OPEN_DELTA: a SETTLE of OPEN_DELTA paid from the router counts as paying the step's whole stated amount against the WETH a WRAP_ETH put in the router, whatever else is in the step. The router pays only what the step still owes for that token when the SETTLE runs. So after a WRAP_ETH of 1 ETH into the router, each of these routes leaves part of the user's WETH in the router and still reads Min. received:
one V4 step swapping 0.5 WETH with two SETTLEs of OPEN_DELTA from the router (the second pays nothing);
a SETTLE of 0.25 WETH and one of OPEN_DELTA, both from the router, for a swap of 0.75 WETH;
a swap action in the same step buying WETH back (the router pays only the difference);
the SETTLE of OPEN_DELTA from the router placed before the swap action, with the user settling the swap afterwards.
Acceptable: such a SETTLE counts the step's amount only when it is the step's only SETTLE or SETTLE_ALL of that token, comes after every swap action in the step, and no swap action in the step buys that token; otherwise it counts nothing. Add tests for these routes expecting Min. paid out, and make the README sentence say the same.
Unverified: how the router pays a SETTLE of OPEN_DELTA was read from the pinned v4-periphery source, not run against a deployed router.
Model: opus-5-5
**Review: FAIL (`needs-rework`)**
1. `src/shared/uniswap.js`, `decode()`, the loop over `v4.settledFromRouter` in the `V4_SWAP` branch, and the README sentence on `OPEN_DELTA`: a `SETTLE` of `OPEN_DELTA` paid from the router counts as paying the step's whole stated amount against the WETH a `WRAP_ETH` put in the router, whatever else is in the step. The router pays only what the step still owes for that token when the `SETTLE` runs. So after a `WRAP_ETH` of 1 ETH into the router, each of these routes leaves part of the user's WETH in the router and still reads `Min. received`:
- one V4 step swapping 0.5 WETH with two `SETTLE`s of `OPEN_DELTA` from the router (the second pays nothing);
- a `SETTLE` of 0.25 WETH and one of `OPEN_DELTA`, both from the router, for a swap of 0.75 WETH;
- a swap action in the same step buying WETH back (the router pays only the difference);
- the `SETTLE` of `OPEN_DELTA` from the router placed before the swap action, with the user settling the swap afterwards.
Acceptable: such a `SETTLE` counts the step's amount only when it is the step's only `SETTLE` or `SETTLE_ALL` of that token, comes after every swap action in the step, and no swap action in the step buys that token; otherwise it counts nothing. Add tests for these routes expecting `Min. paid out`, and make the README sentence say the same.
Unverified: how the router pays a `SETTLE` of `OPEN_DELTA` was read from the pinned `v4-periphery` source, not run against a deployed router.
Model: opus-5-5
Fixed: a SETTLE of OPEN_DELTA from the router now counts its step's amount only when it is the step's only SETTLE or SETTLE_ALL of that token, comes after every swap action, and no swap action buys that token; otherwise it counts nothing. Added tests for the four routes, each expecting Min. paid out, and the README sentence now says the same.
Model: opus-5-5
**Rework**
1. Fixed: a `SETTLE` of `OPEN_DELTA` from the router now counts its step's amount only when it is the step's only `SETTLE` or `SETTLE_ALL` of that token, comes after every swap action, and no swap action buys that token; otherwise it counts nothing. Added tests for the four routes, each expecting `Min. paid out`, and the README sentence now says the same.
Model: opus-5-5
src/shared/uniswap.js, decodeV4Swap(): a SETTLE or SETTLE_ALL whose parameters cannot be read, such as one whose currency word has a nonzero top byte (the router reads the currency from the word's last 20 bytes), is dropped without a trace, so it is not counted among the step's SETTLEs of that token. After a WRAP_ETH of 1 ETH into the router, a V4 step that swaps 1 WETH, has the user pay for it with such an unreadable SETTLE_ALL (or SETTLE) of WETH, and then has a SETTLE of OPEN_DELTA of WETH from the router reads Min. received. The router's SETTLE then pays nothing, the 1 ETH stays in the router, and the user also pays 1 WETH the screen never shows. Acceptable: a SETTLE or SETTLE_ALL that cannot be read makes every SETTLE of OPEN_DELTA from the router in its step count nothing, with a test for this route expecting Min. paid out.
Same rule: it takes what the step's swap actions state they spend as what the SETTLE pays, but a SWAP_EXACT_IN with an empty path states an amountIn and swaps nothing (the router runs no pool for it). After a WRAP_ETH of 1 ETH into the router, a V4 step with an empty-path exact-in of 1 WETH less 1,000 wei, a swap of 1,000 wei of WETH for USDC, and a SETTLE of OPEN_DELTA from the router reads Min. received, while all but 1,000 wei of the WETH stays in the router. Acceptable: such a SETTLE counts nothing when any swap action in the step names no token it buys, with a test for this route, and the README sentence on OPEN_DELTA saying the same as findings 1 and 2.
Comprehensibility: what a SETTLE of OPEN_DELTA from the router pays is decided in two places. decodeV4Swap() sets its amount to null when it cannot be followed and leaves it at zero otherwise, and the V4_SWAP branch of decode() then turns the zero left over into the step's amountIn or null, so a reader of either half has to know the other. Acceptable: decodeV4Swap() gives each SETTLE from the router the amount it pays (a quantity, CONTRACT_BALANCE, or null) in one place, and decode() only spends it.
Unverified: how the router reads a currency word with a nonzero top byte, and that it runs no swap for an empty path, was read from the pinned v4-periphery source, not run against a deployed router.
Model: opus-5-5
**Review: FAIL (`needs-rework`)**
1. `src/shared/uniswap.js`, `decodeV4Swap()`: a `SETTLE` or `SETTLE_ALL` whose parameters cannot be read, such as one whose currency word has a nonzero top byte (the router reads the currency from the word's last 20 bytes), is dropped without a trace, so it is not counted among the step's `SETTLE`s of that token. After a `WRAP_ETH` of 1 ETH into the router, a V4 step that swaps 1 WETH, has the user pay for it with such an unreadable `SETTLE_ALL` (or `SETTLE`) of WETH, and then has a `SETTLE` of `OPEN_DELTA` of WETH from the router reads `Min. received`. The router's `SETTLE` then pays nothing, the 1 ETH stays in the router, and the user also pays 1 WETH the screen never shows. Acceptable: a `SETTLE` or `SETTLE_ALL` that cannot be read makes every `SETTLE` of `OPEN_DELTA` from the router in its step count nothing, with a test for this route expecting `Min. paid out`.
2. Same rule: it takes what the step's swap actions state they spend as what the `SETTLE` pays, but a `SWAP_EXACT_IN` with an empty path states an `amountIn` and swaps nothing (the router runs no pool for it). After a `WRAP_ETH` of 1 ETH into the router, a V4 step with an empty-path exact-in of 1 WETH less 1,000 wei, a swap of 1,000 wei of WETH for USDC, and a `SETTLE` of `OPEN_DELTA` from the router reads `Min. received`, while all but 1,000 wei of the WETH stays in the router. Acceptable: such a `SETTLE` counts nothing when any swap action in the step names no token it buys, with a test for this route, and the README sentence on `OPEN_DELTA` saying the same as findings 1 and 2.
3. Comprehensibility: what a `SETTLE` of `OPEN_DELTA` from the router pays is decided in two places. `decodeV4Swap()` sets its amount to null when it cannot be followed and leaves it at zero otherwise, and the `V4_SWAP` branch of `decode()` then turns the zero left over into the step's `amountIn` or null, so a reader of either half has to know the other. Acceptable: `decodeV4Swap()` gives each `SETTLE` from the router the amount it pays (a quantity, `CONTRACT_BALANCE`, or null) in one place, and `decode()` only spends it.
Unverified: how the router reads a currency word with a nonzero top byte, and that it runs no swap for an empty path, was read from the pinned `v4-periphery` source, not run against a deployed router.
Model: opus-5-5
Fixed: any action of the step that cannot be read, an unreadable SETTLE or SETTLE_ALL among them, gives every SETTLE of OPEN_DELTA from the router in that step no amount; tests for an unreadable SETTLE_ALL and an unreadable SETTLE by the user expect Min. paid out.
Fixed: such a SETTLE gets no amount unless every swap action in the step names the token it spends and the one it buys, so an exact-in with an empty path counts nothing; a test for that route expects Min. paid out, and the README sentence on OPEN_DELTA now states the whole rule as the code applies it.
Fixed: decodeV4Swap() gives each SETTLE from the router the amount it pays (a quantity, CONTRACT_BALANCE, or null) from one list of conditions, and decode() only spends it; an action the router does not run also gives null (with a test), and a V4 exact-in through two pools paid in ETH keeps reading Min. received (with a test).
Also checked, in the pinned v4-periphery source: a TAKE, TAKE_ALL or TAKE_PORTION of that token can only make the router pay more or revert, a token a path passes through nets to zero, and a hook cannot lower what an exact-in owes; the one way left is a pool that runs out of liquidity and fills an exact-in only in part, which the router allows and the calldata cannot show, so the rule cannot exclude it (nor can it for a V3 exact-in paid from the router), and the PR body now says so.
Model: opus-5-5
**Rework**
1. Fixed: any action of the step that cannot be read, an unreadable `SETTLE` or `SETTLE_ALL` among them, gives every `SETTLE` of `OPEN_DELTA` from the router in that step no amount; tests for an unreadable `SETTLE_ALL` and an unreadable `SETTLE` by the user expect `Min. paid out`.
2. Fixed: such a `SETTLE` gets no amount unless every swap action in the step names the token it spends and the one it buys, so an exact-in with an empty path counts nothing; a test for that route expects `Min. paid out`, and the README sentence on `OPEN_DELTA` now states the whole rule as the code applies it.
3. Fixed: `decodeV4Swap()` gives each `SETTLE` from the router the amount it pays (a quantity, `CONTRACT_BALANCE`, or null) from one list of conditions, and `decode()` only spends it; an action the router does not run also gives null (with a test), and a V4 exact-in through two pools paid in ETH keeps reading `Min. received` (with a test).
Also checked, in the pinned `v4-periphery` source: a `TAKE`, `TAKE_ALL` or `TAKE_PORTION` of that token can only make the router pay more or revert, a token a path passes through nets to zero, and a hook cannot lower what an exact-in owes; the one way left is a pool that runs out of liquidity and fills an exact-in only in part, which the router allows and the calldata cannot show, so the rule cannot exclude it (nor can it for a V3 exact-in paid from the router), and the PR body now says so.
Model: opus-5-5
tests/uniswapRecipient.test.js, "any token left in the router is not received": four checks in decode() (src/shared/uniswap.js) limit how the amount a WRAP_ETH states is followed, and none has a test. Each one keeps a route that leaves the user's WETH in the router from reading Min. received. Only a V2 exact-in, a V3 exact-in or a V4 SETTLE paid from the router (payerIsUser false) counts against that amount, and the amount is followed only when the router held no WETH before the WRAP_ETH. Acceptable: tests expecting Min. paid out for these routes:
a WRAP_ETH of 1 ETH into the router, then a swap of 1 WETH that the user pays for, written once as a V2 exact-in, once as a V3 exact-in and once as a V4 step with a SETTLE of 1 WETH by the user;
a swap paying WETH to the router, then a WRAP_ETH of 1 ETH into the router, then a swap of 1 WETH from the router.
README.md, Transaction Decoding, the sentence "Such steps also spend all the WETH a WRAP_ETH paid the router once together they spend the amount the WRAP_ETH states": decode() follows that amount only when the router held no WETH before the WRAP_ETH. Take two WRAP_ETHs of 0.5 ETH into the router and then a swap of 1 WETH from it: the screen says the WETH stays, but the sentence says it is spent. Acceptable: the sentence states that condition.
Unverified: how the router pays a swap and a SETTLE from its own balance was read from the pinned router source, not run against deployed contracts.
Model: opus-5-5
**Review: FAIL (`needs-rework`)**
1. `tests/uniswapRecipient.test.js`, "any token left in the router is not received": four checks in `decode()` (`src/shared/uniswap.js`) limit how the amount a `WRAP_ETH` states is followed, and none has a test. Each one keeps a route that leaves the user's WETH in the router from reading `Min. received`. Only a V2 exact-in, a V3 exact-in or a V4 `SETTLE` paid from the router (`payerIsUser` false) counts against that amount, and the amount is followed only when the router held no WETH before the `WRAP_ETH`. Acceptable: tests expecting `Min. paid out` for these routes:
- a `WRAP_ETH` of 1 ETH into the router, then a swap of 1 WETH that the user pays for, written once as a V2 exact-in, once as a V3 exact-in and once as a V4 step with a `SETTLE` of 1 WETH by the user;
- a swap paying WETH to the router, then a `WRAP_ETH` of 1 ETH into the router, then a swap of 1 WETH from the router.
2. `README.md`, Transaction Decoding, the sentence "Such steps also spend all the WETH a `WRAP_ETH` paid the router once together they spend the amount the `WRAP_ETH` states": `decode()` follows that amount only when the router held no WETH before the `WRAP_ETH`. Take two `WRAP_ETH`s of 0.5 ETH into the router and then a swap of 1 WETH from it: the screen says the WETH stays, but the sentence says it is spent. Acceptable: the sentence states that condition.
Unverified: how the router pays a swap and a `SETTLE` from its own balance was read from the pinned router source, not run against deployed contracts.
Model: opus-5-5
The decoder checked only the swap's output for being left in the router.
It now records every token a step pays the router, the WETH of a
WRAP_ETH and the rest of a V4 SETTLE taken to the router among them, and
any token still there after the last step gets a Paid to line naming it,
so the minimum reads Min. paid out. Steps that spend all the router holds
of a token count as spending it, and so do swap steps from the router
that together spend what a WRAP_ETH stated, when the router held no WETH
before it. A SETTLE of OPEN_DELTA from the router counts only in the
plain shape of Uniswap's own routes.
Model: opus-5-5
Added four rows to "any token left in the router is not received", each expecting Min. paid out: a WRAP_ETH of 1 ETH into the router, then a swap of 1 WETH the user pays for, written as a V2 exact-in, a V3 exact-in and a V4 step with a SETTLE of 1 WETH by the user; and a swap paying WETH to the router, a WRAP_ETH of 1 ETH into it, then a V3 swap of 1 WETH from it. Each fails when the check it covers is removed; src/shared/uniswap.js is unchanged.
The README sentence now names the steps that count against the amount a WRAP_ETH states and says that amount is followed only when it is not CONTRACT_BALANCE and the router held no WETH from an earlier step when the WRAP_ETH ran, with the two-WRAP_ETH example.
Model: opus-5-5
**Rework**
1. Added four rows to "any token left in the router is not received", each expecting `Min. paid out`: a `WRAP_ETH` of 1 ETH into the router, then a swap of 1 WETH the user pays for, written as a V2 exact-in, a V3 exact-in and a V4 step with a `SETTLE` of 1 WETH by the user; and a swap paying WETH to the router, a `WRAP_ETH` of 1 ETH into it, then a V3 swap of 1 WETH from it. Each fails when the check it covers is removed; `src/shared/uniswap.js` is unchanged.
2. The README sentence now names the steps that count against the amount a `WRAP_ETH` states and says that amount is followed only when it is not `CONTRACT_BALANCE` and the router held no WETH from an earlier step when the `WRAP_ETH` ran, with the two-`WRAP_ETH` example.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #606.
The swap decoder checked only the swap's output for being left in the router; it now checks every token a step pays the router, the WETH of a
WRAP_ETHincluded. Each such token still there after the last step gets aPaid toline,The router, where it stays (no later step pays it out), and aToken moved into the routerline naming it, so the minimum readsMin. paid out.Not visible in the diff:
SETTLEpaid from the router withCONTRACT_BALANCE, aWRAP_ETHofCONTRACT_BALANCE, and anUNWRAP_WETHinto the router.WRAP_ETHkeeps its stated amount and those steps count against it. No other amount is followed.Judgement call: an existing test whose second swap is paid by the user, leaving the first swap's USDC in the router, now expects
Min. paid out.Not covered: a pool that runs out of liquidity fills an exact-in swap paid from the router only in part, leaving the rest there; the calldata cannot show that.
Unverified: router behaviour was read from its source at pinned commits, not run against deployed contracts.
Model: opus-5-5
Review: FAIL (
needs-rework)src/shared/uniswap.js,decode(), the loop overv4.settledFromRouterin theV4_SWAPbranch, and the README sentence onOPEN_DELTA: aSETTLEofOPEN_DELTApaid from the router counts as paying the step's whole stated amount against the WETH aWRAP_ETHput in the router, whatever else is in the step. The router pays only what the step still owes for that token when theSETTLEruns. So after aWRAP_ETHof 1 ETH into the router, each of these routes leaves part of the user's WETH in the router and still readsMin. received:SETTLEs ofOPEN_DELTAfrom the router (the second pays nothing);SETTLEof 0.25 WETH and one ofOPEN_DELTA, both from the router, for a swap of 0.75 WETH;SETTLEofOPEN_DELTAfrom the router placed before the swap action, with the user settling the swap afterwards.Acceptable: such a
SETTLEcounts the step's amount only when it is the step's onlySETTLEorSETTLE_ALLof that token, comes after every swap action in the step, and no swap action in the step buys that token; otherwise it counts nothing. Add tests for these routes expectingMin. paid out, and make the README sentence say the same.Unverified: how the router pays a
SETTLEofOPEN_DELTAwas read from the pinnedv4-peripherysource, not run against a deployed router.Model: opus-5-5
1af7c32b02tob07f250926Rework
SETTLEofOPEN_DELTAfrom the router now counts its step's amount only when it is the step's onlySETTLEorSETTLE_ALLof that token, comes after every swap action, and no swap action buys that token; otherwise it counts nothing. Added tests for the four routes, each expectingMin. paid out, and the README sentence now says the same.Model: opus-5-5
Review: FAIL (
needs-rework)src/shared/uniswap.js,decodeV4Swap(): aSETTLEorSETTLE_ALLwhose parameters cannot be read, such as one whose currency word has a nonzero top byte (the router reads the currency from the word's last 20 bytes), is dropped without a trace, so it is not counted among the step'sSETTLEs of that token. After aWRAP_ETHof 1 ETH into the router, a V4 step that swaps 1 WETH, has the user pay for it with such an unreadableSETTLE_ALL(orSETTLE) of WETH, and then has aSETTLEofOPEN_DELTAof WETH from the router readsMin. received. The router'sSETTLEthen pays nothing, the 1 ETH stays in the router, and the user also pays 1 WETH the screen never shows. Acceptable: aSETTLEorSETTLE_ALLthat cannot be read makes everySETTLEofOPEN_DELTAfrom the router in its step count nothing, with a test for this route expectingMin. paid out.Same rule: it takes what the step's swap actions state they spend as what the
SETTLEpays, but aSWAP_EXACT_INwith an empty path states anamountInand swaps nothing (the router runs no pool for it). After aWRAP_ETHof 1 ETH into the router, a V4 step with an empty-path exact-in of 1 WETH less 1,000 wei, a swap of 1,000 wei of WETH for USDC, and aSETTLEofOPEN_DELTAfrom the router readsMin. received, while all but 1,000 wei of the WETH stays in the router. Acceptable: such aSETTLEcounts nothing when any swap action in the step names no token it buys, with a test for this route, and the README sentence onOPEN_DELTAsaying the same as findings 1 and 2.Comprehensibility: what a
SETTLEofOPEN_DELTAfrom the router pays is decided in two places.decodeV4Swap()sets its amount to null when it cannot be followed and leaves it at zero otherwise, and theV4_SWAPbranch ofdecode()then turns the zero left over into the step'samountInor null, so a reader of either half has to know the other. Acceptable:decodeV4Swap()gives eachSETTLEfrom the router the amount it pays (a quantity,CONTRACT_BALANCE, or null) in one place, anddecode()only spends it.Unverified: how the router reads a currency word with a nonzero top byte, and that it runs no swap for an empty path, was read from the pinned
v4-peripherysource, not run against a deployed router.Model: opus-5-5
b07f250926to56014a264bRework
SETTLEorSETTLE_ALLamong them, gives everySETTLEofOPEN_DELTAfrom the router in that step no amount; tests for an unreadableSETTLE_ALLand an unreadableSETTLEby the user expectMin. paid out.SETTLEgets no amount unless every swap action in the step names the token it spends and the one it buys, so an exact-in with an empty path counts nothing; a test for that route expectsMin. paid out, and the README sentence onOPEN_DELTAnow states the whole rule as the code applies it.decodeV4Swap()gives eachSETTLEfrom the router the amount it pays (a quantity,CONTRACT_BALANCE, or null) from one list of conditions, anddecode()only spends it; an action the router does not run also gives null (with a test), and a V4 exact-in through two pools paid in ETH keeps readingMin. received(with a test).Also checked, in the pinned
v4-peripherysource: aTAKE,TAKE_ALLorTAKE_PORTIONof that token can only make the router pay more or revert, a token a path passes through nets to zero, and a hook cannot lower what an exact-in owes; the one way left is a pool that runs out of liquidity and fills an exact-in only in part, which the router allows and the calldata cannot show, so the rule cannot exclude it (nor can it for a V3 exact-in paid from the router), and the PR body now says so.Model: opus-5-5
Review: FAIL (
needs-rework)tests/uniswapRecipient.test.js, "any token left in the router is not received": four checks indecode()(src/shared/uniswap.js) limit how the amount aWRAP_ETHstates is followed, and none has a test. Each one keeps a route that leaves the user's WETH in the router from readingMin. received. Only a V2 exact-in, a V3 exact-in or a V4SETTLEpaid from the router (payerIsUserfalse) counts against that amount, and the amount is followed only when the router held no WETH before theWRAP_ETH. Acceptable: tests expectingMin. paid outfor these routes:WRAP_ETHof 1 ETH into the router, then a swap of 1 WETH that the user pays for, written once as a V2 exact-in, once as a V3 exact-in and once as a V4 step with aSETTLEof 1 WETH by the user;WRAP_ETHof 1 ETH into the router, then a swap of 1 WETH from the router.README.md, Transaction Decoding, the sentence "Such steps also spend all the WETH aWRAP_ETHpaid the router once together they spend the amount theWRAP_ETHstates":decode()follows that amount only when the router held no WETH before theWRAP_ETH. Take twoWRAP_ETHs of 0.5 ETH into the router and then a swap of 1 WETH from it: the screen says the WETH stays, but the sentence says it is spent. Acceptable: the sentence states that condition.Unverified: how the router pays a swap and a
SETTLEfrom its own balance was read from the pinned router source, not run against deployed contracts.Model: opus-5-5
56014a264btobde428e98cRework
Min. paid out: aWRAP_ETHof 1 ETH into the router, then a swap of 1 WETH the user pays for, written as a V2 exact-in, a V3 exact-in and a V4 step with aSETTLEof 1 WETH by the user; and a swap paying WETH to the router, aWRAP_ETHof 1 ETH into it, then a V3 swap of 1 WETH from it. Each fails when the check it covers is removed;src/shared/uniswap.jsis unchanged.WRAP_ETHstates and says that amount is followed only when it is notCONTRACT_BALANCEand the router held no WETH from an earlier step when theWRAP_ETHran, with the two-WRAP_ETHexample.Model: opus-5-5
Review: PASS
Model: opus-5-5