Created
December 3, 2022 16:27
-
-
Save secretshardul/ee990a596d44773b715e290db5f86b20 to your computer and use it in GitHub Desktop.
Uniswap v3 logarithm. https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/TickMath.sol#L61
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio | |
/// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may | |
/// ever return. | |
/// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 | |
/// @return tick The greatest tick for which the ratio is less than or equal to the input ratio | |
function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { | |
// second inequality must be < because the price can never reach the price at the max tick | |
require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R'); | |
uint256 ratio = uint256(sqrtPriceX96) << 32; | |
uint256 r = ratio; | |
uint256 msb = 0; | |
assembly { | |
let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(5, gt(r, 0xFFFFFFFF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(4, gt(r, 0xFFFF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(3, gt(r, 0xFF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(2, gt(r, 0xF)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := shl(1, gt(r, 0x3)) | |
msb := or(msb, f) | |
r := shr(f, r) | |
} | |
assembly { | |
let f := gt(r, 0x1) | |
msb := or(msb, f) | |
} | |
if (msb >= 128) r = ratio >> (msb - 127); | |
else r = ratio << (127 - msb); | |
int256 log_2 = (int256(msb) - 128) << 64; | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(63, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(62, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(61, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(60, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(59, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(58, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(57, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(56, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(55, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(54, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(53, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(52, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(51, f)) | |
r := shr(f, r) | |
} | |
assembly { | |
r := shr(127, mul(r, r)) | |
let f := shr(128, r) | |
log_2 := or(log_2, shl(50, f)) | |
} | |
int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number | |
int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); | |
int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); | |
tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment