@bella-defintech/uniswap-v3-simulator
Version:
the 'Tuner', a Uniswap V3 Simulator
99 lines (98 loc) • 6.08 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqrtPriceMath = void 0;
const jsbi_1 = __importDefault(require("jsbi"));
const FullMath_1 = require("./FullMath");
const InternalConstants_1 = require("../enum/InternalConstants");
const assert_1 = __importDefault(require("assert"));
function multiplyIn256(x, y) {
const product = jsbi_1.default.multiply(x, y);
return jsbi_1.default.bitwiseAnd(product, InternalConstants_1.MaxUint256);
}
function addIn256(x, y) {
const sum = jsbi_1.default.add(x, y);
return jsbi_1.default.bitwiseAnd(sum, InternalConstants_1.MaxUint256);
}
class SqrtPriceMath {
static getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
return jsbi_1.default.lessThan(liquidity, jsbi_1.default.BigInt(0))
? jsbi_1.default.unaryMinus(SqrtPriceMath.getAmount0DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, jsbi_1.default.unaryMinus(liquidity), false))
: SqrtPriceMath.getAmount0DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, liquidity, true);
}
static getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
return jsbi_1.default.lessThan(liquidity, jsbi_1.default.BigInt(0))
? jsbi_1.default.unaryMinus(SqrtPriceMath.getAmount1DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, jsbi_1.default.unaryMinus(liquidity), false))
: SqrtPriceMath.getAmount1DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, liquidity, true);
}
static getNextSqrtPriceFromInput(sqrtPX96, liquidity, amountIn, zeroForOne) {
assert_1.default(jsbi_1.default.greaterThan(sqrtPX96, InternalConstants_1.ZERO));
assert_1.default(jsbi_1.default.greaterThan(liquidity, InternalConstants_1.ZERO));
return zeroForOne
? this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountIn, true)
: this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountIn, true);
}
static getNextSqrtPriceFromOutput(sqrtPX96, liquidity, amountOut, zeroForOne) {
assert_1.default(jsbi_1.default.greaterThan(sqrtPX96, InternalConstants_1.ZERO));
assert_1.default(jsbi_1.default.greaterThan(liquidity, InternalConstants_1.ZERO));
return zeroForOne
? this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountOut, false)
: this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountOut, false);
}
static getAmount0DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, liquidity, roundUp) {
if (jsbi_1.default.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) {
[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
}
const numerator1 = jsbi_1.default.leftShift(liquidity, jsbi_1.default.BigInt(96));
const numerator2 = jsbi_1.default.subtract(sqrtRatioBX96, sqrtRatioAX96);
return roundUp
? FullMath_1.FullMath.mulDivRoundingUp(FullMath_1.FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96), InternalConstants_1.ONE, sqrtRatioAX96)
: jsbi_1.default.divide(jsbi_1.default.divide(jsbi_1.default.multiply(numerator1, numerator2), sqrtRatioBX96), sqrtRatioAX96);
}
static getAmount1DeltaWithRoundUp(sqrtRatioAX96, sqrtRatioBX96, liquidity, roundUp) {
if (jsbi_1.default.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) {
[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
}
return roundUp
? FullMath_1.FullMath.mulDivRoundingUp(liquidity, jsbi_1.default.subtract(sqrtRatioBX96, sqrtRatioAX96), InternalConstants_1.Q96)
: jsbi_1.default.divide(jsbi_1.default.multiply(liquidity, jsbi_1.default.subtract(sqrtRatioBX96, sqrtRatioAX96)), InternalConstants_1.Q96);
}
static getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amount, add) {
if (jsbi_1.default.equal(amount, InternalConstants_1.ZERO))
return sqrtPX96;
const numerator1 = jsbi_1.default.leftShift(liquidity, jsbi_1.default.BigInt(96));
if (add) {
let product = multiplyIn256(amount, sqrtPX96);
if (jsbi_1.default.equal(jsbi_1.default.divide(product, amount), sqrtPX96)) {
const denominator = addIn256(numerator1, product);
if (jsbi_1.default.greaterThanOrEqual(denominator, numerator1)) {
return FullMath_1.FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator);
}
}
return FullMath_1.FullMath.mulDivRoundingUp(numerator1, InternalConstants_1.ONE, jsbi_1.default.add(jsbi_1.default.divide(numerator1, sqrtPX96), amount));
}
else {
let product = multiplyIn256(amount, sqrtPX96);
assert_1.default(jsbi_1.default.equal(jsbi_1.default.divide(product, amount), sqrtPX96));
assert_1.default(jsbi_1.default.greaterThan(numerator1, product));
const denominator = jsbi_1.default.subtract(numerator1, product);
return FullMath_1.FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator);
}
}
static getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amount, add) {
if (add) {
const quotient = jsbi_1.default.lessThanOrEqual(amount, InternalConstants_1.MaxUint160)
? jsbi_1.default.divide(jsbi_1.default.leftShift(amount, jsbi_1.default.BigInt(96)), liquidity)
: jsbi_1.default.divide(jsbi_1.default.multiply(amount, InternalConstants_1.Q96), liquidity);
return jsbi_1.default.add(sqrtPX96, quotient);
}
else {
const quotient = FullMath_1.FullMath.mulDivRoundingUp(amount, InternalConstants_1.Q96, liquidity);
assert_1.default(jsbi_1.default.greaterThan(sqrtPX96, quotient));
return jsbi_1.default.subtract(sqrtPX96, quotient);
}
}
}
exports.SqrtPriceMath = SqrtPriceMath;