Release Whale Tax (token symbol WHAL) on Sepolia as a univ4_hook launch. Token: Whale Tax (WHAL), total supply 1,000,000,000 WHAL with 18 decimals, minted once to the deployer (a separate zero-argument ERC-20, no mint, owner or admin). Hook: WhaleTaxHook, a Uniswap v4 hook on the token's native-ETH pool whose fee grows with the swap's price impact. beforeSwap stores the pre-swap sqrtPriceX96 in transient storage keyed by PoolId. afterSwap reads the post-swap sqrtPriceX96 and computes the price move m in bps, m = |P_after / P_before - 1| x 10,000 with P = sqrtPrice squared, using FullMath.mulDiv so nothing overflows, then clears the transient slot (Solidity 0.8.26, foundry.toml evm_version = "cancun", which Sepolia supports). Fee bps = 30 + floor(470 x min(m, 500) / 500): 0.3% for a swap that barely moves the price, rising linearly to 5% at a 5% move and capped there. The fee is taken from the swap's unspecified leg as a positive unspecified afterSwap delta: exact-in pays it out of the output, exact-out on top of the input, in whichever currency that is. The hook settles it by minting itself ERC-6909 claims (never take() in a callback) and permissionless burnFees(currency) sends accrued claims to 0x000000000000000000000000000000000000dEaD inside the hook's unlockCallback, their only destination. Events: WhaleTax(poolId, moveBps, feeBps, currency, fee). README: the tax is per swap, so splitting a trade across swaps or blocks lowers it; that is the design, not a bug. Deploy shape, matching the live Sepolia hook launches 170 and 186 (168 passed the mainnet PoolManager and is not a model): WhaleTaxHook's only constructor argument is the Sepolia PoolManager 0xE03A1074c86CFeDd5C142C4F04F1a1536e203543; every rate, window and threshold here is a source constant; there is no owner, admin, setter, pause, upgrade or sweep, and no $owner or $token argument. Permissions are exactly beforeSwap, afterSwap, afterSwapReturnDelta (low address bits 0x00C4), all others false; the constructor calls Hooks.validateHookPermissions and the CREATE2 salt is mined for those bits. The factory initializes the pool (currency0 native ETH, currency1 WHAL, fee 3000, tickSpacing 60) and seeds one-sided WHAL liquidity, so nothing in the hook may revert that initialize or that liquidity add (launch 138 was parked when a beforeInitialize gate reverted the factory), and the first buy lands in a pool that holds no ETH. All state is keyed by PoolId; a pool on this hook whose currency0 is not native ETH gets zero deltas and no other effect. Every callback requires msg.sender == PoolManager. Tests (Foundry, a real v4-core PoolManager deployed in the test, hook at a mined address): a launch rehearsal that initializes at the manifest price, seeds one-sided WHAL liquidity like the factory and makes the first buy into the ETH-less pool; exact-in and exact-out in both directions; dust amounts; a pool whose currency0 is not ETH; direct callback calls from a non-PoolManager address revert; fuzzed sizes; and specifically: a tiny swap pays 30 bps; a 2.5% move pays 265 bps; any move of 5% or more pays 500 bps; exact-in and exact-out in both directions; two swaps in one transaction each use their own pre-swap price; burnFees; the hook's claims equal unburned fees (fuzzed). An independent adversarial review (read-only) must attack: impact maths (overflow, rounding, direction), the transient slot across several swaps in one transaction, the fee never exceeding the unspecified leg, the zero-liquidity case where the price jumps to the limit, and burnFees accounting. It reports each finding with the exact call sequence that triggers it. Website: one static page (dist/index.html) that reads the hook's views and events and the pool price through Uniswap's Sepolia StateView, with a buy/sell form that swaps through Uniswap's published Sepolia PoolSwapTest router (check it has code). It shows a fee preview for a typed swap size (simulated with eth_call, showing the price move and fee) and the fee curve.