A Uniswap v4 hook that ranks every pool on-chain by smoothed volume and reinvests LP fees on every swap — for free, in the same range, with no keepers required.
The hook fires inside afterSwap for any pool that installs it. No keeper bots, no off-chain ranking, no privileged operators.
Each swap pushes |amountSpecified| into a 7-day decaying volume score. The pool is re-submitted to a 500-entry min-heap; the weakest member is evicted if a stronger one appears.
If the pool is in the top-500, the hook advances a round-robin cursor and compounds exactly one user position. Fees collected → liquidity added back into the same range, all in one EVM call.
The UNI500 transfer tax (2%, 5% hard cap) flows into the hook contract. Anyone can call compoundTaxBuffer() to convert it into protocol-owned wide-range liquidity in the canonical UNI500 pool.
Anti-whale at launch. Tax routed straight into liquidity. Limits can only be loosened, never tightened — that constraint is enforced in the contract, not by promise.
Each LP keeps their own concentrated range — the hook is the on-chain owner of every position, but PoolManager keys each user's stake under salt = uint160(user), so fee accrual is per-user for free.
Three flags. Address mined with HookMiner so the bottom 14 bits encode the permission set v4 expects.
Bounded min-heap keyed by EMA-style smoothed volume (τ = 7d). Admission is O(log 500) per swap.
Hook is the owner; users are keyed by salt. PoolManager handles fee bookkeeping natively.
Each swap compounds exactly one eligible position (cooldown ≥ 30 min). Per-swap gas stays bounded.
Heap empty — populating post-launch.
Each square is a slot in the min-heap. The brightest are the highest-ranked.
Rankings update on every swap; positions in the top 500 auto-compound their fees.
Addresses below will populate after the Sepolia → Mainnet deploy. The repo's script/Deploy.s.sol uses CREATE2 with HookMiner so the addresses are deterministic per-chain.
|amountSpecified| isn't comparable across token pairs — production deployments should normalise to a numéraire (ETH/USDC) via TWAP. This is called out in the repo README.
setTaxBps(). Anyone can call compoundTaxBuffer() to convert accumulated tax into a wide-range protocol-owned position in the UNI500/WETH pool — making the pool more liquid over time.
script/Deploy.s.sol is chain-agnostic.
setLimits(). There's no fixed timer; the owner decides when liquidity is deep enough that the caps stop being protective and start being friction.
beforeAddLiquidity reverts unless the caller is the hook itself. This is what lets the hook reliably index per-user positions under salt = uint160(user). Use the hook's own deposit() entrypoint instead — it handles approvals, settles deltas, and registers your position.