Skip to content

Commit

Permalink
Fee collection tutorial (#751)
Browse files Browse the repository at this point in the history
Co-authored-by: saucepoint <[email protected]>
  • Loading branch information
Alexhandru and saucepoint authored Sep 15, 2024
1 parent 6626366 commit 90159df
Showing 1 changed file with 84 additions and 1 deletion.
85 changes: 84 additions & 1 deletion docs/contracts/v4/guides/02-manage-liquidity/04-collect.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,86 @@
---
title: Collect Fees
---
---

### Setup

See the [setup guide](./00-setup-liquidity.mdx)

# Guide

In order to collect fees, the integrator must execute encoded actions
using the `PositionManager` contract. **Note** that there is no
`COLLECT` command, instead developers must decrease liquidity with a zero
liquidity change.

### 1. Import and define `IPositionManager`

```solidity
import {IPositionManager} from "v4-periphery/src/interfaces/IPositionManager.sol";
// inside a contract, test, or foundry script:
IPositionManager posm = IPositionManager(<address>);
```

### 2. Encode actions

To collect fees, the following operations are required:
* decrease liquidity - collect fees from the core contract
* take pair - transfer the fee revenue, as both tokens, to a recipient

```solidity
import {Actions} from "v4-periphery/src/libraries/Actions.sol";
bytes memory actions = abi.encodePacked(uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.TAKE_PAIR));
```

### 3. Encode Parameters

```solidity
bytes[] memory params = new bytes[](2);
```

The `DECREASE_LIQUIDITY` action requires the following parameters:

| Parameter | Type | Description |
|--------------|-----------|-------------------------------------------------------------------------------|
| `tokenId` | _uint256_ | position identifier |
| `liquidity` | _uint256_ | the amount of liquidity to withdraw |
| `amount0Min` | _uint128_ | the minimum amount of currency0 liquidity msg.sender is expecting to get back |
| `amount1Min` | _uint128_ | the minimum amount of currency1 liquidity msg.sender is expecting to get back |
| `hookData` | _bytes_ | arbitrary data that will be forwarded to hook functions |

**Note** that in order to collect fees we will default `liquidity`, `amount0Min` and `amount1Min` to 0.
Because fee collection can not be manipulated in a front-run attack, it is safe to set the slippage
values `amount0Min, amount1Min` to `0`.

```solidity
/// @dev collecting fees is achieved with liquidity=0, the second parameter
params[0] = abi.encode(tokenId, 0, 0, 0, hookData);
```

The `TAKE_PAIR` action requires the following parameters:

* `currency0` - _Currency_, one of the tokens to be paid by msg.sender
* `currency1` - _Currency_, the other token to be paid by msg.sender
* `recipient` - _address_, destination of the fee revenue for both tokens

```solidity
params[1] = abi.encode(currency0, currency1, recipient);
```

### 4. Submit Call

The entrypoint for all liquidity operations is `modifyLiquidities()`.

```solidity
uint256 deadline = block.timestamp + 60;
posm.modifyLiquidities(
abi.encode(actions, params),
deadline
);
```

## Additional notes:

* To obtain the amount of fees received, callers should read
token balances before and after the `.modifyLiquidities()` call.

0 comments on commit 90159df

Please sign in to comment.