From ed45375755053179932fa17191abdd81d3d22368 Mon Sep 17 00:00:00 2001 From: mlguys Date: Sat, 27 Apr 2024 13:33:01 +0700 Subject: [PATCH] add new priceToTick calculation --- src/chains/osmosis/osmosis.ts | 9 +++-- src/chains/osmosis/osmosis.utils.ts | 55 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/chains/osmosis/osmosis.ts b/src/chains/osmosis/osmosis.ts index b4a1ac0282..cbf8b11a6b 100755 --- a/src/chains/osmosis/osmosis.ts +++ b/src/chains/osmosis/osmosis.ts @@ -50,7 +50,7 @@ import { Pool as CLPool } from 'osmo-query/dist/codegen/osmosis/concentrated-liq import { TradeInfo } from './osmosis.controllers'; import { HttpException, TRADE_FAILED_ERROR_CODE, TRADE_FAILED_ERROR_MESSAGE, GAS_LIMIT_EXCEEDED_ERROR_MESSAGE, GAS_LIMIT_EXCEEDED_ERROR_CODE, AMOUNT_LESS_THAN_MIN_AMOUNT_ERROR_MESSAGE, AMOUNT_LESS_THAN_MIN_AMOUNT_ERROR_CODE } from '../../services/error-handler'; import { extendPool, filterPoolsSwap, filterPoolsLP, filterPoolsSwapAndLP } from './osmosis.lp.utils'; -import { fetchFees, findTickForPrice, tickToPrice } from './osmosis.utils'; +import { fetchFees, findTickForPrice, tickToPrice, calculatePriceToTick } from './osmosis.utils'; import { getImperatorPriceHash } from './osmosis.prices'; import { GasPrice, calculateFee, setupIbcExtension, SigningStargateClient, AminoTypes } from '@cosmjs/stargate'; import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"; @@ -1361,8 +1361,11 @@ export class Osmosis extends CosmosBase implements Cosmosish{ } // FIXME: The calculation of lowerTick and upperTick is not correct for the case where price is less than 1 - const lowerTick = findTickForPrice(req.lowerPrice!, pool.exponentAtPriceOne, pool.tickSpacing, true) // pool.currentTick, - const upperTick = findTickForPrice(req.upperPrice!, pool.exponentAtPriceOne, pool.tickSpacing, false) + const lowerTick = calculatePriceToTick(req.lowerPrice!, pool.exponentAtPriceOne, pool.tickSpacing, true) // pool.currentTick, + const upperTick = calculatePriceToTick(req.upperPrice!, pool.exponentAtPriceOne, pool.tickSpacing, false) + + console.log('lowerTick', lowerTick) + console.log('upperTick', upperTick) var tokenMinAmount0_final = tokenMinAmount0.toString() var tokenMinAmount1_final = tokenMinAmount1.toString() diff --git a/src/chains/osmosis/osmosis.utils.ts b/src/chains/osmosis/osmosis.utils.ts index b54d387d0a..2aaab0ee9c 100755 --- a/src/chains/osmosis/osmosis.utils.ts +++ b/src/chains/osmosis/osmosis.utils.ts @@ -93,3 +93,58 @@ export function findTickForPrice(desiredPriceString: string, exponentAtPriceOne: return returnTick.toString() } + +export function calculatePriceToTick(desiredPriceString: string, exponentAtPriceOne: number, tickSpacing: number, is_lowerBound: boolean): string { + console.log(`Inputs: desiredPriceString=${desiredPriceString}, exponentAtPriceOne=${exponentAtPriceOne}, tickSpacing=${tickSpacing}, is_lowerBound=${is_lowerBound}`); + + const desiredPrice = new BigNumber(desiredPriceString) + const exponent = new BigNumber(exponentAtPriceOne); + const geometricExponentIncrementDistanceInTicks = new BigNumber(9).multipliedBy(new BigNumber(10).exponentiatedBy(exponent.multipliedBy(-1))) + + console.log(`Initial calculations: desiredPrice=${desiredPrice}, exponent=${exponent}, geometricExponentIncrementDistanceInTicks=${geometricExponentIncrementDistanceInTicks}`); + + let currentPrice = new BigNumber(1); + let ticksPassed = new BigNumber(0); + let exponentAtCurrentTick = exponent; + let currentAdditiveIncrementInTicks = new BigNumber(10).exponentiatedBy(exponent) + + if (desiredPrice.gt(new BigNumber(1))) { + while (currentPrice.lt(desiredPrice)) { + currentAdditiveIncrementInTicks = new BigNumber(10).exponentiatedBy(exponentAtCurrentTick); + const maxPriceForCurrentAdditiveIncrementInTicks = geometricExponentIncrementDistanceInTicks.multipliedBy(currentAdditiveIncrementInTicks); + currentPrice = currentPrice.plus(maxPriceForCurrentAdditiveIncrementInTicks); + exponentAtCurrentTick = exponentAtCurrentTick.plus(1); + ticksPassed = ticksPassed.plus(geometricExponentIncrementDistanceInTicks); + + console.log(`Loop (desiredPrice > 1): currentPrice=${currentPrice}, exponentAtCurrentTick=${exponentAtCurrentTick}, ticksPassed=${ticksPassed}`); + } + } else { + exponentAtCurrentTick = exponent.minus(1); + while (currentPrice.gt(desiredPrice)) { + currentAdditiveIncrementInTicks = new BigNumber(10).exponentiatedBy(exponentAtCurrentTick); + const maxPriceForCurrentAdditiveIncrementInTicks = geometricExponentIncrementDistanceInTicks.multipliedBy(currentAdditiveIncrementInTicks); + currentPrice = currentPrice.minus(maxPriceForCurrentAdditiveIncrementInTicks); + exponentAtCurrentTick = exponentAtCurrentTick.minus(1); + ticksPassed = ticksPassed.minus(geometricExponentIncrementDistanceInTicks); + + console.log(`Loop (desiredPrice <= 1): currentPrice=${currentPrice}, exponentAtCurrentTick=${exponentAtCurrentTick}, ticksPassed=${ticksPassed}`); + } + } + + const ticksToBeFulfilledByExponentAtCurrentTick = desiredPrice.minus(currentPrice).dividedBy(currentAdditiveIncrementInTicks); + console.log(`Ticks to be fulfilled by current exponent: ${ticksToBeFulfilledByExponentAtCurrentTick}`); + + const tickIndex = ticksPassed.plus(ticksToBeFulfilledByExponentAtCurrentTick); + console.log(`Tick index: ${tickIndex}`); + + let returnTick = new BigNumber(0); + if (is_lowerBound){ + returnTick = tickIndex.dividedBy(tickSpacing).integerValue(BigNumber.ROUND_DOWN).multipliedBy(tickSpacing) + } + else{ + returnTick = tickIndex.dividedBy(tickSpacing).integerValue(BigNumber.ROUND_CEIL).multipliedBy(tickSpacing) + } + + console.log(`Final calculations: tickIndex=${tickIndex}, returnTick=${BigInt(returnTick.toNumber()).toString()}`); + return BigInt(returnTick.toNumber()).toString(); +} \ No newline at end of file