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

# NFTX V4 Hook

`NFTXV4Hook` is the sole Uniswap V4-backed implementation the [Locker](/contracts/locker.md) talks to. It creates and initialises each collection's pool, resolves the dynamic swap fee, and routes fee revenue — the single place where pool fees and swaps are integrated. Fees are expressed in **Uniswap V4 pip units**, where `1_000_000` equals 100%.

Signatures and descriptions below come from the `INFTXV4Hook` interface and its implementation. Collection registration and initialisation are callable only by the Locker; the fee controls are `onlyOwner`.

## Pool registration and liquidity

### `registerCollection`

Registers a collection with the hook, creating its pool key and storing its pool parameters.

```solidity
function registerCollection(address _collection, ICollectionToken _collectionToken) external;
```

**Access:** Locker only (reverts `CallerIsNotLocker` otherwise).

| Parameter          | Type               | Description                                    |
| ------------------ | ------------------ | ---------------------------------------------- |
| `_collection`      | `address`          | The address of the collection being registered |
| `_collectionToken` | `ICollectionToken` | The underlying ERC-20 token for the collection |

**Returns:** None.

### `initializeCollection`

Creates the collection's pool and its initial liquidity position via the canonical V4 `PositionManager`. Funding both sides mints a full-range position; supplying zero native mints a token-only, single-sided position.

```solidity
function initializeCollection(address _collection, uint _eth, uint _tokens, uint _amount1Slippage, uint160 _sqrtPriceX96, address _recipient) external;
```

**Access:** Locker only.

| Parameter          | Type      | Description                                                  |
| ------------------ | --------- | ------------------------------------------------------------ |
| `_collection`      | `address` | The address of the collection being initialized              |
| `_eth`             | `uint`    | The amount of ETH-equivalent tokens being passed in          |
| `_tokens`          | `uint`    | The number of underlying tokens being supplied               |
| `_amount1Slippage` | `uint`    | The slippage allowed in the underlying token                 |
| `_sqrtPriceX96`    | `uint160` | The initial pool price                                       |
| `_recipient`       | `address` | The recipient of the LP NFT minted by the V4 PositionManager |

**Returns:** None.

### `depositFees`

Queues donation fees for a collection's pool, ready to be donated on the next hook call.

{% hint style="warning" %}
`_amount0` / `_amount1` are denominated in the pool's **V4-sorted** currency order (`currency0 < currency1` by address), **not** "native vs collection". Callers must resolve the active orientation and pass each fee in the matching slot — passing the collection-token fee in the wrong slot reverts, because the matching ERC-20 won't be approved against the implementation.
{% endhint %}

```solidity
function depositFees(address _collection, uint _amount0, uint _amount1) external;
```

| Parameter     | Type      | Description                                    |
| ------------- | --------- | ---------------------------------------------- |
| `_collection` | `address` | The address of the collection                  |
| `_amount0`    | `uint`    | Fees denominated in `currency0` (post-V4 sort) |
| `_amount1`    | `uint`    | Fees denominated in `currency1` (post-V4 sort) |

**Returns:** None.

## Fee resolution (views)

### `getFee`

Resolves the dynamic fee for a pool for a swap initiated by `_origin` (applying any per-origin exemption).

```solidity
function getFee(PoolId _poolId, address _origin) external view returns (uint24 fee_);
```

| Parameter | Type      | Description                               |
| --------- | --------- | ----------------------------------------- |
| `_poolId` | `PoolId`  | The id of the pool                        |
| `_origin` | `address` | The origin of the swap (e.g. `tx.origin`) |

| Return | Type     | Description                      |
| ------ | -------- | -------------------------------- |
| `fee_` | `uint24` | The dynamic fee, in V4 pip units |

### `getCollectionFee`

The effective base LP fee for a collection's pool, ignoring per-origin swap exemptions. [Listings](/contracts/listings.md) uses this to split listing-tax fees between LPs and the protocol in the same ratio as swap fees.

```solidity
function getCollectionFee(address _collection) external view returns (uint24 fee_);
```

| Parameter     | Type      | Description                              |
| ------------- | --------- | ---------------------------------------- |
| `_collection` | `address` | The collection whose pool fee to resolve |

| Return | Type     | Description                        |
| ------ | -------- | ---------------------------------- |
| `fee_` | `uint24` | The pool's LP fee, in V4 pip units |

### `getCollectionPoolKey` / `poolParams` / `getHookPermissions`

| Function                                    | Returns             | Description                                                                                                                                          |
| ------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getCollectionPoolKey(address _collection)` | `bytes`             | The encoded `PoolKey` for the collection                                                                                                             |
| `poolParams(PoolId _poolId)`                | `PoolParams`        | The on-chain pool parameters for a pool                                                                                                              |
| `getHookPermissions()`                      | `Hooks.Permissions` | The hook's enabled callbacks — `beforeAddLiquidity`, `afterAddLiquidity`, `beforeRemoveLiquidity`, `afterRemoveLiquidity`, `beforeSwap`, `afterSwap` |

## Fee configuration (owner only)

All of the following are `onlyOwner`.

```solidity
function setFeeExemption(address _beneficiary, uint24 _flatFee) external;
function removeFeeExemption(address _beneficiary) external;
function setDefaultFee(uint24 _defaultFee) external;
function setFee(PoolId _poolId, uint24 _fee) external;
function setAmmFee(uint24 _ammFee) external;
function setAmmBeneficiary(address _ammBeneficiary) external;
```

| Function             | Parameters                                        | Description                                                                                               |
| -------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `setFeeExemption`    | `_beneficiary` (`address`), `_flatFee` (`uint24`) | Sets a flat-fee override for a beneficiary (reverts `FeeExemptionInvalid` if above the V4 max LP fee)     |
| `removeFeeExemption` | `_beneficiary` (`address`)                        | Removes a beneficiary's flat-fee override (reverts `NoBeneficiaryExemption` if none)                      |
| `setDefaultFee`      | `_defaultFee` (`uint24`)                          | Sets the protocol-wide default LP fee                                                                     |
| `setFee`             | `_poolId` (`PoolId`), `_fee` (`uint24`)           | Sets a per-pool LP fee override                                                                           |
| `setAmmFee`          | `_ammFee` (`uint24`)                              | Sets the AMM fee taken from the unspecified leg of every swap, credited to the AMM beneficiary via escrow |
| `setAmmBeneficiary`  | `_ammBeneficiary` (`address`)                     | Sets the address that receives AMM fees                                                                   |
