Liquidity and swap for liquidity book pool
In this guide, We'll make use of periphery contracts from v4-periphery
- Liquidity operations with
BinFungiblePositionManager
- Swaps via
BinSwapRouter
Liquidity operations
Add liquidity
IBinFungiblePositionManager.AddLiquidityParams memory params = IBinFungiblePositionManager
.AddLiquidityParams({
poolKey: key,
amount0: amountX,
amount1: amountY,
amount0Min: 0, // note in real world, this should not be 0
amount1Min: 0, // note in real world, this should not be 0
activeIdDesired: uint256(currentActiveId),
idSlippage: 0,
deltaIds: convertToRelative(binIds, currentActiveId),
distributionX: distribX,
distributionY: distribY,
to: address(this),
deadline: block.timestamp + 600
});
(uint128 amount0, uint128 amount1, uint256[] memory tokenIds, uint256[] memory liquidityMinted)
= positionManager.addLiquidity(params);
/// @dev Given list of binIds and activeIds, return the delta ids.
// eg. given id: [100, 101, 102] and activeId: 101, return [-1, 0, 1]
function convertToRelative(uint24[] memory absoluteIds, uint24 activeId)
internal
pure
returns (int256[] memory relativeIds) {
relativeIds = new int256[](absoluteIds.length);
for (uint256 i = 0; i < absoluteIds.length; i++) {
relativeIds[i] = int256(uint256(absoluteIds[i])) - int256(uint256(activeId));
}
}
Input:
poolKey
: struct which identify the poolamount0 | amount1
: amount of token0 and token1amount0Min | amount1Min
: min amount of token0 and token1. transaction will revert if required token is lesseractiveIdDesired
: active id preferred when adding liquidityidSlippage
: max slippage on active id. transaction will revert if activeId changes more than idSlippage valdeltaIds
: list of delta ids to add liquidity (deltaId = activeId - desiredId
). see helper methodconvertToRelative
abovedistributionX
: distribution of token0 with sum(distributionX) = 100e18 (100%)distributionY
: distribution of token1 with sum(distributionY) = 100e18 (100%)to
: address of recipient to receive the 1155 token which represent ownership of liquiditydeadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Output:
amount0
: amount of token0 used for adding liquidityamount0
: amount of token1 used for adding liquiditytokenIds
: list of tokenIds minted for each binliquidityMinted
: list of liquidity minted for each bin
Remove liqudiity
IBinFungiblePositionManager.RemoveLiquidityParams memory params = IBinFungiblePositionManager
.RemoveLiquidityParams({
poolKey: key,
amount0Min: 0,
amount1Min: 0,
ids: ids,
amounts: amounts,
from: address(this),
to: address(this),
deadline: block.timestamp
});
(uint128 amount0, uint128 amount1, uint256[] memory tokenIds)
= positionManager.removeLiquidity(params);
Input:
poolKey
: struct which identify the poolamount0Min | amount1Min
: min amount of token0 and token1. transaction will revert if token out is lesserids
: list of bin idsamounts
: list of lquidity to remove for each binfrom
: Address of holder who have the liquidityto
: user to receive the the token0 and token1 from removing liquiditydeadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Swaps
Exact Input Single
IBinSwapRouterBase.V4BinExactInputSingleParams memory params = IBinSwapRouterBase
.V4BinExactInputSingleParams({
poolKey: key1,
swapForY: true,
recipient: address(this),
amountIn: 1 ether,
amountOutMinimum: 0,
hookData: new bytes(0)
});
uint256 amtOut = router.exactInputSingle(params, block.timestamp);
Input:
poolKey
: struct which identify the poolswapForY
: if true swap token0 for token1, else swap token1 for token0recipient
: address to receive the output tokenamountIn
: desired amount inamountOutMinimum
: min amount out. transaction revert if amount out is lesserhookData
: if set, will be passed to hooks in both beforeSwap and afterSwapdeadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Output:
amountOut
: amount of token out from the swap
Exact Input
bytes32 params;
ISwapRouterBase.PathKey[] memory path = new ISwapRouterBase.PathKey[](2);
path[0] = ISwapRouterBase.PathKey({
intermediateCurrency: currency1,
fee: uint24(3000),
hooks: IHooks(address(0)),
hookData: new bytes(0),
poolManager: poolManager,
parameters: params.setBinStep(10)
});
path[1] = ISwapRouterBase.PathKey({
intermediateCurrency: currency2,
fee: uint24(3000),
hooks: IHooks(address(0)),
hookData: new bytes(0),
poolManager: poolManager,
parameters: params.setBinStep(10)
});
IBinSwapRouterBase.V4BinExactInputParams memory input = IBinSwapRouterBase
.V4BinExactInputParams({
currencyIn: currency0,
path: path,
recipient: address(this),
amountIn: 1 ether,
amountOutMinimum: 0
});
uint256 amountOut = router.exactInput(input, block.timestamp);
Input:
currencyIn
: input tokenpath
: Array ofPathKey[]
which describe the pool to hoprecipient
: address to receive the output tokenamountIn
: desired amount inamountOutMinimum
: min amount out. transaction revert if amount out is lesserdeadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Output:
amountOut
: amount of token out from the swap
Exact Output Single
IBinSwapRouterBase.V4ExactOutputSingleParams memory input = IBinSwapRouterBase
.V4ExactOutputSingleParams({
poolKey: key1,
swapForY: false,
recipient: address(this),
amountOut: 1 ether,
amountInMaximum: 1.1 ether,
hookData: new bytes(0)
});
uint256 amountIn = router.exactOutputSingle(input, block.timestamp);
Input:
poolKey
: struct which identify the poolswapForY
: if true swap token0 for token1, else swap token1 for token0recipient
: address to receive the output tokenamountOut
: desired amount outamountInMaximum
: max amount in. transaction revert if amount out is lesserhookData
: if set, will be passed to hooks in both beforeSwap and afterSwapdeadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Output:
amountIn
: amount of token in from the swap
Exact Output
bytes32 params;
ISwapRouterBase.PathKey[] memory path = new ISwapRouterBase.PathKey[](2);
path[0] = ISwapRouterBase.PathKey({
intermediateCurrency: currency0,
fee: uint24(3000),
hooks: IHooks(address(0)),
hookData: new bytes(0),
poolManager: poolManager,
parameters: params.setBinStep(10)
});
path[1] = ISwapRouterBase.PathKey({
intermediateCurrency: currency1,
fee: uint24(3000),
hooks: IHooks(address(0)),
hookData: new bytes(0),
poolManager: poolManager,
parameters: params.setBinStep(10)
});
IBinSwapRouterBase.V4ExactOutputParams memory input = IBinSwapRouterBase
.V4ExactOutputParams({
currencyOut: currency2,
path: path,
recipient: address(this),
amountOut: 1 ether,
amountInMaximum: 1.1 ether
});
uint256 amountIn = router.exactOutput(input, block.timestamp);
Input:
currencyOut
: output tokenpath
: Array ofPathKey[]
which describe the pool to hoprecipient
: address to receive the output tokenamountOut
: desired amount outamountInMaximum
: max amount out. transaction revert if amountIn required is more.deadline
: deadline of this transaction. transaction will revert ifblock.timestamp
is greater thandeadline
Output:
amountIn
: amount of token in from the swap