UNPKG

@swaptoshi/dex-module

Version:

Klayr decentralized exchange (dex) on-chain module

110 lines 6.28 kB
"use strict"; 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