63 lines
2.7 KiB
Solidity
63 lines
2.7 KiB
Solidity
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
pragma solidity >=0.5.0;
|
|
|
|
import '@uniswap/v3-core/contracts/libraries/FullMath.sol';
|
|
import '@uniswap/v3-core/contracts/libraries/UnsafeMath.sol';
|
|
import '@uniswap/v3-core/contracts/libraries/FixedPoint96.sol';
|
|
|
|
/// @title Functions based on Q64.96 sqrt price and liquidity
|
|
/// @notice Exposes two functions from @uniswap/v3-core SqrtPriceMath
|
|
/// that use square root of price as a Q64.96 and liquidity to compute deltas
|
|
library SqrtPriceMathPartial {
|
|
/// @notice Gets the amount0 delta between two prices
|
|
/// @dev Calculates liquidity / sqrt(lower) - liquidity / sqrt(upper),
|
|
/// i.e. liquidity * (sqrt(upper) - sqrt(lower)) / (sqrt(upper) * sqrt(lower))
|
|
/// @param sqrtRatioAX96 A sqrt price
|
|
/// @param sqrtRatioBX96 Another sqrt price
|
|
/// @param liquidity The amount of usable liquidity
|
|
/// @param roundUp Whether to round the amount up or down
|
|
/// @return amount0 Amount of token0 required to cover a position of size liquidity between the two passed prices
|
|
function getAmount0Delta(
|
|
uint160 sqrtRatioAX96,
|
|
uint160 sqrtRatioBX96,
|
|
uint128 liquidity,
|
|
bool roundUp
|
|
) internal pure returns (uint256 amount0) {
|
|
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
|
|
|
uint256 numerator1 = uint256(liquidity) << FixedPoint96.RESOLUTION;
|
|
uint256 numerator2 = sqrtRatioBX96 - sqrtRatioAX96;
|
|
|
|
require(sqrtRatioAX96 > 0);
|
|
|
|
return
|
|
roundUp
|
|
? UnsafeMath.divRoundingUp(
|
|
FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96),
|
|
sqrtRatioAX96
|
|
)
|
|
: FullMath.mulDiv(numerator1, numerator2, sqrtRatioBX96) / sqrtRatioAX96;
|
|
}
|
|
|
|
/// @notice Gets the amount1 delta between two prices
|
|
/// @dev Calculates liquidity * (sqrt(upper) - sqrt(lower))
|
|
/// @param sqrtRatioAX96 A sqrt price
|
|
/// @param sqrtRatioBX96 Another sqrt price
|
|
/// @param liquidity The amount of usable liquidity
|
|
/// @param roundUp Whether to round the amount up, or down
|
|
/// @return amount1 Amount of token1 required to cover a position of size liquidity between the two passed prices
|
|
function getAmount1Delta(
|
|
uint160 sqrtRatioAX96,
|
|
uint160 sqrtRatioBX96,
|
|
uint128 liquidity,
|
|
bool roundUp
|
|
) internal pure returns (uint256 amount1) {
|
|
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
|
|
|
return
|
|
roundUp
|
|
? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96)
|
|
: FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);
|
|
}
|
|
}
|