Hooked pools
The PoolManager underneath: Uniswap v4's hook model on Solana.
Every Reprise coin is a pool on Reprise's PoolManager, a Solana program with Uniswap v4's hook model. The launchpad itself is one hook. Developers can write their own hooks for other kinds of pools.
Pools and hooks
A pool is a concentrated-liquidity pool keyed by its two tokens, its fee, its tick spacing and its hook: any program whose address carries the permissions it needs. There are 14 permission bits, in the low bits of the hook's program id, exactly where v4 puts them in a hook contract's address. A deployed hook can never gain or lose one.
| Permissions | Lets the hook |
|---|---|
before/afterInitialize | Run when a pool is created. |
before/afterAddLiquidity | Run when liquidity is added, and refuse it. |
before/afterRemoveLiquidity | Run when liquidity is removed. |
before/afterSwap | Run around every swap, and set a per-swap fee on dynamic-fee pools. |
before/afterDonate | Run when someone donates to in-range liquidity. |
beforeSwapReturnDelta | Fill part or all of a swap itself (a custom curve). |
afterSwapReturnDelta | Take or add to a swap's output. |
after…LiquidityReturnDelta | Charge or pay on deposits and withdrawals. |
The launch hook
The Reprise Launch hook has six permissions: beforeInitialize, beforeAddLiquidity, beforeSwap, afterSwap, beforeSwapReturnDelta and afterSwapReturnDelta. That is how it runs a coin:
- The curve:
beforeSwapwithbeforeSwapReturnDeltafills every trade from the curve, so the pool itself doesn't trade. - Graduation: the completing buy returns an action that adds the curve's reserves to the pool, which the PoolManager runs inside the same swap.
- The fee in SOL: after graduation the hook takes it through return deltas, before the swap when SOL is the specified side and after it otherwise.
- Guarding the launch:
beforeInitializerefuses pools not created by a launch, andbeforeAddLiquidityrefuses outside liquidity until graduation.
What's different on Solana
The rules are v4's: deltas are signed the same way, a hook can't take more than a swap's specified amount, a delta returned without its permission is ignored, dynamic-fee hooks set the LP fee and may override it for one swap, hookData reaches every callback, and an operation the hook signs itself skips its own callbacks. Two things work differently, because Solana doesn't let a program call back into one that's still running:
- A hook settles what it owes or is owed through its claims on the pool (v4's ERC-6909 balances) when the operation finishes.
- Instead of calling the PoolManager mid-callback, a hook returns actions (add liquidity, swap, donate), which the PoolManager runs as the hook right after the callback.
Each pool has its own signer for hook calls, so a hook knows the PoolManager called it, and the trader's signature never reaches a hook. Decode any hook, or mine an address for your own, on the Hooks page.