> ## 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.

# Customize and publish a hook

> On this page, you will customize Counter, find contract addresses, and prepare your hook for mainnet.

## Customize the hook

Open [`src/Counter.sol`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/c3cc78a88f10e5ba141cd6fb632f31db83c0daf8/src/Counter.sol). It inherits OpenZeppelin's `BaseHook`:

```solidity theme={null}
import {BaseHook} from "@openzeppelin/uniswap-hooks/src/base/BaseHook.sol";
```

`BaseHook` restricts external callbacks to the configured `PoolManager` and validates the hook address against `getHookPermissions()` during construction. The counter enables four callbacks: `beforeSwap`, `afterSwap`, `beforeAddLiquidity`, and `beforeRemoveLiquidity`.

For example, its swap callback increments a counter for the current pool:

```solidity theme={null}
function _beforeSwap(address, PoolKey calldata key, SwapParams calldata, bytes calldata)
    internal
    override
    returns (bytes4, BeforeSwapDelta, uint24)
{
    beforeSwapCount[key.toId()]++;
    return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0);
}
```

The return values acknowledge the callback, leave swap accounting unchanged, and request no fee override. If you enable or disable a callback, update both `getHookPermissions()` and the address flags in [`DeployHook.s.sol`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/c3cc78a88f10e5ba141cd6fb632f31db83c0daf8/script/monad/DeployHook.s.sol); changing the code or constructor arguments requires a new CREATE2 calculation.

For a custom hook, also test unauthorized callback calls, state isolation across pools, both swap directions, exact-input and exact-output swaps, and failure paths. A callback's `sender` is the caller of the manager, often Universal Router or PositionManager; do not assume it identifies the end user or trust arbitrary `hookData` as authentication.

## Monad Testnet contract addresses

The tutorial uses the following deployments on chain ID `10143`. The same addresses are listed in [`shared-infrastructure.json`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/c3cc78a88f10e5ba141cd6fb632f31db83c0daf8/shared-infrastructure.json), at the root of the example repository.

| Contract               | Monad Testnet address                        |
| ---------------------- | -------------------------------------------- |
| PoolManager            | `0x451D64ab3b650040d2aE1886602b97ed6eDc643d` |
| PositionManager        | `0x3Bb14E3D0Cd50aBe3EdACa06d06c29C78676C31A` |
| PositionDescriptor     | `0x1548b69E74BdD834c2e552a5c673acf921Aa7B11` |
| StateView              | `0xB639209539c61BaF67AC04876315786F8D0b153c` |
| V4Quoter               | `0x869834d127b230283fe63E0d0A9bEB67216a94C7` |
| Universal Router 2.1.1 | `0x1b7bFCd2870329B987191910D85c22C7287f3c22` |
| Permit2                | `0x000000000022D473030F116dDEE9F6B43aC78BA3` |
| WMON                   | `0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541` |
| UnsupportedProtocol    | `0xF5fa008BdB979427545c40fecE80d8cdEE4177C2` |

The PoolManager has no owner or protocol-fee controller. The PoolManager and periphery addresses differ from Uniswap’s mainnet deployments. Permit2 uses the same address on both networks.

## Deploying on Monad Mainnet

Monad Mainnet uses chain ID `143` and RPC `https://rpc.monad.xyz`. Use its PoolManager, `0x188d586ddcf52439676ca21a244753fa19f9ea8e`, from Uniswap’s [deployment list](https://developers.uniswap.org/docs/protocols/v4/deployments#monad-143).

The example’s [`DeployHook.s.sol`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/c3cc78a88f10e5ba141cd6fb632f31db83c0daf8/script/monad/DeployHook.s.sol) deliberately accepts only chain ID `10143`. To adapt it for mainnet, change that check to `143` and supply the mainnet PoolManager through `POOL_MANAGER`. The script passes this address to the hook’s constructor and to [`NamespacedHookMiner.find`](https://github.com/monad-developers/uniswap-v4-hooks-example/blob/c3cc78a88f10e5ba141cd6fb632f31db83c0daf8/src/NamespacedHookMiner.sol), which searches for a salt with the required permission bits.

The CREATE2 factory address is the same on both networks. The hook address also depends on the salt and initialization code, including constructor arguments. Because the PoolManager address changes, calculate the hook address again for mainnet. Test your custom hook and its pool interactions before deploying it with real liquidity.

### Existing Monad hooks

The [Uniswap hook registry includes Monad](https://github.com/Uniswap/hooklist/tree/main/hooks/monad). Registry inclusion is not a security audit or a prerequisite for deploying a hook. The registry's Doppler entry for [`UniswapV4ScheduledMulticurveInitializerHook`](https://github.com/Uniswap/hooklist/blob/main/hooks/monad/0x580ca49389d83b019d07E17e99454f2F218e2dc0.json) restricts initialization and liquidity additions to an authorized initializer and blocks swaps until its configured start time. Its source is an example of launch controls implemented with hooks.

## Publish and extend your hook

Publish and verify source code, document enabled permissions and administrator powers, and test the full pool lifecycle before using a custom hook with real liquidity. A hook revert can prevent the associated pool operation from completing.

To make a deployed mainnet hook discoverable, follow the [hook registry contribution instructions](https://github.com/Uniswap/hooklist#submit-a-hook) for `hooks/monad`. Registry metadata does not automatically make a pool available in every router or interface; check each integration's support for your hook's behavior.

For further examples, explore [OpenZeppelin Uniswap Hooks](https://github.com/OpenZeppelin/uniswap-hooks), [Uniswap's hook guides](https://developers.uniswap.org/docs/protocols/v4/guides/hooks/getting-started), and the [Monad hook registry](https://github.com/Uniswap/hooklist/tree/main/hooks/monad).
