> For the complete documentation index, see [llms.txt](https://metapool.bloklab.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://metapool.bloklab.fi/basics/how-to-implement-a-hook.md).

# How to Implement a Hook

Hooks can be plugged into the Uniswap V4 ecosystem by extending the standard **Hooks.Permissions** and **BaseHook** contracts. The developer specifies the conditions for the custom hook at key moments like **beforeSwap**, **afterSwap**, or **afterAddLiquidity (and all other base hooks)**.

````solidity
```solidity
 function afterSwap(
        address,
        PoolKey calldata key,
        IPoolManager.SwapParams calldata params,
        BalanceDelta delta,
        bytes calldata hookData
    )
        external
        override
        onlyPoolManager
        onlyRegisteredPools(key)
        returns (bytes4, int128)
    {
        (address user, int24 tickLower, int24 tickUpper) = abi.decode(
            hookData,
            (address, int24, int24)
        );

        PoolId poolId = key.toId();
        ICustomPoolHook customHook = customPoolHooks[poolId];

        /* ------------------------------- Hooks ! the CUSTOM HOOKS -------------------------------- */

        if (address(customHook) != address(0)) {
            require(
                address(customHook).supportsInterface(
                    type(ICustomPoolHook).interfaceId
                ),
                "Custom hook does not implement ICustomPoolHook"
            );

            ICustomPoolHook.CustomHookResult memory result = customHook
                .afterSwap(user, key, params, delta, hookData);

            ICustomPoolHook.CustomHookResult memory result2 = customHook
                .whenTickRangeIsBetween(
                    user,
                    key,
                    -60,
                    60,
                    params,
                    delta,
                    hookData
                );

            ICustomPoolHook.CustomHookResult memory result3 = customHook
                .whenTheWeatherIsRainy(user, key, params, delta, hookData);

            bytes[] memory results = new bytes[](3);
            results[0] = result.extraData;
            results[1] = result2.extraData;
            results[3] = result3.extraData;
            ICustomPoolHook.CustomHookResult memory __result4 = customHook
                .whenHooksChained(user, key, params, delta, hookData, "genesis", results);
            // customResult can be used for further processing...
        }

        /* ------------------------------- Hooks ! the CUSTOM HOOKS -------------------------------- */
```
````
