TTurkDex Developers
HelpBlogLaunch app

Managing Liquidity

Bu açık kaynak protokol/SDK referansı TurkDex markasıyla sunulan uyarlamadır; sayfadaki entegrasyon örnekleri Turkchain’de etkin özelliklerin garantisi değildir. Ağ, kontrat ve işlem değerlerinde yalnızca bu kurulumun doğrulanmış ENV/registry bilgilerini kullanın.

This guide covers the full lifecycle of a TurkDex v4 liquidity position: minting a new position, increasing and decreasing liquidity, and collecting accrued fees. All operations go through the PositionManager contract using an encoded command system.

Prerequisites

Developing with TurkDex v4 requires Foundry.

Use v4-template for a pre-configured project, or install manually:

forge install uniswap/v4-core
forge install uniswap/v4-periphery

All examples below assume you have already imported and instantiated the PositionManager:

import  from "v4-periphery/src/interfaces/IPositionManager.sol";
import  from "v4-periphery/src/libraries/Actions.sol";

IPositionManager posm = IPositionManager(<address>);

Minting a Position

Minting creates a new ERC-721 liquidity position in a specific pool and tick range.

Encode actions

bytes memory actions = abi.encodePacked(
    uint8(Actions.MINT_POSITION),
    uint8(Actions.SETTLE_PAIR)
);

For ETH liquidity positions, add a SWEEP action to recover excess ETH:

bytes memory actions = abi.encodePacked(
    uint8(Actions.MINT_POSITION),
    uint8(Actions.SETTLE_PAIR),
    uint8(Actions.SWEEP)
);

Encode parameters

bytes[] memory params = new bytes[](2); // 3 for ETH positions

params[0] = abi.encode(
    poolKey, tickLower, tickUpper, liquidity,
    amount0Max, amount1Max, recipient, hookData
);

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

// For ETH positions:
// params[2] = abi.encode(CurrencyLibrary.ADDRESS_ZERO, recipient);
ParameterTypeDescription
poolKey_PoolKey_the pool to add liquidity to
tickLower_int24_lower tick boundary of the position
tickUpper_int24_upper tick boundary of the position
liquidity_uint256_amount of liquidity units to mint
amount0Max_uint128_maximum currency0 the caller is willing to pay
amount1Max_uint128_maximum currency1 the caller is willing to pay
recipient_address_address that receives the position NFT
hookData_bytes_arbitrary data forwarded to hook functions

Submit the call

uint256 deadline = block.timestamp + 60;
uint256 valueToPass = currency0.isAddressZero() ? amount0Max : 0;

posm.modifyLiquidities(
    abi.encode(actions, params),
    deadline
);

Increasing Liquidity

Add more tokens to an existing position. In v4, fee revenue is automatically credited when increasing liquidity.

Encode actions

bytes memory actions = abi.encodePacked(
    uint8(Actions.INCREASE_LIQUIDITY),
    uint8(Actions.SETTLE_PAIR)
);

If accrued fees fully cover the increase (rare), use CLOSE_CURRENCY instead of SETTLE_PAIR to handle any remainder:

bytes memory actions = abi.encodePacked(
    uint8(Actions.INCREASE_LIQUIDITY),
    uint8(Actions.CLOSE_CURRENCY),
    uint8(Actions.CLOSE_CURRENCY)
);

Encode parameters

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

params[0] = abi.encode(tokenId, liquidity, amount0Max, amount1Max, hookData);
params[1] = abi.encode(currency0, currency1);
ParameterTypeDescription
tokenId_uint256_position identifier (ERC-721 token ID)
liquidity_uint256_amount of liquidity to add
amount0Max_uint128_maximum currency0 the caller is willing to pay
amount1Max_uint128_maximum currency1 the caller is willing to pay
hookData_bytes_arbitrary data forwarded to hook functions

Submit the call

uint256 deadline = block.timestamp + 60;

posm.modifyLiquidities(
    abi.encode(actions, params),
    deadline
);

Decreasing Liquidity

Remove tokens from an existing position. Fee revenue is automatically debited when decreasing liquidity.

Encode actions

bytes memory actions = abi.encodePacked(
    uint8(Actions.DECREASE_LIQUIDITY),
    uint8(Actions.TAKE_PAIR)
);

Encode parameters

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

params[0] = abi.encode(tokenId, liquidity, amount0Min, amount1Min, hookData);
params[1] = abi.encode(currency0, currency1, recipient);
ParameterTypeDescription
tokenId_uint256_position identifier
liquidity_uint256_amount of liquidity to remove
amount0Min_uint128_minimum currency0 the caller expects to receive
amount1Min_uint128_minimum currency1 the caller expects to receive
hookData_bytes_arbitrary data forwarded to hook functions

Submit the call

uint256 deadline = block.timestamp + 60;

posm.modifyLiquidities(
    abi.encode(actions, params),
    deadline
);

Collecting Fees

There is no dedicated COLLECT command. To collect fees, decrease liquidity by zero:

Encode actions

bytes memory actions = abi.encodePacked(
    uint8(Actions.DECREASE_LIQUIDITY),
    uint8(Actions.TAKE_PAIR)
);

Encode parameters

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

// liquidity = 0, amount0Min = 0, amount1Min = 0
params[0] = abi.encode(tokenId, 0, 0, 0, hookData);
params[1] = abi.encode(currency0, currency1, recipient);
Bilgi:

Setting amount0Min and amount1Min to 0 is safe for fee collection because fee amounts cannot be manipulated via front-running.

Submit the call

uint256 deadline = block.timestamp + 60;

posm.modifyLiquidities(
    abi.encode(actions, params),
    deadline
);

To determine how many fee tokens were collected, read the token balances of the recipient before and after calling modifyLiquidities().

Next Steps

Uyarlanmış geliştirici referansı. Kaynak: kaynak dokümantasyon reposu. Kaynak ve lisans bildirimi: NOTICE.