A V3 path with bytes after its last hop names a token the router does not pay #637

Closed
opened 2026-10-20 09:06:01 +02:00 by clawbot · 1 comment
Collaborator

Seen by the review of #636.

Where

The swap decoder, decodeV3Path() and decodeV3SwapExactIn() in src/shared/uniswap.js. A V3 path is a token, then whole hops of a 3-byte fee and a 20-byte token; the router reads only whole hops and ignores any bytes after the last one.

What happens

A V3_SWAP_EXACT_IN whose path has bytes after its last whole hop (for example WETH, a fee, USDC and 19 more bytes) is shown with Token Out taken from the path's last 20 bytes: an address formed from USDC's last byte and those 19 bytes, which can be made to be a bundled token. The router pays out USDC. The screen names a token the swap does not pay.

What should happen

The decoder reads a path as the router reads it, or, for a path whose length is not 20 bytes plus a whole number of 23-byte hops, treats the step as unread, as it already treats a path shorter than one token.

Severity: major

Definition of done

  • A V3 path with bytes after its last whole hop never names a token the router does not read.
  • A test with such a path on a V3_SWAP_EXACT_IN, failing on next.

Model: opus-5-5

Seen by the review of https://git.eeqj.de/sneak/AutistMask/pulls/636. ## Where The swap decoder, `decodeV3Path()` and `decodeV3SwapExactIn()` in `src/shared/uniswap.js`. A V3 path is a token, then whole hops of a 3-byte fee and a 20-byte token; the router reads only whole hops and ignores any bytes after the last one. ## What happens A `V3_SWAP_EXACT_IN` whose path has bytes after its last whole hop (for example WETH, a fee, USDC and 19 more bytes) is shown with `Token Out` taken from the path's last 20 bytes: an address formed from USDC's last byte and those 19 bytes, which can be made to be a bundled token. The router pays out USDC. The screen names a token the swap does not pay. ## What should happen The decoder reads a path as the router reads it, or, for a path whose length is not 20 bytes plus a whole number of 23-byte hops, treats the step as unread, as it already treats a path shorter than one token. Severity: major ## Definition of done - [ ] A V3 path with bytes after its last whole hop never names a token the router does not read. - [ ] A test with such a path on a `V3_SWAP_EXACT_IN`, failing on `next`. Model: opus-5-5
clawbot self-assigned this 2026-10-20 09:06:01 +02:00
Author
Collaborator

Plan: folded into #636, whose review found the same misread in its exact-out reader. decodeV3Path() treats a path whose length is not 20 bytes plus a whole number of 23-byte hops as unread, so both V3 swap readers leave such a step unread, as a path shorter than one token already is. That PR closes this issue too.

Model: opus-5-5

Plan: folded into https://git.eeqj.de/sneak/AutistMask/pulls/636, whose review found the same misread in its exact-out reader. `decodeV3Path()` treats a path whose length is not 20 bytes plus a whole number of 23-byte hops as unread, so both V3 swap readers leave such a step unread, as a path shorter than one token already is. That PR closes this issue too. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#637