> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Build with Uniswap v4 Hooks

> Build, test, and deploy custom Uniswap v4 pool behavior on Monad with Foundry.

[Uniswap v4 hooks](https://developers.uniswap.org/docs/protocols/v4/concepts/hooks) let you add custom logic to liquidity pools. In this guide, you will build and deploy a `Counter` hook on Monad Testnet, create a pool with two mock tokens, and run swaps that trigger its callbacks.

## What are hooks?

Uniswap v4 stores pools in a shared contract called the `PoolManager`. A hook is a separate smart contract that the manager calls at selected points in a pool's lifecycle:

| Operation                     | Callbacks                                       |
| ----------------------------- | ----------------------------------------------- |
| Initialize a pool             | `beforeInitialize`, `afterInitialize`           |
| Add liquidity                 | `beforeAddLiquidity`, `afterAddLiquidity`       |
| Remove liquidity              | `beforeRemoveLiquidity`, `afterRemoveLiquidity` |
| Swap                          | `beforeSwap`, `afterSwap`                       |
| Donate to liquidity providers | `beforeDonate`, `afterDonate`                   |

You choose the hook when initializing a pool. Its address is part of the `PoolKey`, alongside the two currencies, fee, and tick spacing. Changing the hook address creates a different pool identity; it does not update an existing pool. One hook can serve multiple pools, so pool-specific state should be keyed by `PoolId`.

Hooks execute synchronously within the transaction. They do not run on a timer: scheduled strategies also need transactions from users or automation. See Uniswap's [hooks overview](https://developers.uniswap.org/docs/protocols/v4/concepts/hooks) and [core contracts](https://github.com/Uniswap/v4-core).

## Common use cases

| Use case                             | Example behavior                                                                                                                    |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| Launch controls                      | Reject swaps before a launch time or restrict who can add initial liquidity.                                                        |
| Dynamic fees                         | Adjust swap fees based on pool activity or market conditions.                                                                       |
| Limit orders and scheduled execution | Execute an order when a swap reaches a target price. Time-based strategies still need an external transaction to trigger execution. |
| LP incentives and analytics          | Track liquidity changes and swaps to calculate rewards or collect pool statistics.                                                  |

## Testnet walkthrough

The [example project](https://github.com/monad-developers/uniswap-v4-hooks-example) contains the hook, Foundry scripts, and tests. It uses contracts already deployed on Monad Testnet (chain ID `10143`):

| Contract                   | Purpose                                                                    |
| -------------------------- | -------------------------------------------------------------------------- |
| `PoolManager`              | Stores pool state and calls the hook.                                      |
| `PositionManager`          | Adds and removes liquidity; issues a position NFT to your account.         |
| `UniversalRouter`          | Executes swaps.                                                            |
| `Permit2`                  | Handles token approvals and transfers for the router and position manager. |
| `V4Quoter` and `StateView` | Quote swaps and read pool state.                                           |

Anyone can use these testnet contracts. Their addresses are in [`shared-infrastructure.json`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/main/shared-infrastructure.json) at the root of the example project. The PoolManager and periphery addresses differ from Uniswap’s official mainnet deployments.

You deploy your own hook and two mock tokens. The mock tokens are publicly mintable and have no monetary value.

## Follow the guide

Follow the pages in order, running commands from the same `monad-hook` directory.

<CardGroup cols={2}>
  <Card title="Setup" href="/guides/uniswap-v4-hooks/setup">
    Clone the pinned example and its submodules, install Node dependencies, run local tests, and prepare a testnet account.
  </Card>

  <Card title="Deploy" href="/guides/uniswap-v4-hooks/deploy">
    Deploy the Counter hook and two mock tokens.
  </Card>

  <Card title="Pool lifecycle" href="/guides/uniswap-v4-hooks/pool-lifecycle">
    Initialize a pool, mint an owned PositionManager NFT, swap through Universal Router, remove liquidity, and revoke approvals.
  </Card>

  <Card title="Customize and publish" href="/guides/uniswap-v4-hooks/customize-and-publish">
    Change the hook’s behavior and prepare it for mainnet.
  </Card>
</CardGroup>
