// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; import "./MulDivMath.sol"; import "./TwoPower.sol"; import "./LogPowMath.sol"; library AmountMath { function getAmountY( uint128 liquidity, uint160 sqrtPriceL_96, uint160 sqrtPriceR_96, uint160 sqrtRate_96, bool upper ) internal pure returns (uint256 amount) { uint160 numerator = sqrtPriceR_96 - sqrtPriceL_96; uint160 denominator = sqrtRate_96 - uint160(TwoPower.Pow96); if (!upper) { amount = MulDivMath.mulDivFloor(liquidity, numerator, denominator); } else { amount = MulDivMath.mulDivCeil(liquidity, numerator, denominator); } } function getAmountX( uint128 liquidity, int24 leftPt, int24 rightPt, uint160 sqrtPriceR_96, uint160 sqrtRate_96, bool upper ) internal pure returns (uint256 amount) { // rightPt - (leftPt - 1), pc = leftPt - 1 uint160 sqrtPricePrPl_96 = LogPowMath.getSqrtPrice(rightPt - leftPt); // 1. sqrtPriceR_96 * 2^96 < 2^256 // 2. sqrtRate_96 > 2^96, so sqrtPricePrM1_96 < sqrtPriceR_96 < 2^160 uint160 sqrtPricePrM1_96 = uint160(uint256(sqrtPriceR_96) * TwoPower.Pow96 / sqrtRate_96); uint160 numerator = sqrtPricePrPl_96 - uint160(TwoPower.Pow96); uint160 denominator = sqrtPriceR_96 - sqrtPricePrM1_96; if (!upper) { amount = MulDivMath.mulDivFloor(liquidity, numerator, denominator); } else { amount = MulDivMath.mulDivCeil(liquidity, numerator, denominator); } } }