# Potential authorization replay in `fakfun-wallet-v18` ## Summary The passkey authorization hash built by `authorize-smart` does not bind the `token` principal or `token-name` arguments used by `smart-sell-sbtc` and `smart-sell-stx`. A valid signature for one token can therefore be reused once with a different token argument, subject to the same `op`, router, amount, minimum output, ratio, and flag. The wallet's `with-ft` allowance then authorizes movement of the attacker-selected token. This is reported as a potential replay until confirmed with a live Clarinet or chain execution; the source-level binding gap is concrete, but this report does not claim a confirmed fund-loss exploit. ## Evidence `contracts/fakfun-wallet-v18.clar`: - `authorize-smart` constructs `build-smart-execute-hash` with only `op`, `smart`, `amount`, `min-out`, `fak-ratio`, and `flag` (around line 1248). - `smart-sell-sbtc` accepts `(token )` and `token-name`, creates a `with-ft` allowance for `(contract-of token)` and `token-name`, then calls `authorize-smart` without including either token value in the signed hash (around lines 1333–1360). - `smart-sell-stx` has the same omission (around lines 1362–1389). The subsequent `with-ft (contract-of token) token-name amount` uses the caller-supplied asset, so the asset selected for the allowance is not part of the signed authorization preimage. ## Reproduction sketch 1. Obtain a valid passkey signature for `smart-sell-sbtc` with router `R`, amount `A`, `min-out` `M`, ratio `Q`, and flag `F`, while the caller intends to sell token `T1`. 2. Before the signature is consumed, submit `smart-sell-sbtc` with the same `R/A/M/Q/F/auth-id/signature` but pass a different approved token `T2` and its token name. 3. The signed message hash is identical because `T1`/`T2` are not encoded in it. The call reaches `with-ft` for `T2`, so the router receives the selected token rather than the token the user signed. ## Impact If a wallet holds multiple approved SIP-010 assets and a router can cause or front-run a signed sell invocation, the signature's authorization boundary is ambiguous: it does not prove which asset is being spent. This can redirect a user-approved sale to another wallet-held token. Severity depends on the router's ability to influence the token argument, but the missing binding is independently verifiable from the contract source. ## Suggested fix Include `(contract-of token)` and `token-name` in the message hash for both sell entry points, and add regression tests proving that a signature generated for T1 is rejected when replayed with T2.