HookForge

Docs

Deploy a hook

Why deployment is unusual

Uniswap v4 reads a hook's permissions from the low fourteen bits of its address, and the PoolManager rejects a pool whose hook address does not match the permissions the hook declares. So you cannot deploy a hook to whatever address you happen to get: you mine a CREATE2 salt until the resulting address has the right bits, then deploy with that salt through a deterministic factory.

A useful consequence is that the same hook lands on the same address on every chain, so the address book is computable rather than recorded.

Running the script

cd contracts

# Dry run: mines every salt and prints the addresses without sending anything.
forge script script/DeployHooks.s.sol --rpc-url $BASE_RPC_URL

# For real.
forge script script/DeployHooks.s.sol \
  --rpc-url $BASE_RPC_URL --broadcast --verify

The script writes contracts/deployments/<chainId>.json, which the registry generator reads. Run npm run build:registry afterwards and every manifest, the SDK and this site pick the addresses up, with status flipping from deterministic to a live deployment.

You need a funded deployer key on the target chain. Nothing in this repository ships one.

Verify and register

Verify the source on the chain's explorer as part of the deploy (--verify above), then submit the hook to Uniswap's hooklist, which takes a chain and an address and derives the rest from verified source.

Being on a list is not an endorsement

Uniswap's registry is explicit that submitting a hook does not make it allowlisted for routing, and this catalogue is explicit that its contracts are unaudited. Both statements are worth repeating to anyone who reads a listing as a safety claim.