Skip to content

Commit

Permalink
v4 guides: decrease liquidity (#775)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdevant committed Sep 20, 2024
1 parent c08e77e commit 9d66fe7
Showing 1 changed file with 121 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,3 +1,123 @@
---
title: Decrease Liquidity
---
---

### Context

Please note that `PositionManager` is a command-based contract, where integrators will be encoding commands and their corresponding
parameters.

Decreasing liquidity assumes the position already exists and the user wants to remove tokens from the position.

### Setup

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

# Guide

Below is a step-by-step guide for decreasing a position's liquidity, in *solidity*.

### 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 decrease a position's liquidity, the first action must be:

* _decrease_ operation - the subtraction of liquidity to an existing position.

For _delta resolving_ operations, developers may need to choose between `TAKE_PAIR`, `CLOSE_CURRENCY`, or `CLEAR_OR_TAKE` actions.

> In Uniswap v4, fee revenue is automatically debited to a position on decreasing liquidity
If decreasing the liquidity requires the transfer of both tokens:

* _take pair_ - receives a pair of tokens, to decrease liquidity

Otherwise:

* _clear or take_ - if the token amount to-be-collected is below a threshold, opt to forfeit the dust. Otherwise, claim the tokens

```solidity
import {Actions} from "v4-periphery/src/libraries/Actions.sol";
```

If both tokens need to be sent:
```solidity
bytes memory actions = abi.encodePacked(uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.TAKE_PAIR));
```

If converting fees to liquidity, forfeiting dust:
```solidity
bytes memory actions = abi.encodePacked(uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.CLEAR_OR_TAKE), uint8(Actions.CLEAR_OR_TAKE));
```

### 3. Encoded Parameters

When taking pair:

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

Otherwise:

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

The `DECREASE_LIQUIDITY` action requires the following parameters:

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

```solidity
params[0] = abi.encode(tokenId, liquidity, amount0Min, amount1Min, hookData);
```

The `TAKE_PAIR` action requires the following parameters:

* `currency0` - _Currency_, one of the tokens to be received
* `currency1` - _Currency_, the other token to be received
* `recipient` - _Recipient_, the recipient to receive the tokens

In the above case, the parameter encoding is:

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

The `CLEAR_OR_TAKE` action requires one `currency` and:

* `amountMax` - _uint256_, the maximum threshold to concede dust,
otherwise taking the dust.

In this case, the parameter encoding is:

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

### 4. Submit Call

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

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

0 comments on commit 9d66fe7

Please sign in to comment.