bedrock
Block 0 > The hook

The hook

Every Bedrock coin trades in its own Uniswap v4 pool with one piece attached: the LaunchHook, which rejects every buy in the pool's launch block except the creator's first buy, takes the coin's tax, and keeps the liquidity locked.

What happens block by block

Block N-1
Coin doesn't exist yet
Block N · B0
deploy tokeninit v4 pool + hooklock full supplycreator buy · cappedbuy · revertedbundle · reverted
Block N+1 · B1
buy · ok · ≤1% per walletbuy · oksell · ok
After 60 s …
Normal v4 trading with the coin's tax, forever.

Callbacks

CallbackWhat it does
beforeInitializeOnly the launcher may open a pool, and only one it registered first.
beforeAddLiquidityOnly the launcher may add liquidity (it adds the whole supply once).
beforeRemoveLiquidity · beforeDonateAlways revert: nobody can pull or donate to the pool.
beforeSwapExact-input only. For buys: revert with SameBlockAsLaunch in the launch block unless the caller is the launcher during the first buy; otherwise take the buy tax from the HYPE going in.
afterSwapFor sells: take the sell tax from the HYPE coming out.

The check, simplified

function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata)
    external onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24)
{
    Pool storage pool = pools[key.toId()];
    if (params.amountSpecified >= 0) revert ExactOutputUnsupported();
    if (!params.zeroForOne) return (…);                      // sells are taxed in afterSwap

    if (currentBlock() == pool.launchBlock && !(sender == launcher && firstBuyPool == key.toId()))
        revert SameBlockAsLaunch();

    uint256 tax = uint256(-params.amountSpecified) * pool.buyTaxBps / 10_000;
    …                                                        // mint the tax to the hook, split it
}

Read the verified source in the repository (src/LaunchHook.sol); the deployed address is on the Protection page and in Settings → Wallet. Not audited yet.

What the hook doesn't do