@swaptoshi/dex-module
Version:
Klayr decentralized exchange (dex) on-chain module
110 lines • 6.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.consult = consult;
exports.getQuoteAtTick = getQuoteAtTick;
exports.getOldestObservationSecondsAgo = getOldestObservationSecondsAgo;
exports.getBlockStartingTickAndLiquidity = getBlockStartingTickAndLiquidity;
exports.getWeightedArithmeticMeanTick = getWeightedArithmeticMeanTick;
exports.getChainedPrice = getChainedPrice;
const int_1 = require("../int");
const TickMath = require("../core/tick_math");
const FullMath = require("../core/full_math");
function consult(pool, secondsAgo) {
if (int_1.Uint32.from(secondsAgo).eq(0))
throw new Error('BP');
let arithmeticMeanTick;
const secondsAgos = [];
secondsAgos.push(secondsAgo);
secondsAgos.push('0');
const [tickCumulatives, secondsPerLiquidityCumulativeX128s] = pool.observe(secondsAgos);
const tickCumulativesDelta = int_1.Int56.from(tickCumulatives[1]).sub(tickCumulatives[0]);
const secondsPerLiquidityCumulativesDelta = int_1.Uint160.from(secondsPerLiquidityCumulativeX128s[1]).sub(secondsPerLiquidityCumulativeX128s[0]);
arithmeticMeanTick = int_1.Int24.from(tickCumulativesDelta).div(secondsAgo);
if (tickCumulativesDelta.lt(0) && !tickCumulativesDelta.mod(secondsAgo).eq(0))
arithmeticMeanTick = arithmeticMeanTick.sub(1);
const secondsAgoX160 = int_1.Uint192.from(secondsAgo).mul(int_1.Uint160.MAX);
const harmonicMeanLiquidity = int_1.Uint128.from(0).add(secondsAgoX160.div(int_1.Uint192.from(secondsPerLiquidityCumulativesDelta).shl(32)));
return [arithmeticMeanTick.toString(), harmonicMeanLiquidity.toString()];
}
function getQuoteAtTick(tick, baseAmount, baseToken, quoteToken) {
let quoteAmount;
const sqrtRatioX96 = int_1.Uint160.from(TickMath.getSqrtRatioAtTick(tick));
if (sqrtRatioX96.lte(int_1.Uint128.MAX)) {
const ratioX192 = int_1.Uint256.from(sqrtRatioX96).mul(sqrtRatioX96);
quoteAmount =
baseToken.compare(quoteToken) < 0
? FullMath.mulDiv(ratioX192.toString(), baseAmount, int_1.Uint256.from(1).shl(192).toString())
: FullMath.mulDiv(int_1.Uint256.from(1).shl(192).toString(), baseAmount, ratioX192.toString());
}
else {
const ratioX128 = int_1.Uint256.from(FullMath.mulDiv(sqrtRatioX96.toString(), sqrtRatioX96.toString(), int_1.Uint256.from(1).shl(64).toString()));
quoteAmount =
baseToken.compare(quoteToken) < 0
? FullMath.mulDiv(ratioX128.toString(), baseAmount, int_1.Uint256.from(1).shl(128).toString())
: FullMath.mulDiv(int_1.Uint256.from(1).shl(128).toString(), baseAmount, ratioX128.toString());
}
return quoteAmount;
}
function getOldestObservationSecondsAgo(pool, _timestamp) {
const { observationIndex, observationCardinality } = pool.slot0;
if (int_1.Uint16.from(observationCardinality).lte(0))
throw new Error('NI');
let observationTimestamp = '0';
const { blockTimestamp, initialized } = pool.observations[int_1.Uint16.from(observationIndex).add(1).mod(observationCardinality).toNumber()];
observationTimestamp = blockTimestamp;
if (!initialized) {
const { blockTimestamp: timestamp } = pool.observations[0];
observationTimestamp = timestamp;
}
const secondsAgo = int_1.Uint32.from(_timestamp).sub(observationTimestamp);
return secondsAgo.toString();
}
function getBlockStartingTickAndLiquidity(pool, timestamp) {
let tick;
const { tick: slot0tick, observationIndex, observationCardinality } = pool.slot0;
tick = slot0tick;
if (int_1.Uint16.from(observationCardinality).lte(1))
throw new Error('NEO');
const { blockTimestamp: observationTimestamp, tickCumulative, secondsPerLiquidityCumulativeX128 } = pool.observations[int_1.Uint16.from(observationIndex).toNumber()];
if (!int_1.Uint32.from(observationTimestamp).eq(timestamp)) {
return [tick, pool.liquidity];
}
const prevIndex = int_1.Uint256.from(int_1.Uint256.from(observationIndex).add(observationCardinality).sub(1)).mod(observationCardinality);
const { blockTimestamp: prevObservationTimestamp, tickCumulative: prevTickCumulative, secondsPerLiquidityCumulativeX128: prevSecondsPerLiquidityCumulativeX128, initialized: prevInitialized, } = pool.observations[prevIndex.toNumber()];
if (!prevInitialized)
throw new Error('ONI');
const delta = int_1.Uint32.from(observationTimestamp).sub(prevObservationTimestamp);
tick = int_1.Int24.from(tickCumulative).sub(prevTickCumulative).div(delta).toString();
const liquidity = int_1.Uint128.from(0)
.add(int_1.Uint192.from(delta).mul(int_1.Uint160.MAX).div(int_1.Uint192.from(secondsPerLiquidityCumulativeX128).sub(prevSecondsPerLiquidityCumulativeX128).shl(32)))
.toString();
return [tick, liquidity];
}
function getWeightedArithmeticMeanTick(weightedTickData) {
let weightedArithmeticMeanTick = int_1.Int24.from(0);
let numerator = int_1.Int256.from(0);
let denominator = int_1.Uint256.from(0);
for (let i = int_1.Uint256.from(0); i.lt(weightedTickData.length); i = i.add(1)) {
numerator = numerator.add(int_1.Int256.from(weightedTickData[i.toNumber()].tick).mul(weightedTickData[i.toNumber()].weight));
denominator = denominator.add(weightedTickData[i.toNumber()].weight);
}
weightedArithmeticMeanTick = int_1.Int24.from(0).add(numerator.div(int_1.Int256.from(0).add(denominator)));
if (numerator.lt(0) && !numerator.mod(int_1.Int256.from(0).add(denominator)).eq(0))
weightedArithmeticMeanTick = weightedArithmeticMeanTick.sub(1);
return weightedArithmeticMeanTick.toString();
}
function getChainedPrice(tokens, ticks) {
let syntheticTick = int_1.Int256.from(0);
if (tokens.length - 1 !== ticks.length)
throw new Error('DL');
for (let i = int_1.Uint256.from(1); i.lte(ticks.length); i = i.add(1)) {
if (tokens[i.sub(1).toNumber()].compare(tokens[i.toNumber()]) < 0) {
syntheticTick = syntheticTick.add(ticks[i.sub(1).toNumber()]);
}
else {
syntheticTick = syntheticTick.sub(ticks[i.sub(1).toNumber()]);
}
}
return syntheticTick.toString();
}
//# sourceMappingURL=oracle_library.js.map