@firefly-exchange/library-sui
Version:
Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui
265 lines (264 loc) • 11.9 kB
JavaScript
"use strict";
/**
* This file incorporates code from cetus-clmm-sui-sdk by CetusProtocol,
* licensed under the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* which can be found at https://github.com/CetusProtocol/cetus-clmm-sui-sdk/blob/main/LICENSE
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.tickScore = exports.getTickDataFromUrlData = exports.TickMath = void 0;
/* eslint-disable no-bitwise */
const bn_js_1 = __importDefault(require("bn.js"));
const utils_1 = require("./utils");
const decimal_1 = __importDefault(require("./decimal"));
const constants_1 = require("./constants");
const errors_1 = require("./errors");
const common_1 = require("./common");
const number_1 = require("./number");
const BIT_PRECISION = 14;
const LOG_B_2_X32 = "59543866431248";
const LOG_B_P_ERR_MARGIN_LOWER_X64 = "184467440737095516";
const LOG_B_P_ERR_MARGIN_UPPER_X64 = "15793534762490258745";
const TICK_BOUND = 443636;
function signedShiftLeft(n0, shiftBy, bitWidth) {
const twosN0 = n0.toTwos(bitWidth).shln(shiftBy);
twosN0.imaskn(bitWidth + 1);
return twosN0.fromTwos(bitWidth);
}
function signedShiftRight(n0, shiftBy, bitWidth) {
const twoN0 = n0.toTwos(bitWidth).shrn(shiftBy);
twoN0.imaskn(bitWidth - shiftBy + 1);
return twoN0.fromTwos(bitWidth - shiftBy);
}
function tickIndexToSqrtPricePositive(tick) {
let ratio;
if ((tick & 1) !== 0) {
ratio = new bn_js_1.default("79232123823359799118286999567");
}
else {
ratio = new bn_js_1.default("79228162514264337593543950336");
}
if ((tick & 2) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79236085330515764027303304731")), 96, 256);
}
if ((tick & 4) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79244008939048815603706035061")), 96, 256);
}
if ((tick & 8) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79259858533276714757314932305")), 96, 256);
}
if ((tick & 16) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79291567232598584799939703904")), 96, 256);
}
if ((tick & 32) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79355022692464371645785046466")), 96, 256);
}
if ((tick & 64) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79482085999252804386437311141")), 96, 256);
}
if ((tick & 128) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("79736823300114093921829183326")), 96, 256);
}
if ((tick & 256) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("80248749790819932309965073892")), 96, 256);
}
if ((tick & 512) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("81282483887344747381513967011")), 96, 256);
}
if ((tick & 1024) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("83390072131320151908154831281")), 96, 256);
}
if ((tick & 2048) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("87770609709833776024991924138")), 96, 256);
}
if ((tick & 4096) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("97234110755111693312479820773")), 96, 256);
}
if ((tick & 8192) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("119332217159966728226237229890")), 96, 256);
}
if ((tick & 16384) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("179736315981702064433883588727")), 96, 256);
}
if ((tick & 32768) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("407748233172238350107850275304")), 96, 256);
}
if ((tick & 65536) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("2098478828474011932436660412517")), 96, 256);
}
if ((tick & 131072) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("55581415166113811149459800483533")), 96, 256);
}
if ((tick & 262144) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("38992368544603139932233054999993551")), 96, 256);
}
return signedShiftRight(ratio, 32, 256);
}
function tickIndexToSqrtPriceNegative(tickIndex) {
const tick = Math.abs(tickIndex);
let ratio;
if ((tick & 1) !== 0) {
ratio = new bn_js_1.default("18445821805675392311");
}
else {
ratio = new bn_js_1.default("18446744073709551616");
}
if ((tick & 2) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18444899583751176498")), 64, 256);
}
if ((tick & 4) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18443055278223354162")), 64, 256);
}
if ((tick & 8) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18439367220385604838")), 64, 256);
}
if ((tick & 16) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18431993317065449817")), 64, 256);
}
if ((tick & 32) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18417254355718160513")), 64, 256);
}
if ((tick & 64) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18387811781193591352")), 64, 256);
}
if ((tick & 128) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18329067761203520168")), 64, 256);
}
if ((tick & 256) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("18212142134806087854")), 64, 256);
}
if ((tick & 512) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("17980523815641551639")), 64, 256);
}
if ((tick & 1024) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("17526086738831147013")), 64, 256);
}
if ((tick & 2048) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("16651378430235024244")), 64, 256);
}
if ((tick & 4096) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("15030750278693429944")), 64, 256);
}
if ((tick & 8192) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("12247334978882834399")), 64, 256);
}
if ((tick & 16384) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("8131365268884726200")), 64, 256);
}
if ((tick & 32768) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("3584323654723342297")), 64, 256);
}
if ((tick & 65536) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("696457651847595233")), 64, 256);
}
if ((tick & 131072) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("26294789957452057")), 64, 256);
}
if ((tick & 262144) !== 0) {
ratio = signedShiftRight(ratio.mul(new bn_js_1.default("37481735321082")), 64, 256);
}
return ratio;
}
class TickMath {
static priceToSqrtPriceX64(price, decimalsA, decimalsB) {
return utils_1.MathUtil.toX64(price.mul(decimal_1.default.pow(10, decimalsB - decimalsA)).sqrt());
}
static sqrtPriceX64ToPrice(sqrtPriceX64, decimalsA, decimalsB) {
return utils_1.MathUtil.fromX64(sqrtPriceX64)
.pow(2)
.mul(decimal_1.default.pow(10, decimalsA - decimalsB));
}
static tickIndexToSqrtPriceX64(tickIndex) {
if (tickIndex > 0) {
return new bn_js_1.default(tickIndexToSqrtPricePositive(tickIndex));
}
return new bn_js_1.default(tickIndexToSqrtPriceNegative(tickIndex));
}
static sqrtPriceX64ToTickIndex(sqrtPriceX64) {
if (sqrtPriceX64.gt(new bn_js_1.default(constants_1.MAX_SQRT_PRICE)) ||
sqrtPriceX64.lt(new bn_js_1.default(constants_1.MIN_SQRT_PRICE))) {
throw new errors_1.ClmmpoolsError("The provided sqrtPrice is outside the supported sqrtPrice range", errors_1.MathErrorCode.InvalidSqrtPrice);
}
const msb = sqrtPriceX64.bitLength() - 1;
const adjustedMsb = new bn_js_1.default(msb - 64);
const log2pIntegerX32 = signedShiftLeft(adjustedMsb, 32, 128);
let bit = new bn_js_1.default("8000000000000000", "hex");
let precision = 0;
let log2pFractionX64 = new bn_js_1.default(0);
let r = msb >= 64 ? sqrtPriceX64.shrn(msb - 63) : sqrtPriceX64.shln(63 - msb);
while (bit.gt(new bn_js_1.default(0)) && precision < BIT_PRECISION) {
r = r.mul(r);
const rMoreThanTwo = r.shrn(127);
r = r.shrn(63 + rMoreThanTwo.toNumber());
log2pFractionX64 = log2pFractionX64.add(bit.mul(rMoreThanTwo));
bit = bit.shrn(1);
precision += 1;
}
const log2pFractionX32 = log2pFractionX64.shrn(32);
const log2pX32 = log2pIntegerX32.add(log2pFractionX32);
const logbpX64 = log2pX32.mul(new bn_js_1.default(LOG_B_2_X32));
const tickLow = signedShiftRight(logbpX64.sub(new bn_js_1.default(LOG_B_P_ERR_MARGIN_LOWER_X64)), 64, 128).toNumber();
const tickHigh = signedShiftRight(logbpX64.add(new bn_js_1.default(LOG_B_P_ERR_MARGIN_UPPER_X64)), 64, 128).toNumber();
if (tickLow === tickHigh) {
return tickLow;
}
const derivedTickHighSqrtPriceX64 = TickMath.tickIndexToSqrtPriceX64(tickHigh);
if (derivedTickHighSqrtPriceX64.lte(sqrtPriceX64)) {
return tickHigh;
}
return tickLow;
}
static tickIndexToPrice(tickIndex, decimalsA, decimalsB) {
return TickMath.sqrtPriceX64ToPrice(TickMath.tickIndexToSqrtPriceX64(tickIndex), decimalsA, decimalsB);
}
static priceToTickIndex(price, decimalsA, decimalsB) {
return TickMath.sqrtPriceX64ToTickIndex(TickMath.priceToSqrtPriceX64(price, decimalsA, decimalsB));
}
static priceToInitializableTickIndex(price, decimalsA, decimalsB, tickSpacing) {
return TickMath.getInitializableTickIndex(TickMath.priceToTickIndex(price, decimalsA, decimalsB), tickSpacing);
}
static getInitializableTickIndex(tickIndex, tickSpacing) {
return tickIndex - (tickIndex % tickSpacing);
}
/**
*
* @param tickIndex
* @param tickSpacing
* @returns
*/
static getNextInitializableTickIndex(tickIndex, tickSpacing) {
return TickMath.getInitializableTickIndex(tickIndex, tickSpacing) + tickSpacing;
}
static getPrevInitializableTickIndex(tickIndex, tickSpacing) {
return TickMath.getInitializableTickIndex(tickIndex, tickSpacing) - tickSpacing;
}
}
exports.TickMath = TickMath;
function getTickDataFromUrlData(ticks) {
const tickdatas = [];
for (const tick of ticks) {
const td = {
objectId: tick.objectId,
index: Number((0, common_1.asIntN)(BigInt(tick.index)).toString()),
sqrtPrice: tick.sqrtPrice,
liquidityNet: new bn_js_1.default(BigInt.asIntN(128, BigInt(BigInt(tick.liquidityNet.toString()))).toString()),
liquidityGross: tick.liquidityGross,
feeGrowthOutsideA: tick.feeGrowthOutsideA,
feeGrowthOutsideB: tick.feeGrowthOutsideB,
rewardersGrowthOutside: [
new bn_js_1.default(tick.rewardersGrowthOutside[0]),
new bn_js_1.default(tick.rewardersGrowthOutside[1]),
new bn_js_1.default(tick.rewardersGrowthOutside[2])
]
};
tickdatas.push(td);
}
return tickdatas;
}
exports.getTickDataFromUrlData = getTickDataFromUrlData;
function tickScore(tickIndex) {
return (0, number_1.d)(tickIndex).add((0, number_1.d)(TICK_BOUND));
}
exports.tickScore = tickScore;