# Free eth_call sell simulation, hooked v4 pools (#777, #767, #769) — auditor2, 10 Oct 2026

Method: UniversalRouter V4_SWAP via eth_call at the trade's exit block, state override for a fresh holder (balance + Permit2/UR allowance), minOut=0 and minOut=huge (revert data gives output). Scripts: /opt/crew/work/auditor2/v4sim.py, cmp.py, census.py. Calibrated against REAL sells (same pool, block-1, same amount).

## Headline
**The fresh-address sell on the 0xcc-hook pools (h3n, h3k native, 0x..cc) pays exactly 0.0100% of what real sellers got: 11 of 11 real sells replayed, ratio 1.0000e-4 each (pool 0xf1b877 x8, 0x7a1246 x3).** The same call from a real seller's address (0x2d5f...) pays 100%. The hook calls registry 0xdf48480f27abbc7601757ccd5345911fe9a856ae `fe9fbb80(address)` (read-only; owner-curated: `b67bcfa5` set, `f2fde38b` transferOwnership). Fresh address = 0 -> 99.99% skimmed on the sell; listed = 1 -> full.
- Who trades there: 17/17 sellers are listed; 40/43 distinct traders listed (3 unlisted ones only bought, never sold in the window). 25 traced buy/sell txs: registry never written by the hook (no auto-listing on buy), so buying does not make us listed.
- A sell does NOT revert (the old "sell_ok" test passes) — it just returns dust. That is why earlier checks missed it.

## Per test
| test | result |
|---|---|
| h3n (native 0xcc) | **KILL as tradable.** 10 sampled exit blocks (+595 s): swap executes, outsider payout ~1e-4. Paper net_x 10-14x is only reachable by listed wallets. |
| h3k native 0xcc pools | same, **not sellable by an outsider**. |
| h3k WETH a80 pools (9 pools) | closed: 448 of 450 swaps in first 1500 blocks come from 2 private routers (0x7680..., 0xf4275f24); 0x7680 reverts "caller is not in whitelist" for a fresh caller. UR (public) 2 swaps. Unproven/likely blocked. |
| h100 / h100s (WETH, 0x..144 hooks) | sim builder reverts empty on ALL WETH-quote pools incl. unhooked (tool limit, not a hook finding). Evidence instead: sells go through UR (public) on 4/4 sampled pools (10-40 sells each), BUT hook beforeSwap calls registry 0x6f8e52e1...c683630d(addr): 19/19 traders listed, fresh address = 0. Gate type unknown (skim or block) -> **sellability NOT proven**. |
| d0fd (native, no hook) | unhooked: 0.1 ETH ratio 0.96, 0.25 ETH 0.90 on sizing sim, but settle fails TRANSFER_FROM_FAILED: token reverts "salg spaerret" on transfer to PoolManager for a fresh address (every block since creation); real sellers (0x99e3, 0xaf9b, bought earlier) pass. Gate = list/bought-state unknown -> **sellability NOT proven**; a fresh-address sim cannot answer it. |

## What would change the verdict
1. Whitelist question: only way to know if a buyer who goes through our own buy can sell: a real $5 buy-then-sell on a d0fd or h100 pool (Ben's decision, exact CA to follow from testmgr). For 0xcc pools the answer from chain is already no (registry is operator-curated).
2. Replay the paper P&L counting only listed-wallet-exits as impossible: re-run h3n/h3k with sell value x1e-4 for unlisted = loss ~100%.

## Verdicts
h3n: KILL (not sellable by outsiders). h3k: FIX (drop native 0xcc; WETH a80 closed router, unproven). h100/h100s/d0fd: not verified, gate evidence above.
