> For the complete documentation index, see [llms.txt](https://docs.turbine.exchange/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.turbine.exchange/reference/contracts/solidity-documentation/univ4-hook/contract.turbinehook.md).

# TurbineHook

[Git Source](https://github.com/propeller-heads/turbine/blob/90514973167f1eb25cb9eb7756354fb3de34824d/src/univ4-hook/TurbineHook.sol)

**Inherits:** [BaseHook](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/BaseHook.sol/abstract.BaseHook.md)

**Title:** TurbineHook

Implements a Uniswap V4 hook that acts as an intermediary between the pool manager and the router for performing swaps and liquidity operations. It also mints an ERC20 token (representing LP shares) to track liquidity positions. The hook maintains per-pool reserves and restricts all swap and liquidity operations to the designated router.

See the readme for deployment instructions.

## State Variables

### router

Address of the Turbine Router which is allowed to perform swap and liquidity operations.

```solidity
address public immutable router
```

### MINIMUM\_LIQUIDITY

Minimum liquidity burned on first mint to prevent inflation attacks.

```solidity
uint256 public constant MINIMUM_LIQUIDITY = 10 ** 17
```

### registeredPoolIds

Array of all registered pool IDs for enumeration

```solidity
bytes32[] internal registeredPoolIds
```

### pools

Mapping from pool ID to comprehensive pool data

```solidity
mapping(bytes32 => PoolData) public pools
```

## Functions

### constructor

Initializes the TurbineHook.

Sets the router as an operator in the pool manager so that the router can later burn liquidity on behalf of the hook.

```solidity
constructor(address _router) ;
```

**Parameters**

| Name      | Type      | Description                                 |
| --------- | --------- | ------------------------------------------- |
| `_router` | `address` | The address of the Turbine Router contract. |

### routerOnly

Restricts function access to the router only.

```solidity
modifier routerOnly(address sender) ;
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `sender` | `address` | The caller address to be checked. |

### \_routerOnly

```solidity
function _routerOnly(address sender) internal view;
```

### getPoolStates

Returns pool states for multiple pools in a single call

```solidity
function getPoolStates(bytes32[] calldata poolIds) public view returns (PoolState[] memory states);
```

**Parameters**

| Name      | Type        | Description                |
| --------- | ----------- | -------------------------- |
| `poolIds` | `bytes32[]` | Array of pool IDs to query |

**Returns**

| Name     | Type          | Description                                           |
| -------- | ------------- | ----------------------------------------------------- |
| `states` | `PoolState[]` | Array of PoolStates containing reserves and liquidity |

### getReserves

Retrieves the current reserves for a registered pool.

Reverts if the pool is not registered.

```solidity
function getReserves(address currency0, address currency1, uint24 fee) public view returns (uint256, uint256);
```

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| `currency0` | `address` | The address of the first currency.  |
| `currency1` | `address` | The address of the second currency. |
| `fee`       | `uint24`  | The fee associated with the pool.   |

**Returns**

| Name     | Type      | Description                                          |
| -------- | --------- | ---------------------------------------------------- |
| `<none>` | `uint256` | reserve0 The current reserve of the first currency.  |
| `<none>` | `uint256` | reserve1 The current reserve of the second currency. |

### getLpTokenAddress

Retrieves the lpToken address of a registered pool.

Reverts if the pool is not registered.

```solidity
function getLpTokenAddress(address currency0, address currency1, uint24 fee) public view returns (address);
```

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| `currency0` | `address` | The address of the first currency.  |
| `currency1` | `address` | The address of the second currency. |
| `fee`       | `uint24`  | The fee associated with the pool.   |

**Returns**

| Name     | Type      | Description                               |
| -------- | --------- | ----------------------------------------- |
| `<none>` | `address` | The address of the LP token for the pool. |

### isRegisteredPool

Checks if a pool is registered with the TurbineHook.

```solidity
function isRegisteredPool(address currency0, address currency1, uint24 fee) public view returns (bool);
```

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| `currency0` | `address` | The address of the first currency.  |
| `currency1` | `address` | The address of the second currency. |
| `fee`       | `uint24`  | The fee associated with the pool.   |

**Returns**

| Name     | Type   | Description                                      |
| -------- | ------ | ------------------------------------------------ |
| `<none>` | `bool` | True if the pool is registered, False otherwise. |

### getNumberOfRegisteredPools

Returns the number of registered pools

```solidity
function getNumberOfRegisteredPools() public view returns (uint256);
```

**Returns**

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `<none>` | `uint256` | The number of registered pools |

### getRegisteredPoolsSlice

Returns all registered pools with their complete information

```solidity
function getRegisteredPoolsSlice(
    uint256 startIndex,
    uint256 endIndex
) public view returns (PoolInfo[] memory poolsInfo);
```

**Parameters**

| Name         | Type      | Description                                      |
| ------------ | --------- | ------------------------------------------------ |
| `startIndex` | `uint256` | The index of the first pool to return            |
| `endIndex`   | `uint256` | The index of the last pool to return (exclusive) |

**Returns**

| Name        | Type         | Description                                       |
| ----------- | ------------ | ------------------------------------------------- |
| `poolsInfo` | `PoolInfo[]` | Array of PoolInfo structs containing pool details |

### mint

Mints liquidity tokens corresponding to deposited tokens.

Can only be called by the router. Emits a [Mint](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/TurbineHook.sol/contract.TurbineHook.md#mint) event and updates pool reserves.

```solidity
function mint(
    address to,
    uint256 amount0,
    uint256 amount1,
    PoolKey calldata key,
    uint256 liquidity
) external routerOnly(msg.sender) returns (uint256);
```

**Parameters**

| Name        | Type      | Description                                                |
| ----------- | --------- | ---------------------------------------------------------- |
| `to`        | `address` | The address that will receive the minted liquidity tokens. |
| `amount0`   | `uint256` | The amount of the first currency to be deposited.          |
| `amount1`   | `uint256` | The amount of the second currency to be deposited.         |
| `key`       | `PoolKey` | The PoolKey structure containing pool details.             |
| `liquidity` | `uint256` | The amount of liquidity tokens to mint.                    |

**Returns**

| Name     | Type      | Description                                      |
| -------- | --------- | ------------------------------------------------ |
| `<none>` | `uint256` | liquidity The amount of liquidity tokens minted. |

### burn

Burns liquidity tokens, returning the underlying assets.

We expect the router to have already transferred the lpTokens from the user to the hook.

Can only be called by the router. Retrieves current balances from the hook's reserves, burns the liquidity tokens, updates reserves, and emits a [Burn](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/TurbineHook.sol/contract.TurbineHook.md#burn) event.

```solidity
function burn(
    address to,
    uint256 liquidity,
    uint256 amount0,
    uint256 amount1,
    PoolKey calldata key
) external routerOnly(msg.sender);
```

**Parameters**

| Name        | Type      | Description                                          |
| ----------- | --------- | ---------------------------------------------------- |
| `to`        | `address` | The address that will receive the underlying tokens. |
| `liquidity` | `uint256` | The amount of liquidity to burn.                     |
| `amount0`   | `uint256` | The amount of the first currency to be removed.      |
| `amount1`   | `uint256` | The amount of the second currency to be removed.     |
| `key`       | `PoolKey` | The PoolKey structure containing pool details.       |

### beforeInitialize

```solidity
function beforeInitialize(
    address,
    PoolKey calldata key,
    uint160
) external override poolManagerOnly returns (bytes4);
```

### \_registerPool

Registers a new pool with the TurbineHook.

Reverts if either currency address is zero, if the addresses are not ordered (currency0 must be less than currency1), or if the pool has already been registered. Emits a [PoolRegistered](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/TurbineHook.sol/contract.TurbineHook.md#poolregistered) event upon successful registration.

```solidity
function _registerPool(address currency0, address currency1, uint24 fee) private;
```

**Parameters**

| Name        | Type      | Description                                     |
| ----------- | --------- | ----------------------------------------------- |
| `currency0` | `address` | The address of the first currency in the pool.  |
| `currency1` | `address` | The address of the second currency in the pool. |
| `fee`       | `uint24`  | The fee associated with the pool.               |

### beforeSwap

Called by the poolManager before a swap occurs.

Performs the following steps:

* Decodes the expected output amount from hookData.
* Determines input and output currencies based on swap direction.
* Mints input tokens and burns output tokens from the poolManager.
* Updates internal reserves and emits a [Swap](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/TurbineHook.sol/contract.TurbineHook.md#swap) event.
* Calculates swap deltas via {\_calculateDeltas} and converts them using toBeforeSwapDelta.

```solidity
function beforeSwap(
    address sender,
    PoolKey calldata key,
    IPoolManager.SwapParams calldata params,
    bytes calldata hookData
) external override routerOnly(sender) poolManagerOnly returns (bytes4, BeforeSwapDelta, uint24);
```

**Parameters**

| Name       | Type                      | Description                                                                 |
| ---------- | ------------------------- | --------------------------------------------------------------------------- |
| `sender`   | `address`                 | The caller (must be the router).                                            |
| `key`      | `PoolKey`                 | The PoolKey structure with pool details.                                    |
| `params`   | `IPoolManager.SwapParams` | The swap parameters from the poolManager.                                   |
| `hookData` | `bytes`                   | Encoded data carrying additional swap parameters (e.g. expected amountOut). |

**Returns**

| Name     | Type              | Description                                                                 |
| -------- | ----------------- | --------------------------------------------------------------------------- |
| `<none>` | `bytes4`          | selector The function selector for beforeSwap (IHooks.beforeSwap.selector). |
| `<none>` | `BeforeSwapDelta` | hookDelta The BeforeSwapDelta struct that encodes the swap deltas.          |
| `<none>` | `uint24`          | feeProtocol A fee value (unused, returns 0).                                |

### getHookPermissions

Returns the hook permissions indicating which callbacks are implemented.

Only beforeSwap and beforeSwapReturnDelta are enabled in this hook.

```solidity
function getHookPermissions() public pure override returns (Hooks.Permissions memory);
```

**Returns**

| Name     | Type                | Description                                                      |
| -------- | ------------------- | ---------------------------------------------------------------- |
| `<none>` | `Hooks.Permissions` | A Hooks.Permissions struct with booleans for each callback type. |

### getPoolLpToken

```solidity
function getPoolLpToken(bytes32 poolId) public view returns (address);
```

### \_updateReserves

Updates the stored reserves for a pool based on new token balances.

Emits a [Sync](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/TurbineHook.sol/contract.TurbineHook.md#sync) event with the updated reserve values.

```solidity
function _updateReserves(PoolKey calldata key, uint256 balance0, uint256 balance1) private;
```

**Parameters**

| Name       | Type      | Description                                    |
| ---------- | --------- | ---------------------------------------------- |
| `key`      | `PoolKey` | The PoolKey structure containing pool details. |
| `balance0` | `uint256` | The new balance for the first currency.        |
| `balance1` | `uint256` | The new balance for the second currency.       |

### computePoolId

Computes a unique pool identifier based on currency addresses and fee.

Uses keccak256 to encode the parameters.

```solidity
function computePoolId(address currency0, address currency1, uint24 fee) public pure returns (bytes32);
```

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| `currency0` | `address` | The address of the first currency.  |
| `currency1` | `address` | The address of the second currency. |
| `fee`       | `uint24`  | The fee associated with the pool.   |

**Returns**

| Name     | Type      | Description                                   |
| -------- | --------- | --------------------------------------------- |
| `<none>` | `bytes32` | A bytes32 hash serving as the unique pool ID. |

## Events

### Mint

```solidity
event Mint(bytes32 indexed poolId, address indexed sender, uint256 amount0, uint256 amount1);
```

### Burn

```solidity
event Burn(bytes32 indexed poolId, address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
```

### Swap

```solidity
event Swap(bytes32 indexed poolId, uint256 amountIn, uint256 amountOut);
```

### Sync

```solidity
event Sync(bytes32 indexed poolId, uint256 reserves0, uint256 reserves1);
```

### PoolRegistered

```solidity
event PoolRegistered(bytes32 indexed poolId, address indexed currency0, address indexed currency1, uint24 fee);
```

### LPTokenDeployed

```solidity
event LPTokenDeployed(bytes32 indexed poolId, address lpToken, string name, string symbol);
```

### RouterSet

```solidity
event RouterSet(address indexed router);
```

## Errors

### RouterOnly

```solidity
error RouterOnly();
```

### PoolNotRegistered

```solidity
error PoolNotRegistered();
```

### PoolAlreadyRegistered

```solidity
error PoolAlreadyRegistered();
```

### ZeroCurrencyAddress

```solidity
error ZeroCurrencyAddress();
```

### BalanceOverflow

```solidity
error BalanceOverflow();
```

### InsufficientInitialLiquidity

Liquidity minted must be at least MINIMUM\_LIQUIDITY for initial mint

```solidity
error InsufficientInitialLiquidity();
```

## Structs

### PoolState

Structure to hold pool state information.

```solidity
struct PoolState {
    uint256 reserve0;
    uint256 reserve1;
    uint256 liquidity;
}
```

### PoolData

Structure to hold pool information in storage

```solidity
struct PoolData {
    address token0;
    address token1;
    uint24 fee;
    address lpToken;
    uint256 reserve0;
    uint256 reserve1;
}
```

### PoolInfo

Comprehensive structure to hold all pool data for returning from view functions

```solidity
struct PoolInfo {
    bytes32 poolId;
    address token0;
    address token1;
    uint24 fee;
    address lpToken;
    uint256 reserve0;
    uint256 reserve1;
    uint256 liquidity;
}
```


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.turbine.exchange/reference/contracts/solidity-documentation/univ4-hook/contract.turbinehook.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
