harden: pair every swap amount with the token that supplied it (closes #359)
`src/shared/uniswap.js` gated the token and the amount on truthiness, and gated them independently. An address is never falsy once set, but an amount of `0n` is, so a hop supplying a zero amount fixed the token permanently while leaving the amount open, and the next hop's figure was then displayed against the first hop's token, at that token's scale. Input side: a V3 `USDT -> WETH` hop with `amountIn = 0n` followed by a V2 `WETH -> USDC` hop of `0.5e18` rendered `Token In = USDT` with `Amount = 500000000000.0000 USDT`. Output side: a V3 hop followed by a V4 step with `amountOutMin = 0n` kept `Min. received = 0.5000 WETH` on screen for a final leg that guarantees nothing. Both halves are the same gate in the same file and take the same remedy, so they are one change rather than two statements of one rule. - One `present()` helper replaces every truthiness gate on a decoded value. - The input and output sides are each set as a PAIR, never field by field: an amount and the token it is counted in always come from the same hop. The input side is fixed by the first hop that states either half, the output side by the last. A half the establishing hop did not state stays null and the line says so. - A zero slippage floor reads `None (no minimum guaranteed)` rather than `0.0000`, which reads as an artifact of the four-decimal rule. - A V4 `amountIn` of zero is `ActionConstants.OPEN_DELTA` -- v4-periphery's `V4Router` substitutes the full open credit for it -- so it reads `All available (V4 open delta)`, not `0.0000`, which would have stated the exact inverse of what the step does. `amountOutMinimum` gets no such mapping and a zero there is a literal floor of zero. Tests: the two fail-first cases from the issues, two further pairing cases (a zero minimum against a named output token, and a final leg naming a token but no minimum), the open-delta amount, and the PERMIT2_PERMIT-only `execute()` that must invent no output token. Native ETH is pinned on both sides against the real mainnet fixture and the WRAP_ETH/UNWRAP_WETH paths. closes #364
This commit is contained in:
15
TODO.md
15
TODO.md
@@ -45,6 +45,21 @@ but the review is broader than any of them.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-08-23: A swap amount and the token it is counted in now always come from
|
||||
the same hop, on both sides of the approval screen
|
||||
([#359](https://git.eeqj.de/sneak/AutistMask/issues/359) and
|
||||
[#364](https://git.eeqj.de/sneak/AutistMask/issues/364), the output and input
|
||||
halves of one gate, fixed as one unit). `src/shared/uniswap.js` gated the
|
||||
token and the amount on truthiness and independently; an address is never
|
||||
falsy once set but an amount of `0n` is, so a hop supplying a zero amount
|
||||
fixed the token and left the amount open, and the next hop's figure was then
|
||||
rendered against the first hop's token at that token's scale — 0.5 WETH shown
|
||||
as `500000000000.0000 USDT`, and an earlier hop's `Min. received` shown for a
|
||||
final leg that guarantees nothing. Both sides are now set as a pair through
|
||||
explicit presence, a zero slippage floor reads `None (no minimum guaranteed)`,
|
||||
and V4's `OPEN_DELTA` (an `amountIn` of zero, which `V4Router` reads as "swap
|
||||
the whole open credit") reads `All available (V4 open delta)` instead of
|
||||
`0.0000`.
|
||||
- 2026-08-23: A swap whose input token the calldata never named is said to be
|
||||
unknown instead of being called ETH
|
||||
([#357](https://git.eeqj.de/sneak/AutistMask/issues/357)), the twin on the
|
||||
|
||||
Reference in New Issue
Block a user