> For the complete documentation index, see [llms.txt](https://docs.kyte.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kyte.sh/protocol/uniswap-v4/kytehook.md).

# KyteHook deep dive

Inside the Uniswap v4 hook on the $KYTE/WETH pool.

KyteHook is a Uniswap v4 hook attached to the `$KYTE`/WETH pool. Think of it as a toll booth and a price camera built into the pool. It does two jobs on every swap.

## Callbacks and the mined address

| Callback                                                         | Used | What it does                                                                                     |
| ---------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------ |
| `afterInitialize`                                                | Yes  | Writes the first price observation when the pool is created                                      |
| `afterSwap`                                                      | Yes  | Records the new tick and takes the fee                                                           |
| `afterSwapReturnDelta`                                           | Yes  | Permission that lets `afterSwap` return a delta: the fee, charged on the swap's unspecified side |
| All others (`beforeInitialize`, `beforeSwap`, liquidity, donate) | No   | `revert NotImplemented()`                                                                        |

In Uniswap v4, a hook's permissions are the low 14 bits of its address. KyteHook needs `afterInitialize (1<<12) | afterSwap (1<<6) | afterSwapReturnDelta (1<<2) = 0x1044`, so the address must satisfy `address & 0x3FFF == 0x1044`. `contracts/script/HookDeployer.sol` is a small CREATE2 factory: `mine(initCodeHash, maxTries)` tries salts until the predicted address has those bits (about 16,000 tries on average; the script allows 400,000), and `deploy(salt, initCode)` deploys it. The constructor runs `Hooks.validateHookPermissions`, so a wrong address reverts.

Constructor arguments: `poolManager`, `owner` (the timelock), `feeVault`, `feeBps` (10), `feeCurrencyOnly` (WETH).

## Job 1: protocol fee

After every swap:

1. The hook looks at the swap's **unspecified currency**: the side the trader did not give an exact amount for.
2. If that currency is WETH (`feeCurrencyOnly`), it takes `amount × feeBps / 10,000`.
3. `poolManager.take(WETH, feeVault, fee)` sends it straight to the FeeVault, and `HookFee(id, currency, amount)` is emitted.
4. `afterSwap` returns the fee as its delta, so the PoolManager's accounting stays balanced.

**Which swaps pay:** the fee is charged only when WETH is the unspecified side.

| Swap                                  | Trader fixes | Unspecified side | Hook fee                                        |
| ------------------------------------- | ------------ | ---------------- | ----------------------------------------------- |
| Sell `$KYTE` for WETH, exact input    | `$KYTE` in   | WETH out         | **Yes**, 0.1% of the WETH out, deducted from it |
| Buy an exact amount of `$KYTE`        | `$KYTE` out  | WETH in          | **Yes**, 0.1% of the WETH in, added to it       |
| Buy `$KYTE` with an exact WETH input  | WETH in      | `$KYTE` out      | No                                              |
| Sell `$KYTE` for an exact WETH output | WETH out     | `$KYTE` in       | No                                              |

Protocol buybacks swap an exact WETH input, so they pay no hook fee. This is deliberate: the vault only ever receives WETH, which it can split.

**Example:** a trader sells 1,000 `$KYTE` and the pool pays out about 1 WETH. The hook takes 0.001 WETH for the FeeVault. At the next split that becomes 0.0003 WETH to stakers, 0.0002 to buy-and-burn, and 0.0005 to ops.

The Proof page shows `FeesSplit` and `Burned`. Hook fees are included in the FeeVault splits; individual `HookFee` events can be read from the hook contract on the explorer.

## Job 2: TWAP oracle

After every swap the hook stores `Observation { blockTimestamp, tickCumulative, tick }` in a 128-slot ring buffer per pool. Several swaps in one block keep only the last tick. `consult(poolId, secondsAgo)` returns the time-weighted mean tick over the window, clamped to the oldest observation if the history is shorter. `twapSqrtPriceX96(poolId, secondsAgo)` returns the price ready for quoting, and `observationAt(poolId, i)` exposes the raw buffer.

The UniswapV4Adapter quotes buybacks from the **10-minute** TWAP. On a hooked pool it **never falls back to spot**: if the oracle can't answer, the quote reverts. The adapter's constructor also checks that the hook it is given is the one in the pool key (`BadPool` otherwise).

## Trust properties

| Point                   | Detail                                                          |
| ----------------------- | --------------------------------------------------------------- |
| Owner                   | The timelock. It can only change `feeBps` (≤ 1%) and `feeVault` |
| Who calls the callbacks | Only the PoolManager (`onlyPoolManager`)                        |
| Funds held              | None: fees go to the vault in the same transaction              |
| Swap control            | None: the hook can't block, pause or reroute swaps              |
| Upgradability           | Not upgradeable                                                 |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.kyte.sh/protocol/uniswap-v4/kytehook.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
