-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathLiquidityManagement.sol
77 lines (64 loc) · 2.61 KB
/
LiquidityManagement.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;
import "src/core/interfaces/IKatanaV3Factory.sol";
import "src/core/interfaces/callback/IKatanaV3MintCallback.sol";
import "src/core/libraries/TickMath.sol";
import "../libraries/PoolAddress.sol";
import "../libraries/CallbackValidation.sol";
import "../libraries/LiquidityAmounts.sol";
import "./PeripheryPayments.sol";
import "./PeripheryImmutableState.sol";
/// @title Liquidity management functions
/// @notice Internal functions for safely managing liquidity in Katana V3
abstract contract LiquidityManagement is IKatanaV3MintCallback, PeripheryImmutableState, PeripheryPayments {
struct MintCallbackData {
PoolAddress.PoolKey poolKey;
address payer;
}
/// @inheritdoc IKatanaV3MintCallback
function katanaV3MintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata data) external override {
MintCallbackData memory decoded = abi.decode(data, (MintCallbackData));
CallbackValidation.verifyCallback(factory, decoded.poolKey);
if (amount0Owed > 0) pay(decoded.poolKey.token0, decoded.payer, msg.sender, amount0Owed);
if (amount1Owed > 0) pay(decoded.poolKey.token1, decoded.payer, msg.sender, amount1Owed);
}
struct AddLiquidityParams {
address token0;
address token1;
uint24 fee;
address recipient;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
}
/// @notice Add liquidity to an initialized pool
function addLiquidity(AddLiquidityParams memory params)
internal
returns (uint128 liquidity, uint256 amount0, uint256 amount1, IKatanaV3Pool pool)
{
PoolAddress.PoolKey memory poolKey =
PoolAddress.PoolKey({ token0: params.token0, token1: params.token1, fee: params.fee });
pool = IKatanaV3Pool(PoolAddress.computeAddress(factory, poolKey));
// compute the liquidity amount
{
(uint160 sqrtPriceX96,,,,,,,) = pool.slot0();
uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
liquidity = LiquidityAmounts.getLiquidityForAmounts(
sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, params.amount0Desired, params.amount1Desired
);
}
(amount0, amount1) = pool.mint(
params.recipient,
params.tickLower,
params.tickUpper,
liquidity,
abi.encode(MintCallbackData({ poolKey: poolKey, payer: msg.sender }))
);
require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, "Price slippage check");
}
}