Hooks
Limits
What holds in every pool on Uniswap v4 and Socket, whatever its hook does, and who pays for a hook's gas.
A hook decides a lot about its pool, inside rules it can't change. Some come from Uniswap v4's PoolManager and apply to every hook. Others come from Socket's contracts and apply to pools on Socket's hooks.
What holds whatever a hook does#
| Limit | Set by | What it means |
|---|---|---|
| The pool key is immutable | v4 | Currencies, fee setting, tick spacing and hook are fixed for the pool's life. No vote and no hook can change them. |
| Permissions are in the hook's address | v4 | A deployed hook can't gain or drop a callback. Different permissions need a different contract at a different address. |
| Deltas settle or the transaction reverts | v4 | Every operation runs inside unlock. If any currency is left unsettled at the end, PoolManager reverts with CurrencyNotSettled and nothing moves. |
| The swapper's minimum output | the router | The Universal Router checks what the swapper receives against the minimum set in the swap, after every hook has run. Less reverts the swap. |
| A hook revert is a swap revert | v4 | If any hook call reverts, the whole operation reverts. Routers quote another pool. |
| LP fees stay within 100% | v4 | A fee above 1,000,000, stored or per swap, reverts. |
| Settings are fixed at initialization | Socket | A Socket hook's settings are stored when the pool is initialized, and none can change after. |
| The dynamic fee stays under the pool's max fee | Socket | fee = min(base_fee + extra, max_fee). The max fee is set per pool, at initialization. |
| The buyback share is at most 50% | Socket | Each pool keeps the share it was initialized with. A vote sets the share only for pools initialized afterwards. |
What a vote can't do#
SOCKET holders keep the allowlist and set the buyback share for new pools. No vote can:
- change an existing pool;
- move tokens out of PoolManager or anyone's position;
- pause trading.
Gas#
PoolManager calls a hook in the middle of the operation and forwards the gas that remains. A hook's gas is paid by the transaction that triggers it: the swap pays for beforeSwap and afterSwap, and the position change pays for the liquidity callbacks.
The Quoter runs the real swap, hooks included, so its gasEstimate covers them. Set the transaction's gas limit from that estimate. A range order that fills is taken out of the pool in the crossing swap's afterSwap, so that swap pays for it.
Failure is the safe default#
A hook that reverts, returns the wrong selector or runs out of gas doesn't leave a half-done swap. Nothing is swapped and no balance changes; the swapper pays only the gas used. A router's quote fails on that pool and it can quote another.
That is also how a hook refuses something on purpose: it reverts.