> 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.turbineliquidityrouter.md).

# TurbineLiquidityRouter

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

**Inherits:** IUnlockCallback, [ITurbineLiquidityRouter](https://github.com/propeller-heads/turbine-docs/blob/master/src/univ4-hook/interfaces/ITurbineLiquidityRouter.sol/interface.ITurbineLiquidityRouter.md)

## State Variables

### PERMIT2\_CONTRACT

```solidity
IPermit2 public constant PERMIT2_CONTRACT = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3)
```

### POOL\_MANAGER

```solidity
IPoolManager public immutable POOL_MANAGER = IPoolManager(UNIV4_POOL_MANAGER)
```

### turbineSettler

```solidity
address public immutable turbineSettler
```

### MIN\_INTENT\_EXPIRY

```solidity
uint256 public constant MIN_INTENT_EXPIRY = 36 seconds
```

### SPEEDBUMP\_DURATION

```solidity
uint256 public constant SPEEDBUMP_DURATION = 12 seconds
```

### MAX\_INTENT\_EXPIRY

```solidity
uint256 public constant MAX_INTENT_EXPIRY = 3 hours
```

### \_TOKEN\_PERMISSIONS\_TYPEHASH

```solidity
bytes32 public constant _TOKEN_PERMISSIONS_TYPEHASH = keccak256("TokenPermissions(address token,uint256 amount)")
```

### \_PERMIT\_TRANSFER\_FROM\_TYPEHASH

```solidity
bytes32 public constant _PERMIT_TRANSFER_FROM_TYPEHASH = keccak256(
    "PermitTransferFrom(TokenPermissions permitted,address spender,uint256 nonce,uint256 deadline)TokenPermissions(address token,uint256 amount)"
)
```

### hook

```solidity
TurbineHook public immutable hook
```

### removeLiquidityIntents

```solidity
mapping(RemoveLiquidityIntentHash => RemoveLiquidityIntent) public removeLiquidityIntents
```

### removeLiquidityPermits

```solidity
mapping(RemoveLiquidityIntentHash => SignatureTransferParams) public removeLiquidityPermits
```

### removeLiquidityCreatedAt

```solidity
mapping(RemoveLiquidityIntentHash => uint256) public removeLiquidityCreatedAt
```

## Functions

### constructor

```solidity
constructor(address _turbineSettler, address _turbineHook) ;
```

### ensure

```solidity
modifier ensure(uint256 deadline) ;
```

### \_ensure

```solidity
function _ensure(uint256 deadline) internal view;
```

### turbineSettlerOnly

Only Turbine OrderSettler may call this function

```solidity
modifier turbineSettlerOnly() virtual;
```

### \_turbineSettlerOnly

```solidity
function _turbineSettlerOnly() internal view;
```

### poolManagerOnly

Only PoolManager may call this function

```solidity
modifier poolManagerOnly() virtual;
```

### \_poolManagerOnly

```solidity
function _poolManagerOnly() internal view;
```

### settlerOrPoolManagerOnly

Only TurbineSettler or the PoolManager may call this function

Some functions are marked as external to allow calling them via delegatecall, but they are not intended to be called externally. They can only be called by the PoolManager, or by this contract itself in the context of a call from the TurbineSettler (msg.sender is therefore TurbineSettler).

```solidity
modifier settlerOrPoolManagerOnly() ;
```

### \_settlerOrPoolManagerOnly

```solidity
function _settlerOrPoolManagerOnly() internal view;
```

### getTurbineSettler

Returns the address of the TurbineSettler

```solidity
function getTurbineSettler() external view returns (address);
```

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `address` | The address of the TurbineSettler |

### getTurbineHook

Returns the address of the TurbineHook

Return type is address to avoid unnecessary imports

```solidity
function getTurbineHook() external view returns (address);
```

**Returns**

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `<none>` | `address` | The address of the TurbineHook |

### submitRemoveLiquidityIntent

Submits a new remove-liquidity intent for later execution.

The caller must be `intent.owner`. The provided Permit2 authorization must match the LP token and cover at least `intent.lpTokenAmount`.

```solidity
function submitRemoveLiquidityIntent(
    RemoveLiquidityIntent calldata intent,
    SignatureTransferParams calldata signatureTransferParams
) external returns (RemoveLiquidityIntentHash intentHash);
```

**Parameters**

| Name                      | Type                      | Description                                                                       |
| ------------------------- | ------------------------- | --------------------------------------------------------------------------------- |
| `intent`                  | `RemoveLiquidityIntent`   | The remove-liquidity instruction containing pool and LP token amount details.     |
| `signatureTransferParams` | `SignatureTransferParams` | Permit2 SignatureTransfer parameters and signature authorizing LP token transfer. |

**Returns**

| Name         | Type                        | Description                                        |
| ------------ | --------------------------- | -------------------------------------------------- |
| `intentHash` | `RemoveLiquidityIntentHash` | The intent hash used to reference this submission. |

### executePendingIntents

Executes the provided intent hashes and deletes the executed intents.

```solidity
function executePendingIntents(RemoveLiquidityIntentHash[] calldata hashes) external;
```

**Parameters**

| Name     | Type                          | Description                        |
| -------- | ----------------------------- | ---------------------------------- |
| `hashes` | `RemoveLiquidityIntentHash[]` | Array of intent hashes to execute. |

### getRemoveLiquidityIntents

Returns remove-liquidity intent data for the given hashes. Skips deleted/unknown intents (owner == address(0)).

```solidity
function getRemoveLiquidityIntents(RemoveLiquidityIntentHash[] calldata hashes)
    external
    view
    returns (RemoveLiquidityData[] memory result);
```

**Parameters**

| Name     | Type                          | Description                      |
| -------- | ----------------------------- | -------------------------------- |
| `hashes` | `RemoveLiquidityIntentHash[]` | Array of intent hashes to query. |

**Returns**

| Name     | Type                    | Description                                          |
| -------- | ----------------------- | ---------------------------------------------------- |
| `result` | `RemoveLiquidityData[]` | Array of RemoveLiquidityData for valid intents only. |

### \_buildRemoveLiquidityData

```solidity
function _buildRemoveLiquidityData(
    RemoveLiquidityIntentHash intentHash,
    RemoveLiquidityIntent storage intent
) internal view returns (RemoveLiquidityData memory);
```

### \_executePendingIntent

```solidity
function _executePendingIntent(
    RemoveLiquidityIntentHash intentHash,
    RemoveLiquidityIntent storage intent
) internal;
```

### unlockCallback

Callback function invoked by the `poolManager` when `unlock` is called.

* Only the `poolManager` can call this function (`require(msg.sender == address(poolManager))`).
* Reverts if the delegatecall fails.

```solidity
function unlockCallback(bytes calldata encodedData) external poolManagerOnly returns (bytes memory);
```

**Parameters**

| Name          | Type    | Description                                                                                                                       |
| ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `encodedData` | `bytes` | Encoded data passed from the `poolManager`. The first parameter is the command (uint256), and the second is the raw data (bytes). |

**Returns**

| Name     | Type    | Description                                         |
| -------- | ------- | --------------------------------------------------- |
| `<none>` | `bytes` | The return data from the invoked callback function. |

### \_maybeUnlockPoolManager

Wrapper function around poolManager.unlock that checks if the manager is already unlocked (because we are taking loans from the pool manager)

If the manager is already unlocked, it will delegatecall directly. Otherwise, it will unlock and pass the calldata.

```solidity
function _maybeUnlockPoolManager(bytes memory data) internal returns (bytes memory result);
```

**Parameters**

| Name   | Type    | Description                             |
| ------ | ------- | --------------------------------------- |
| `data` | `bytes` | The data to pass to the unlock callback |

**Returns**

| Name     | Type    | Description                         |
| -------- | ------- | ----------------------------------- |
| `result` | `bytes` | The result from the unlock callback |

### swapExactTokens

Swaps an exact amount of a token for an exact amount of another token.

* This function assumes that amountIn is already transferred to this contract.
* This function transfers tokens to the `poolManager` via `poolManager.unlock(...)`.
* The `poolManager` will perform the swap and return the output amount via the callback (`unlockCallback`).

```solidity
function swapExactTokens(
    uint256 amountIn,
    uint256 amountOut,
    address poolToken0,
    address poolToken1,
    uint24 poolFee,
    bool zeroForOne,
    uint256 deadline
) external payable turbineSettlerOnly ensure(deadline);
```

**Parameters**

| Name         | Type      | Description                                                       |
| ------------ | --------- | ----------------------------------------------------------------- |
| `amountIn`   | `uint256` | The exact amount of input tokens to be sent for the swap.         |
| `amountOut`  | `uint256` | The exact amount of tokens expected to be received from the swap. |
| `poolToken0` | `address` | The address of the first token in the pool.                       |
| `poolToken1` | `address` | The address of the second token in the pool.                      |
| `poolFee`    | `uint24`  | The fee of the pool.                                              |
| `zeroForOne` | `bool`    | The direction of the swap.                                        |
| `deadline`   | `uint256` | A timestamp by which the call be finished to be valid.            |

### \_swapCallback

Callback function invoked by the `poolManager` during the swap execution.

* Only the `poolManager` (or this contract if the pool manager is already unlocked) can call this function.
* Performs a swap via `poolManager.swap(...)`, and ensures the output is exactly `amountOut`.
* Handles token transfers: input tokens are transferred from `turbineAddress` to `poolManager`, then output tokens are taken from the `poolManager` and sent to `turbineAddress`.

```solidity
function _swapCallback(
    uint256 amountIn,
    uint256 amountOut,
    PoolKey memory key,
    bool zeroForOne
) external settlerOrPoolManagerOnly returns (bytes memory);
```

**Parameters**

| Name         | Type      | Description                                               |
| ------------ | --------- | --------------------------------------------------------- |
| `amountIn`   | `uint256` | The exact amount of input tokens to be sent for the swap. |
| `amountOut`  | `uint256` | The exact amount of tokens to be received from the swap.  |
| `key`        | `PoolKey` | The pool key containing the token addresses and fee.      |
| `zeroForOne` | `bool`    | The direction of the swap.                                |

**Returns**

| Name     | Type    | Description  |
| -------- | ------- | ------------ |
| `<none>` | `bytes` | Empty bytes. |

### addLiquidity

Adds liquidity to the pair represented by the given hook.

```solidity
function addLiquidity(
    address to,
    uint256 amount0,
    uint256 amount1,
    address poolToken0,
    address poolToken1,
    uint24 poolFee,
    uint256 liquidity,
    BatchSignatureTransferParams memory batchSignatureTransferParams
) external payable turbineSettlerOnly returns (uint256);
```

**Parameters**

| Name                           | Type                           | Description                                                                     |
| ------------------------------ | ------------------------------ | ------------------------------------------------------------------------------- |
| `to`                           | `address`                      | The address receiving the minted liquidity.                                     |
| `amount0`                      | `uint256`                      | The amount of token0 to add as liquidity.                                       |
| `amount1`                      | `uint256`                      | The amount of token1 to add as liquidity.                                       |
| `poolToken0`                   | `address`                      | The address of the first token in the pool.                                     |
| `poolToken1`                   | `address`                      | The address of the second token in the pool.                                    |
| `poolFee`                      | `uint24`                       | The fee of the pool.                                                            |
| `liquidity`                    | `uint256`                      | The liquidity amount to mint for the caller.                                    |
| `batchSignatureTransferParams` | `BatchSignatureTransferParams` | The Permit2 batch SignatureTransfer permit and signature for token0 and token1. |

**Returns**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `<none>` | `uint256` | liquidity The minted liquidity amount for the caller. |

### \_addLiquidityCallback

Callback function invoked by the PoolManager when adding liquidity.

* Only the PoolManager should call this function.
* Uses a single batch permitTransferFrom to transfer both tokens to this router.
* Then settles each token individually with the PoolManager via sync -> transfer -> settle.
* Mints the corresponding amounts to the `hook` contract via `poolManager.mint(...)`.

```solidity
function _addLiquidityCallback(
    address caller,
    uint256 amount0,
    uint256 amount1,
    PoolKey memory key,
    BatchSignatureTransferParams memory batchSignatureTransferParams
) external poolManagerOnly returns (bytes memory);
```

**Parameters**

| Name                           | Type                           | Description                                                                     |
| ------------------------------ | ------------------------------ | ------------------------------------------------------------------------------- |
| `caller`                       | `address`                      | The address that initiated the liquidity addition.                              |
| `amount0`                      | `uint256`                      | The amount of token0 to add as liquidity.                                       |
| `amount1`                      | `uint256`                      | The amount of token1 to add as liquidity.                                       |
| `key`                          | `PoolKey`                      | The pool key containing the token addresses and fee.                            |
| `batchSignatureTransferParams` | `BatchSignatureTransferParams` | The Permit2 batch SignatureTransfer permit and signature for token0 and token1. |

**Returns**

| Name     | Type    | Description                                                      |
| -------- | ------- | ---------------------------------------------------------------- |
| `<none>` | `bytes` | Encoded data containing the hook reference (`abi.encode(hook)`). |

### removeLiquidity

Burns liquidity to the pair represented by the given hook.

```solidity
function removeLiquidity(
    address to,
    uint256 liquidity,
    address poolToken0,
    address poolToken1,
    uint24 poolFee,
    SignatureTransferParams memory signatureTransferParams
) external payable turbineSettlerOnly returns (uint256, uint256);
```

**Parameters**

| Name                      | Type                      | Description                                                          |
| ------------------------- | ------------------------- | -------------------------------------------------------------------- |
| `to`                      | `address`                 | The address receiving the burnt liquidity.                           |
| `liquidity`               | `uint256`                 | The burnt liquidity amount from the caller.                          |
| `poolToken0`              | `address`                 | The address of the first token in the pool.                          |
| `poolToken1`              | `address`                 | The address of the second token in the pool.                         |
| `poolFee`                 | `uint24`                  | The fee of the pool.                                                 |
| `signatureTransferParams` | `SignatureTransferParams` | The Permit2 SignatureTransfer permit and signature for the LP token. |

**Returns**

| Name     | Type      | Description                                                   |
| -------- | --------- | ------------------------------------------------------------- |
| `<none>` | `uint256` | amount0 The amount of token0 received from burning liquidity. |
| `<none>` | `uint256` | amount1 The amount of token1 received from burning liquidity. |

### \_removeLiquidity

```solidity
function _removeLiquidity(
    address to,
    uint256 liquidity,
    address poolToken0,
    address poolToken1,
    uint24 poolFee,
    SignatureTransferParams memory signatureTransferParams
) internal returns (uint256, uint256);
```

### calculateWithdrawnAmounts

```solidity
function calculateWithdrawnAmounts(
    uint256 reserve0,
    uint256 reserve1,
    uint256 lpTokenTotalSupply,
    uint256 lpTokenBurnt
) internal pure returns (uint256 amount0, uint256 amount1);
```

### \_removeLiquidityCallback

Callback function invoked by the PoolManager when removing liquidity.

* Only the PoolManager should call this function.
* Takes both token0 and token1 from the PoolManager to the caller.
* Burns the corresponding amount from the `hook` contract via `poolManager.burn(...)`.

```solidity
function _removeLiquidityCallback(
    address caller,
    uint256 liquidity,
    PoolKey memory key,
    uint256 amount0,
    uint256 amount1,
    SignatureTransferParams memory signatureTransferParams
) external poolManagerOnly returns (bytes memory);
```

**Parameters**

| Name                      | Type                      | Description                                                          |
| ------------------------- | ------------------------- | -------------------------------------------------------------------- |
| `caller`                  | `address`                 | The address that initiated the liquidity removal.                    |
| `liquidity`               | `uint256`                 | The amount of liquidity to remove.                                   |
| `key`                     | `PoolKey`                 | The pool key containing the token addresses and fee.                 |
| `amount0`                 | `uint256`                 | The amount of token0 to receive from burning liquidity.              |
| `amount1`                 | `uint256`                 | The amount of token1 to receive from burning liquidity.              |
| `signatureTransferParams` | `SignatureTransferParams` | The Permit2 SignatureTransfer permit and signature for the LP token. |

**Returns**

| Name     | Type    | Description                                                           |
| -------- | ------- | --------------------------------------------------------------------- |
| `<none>` | `bytes` | Encoded data containing the amounts of tokens from burning liquidity. |

### \_settleFromRouter

Settle a currency with the PoolManager when tokens are already held by the router

Used after batch permitTransferFrom has transferred tokens to this contract.

```solidity
function _settleFromRouter(Currency currency, uint256 amount) internal;
```

**Parameters**

| Name       | Type       | Description        |
| ---------- | ---------- | ------------------ |
| `currency` | `Currency` | Currency to settle |
| `amount`   | `uint256`  | Amount to send     |

### isNonceUsed

Check if a SignatureTransfer nonce has already been used

```solidity
function isNonceUsed(address owner, uint256 nonce) public view returns (bool);
```

**Parameters**

| Name    | Type      | Description            |
| ------- | --------- | ---------------------- |
| `owner` | `address` | The owner of the nonce |
| `nonce` | `uint256` | The nonce to check     |

**Returns**

| Name     | Type   | Description                                      |
| -------- | ------ | ------------------------------------------------ |
| `<none>` | `bool` | True if the nonce has been used, false otherwise |

### \_hashRemoveLiquidityIntent

```solidity
function _hashRemoveLiquidityIntent(RemoveLiquidityIntent calldata intent)
    internal
    pure
    returns (RemoveLiquidityIntentHash);
```

### \_isTooYoung

```solidity
function _isTooYoung(RemoveLiquidityIntentHash intentHash, uint256 createdBefore) internal view returns (bool);
```

### \_isExpired

```solidity
function _isExpired(RemoveLiquidityIntentHash intentHash, uint256 validUntil) internal view returns (bool);
```

### \_deleteIntentData

Deletes intent mapping data for the given hash.

```solidity
function _deleteIntentData(RemoveLiquidityIntentHash intentHash) internal;
```

### hash

Hash a PermitTransferFrom struct to create a unique identifier for the permit.

Adapted from <https://github.com/Uniswap/permit2/blob/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219/src/libraries/PermitHash.sol#L59> replacing the `spender` address with this router contract (address(this)), instead of msg.sender.

```solidity
function hash(ISignatureTransfer.PermitTransferFrom memory permit) internal view returns (bytes32);
```

**Parameters**

| Name     | Type                                    | Description                            |
| -------- | --------------------------------------- | -------------------------------------- |
| `permit` | `ISignatureTransfer.PermitTransferFrom` | The PermitTransferFrom struct to hash. |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `bytes32` | The hash of the PermitTransferFrom struct. |


---

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