Commit Graph

4 Commits

Author SHA1 Message Date
bbfbe885cd harden: pair every swap amount with the token that supplied it (closes #359)
All checks were successful
check / check (push) Successful in 33s
e2e / e2e-chrome (push) Successful in 1m47s
e2e / e2e-firefox (push) Successful in 37s
`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
2026-08-23 18:34:03 +00:00
47bf38644d build: add ESLint to script/lint and containerize linting (closes #152)
All checks were successful
check / check (push) Successful in 39s
e2e / e2e-chrome (push) Successful in 48s
e2e / e2e-firefox (push) Successful in 24s
2026-08-17 09:10:03 +02:00
clawbot
3c2d553070 test: add V4 swap ERC20→ERC20 decoder regression test
All checks were successful
check / check (push) Successful in 37s
Adds a test that constructs a Uniswap V4 USDT→USDC swap using
SETTLE/SWAP_EXACT_IN_SINGLE/TAKE sub-actions inside a V4_SWAP command.
Without decodeV4Swap(), the output token would be unresolvable and the
swap name would not show 'USDT → USDC'. This test fails on the old code
and passes with the decodeV4Swap() fix.

Refs: #59
2026-02-28 11:22:14 -08:00
9e45c75d29 Implement personal_sign and eth_signTypedData_v4 message signing
All checks were successful
check / check (push) Successful in 4s
Replace stub error handlers with full approval flow for personal_sign,
eth_sign, eth_signTypedData_v4, and eth_signTypedData. Uses toolbar
popup only (no fallback window) and keeps sign approvals pending across
popup close/reopen cycles so the user can respond via the toolbar icon.
2026-02-27 15:27:14 +07:00