From 564a240684e5a652e113447c558bd856f392f2fa Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 01:04:10 -0400 Subject: [PATCH 01/14] perf: convert ticks to int64 --- x/concentrated-liquidity/export_internal.go | 11 - x/concentrated-liquidity/export_test.go | 10 +- x/concentrated-liquidity/fees_test.go | 7 +- x/concentrated-liquidity/keeper_test.go | 4 +- x/concentrated-liquidity/lp.go | 2 +- x/concentrated-liquidity/math/tick.go | 94 ++++---- x/concentrated-liquidity/math/tick_test.go | 216 +++++++++--------- x/concentrated-liquidity/model/pool.go | 2 +- x/concentrated-liquidity/model/pool_test.go | 8 +- x/concentrated-liquidity/swaps.go | 82 +++---- x/concentrated-liquidity/swaps_test.go | 118 +++++----- .../swapstrategy/one_for_zero.go | 10 +- .../swapstrategy/swap_strategy.go | 4 +- .../swapstrategy/zero_for_one.go | 10 +- x/concentrated-liquidity/tick.go | 21 +- x/concentrated-liquidity/tick_test.go | 22 +- x/concentrated-liquidity/types/constants.go | 8 +- 17 files changed, 309 insertions(+), 320 deletions(-) delete mode 100644 x/concentrated-liquidity/export_internal.go diff --git a/x/concentrated-liquidity/export_internal.go b/x/concentrated-liquidity/export_internal.go deleted file mode 100644 index 4eb7cb713a4..00000000000 --- a/x/concentrated-liquidity/export_internal.go +++ /dev/null @@ -1,11 +0,0 @@ -package concentrated_liquidity - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/math" -) - -func TickToSqrtPrice(tickIndex sdk.Int) (price sdk.Dec, sqrtPrice sdk.Dec, err error) { - return math.TickToSqrtPrice(tickIndex) -} diff --git a/x/concentrated-liquidity/export_test.go b/x/concentrated-liquidity/export_test.go index 4ef0a24224a..ce1058de969 100644 --- a/x/concentrated-liquidity/export_test.go +++ b/x/concentrated-liquidity/export_test.go @@ -51,7 +51,7 @@ func (k Keeper) SendCoinsBetweenPoolAndUser(ctx sdk.Context, denom0, denom1 stri return k.sendCoinsBetweenPoolAndUser(ctx, denom0, denom1, amount0, amount1, sender, receiver) } -func (k Keeper) CalcInAmtGivenOutInternal(ctx sdk.Context, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { +func (k Keeper) CalcInAmtGivenOutInternal(ctx sdk.Context, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick int64, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { return k.calcInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, swapFee, priceLimit, poolId) } @@ -62,7 +62,7 @@ func (k Keeper) SwapOutAmtGivenIn( tokenIn sdk.Coin, tokenOutDenom string, swapFee sdk.Dec, - priceLimit sdk.Dec) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) { + priceLimit sdk.Dec) (calcTokenIn, calcTokenOut sdk.Coin, currentTick int64, liquidity, sqrtPrice sdk.Dec, err error) { return k.swapOutAmtGivenIn(ctx, sender, pool, tokenIn, tokenOutDenom, swapFee, priceLimit) } @@ -74,11 +74,11 @@ func (k Keeper) ComputeOutAmtGivenIn( swapFee sdk.Dec, priceLimit sdk.Dec, -) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) { +) (calcTokenIn, calcTokenOut sdk.Coin, currentTick int64, liquidity, sqrtPrice sdk.Dec, err error) { return k.computeOutAmtGivenIn(ctx, poolId, tokenInMin, tokenOutDenom, swapFee, priceLimit) } -func (k *Keeper) SwapInAmtGivenOut(ctx sdk.Context, sender sdk.AccAddress, pool types.ConcentratedPoolExtension, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) { +func (k *Keeper) SwapInAmtGivenOut(ctx sdk.Context, sender sdk.AccAddress, pool types.ConcentratedPoolExtension, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec) (calcTokenIn, calcTokenOut sdk.Coin, currentTick int64, liquidity, sqrtPrice sdk.Dec, err error) { return k.swapInAmtGivenOut(ctx, sender, pool, desiredTokenOut, tokenInDenom, swapFee, priceLimit) } @@ -281,7 +281,7 @@ func (k Keeper) GetAllPositions(ctx sdk.Context) ([]model.Position, error) { return k.getAllPositions(ctx) } -func (k Keeper) UpdatePoolForSwap(ctx sdk.Context, pool types.ConcentratedPoolExtension, sender sdk.AccAddress, tokenIn sdk.Coin, tokenOut sdk.Coin, newCurrentTick sdk.Int, newLiquidity sdk.Dec, newSqrtPrice sdk.Dec) error { +func (k Keeper) UpdatePoolForSwap(ctx sdk.Context, pool types.ConcentratedPoolExtension, sender sdk.AccAddress, tokenIn sdk.Coin, tokenOut sdk.Coin, newCurrentTick int64, newLiquidity sdk.Dec, newSqrtPrice sdk.Dec) error { return k.updatePoolForSwap(ctx, pool, sender, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice) } diff --git a/x/concentrated-liquidity/fees_test.go b/x/concentrated-liquidity/fees_test.go index 0cb7231928a..295184239c6 100644 --- a/x/concentrated-liquidity/fees_test.go +++ b/x/concentrated-liquidity/fees_test.go @@ -489,8 +489,7 @@ func (suite *KeeperTestSuite) TestGetInitialFeeGrowthOppositeDirectionOfLastTrav validPoolId = 1 ) - initialPoolTickInt, err := math.PriceToTickRoundDown(DefaultAmt1.ToDec().Quo(DefaultAmt0.ToDec()), DefaultTickSpacing) - initialPoolTick := initialPoolTickInt.Int64() + initialPoolTick, err := math.PriceToTickRoundDown(DefaultAmt1.ToDec().Quo(DefaultAmt0.ToDec()), DefaultTickSpacing) suite.Require().NoError(err) tests := map[string]struct { @@ -1580,12 +1579,12 @@ func (s *KeeperTestSuite) CollectAndAssertFees(ctx sdk.Context, poolId uint64, t // Claim consecutive range position fees across two of four accounts for i := 0; i < positions.numConsecutive; i++ { - totalFeesCollected = s.collectFeesAndCheckInvariance(ctx, i, DefaultExponentConsecutivePositionLowerTick.Int64(), DefaultExponentConsecutivePositionUpperTick.Int64(), positionIds[2][i], totalFeesCollected, expectedFeeDenoms[2], activeTicks) + totalFeesCollected = s.collectFeesAndCheckInvariance(ctx, i, DefaultExponentConsecutivePositionLowerTick, DefaultExponentConsecutivePositionUpperTick, positionIds[2][i], totalFeesCollected, expectedFeeDenoms[2], activeTicks) } // Claim overlapping range position fees on one of four accounts for i := 0; i < positions.numOverlapping; i++ { - totalFeesCollected = s.collectFeesAndCheckInvariance(ctx, i, DefaultExponentOverlappingPositionLowerTick.Int64(), DefaultExponentOverlappingPositionUpperTick.Int64(), positionIds[3][i], totalFeesCollected, expectedFeeDenoms[3], activeTicks) + totalFeesCollected = s.collectFeesAndCheckInvariance(ctx, i, DefaultExponentOverlappingPositionLowerTick, DefaultExponentOverlappingPositionUpperTick, positionIds[3][i], totalFeesCollected, expectedFeeDenoms[3], activeTicks) } // Define error tolerance diff --git a/x/concentrated-liquidity/keeper_test.go b/x/concentrated-liquidity/keeper_test.go index 0abfb7885f5..14e541bd4bc 100644 --- a/x/concentrated-liquidity/keeper_test.go +++ b/x/concentrated-liquidity/keeper_test.go @@ -113,12 +113,12 @@ func (s *KeeperTestSuite) SetupFullRangePositionAcc(poolId uint64, owner sdk.Acc } func (s *KeeperTestSuite) SetupConsecutiveRangePositionAcc(poolId uint64, owner sdk.AccAddress) uint64 { - _, positionId := s.SetupPosition(poolId, owner, DefaultCoins, DefaultExponentConsecutivePositionLowerTick.Int64(), DefaultExponentConsecutivePositionUpperTick.Int64(), s.Ctx.BlockTime()) + _, positionId := s.SetupPosition(poolId, owner, DefaultCoins, DefaultExponentConsecutivePositionLowerTick, DefaultExponentConsecutivePositionUpperTick, s.Ctx.BlockTime()) return positionId } func (s *KeeperTestSuite) SetupOverlappingRangePositionAcc(poolId uint64, owner sdk.AccAddress) uint64 { - _, positionId := s.SetupPosition(poolId, owner, DefaultCoins, DefaultExponentOverlappingPositionLowerTick.Int64(), DefaultExponentOverlappingPositionUpperTick.Int64(), s.Ctx.BlockTime()) + _, positionId := s.SetupPosition(poolId, owner, DefaultCoins, DefaultExponentOverlappingPositionLowerTick, DefaultExponentOverlappingPositionUpperTick, s.Ctx.BlockTime()) return positionId } diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 30dbec38026..388aef77b64 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -438,7 +438,7 @@ func (k Keeper) initializeInitialPositionForPool(ctx sdk.Context, pool types.Con // In such a case, we do not want to round the sqrt price to 100_000_000 X/Y, but rather // let it float within the possible tick range. pool.SetCurrentSqrtPrice(initialCurSqrtPrice) - pool.SetCurrentTick(initialTick) + pool.SetCurrentTick(sdk.NewInt(initialTick)) err = k.setPool(ctx, pool) if err != nil { return err diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 45972a17dba..50623ad256c 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -21,11 +21,11 @@ func TicksToSqrtPrice(lowerTick, upperTick int64) (sdk.Dec, sdk.Dec, sdk.Dec, sd if lowerTick >= upperTick { return sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, types.InvalidLowerUpperTickError{LowerTick: lowerTick, UpperTick: upperTick} } - priceUpperTick, sqrtPriceUpperTick, err := TickToSqrtPrice(sdk.NewInt(upperTick)) + priceUpperTick, sqrtPriceUpperTick, err := TickToSqrtPrice(upperTick) if err != nil { return sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, err } - priceLowerTick, sqrtPriceLowerTick, err := TickToSqrtPrice(sdk.NewInt(lowerTick)) + priceLowerTick, sqrtPriceLowerTick, err := TickToSqrtPrice(lowerTick) if err != nil { return sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, sdk.Dec{}, err } @@ -35,7 +35,7 @@ func TicksToSqrtPrice(lowerTick, upperTick int64) (sdk.Dec, sdk.Dec, sdk.Dec, sd // TickToSqrtPrice returns the sqrtPrice given a tickIndex // If tickIndex is zero, the function returns sdk.OneDec(). // It is the combination of calling TickToPrice followed by Sqrt. -func TickToSqrtPrice(tickIndex sdk.Int) (sdk.Dec, sdk.Dec, error) { +func TickToSqrtPrice(tickIndex int64) (sdk.Dec, sdk.Dec, error) { price, err := TickToPrice(tickIndex) if err != nil { return sdk.Dec{}, sdk.Dec{}, err @@ -51,33 +51,33 @@ func TickToSqrtPrice(tickIndex sdk.Int) (sdk.Dec, sdk.Dec, error) { // TickToPrice returns the price given a tickIndex // If tickIndex is zero, the function returns sdk.OneDec(). -func TickToPrice(tickIndex sdk.Int) (price sdk.Dec, err error) { - if tickIndex.IsZero() { +func TickToPrice(tickIndex int64) (price sdk.Dec, err error) { + if tickIndex == 0 { return sdk.OneDec(), nil } // The formula is as follows: geometricExponentIncrementDistanceInTicks = 9 * 10**(-exponentAtPriceOne) // Due to sdk.Power restrictions, if the resulting power is negative, we take 9 * (1/10**exponentAtPriceOne) exponentAtPriceOne := types.ExponentAtPriceOne - geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne.Neg())) + geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne * -1)).TruncateInt64() // Check that the tick index is between min and max value - if tickIndex.LT(sdk.NewInt(types.MinTick)) { + if tickIndex < types.MinTick { return sdk.Dec{}, types.TickIndexMinimumError{MinTick: types.MinTick} } - if tickIndex.GT(sdk.NewInt(types.MaxTick)) { + if tickIndex > types.MaxTick { return sdk.Dec{}, types.TickIndexMaximumError{MaxTick: types.MaxTick} } // Use floor division to determine what the geometricExponent is now (the delta) - geometricExponentDelta := tickIndex.ToDec().QuoIntMut(geometricExponentIncrementDistanceInTicks.TruncateInt()).TruncateInt() + geometricExponentDelta := tickIndex / geometricExponentIncrementDistanceInTicks // Calculate the exponentAtCurrentTick from the starting exponentAtPriceOne and the geometricExponentDelta - exponentAtCurrentTick := exponentAtPriceOne.Add(geometricExponentDelta) - if tickIndex.IsNegative() { + exponentAtCurrentTick := exponentAtPriceOne + geometricExponentDelta + if tickIndex < 0 { // We must decrement the exponentAtCurrentTick when entering the negative tick range in order to constantly step up in precision when going further down in ticks // Otherwise, from tick 0 to tick -(geometricExponentIncrementDistanceInTicks), we would use the same exponent as the exponentAtPriceOne - exponentAtCurrentTick = exponentAtCurrentTick.Sub(sdk.OneInt()) + exponentAtCurrentTick = exponentAtCurrentTick - 1 } // Knowing what our exponentAtCurrentTick is, we can then figure out what power of 10 this exponent corresponds to @@ -85,10 +85,10 @@ func TickToPrice(tickIndex sdk.Int) (price sdk.Dec, err error) { currentAdditiveIncrementInTicks := powTenBigDec(exponentAtCurrentTick) // Now, starting at the minimum tick of the current increment, we calculate how many ticks in the current geometricExponent we have passed - numAdditiveTicks := tickIndex.ToDec().Sub(geometricExponentDelta.ToDec().Mul(geometricExponentIncrementDistanceInTicks)) + numAdditiveTicks := tickIndex - (geometricExponentDelta * geometricExponentIncrementDistanceInTicks) // Finally, we can calculate the price - price = PowTenInternal(geometricExponentDelta).Add(osmomath.BigDecFromSDKDec(numAdditiveTicks).Mul(currentAdditiveIncrementInTicks).SDKDec()) + price = PowTenInternal(geometricExponentDelta).Add(osmomath.NewBigDec(numAdditiveTicks).Mul(currentAdditiveIncrementInTicks).SDKDec()) if price.GT(types.MaxSpotPrice) || price.LT(types.MinSpotPrice) { return sdk.Dec{}, types.PriceBoundError{ProvidedPrice: price, MinSpotPrice: types.MinSpotPrice, MaxSpotPrice: types.MaxSpotPrice} @@ -98,17 +98,17 @@ func TickToPrice(tickIndex sdk.Int) (price sdk.Dec, err error) { // PriceToTick takes a price and returns the corresponding tick index assuming // tick spacing of 1. -func PriceToTick(price sdk.Dec) (sdk.Int, error) { +func PriceToTick(price sdk.Dec) (int64, error) { if price.Equal(sdk.OneDec()) { - return sdk.ZeroInt(), nil + return 0, nil } if price.IsNegative() { - return sdk.Int{}, fmt.Errorf("price must be greater than zero") + return 0, fmt.Errorf("price must be greater than zero") } if price.GT(types.MaxSpotPrice) || price.LT(types.MinSpotPrice) { - return sdk.Int{}, types.PriceBoundError{ProvidedPrice: price, MinSpotPrice: types.MinSpotPrice, MaxSpotPrice: types.MaxSpotPrice} + return 0, types.PriceBoundError{ProvidedPrice: price, MinSpotPrice: types.MinSpotPrice, MaxSpotPrice: types.MaxSpotPrice} } // Determine the tick that corresponds to the price @@ -120,23 +120,27 @@ func PriceToTick(price sdk.Dec) (sdk.Int, error) { // PriceToTickRoundDown takes a price and returns the corresponding tick index. // If tickSpacing is provided, the tick index will be rounded down to the nearest multiple of tickSpacing. -func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (sdk.Int, error) { +func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (int64, error) { tickIndex, err := PriceToTick(price) if err != nil { - return sdk.Int{}, err + return 0, err } // Round the tick index down to the nearest tick spacing if the tickIndex is in between authorized tick values - tickSpacingInt := sdk.NewIntFromUint64(tickSpacing) - tickIndexModulus := tickIndex.Mod(tickSpacingInt) - if !tickIndexModulus.Equal(sdk.ZeroInt()) { - tickIndex = tickIndex.Sub(tickIndexModulus) + // Note that this is Euclidean modulus. + tickIndexModulus := tickIndex % int64(tickSpacing) + if tickIndexModulus < 0 { + tickIndexModulus += int64(tickSpacing) + } + + if tickIndexModulus != 0 { + tickIndex = tickIndex - tickIndexModulus } // Defense-in-depth check to ensure that the tick index is within the authorized range // Should never get here. - if tickIndex.GT(sdk.NewInt(types.MaxTick)) || tickIndex.LT(sdk.NewInt(types.MinTick)) { - return sdk.Int{}, types.TickIndexNotWithinBoundariesError{ActualTick: tickIndex.Int64(), MinTick: types.MinTick, MaxTick: types.MaxTick} + if tickIndex > types.MaxTick || tickIndex < types.MinTick { + return 0, types.TickIndexNotWithinBoundariesError{ActualTick: tickIndex, MinTick: types.MinTick, MaxTick: types.MaxTick} } return tickIndex, nil @@ -144,31 +148,31 @@ func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (sdk.Int, error) { // powTen treats negative exponents as 1/(10**|exponent|) instead of 10**-exponent // This is because the sdk.Dec.Power function does not support negative exponents -func PowTenInternal(exponent sdk.Int) sdk.Dec { - if exponent.GTE(sdk.ZeroInt()) { - return sdkTenDec.Power(exponent.Uint64()) +func PowTenInternal(exponent int64) sdk.Dec { + if exponent > 0 { + return sdkTenDec.Power(uint64(exponent)) } - return sdk.OneDec().Quo(sdkTenDec.Power(exponent.Abs().Uint64())) + return sdk.OneDec().Quo(sdkTenDec.Power(uint64(exponent * -1))) } -func powTenBigDec(exponent sdk.Int) osmomath.BigDec { - if exponent.GTE(sdk.ZeroInt()) { - return osmomath.NewBigDec(10).PowerInteger(exponent.Uint64()) +func powTenBigDec(exponent int64) osmomath.BigDec { + if exponent > 0 { + return osmomath.NewBigDec(10).PowerInteger(uint64(exponent)) } - return osmomath.OneDec().Quo(osmomath.NewBigDec(10).PowerInteger(exponent.Abs().Uint64())) + return osmomath.OneDec().Quo(osmomath.NewBigDec(10).PowerInteger(uint64(exponent * -1))) } // CalculatePriceToTick takes in a price and returns the corresponding tick index. // This function does not take into consideration tick spacing. -func CalculatePriceToTick(price sdk.Dec) (tickIndex sdk.Int) { +func CalculatePriceToTick(price sdk.Dec) (tickIndex int64) { // The formula is as follows: geometricExponentIncrementDistanceInTicks = 9 * 10**(-exponentAtPriceOne) // Due to sdk.Power restrictions, if the resulting power is negative, we take 9 * (1/10**exponentAtPriceOne) exponentAtPriceOne := types.ExponentAtPriceOne - geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne.Neg())) + geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne * -1)).TruncateInt64() // Initialize the current price to 1, the current precision to exponentAtPriceOne, and the number of ticks passed to 0 currentPrice := sdk.OneDec() - ticksPassed := sdk.ZeroInt() + ticksPassed := int64(0) exponentAtCurrentTick := exponentAtPriceOne @@ -183,21 +187,21 @@ func CalculatePriceToTick(price sdk.Dec) (tickIndex sdk.Int) { if price.GT(sdk.OneDec()) { for currentPrice.LT(price) { currentAdditiveIncrementInTicks = powTenBigDec(exponentAtCurrentTick) - maxPriceForCurrentAdditiveIncrementInTicks := osmomath.BigDecFromSDKDec(geometricExponentIncrementDistanceInTicks).Mul(currentAdditiveIncrementInTicks) + maxPriceForCurrentAdditiveIncrementInTicks := osmomath.NewBigDec(geometricExponentIncrementDistanceInTicks).Mul(currentAdditiveIncrementInTicks) currentPrice = currentPrice.Add(maxPriceForCurrentAdditiveIncrementInTicks.SDKDec()) - exponentAtCurrentTick = exponentAtCurrentTick.Add(sdk.OneInt()) - ticksPassed = ticksPassed.Add(geometricExponentIncrementDistanceInTicks.TruncateInt()) + exponentAtCurrentTick = exponentAtCurrentTick + 1 + ticksPassed = ticksPassed + geometricExponentIncrementDistanceInTicks } } else { // We must decrement the exponentAtCurrentTick by one when traversing negative ticks in order to constantly step up in precision when going further down in ticks // Otherwise, from tick 0 to tick -(geometricExponentIncrementDistanceInTicks), we would use the same exponent as the exponentAtPriceOne - exponentAtCurrentTick := exponentAtPriceOne.Sub(sdk.OneInt()) + exponentAtCurrentTick := exponentAtPriceOne - 1 for currentPrice.GT(price) { currentAdditiveIncrementInTicks = powTenBigDec(exponentAtCurrentTick) - maxPriceForCurrentAdditiveIncrementInTicks := osmomath.BigDecFromSDKDec(geometricExponentIncrementDistanceInTicks).Mul(currentAdditiveIncrementInTicks) + maxPriceForCurrentAdditiveIncrementInTicks := osmomath.NewBigDec(geometricExponentIncrementDistanceInTicks).Mul(currentAdditiveIncrementInTicks) currentPrice = currentPrice.Sub(maxPriceForCurrentAdditiveIncrementInTicks.SDKDec()) - exponentAtCurrentTick = exponentAtCurrentTick.Sub(sdk.OneInt()) - ticksPassed = ticksPassed.Sub(geometricExponentIncrementDistanceInTicks.TruncateInt()) + exponentAtCurrentTick = exponentAtCurrentTick - 1 + ticksPassed = ticksPassed - geometricExponentIncrementDistanceInTicks } } @@ -205,6 +209,6 @@ func CalculatePriceToTick(price sdk.Dec) (tickIndex sdk.Int) { ticksToBeFulfilledByExponentAtCurrentTick := osmomath.BigDecFromSDKDec(price.Sub(currentPrice)).Quo(currentAdditiveIncrementInTicks) // Finally, add the ticks we have passed from the completed geometricExponent values, as well as the ticks we have passed in the current geometricExponent value - tickIndex = ticksPassed.Add(ticksToBeFulfilledByExponentAtCurrentTick.SDKDec().RoundInt()) + tickIndex = ticksPassed + ticksToBeFulfilledByExponentAtCurrentTick.SDKDec().RoundInt64() return tickIndex } diff --git a/x/concentrated-liquidity/math/tick_test.go b/x/concentrated-liquidity/math/tick_test.go index 18eb73bd0f3..e0b4e9e47d8 100644 --- a/x/concentrated-liquidity/math/tick_test.go +++ b/x/concentrated-liquidity/math/tick_test.go @@ -14,9 +14,9 @@ const ( var ( // spot price - (10^(spot price exponent - 6 - 1)) // Note we get spot price exponent by counting the number of digits in the max spot price and subtracting 1. - closestPriceBelowMaxPriceDefaultTickSpacing = types.MaxSpotPrice.Sub(sdk.NewDec(10).PowerMut(uint64(len(types.MaxSpotPrice.TruncateInt().String()) - 1 - int(types.ExponentAtPriceOne.Neg().Int64()) - 1))) + closestPriceBelowMaxPriceDefaultTickSpacing = types.MaxSpotPrice.Sub(sdk.NewDec(10).PowerMut(uint64(len(types.MaxSpotPrice.TruncateInt().String()) - 1 - int(types.ExponentAtPriceOne*-1) - 1))) // min tick + 10 ^ -expoentAtPriceOne - closestTickAboveMinPriceDefaultTickSpacing = sdk.NewInt(types.MinTick).Add(sdk.NewInt(10).ToDec().Power(types.ExponentAtPriceOne.Neg().Uint64()).TruncateInt()) + closestTickAboveMinPriceDefaultTickSpacing = sdk.NewInt(types.MinTick).Add(sdk.NewInt(10).ToDec().Power(uint64(types.ExponentAtPriceOne * -1)).TruncateInt()) ) // use following equations to test testing vectors using sage @@ -29,152 +29,152 @@ var ( // (numAdditiveTicks(tickIndex, exponentAtPriceOne) * currentAdditiveIncrementInTicks(tickIndex, exponentAtPriceOne)) func (suite *ConcentratedMathTestSuite) TestTickToSqrtPrice() { testCases := map[string]struct { - tickIndex sdk.Int + tickIndex int64 expectedPrice sdk.Dec expectedError error }{ "Ten billionths cent increments at the millionths place: 1": { - tickIndex: sdk.NewInt(-51630100), + tickIndex: -51630100, expectedPrice: sdk.MustNewDecFromStr("0.0000033699"), }, "Ten billionths cent increments at the millionths place: 2": { - tickIndex: sdk.NewInt(-51630000), + tickIndex: -51630000, expectedPrice: sdk.MustNewDecFromStr("0.0000033700"), }, "One millionths cent increments at the hundredths place: 1": { - tickIndex: sdk.NewInt(-11999800), + tickIndex: -11999800, expectedPrice: sdk.MustNewDecFromStr("0.070002"), }, "One millionths cent increments at the hundredths place: 2": { - tickIndex: sdk.NewInt(-11999700), + tickIndex: -11999700, expectedPrice: sdk.MustNewDecFromStr("0.070003"), }, "One hundred thousandth cent increments at the tenths place: 1": { - tickIndex: sdk.NewInt(-999800), + tickIndex: -999800, expectedPrice: sdk.MustNewDecFromStr("0.90002"), }, "One hundred thousandth cent increments at the tenths place: 2": { - tickIndex: sdk.NewInt(-999700), + tickIndex: -999700, expectedPrice: sdk.MustNewDecFromStr("0.90003"), }, "One ten thousandth cent increments at the ones place: 1": { - tickIndex: sdk.NewInt(1000000), + tickIndex: 1000000, expectedPrice: sdk.MustNewDecFromStr("2"), }, "One dollar increments at the ten thousands place: 2": { - tickIndex: sdk.NewInt(1000100), + tickIndex: 1000100, expectedPrice: sdk.MustNewDecFromStr("2.0001"), }, "One thousandth cent increments at the tens place: 1": { - tickIndex: sdk.NewInt(9200100), + tickIndex: 9200100, expectedPrice: sdk.MustNewDecFromStr("12.001"), }, "One thousandth cent increments at the tens place: 2": { - tickIndex: sdk.NewInt(9200200), + tickIndex: 9200200, expectedPrice: sdk.MustNewDecFromStr("12.002"), }, "One cent increments at the hundreds place: 1": { - tickIndex: sdk.NewInt(18320100), + tickIndex: 18320100, expectedPrice: sdk.MustNewDecFromStr("132.01"), }, "One cent increments at the hundreds place: 2": { - tickIndex: sdk.NewInt(18320200), + tickIndex: 18320200, expectedPrice: sdk.MustNewDecFromStr("132.02"), }, "Ten cent increments at the thousands place: 1": { - tickIndex: sdk.NewInt(27732100), + tickIndex: 27732100, expectedPrice: sdk.MustNewDecFromStr("1732.10"), }, "Ten cent increments at the thousands place: 2": { - tickIndex: sdk.NewInt(27732200), + tickIndex: 27732200, expectedPrice: sdk.MustNewDecFromStr("1732.20"), }, "Dollar increments at the ten thousands place: 1": { - tickIndex: sdk.NewInt(36073200), + tickIndex: 36073200, expectedPrice: sdk.MustNewDecFromStr("10732"), }, "Dollar increments at the ten thousands place: 2": { - tickIndex: sdk.NewInt(36073300), + tickIndex: 36073300, expectedPrice: sdk.MustNewDecFromStr("10733"), }, "Max tick and min k": { - tickIndex: sdk.NewInt(342000000), + tickIndex: 342000000, expectedPrice: types.MaxSpotPrice, }, "Min tick and max k": { - tickIndex: sdk.NewInt(-162000000), + tickIndex: -162000000, expectedPrice: types.MinSpotPrice, }, "error: tickIndex less than minimum": { - tickIndex: sdk.NewInt(-162000000 - 1), + tickIndex: -162000000 - 1, expectedError: types.TickIndexMinimumError{MinTick: -162000000}, }, "error: tickIndex greater than maximum": { - tickIndex: sdk.NewInt(342000000 + 1), + tickIndex: 342000000 + 1, expectedError: types.TickIndexMaximumError{MaxTick: 342000000}, }, "Gyen <> USD, tick -20594000 -> price 0.0074060": { - tickIndex: sdk.NewInt(-20594000), + tickIndex: -20594000, expectedPrice: sdk.MustNewDecFromStr("0.007406000000000000"), }, "Gyen <> USD, tick -20594000 + 100 -> price 0.0074061": { - tickIndex: sdk.NewInt(-20593900), + tickIndex: -20593900, expectedPrice: sdk.MustNewDecFromStr("0.007406100000000000"), }, "Spell <> USD, tick -29204000 -> price 0.00077960": { - tickIndex: sdk.NewInt(-29204000), + tickIndex: -29204000, expectedPrice: sdk.MustNewDecFromStr("0.000779600000000000"), }, "Spell <> USD, tick -29204000 + 100 -> price 0.00077961": { - tickIndex: sdk.NewInt(-29203900), + tickIndex: -29203900, expectedPrice: sdk.MustNewDecFromStr("0.000779610000000000"), }, "Atom <> Osmo, tick -12150000 -> price 0.068500": { - tickIndex: sdk.NewInt(-12150000), + tickIndex: -12150000, expectedPrice: sdk.MustNewDecFromStr("0.068500000000000000"), }, "Atom <> Osmo, tick -12150000 + 100 -> price 0.068501": { - tickIndex: sdk.NewInt(-12149900), + tickIndex: -12149900, expectedPrice: sdk.MustNewDecFromStr("0.068501000000000000"), }, "Boot <> Osmo, tick 64576000 -> price 25760000": { - tickIndex: sdk.NewInt(64576000), + tickIndex: 64576000, expectedPrice: sdk.MustNewDecFromStr("25760000"), }, "Boot <> Osmo, tick 64576000 + 100 -> price 25760000": { - tickIndex: sdk.NewInt(64576100), + tickIndex: 64576100, expectedPrice: sdk.MustNewDecFromStr("25761000"), }, "BTC <> USD, tick 38035200 -> price 30352": { - tickIndex: sdk.NewInt(38035200), + tickIndex: 38035200, expectedPrice: sdk.MustNewDecFromStr("30352"), }, "BTC <> USD, tick 38035200 + 100 -> price 30353": { - tickIndex: sdk.NewInt(38035300), + tickIndex: 38035300, expectedPrice: sdk.MustNewDecFromStr("30353"), }, "SHIB <> USD, tick -44821000 -> price 0.000011790": { - tickIndex: sdk.NewInt(-44821000), + tickIndex: -44821000, expectedPrice: sdk.MustNewDecFromStr("0.00001179"), }, "SHIB <> USD, tick -44821100 + 100 -> price 0.000011791": { - tickIndex: sdk.NewInt(-44820900), + tickIndex: -44820900, expectedPrice: sdk.MustNewDecFromStr("0.000011791"), }, "ETH <> BTC, tick -12104000 -> price 0.068960": { - tickIndex: sdk.NewInt(-12104000), + tickIndex: -12104000, expectedPrice: sdk.MustNewDecFromStr("0.068960"), }, "ETH <> BTC, tick -121044000 + 1 -> price 0.068961": { - tickIndex: sdk.NewInt(-12103900), + tickIndex: -12103900, expectedPrice: sdk.MustNewDecFromStr("0.068961"), }, "one tick spacing interval smaller than max sqrt price, max tick neg six - 100 -> one tick spacing interval smaller than max sqrt price": { - tickIndex: sdk.NewInt(types.MaxTick).Sub(sdk.NewInt(100)), + tickIndex: types.MaxTick - 100, expectedPrice: sdk.MustNewDecFromStr("99999000000000000000000000000000000000"), }, "max sqrt price, max tick neg six -> max spot price": { - tickIndex: sdk.NewInt(types.MaxTick), + tickIndex: types.MaxTick, expectedPrice: types.MaxSpotPrice, }, } @@ -279,71 +279,71 @@ func (suite *ConcentratedMathTestSuite) TestPriceToTick() { testCases := map[string]struct { price sdk.Dec - tickExpected string + tickExpected int64 }{ "BTC <> USD, tick 38035200 -> price 30352": { price: sdk.MustNewDecFromStr("30352"), - tickExpected: "38035200", + tickExpected: 38035200, }, "BTC <> USD, tick 38035300 + 100 -> price 30353": { price: sdk.MustNewDecFromStr("30353"), - tickExpected: "38035300", + tickExpected: 38035300, }, "SHIB <> USD, tick -44821000 -> price 0.000011790": { price: sdk.MustNewDecFromStr("0.000011790"), - tickExpected: "-44821000", + tickExpected: -44821000, }, "SHIB <> USD, tick -44820900 -> price 0.000011791": { price: sdk.MustNewDecFromStr("0.000011791"), - tickExpected: "-44820900", + tickExpected: -44820900, }, "ETH <> BTC, tick -12104000 -> price 0.068960": { price: sdk.MustNewDecFromStr("0.068960"), - tickExpected: "-12104000", + tickExpected: -12104000, }, "ETH <> BTC, tick -12104000 + 100 -> price 0.068961": { price: sdk.MustNewDecFromStr("0.068961"), - tickExpected: "-12103900", + tickExpected: -12103900, }, "max sqrt price -1, max neg tick six - 100 -> max tick neg six - 100": { price: sdk.MustNewDecFromStr("99999000000000000000000000000000000000"), - tickExpected: sdk.NewInt(types.MaxTick - 100).String(), + tickExpected: types.MaxTick - 100, }, "max sqrt price, max tick neg six -> max spot price": { price: types.MaxSqrtPrice.Power(2), - tickExpected: sdk.NewInt(types.MaxTick).String(), + tickExpected: types.MaxTick, }, "Gyen <> USD, tick -20594000 -> price 0.0074060": { price: sdk.MustNewDecFromStr("0.007406"), - tickExpected: "-20594000", + tickExpected: -20594000, }, "Gyen <> USD, tick -20594000 + 100 -> price 0.0074061": { price: sdk.MustNewDecFromStr("0.0074061"), - tickExpected: "-20593900", + tickExpected: -20593900, }, "Spell <> USD, tick -29204000 -> price 0.00077960": { price: sdk.MustNewDecFromStr("0.0007796"), - tickExpected: "-29204000", + tickExpected: -29204000, }, "Spell <> USD, tick -29204000 + 100 -> price 0.00077961": { price: sdk.MustNewDecFromStr("0.00077961"), - tickExpected: "-29203900", + tickExpected: -29203900, }, "Atom <> Osmo, tick -12150000 -> price 0.068500": { price: sdk.MustNewDecFromStr("0.0685"), - tickExpected: "-12150000", + tickExpected: -12150000, }, "Atom <> Osmo, tick -12150000 + 100 -> price 0.068501": { price: sdk.MustNewDecFromStr("0.068501"), - tickExpected: "-12149900", + tickExpected: -12149900, }, "Boot <> Osmo, tick 64576000 -> price 25760000": { price: sdk.MustNewDecFromStr("25760000"), - tickExpected: "64576000", + tickExpected: 64576000, }, "Boot <> Osmo, tick 64576000 + 100 -> price 25761000": { price: sdk.MustNewDecFromStr("25761000"), - tickExpected: "64576100", + tickExpected: 64576100, }, } for name, tc := range testCases { @@ -356,8 +356,8 @@ func (suite *ConcentratedMathTestSuite) TestPriceToTick() { suite.Require().NoError(err) suite.Require().NoError(err1) - suite.Require().Equal(tc.tickExpected, tick.String()) - suite.Require().Equal(tc.tickExpected, tickRoundDown.String()) + suite.Require().Equal(tc.tickExpected, tick) + suite.Require().Equal(tc.tickExpected, tickRoundDown) }) } } @@ -366,57 +366,57 @@ func (suite *ConcentratedMathTestSuite) TestPriceToTickRoundDown() { testCases := map[string]struct { price sdk.Dec tickSpacing uint64 - tickExpected string + tickExpected int64 }{ "tick spacing 100, price of 1": { price: sdk.OneDec(), tickSpacing: defaultTickSpacing, - tickExpected: "0", + tickExpected: 0, }, "tick spacing 100, price of 1.000030, tick 30 -> 0": { price: sdk.MustNewDecFromStr("1.000030"), tickSpacing: defaultTickSpacing, - tickExpected: "0", + tickExpected: 0, }, "tick spacing 100, price of 0.9999970, tick -30 -> -100": { price: sdk.MustNewDecFromStr("0.9999970"), tickSpacing: defaultTickSpacing, - tickExpected: "-100", + tickExpected: -100, }, "tick spacing 50, price of 0.9999730, tick -270 -> -300": { price: sdk.MustNewDecFromStr("0.9999730"), tickSpacing: 50, - tickExpected: "-300", + tickExpected: -300, }, "tick spacing 100, MinSpotPrice, MinTick": { price: types.MinSpotPrice, tickSpacing: defaultTickSpacing, - tickExpected: sdk.NewInt(types.MinTick).String(), + tickExpected: types.MinTick, }, "tick spacing 100, Spot price one tick above min, one tick above min -> MinTick": { price: types.MinSpotPrice.Add(sdk.SmallestDec()), tickSpacing: defaultTickSpacing, - tickExpected: closestTickAboveMinPriceDefaultTickSpacing.String(), + tickExpected: closestTickAboveMinPriceDefaultTickSpacing.Int64(), }, "tick spacing 100, Spot price one tick below max, one tick below max -> MaxTick - 1": { price: closestPriceBelowMaxPriceDefaultTickSpacing, tickSpacing: defaultTickSpacing, - tickExpected: sdk.NewInt(types.MaxTick - 100).String(), + tickExpected: types.MaxTick - 100, }, "tick spacing 100, Spot price 100_000_050 -> 72000000": { price: sdk.NewDec(100_000_050), tickSpacing: defaultTickSpacing, - tickExpected: "72000000", + tickExpected: 72000000, }, "tick spacing 100, Spot price 100_000_051 -> 72000100 (rounded up to tick spacing)": { price: sdk.NewDec(100_000_051), tickSpacing: defaultTickSpacing, - tickExpected: "72000000", + tickExpected: 72000000, }, "tick spacing 1, Spot price 100_000_051 -> 72000001 no tick spacing rounding": { price: sdk.NewDec(100_000_051), tickSpacing: 1, - tickExpected: "72000001", + tickExpected: 72000001, }, } for name, tc := range testCases { @@ -426,7 +426,7 @@ func (suite *ConcentratedMathTestSuite) TestPriceToTickRoundDown() { tick, err := math.PriceToTickRoundDown(tc.price, tc.tickSpacing) suite.Require().NoError(err) - suite.Require().Equal(tc.tickExpected, tick.String()) + suite.Require().Equal(tc.tickExpected, tick) }) } } @@ -437,117 +437,117 @@ func (suite *ConcentratedMathTestSuite) TestTickToSqrtPricePriceToTick_InverseRe testCases := map[string]struct { price sdk.Dec truncatedPrice sdk.Dec - tickExpected string + tickExpected int64 }{ "50000 to tick": { price: sdk.MustNewDecFromStr("50000"), - tickExpected: "40000000", + tickExpected: 40000000, }, "5.01 to tick": { price: sdk.MustNewDecFromStr("5.01"), - tickExpected: "4010000", + tickExpected: 4010000, }, "50000.01 to tick": { price: sdk.MustNewDecFromStr("50000.01"), - tickExpected: "40000001", + tickExpected: 40000001, }, "0.090001 to tick": { price: sdk.MustNewDecFromStr("0.090001"), - tickExpected: "-9999900", + tickExpected: -9999900, }, "0.9998 to tick": { price: sdk.MustNewDecFromStr("0.9998"), - tickExpected: "-2000", + tickExpected: -2000, }, "53030 to tick": { price: sdk.MustNewDecFromStr("53030"), - tickExpected: "40303000", + tickExpected: 40303000, }, "max spot price": { price: types.MaxSpotPrice, - tickExpected: sdk.NewInt(types.MaxTick).String(), + tickExpected: types.MaxTick, }, "max spot price - smallest price delta given exponent at price one of -6": { // 37 - 6 is calculated by counting the exponent of max spot price and subtracting exponent at price one price: types.MaxSpotPrice.Sub(sdk.NewDec(10).PowerMut(37 - 6)), - tickExpected: sdk.NewInt(types.MaxTick).Sub(sdk.OneInt()).String(), // still max + tickExpected: types.MaxTick - 1, // still max }, "min spot price": { price: types.MinSpotPrice, - tickExpected: "-162000000", + tickExpected: -162000000, }, "smallest + min price increment": { price: sdk.MustNewDecFromStr("0.000000000000000002"), - tickExpected: "-161000000", + tickExpected: -161000000, }, "min price increment 10^1": { price: sdk.MustNewDecFromStr("0.000000000000000009"), - tickExpected: "-154000000", + tickExpected: -154000000, }, "smallest + min price increment 10^1": { price: sdk.MustNewDecFromStr("0.000000000000000010"), - tickExpected: "-153000000", + tickExpected: -153000000, }, "smallest + min price increment * 10^2": { price: sdk.MustNewDecFromStr("0.000000000000000100"), - tickExpected: "-144000000", + tickExpected: -144000000, }, "smallest + min price increment * 10^3": { price: sdk.MustNewDecFromStr("0.000000000000001000"), - tickExpected: "-135000000", + tickExpected: -135000000, }, "smallest + min price increment * 10^4": { price: sdk.MustNewDecFromStr("0.000000000000010000"), - tickExpected: "-126000000", + tickExpected: -126000000, }, "smallest + min price * increment 10^5": { price: sdk.MustNewDecFromStr("0.000000000000100000"), - tickExpected: "-117000000", + tickExpected: -117000000, }, "smallest + min price * increment 10^6": { price: sdk.MustNewDecFromStr("0.000000000001000000"), - tickExpected: "-108000000", + tickExpected: -108000000, }, "smallest + min price * increment 10^6 + tick": { price: sdk.MustNewDecFromStr("0.000000000001000001"), - tickExpected: "-107999999", + tickExpected: -107999999, }, "smallest + min price * increment 10^17": { price: sdk.MustNewDecFromStr("0.100000000000000000"), - tickExpected: "-9000000", + tickExpected: -9000000, }, "smallest + min price * increment 10^18": { price: sdk.MustNewDecFromStr("1.000000000000000000"), - tickExpected: "0", + tickExpected: 0, }, "at price level of 0.01 - odd": { price: sdk.MustNewDecFromStr("0.012345670000000000"), - tickExpected: "-17765433", + tickExpected: -17765433, }, "at price level of 0.01 - even": { price: sdk.MustNewDecFromStr("0.01234568000000000"), - tickExpected: "-17765432", + tickExpected: -17765432, }, "at min price level of 0.01 - odd": { price: sdk.MustNewDecFromStr("0.000000000001234567"), - tickExpected: "-107765433", + tickExpected: -107765433, }, "at min price level of 0.01 - even": { price: sdk.MustNewDecFromStr("0.000000000001234568"), - tickExpected: "-107765432", + tickExpected: -107765432, }, "at price level of 1_000_000_000 - odd end": { price: sdk.MustNewDecFromStr("1234567000"), - tickExpected: "81234567", + tickExpected: 81234567, }, "at price level of 1_000_000_000 - in-between supported": { price: sdk.MustNewDecFromStr("1234567500"), - tickExpected: "81234568", + tickExpected: 81234568, truncatedPrice: sdk.MustNewDecFromStr("1234568000"), }, "at price level of 1_000_000_000 - even end": { price: sdk.MustNewDecFromStr("1234568000"), - tickExpected: "81234568", + tickExpected: 81234568, }, } for name, tc := range testCases { @@ -559,7 +559,7 @@ func (suite *ConcentratedMathTestSuite) TestTickToSqrtPricePriceToTick_InverseRe // 1. Compute tick from price. tickFromPrice, err := math.PriceToTickRoundDown(tc.price, tickSpacing) suite.Require().NoError(err) - suite.Require().Equal(tc.tickExpected, tickFromPrice.String()) + suite.Require().Equal(tc.tickExpected, tickFromPrice) // 2. Compute price from tick (inverse price) price, err := math.TickToPrice(tickFromPrice) @@ -577,7 +577,7 @@ func (suite *ConcentratedMathTestSuite) TestTickToSqrtPricePriceToTick_InverseRe suite.Require().NoError(err) // Make sure original tick and inverse tick match. - suite.Require().Equal(tickFromPrice.String(), inverseTickFromPrice.String()) + suite.Require().Equal(tickFromPrice, inverseTickFromPrice) // 4. Validate PriceToTick and TickToSqrtPrice functions _, sqrtPrice, err := math.TickToSqrtPrice(tickFromPrice) @@ -601,37 +601,37 @@ func (suite *ConcentratedMathTestSuite) TestTickToSqrtPricePriceToTick_InverseRe func (suite *ConcentratedMathTestSuite) TestCalculatePriceToTick() { testCases := map[string]struct { price sdk.Dec - expectedTickIndex sdk.Int + expectedTickIndex int64 }{ "Price greater than 1": { price: sdk.MustNewDecFromStr("9.78"), - expectedTickIndex: sdk.NewInt(8780000), + expectedTickIndex: 8780000, }, "Price less than 1": { price: sdk.MustNewDecFromStr("0.71"), - expectedTickIndex: sdk.NewInt(-2900000), + expectedTickIndex: -2900000, }, "100_000_000 -> 72000000": { price: sdk.NewDec(100_000_000), - expectedTickIndex: sdk.NewInt(72000000), + expectedTickIndex: 72000000, }, "100_000_050 -> 72000000": { price: sdk.NewDec(100_000_050), - expectedTickIndex: sdk.NewInt(72000000), + expectedTickIndex: 72000000, }, "100_000_051 -> 72000001": { price: sdk.NewDec(100_000_051), - expectedTickIndex: sdk.NewInt(72000001), + expectedTickIndex: 72000001, }, "100_000_100 -> 72000001": { price: sdk.NewDec(100_000_100), - expectedTickIndex: sdk.NewInt(72000001), + expectedTickIndex: 72000001, }, } for name, t := range testCases { suite.Run(name, func() { tickIndex := math.CalculatePriceToTick(t.price) - suite.Require().Equal(t.expectedTickIndex.String(), tickIndex.String()) + suite.Require().Equal(t.expectedTickIndex, tickIndex) }) } } diff --git a/x/concentrated-liquidity/model/pool.go b/x/concentrated-liquidity/model/pool.go index 4e3d0857203..d1693043631 100644 --- a/x/concentrated-liquidity/model/pool.go +++ b/x/concentrated-liquidity/model/pool.go @@ -46,7 +46,7 @@ func NewConcentratedLiquidityPool(poolId uint64, denom0, denom1 string, tickSpac Token0: denom0, Token1: denom1, TickSpacing: tickSpacing, - ExponentAtPriceOne: types.ExponentAtPriceOne, + ExponentAtPriceOne: sdk.NewInt(types.ExponentAtPriceOne), SwapFee: swapFee, } return pool, nil diff --git a/x/concentrated-liquidity/model/pool_test.go b/x/concentrated-liquidity/model/pool_test.go index 0a532cb43c5..820baef8656 100644 --- a/x/concentrated-liquidity/model/pool_test.go +++ b/x/concentrated-liquidity/model/pool_test.go @@ -271,7 +271,7 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { s.Run(tt.name, func() { // Create a concentrated liquidity pool struct instance mock_pool := model.Pool{ - ExponentAtPriceOne: types.ExponentAtPriceOne, + ExponentAtPriceOne: sdk.NewInt(types.ExponentAtPriceOne), CurrentTickLiquidity: tt.currentLiquidity, CurrentTick: tt.currentTick, CurrentSqrtPrice: tt.currentSqrtPrice, @@ -406,7 +406,7 @@ func (s *ConcentratedPoolTestSuite) TestNewConcentratedLiquidityPool() { func (suite *ConcentratedPoolTestSuite) TestCalcActualAmounts() { var ( tickToSqrtPrice = func(tick int64) sdk.Dec { - _, sqrtPrice, err := clmath.TickToSqrtPrice(sdk.NewInt(tick)) + _, sqrtPrice, err := clmath.TickToSqrtPrice(tick) suite.Require().NoError(err) return sqrtPrice } @@ -517,7 +517,7 @@ func (suite *ConcentratedPoolTestSuite) TestCalcActualAmounts() { pool := model.Pool{ CurrentTick: sdk.NewInt(tc.currentTick), } - _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick) + _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick.Int64()) actualAmount0, actualAmount1, err := pool.CalcActualAmounts(suite.Ctx, tc.lowerTick, tc.upperTick, tc.liquidityDelta) @@ -611,7 +611,7 @@ func (suite *ConcentratedPoolTestSuite) TestUpdateLiquidityIfActivePosition() { CurrentTick: sdk.NewInt(tc.currentTick), CurrentTickLiquidity: defaultLiquidityAmt, } - _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick) + _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick.Int64()) wasUpdated := pool.UpdateLiquidityIfActivePosition(suite.Ctx, tc.lowerTick, tc.upperTick, tc.liquidityDelta) if tc.lowerTick <= tc.currentTick && tc.currentTick <= tc.upperTick { diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 1cba311d2a3..932c6e5b2a6 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -41,7 +41,7 @@ type SwapState struct { // Current tick while calculating swap. // Initialized to the pool's current tick. // Updated each time a tick is crossed. - tick sdk.Int + tick int64 // Current liqudiity within the active tick. // Initialized to the pool's current tick's liquidity. @@ -159,20 +159,20 @@ func (k Keeper) swapOutAmtGivenIn( tokenOutDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, -) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) { +) (calcTokenIn, calcTokenOut sdk.Coin, currentTick int64, liquidity, sqrtPrice sdk.Dec, err error) { tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.computeOutAmtGivenIn(ctx, pool.GetId(), tokenIn, tokenOutDenom, swapFee, priceLimit) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } if !tokenOut.Amount.IsPositive() { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.InvalidAmountCalculatedError{Amount: tokenOut.Amount} + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.InvalidAmountCalculatedError{Amount: tokenOut.Amount} } // Settles balances between the tx sender and the pool to match the swap that was executed earlier. // Also emits swap event and updates related liquidity metrics if err := k.updatePoolForSwap(ctx, pool, sender, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice); err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } return tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, nil @@ -186,15 +186,15 @@ func (k *Keeper) swapInAmtGivenOut( tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, -) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) { +) (calcTokenIn, calcTokenOut sdk.Coin, currentTick int64, liquidity, sqrtPrice sdk.Dec, err error) { writeCtx, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.calcInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, swapFee, priceLimit, pool.GetId()) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } // check that the tokenOut calculated is both valid and less than specified limit if !tokenIn.Amount.IsPositive() { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.InvalidAmountCalculatedError{Amount: tokenIn.Amount} + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.InvalidAmountCalculatedError{Amount: tokenIn.Amount} } // N.B. making the call below ensures that any mutations done inside calcInAmtGivenOut @@ -205,7 +205,7 @@ func (k *Keeper) swapInAmtGivenOut( // Settles balances between the tx sender and the pool to match the swap that was executed earlier. // Also emits swap event and updates related liquidity metrics if err := k.updatePoolForSwap(ctx, pool, sender, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice); err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } return tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, nil @@ -253,11 +253,11 @@ func (k Keeper) computeOutAmtGivenIn( tokenOutDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, -) (tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { +) (tokenIn, tokenOut sdk.Coin, updatedTick int64, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { // Get pool and asset info p, err := k.getPoolById(ctx, poolId) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } asset0 := p.GetToken0() asset1 := p.GetToken1() @@ -276,7 +276,7 @@ func (k Keeper) computeOutAmtGivenIn( // Take provided price limit and turn this into a sqrt price limit since formulas use sqrtPrice sqrtPriceLimit, err := priceLimit.ApproxSqrt() if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit") + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit") } // Set the swap strategy @@ -286,20 +286,20 @@ func (k Keeper) computeOutAmtGivenIn( // on the correct side of the price limit given swap direction. curSqrtPrice := p.GetCurrentSqrtPrice() if err := swapStrategy.ValidateSqrtPrice(sqrtPriceLimit, curSqrtPrice); err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } // Check that the specified tokenIn matches one of the assets in the specified pool if tokenInMin.Denom != asset0 && tokenInMin.Denom != asset1 { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInMin.Denom} + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInMin.Denom} } // Check that the specified tokenOut matches one of the assets in the specified pool if tokenOutDenom != asset0 && tokenOutDenom != asset1 { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: tokenOutDenom} + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: tokenOutDenom} } // Check that token in and token out are different denominations if tokenInMin.Denom == tokenOutDenom { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom} + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom} } // initialize swap state with the following parameters: @@ -309,7 +309,7 @@ func (k Keeper) computeOutAmtGivenIn( amountCalculated: sdk.ZeroDec(), // tokenOut sqrtPrice: curSqrtPrice, // Pad (or don't pad) current tick based on swap direction to avoid off-by-one errors - tick: swapStrategy.InitializeTickValue(p.GetCurrentTick()), + tick: swapStrategy.InitializeTickValue(p.GetCurrentTick().Int64()), liquidity: p.GetLiquidity(), feeGrowthGlobal: sdk.ZeroDec(), } @@ -326,15 +326,15 @@ func (k Keeper) computeOutAmtGivenIn( // if zeroForOneStrategy, we look to the left of the tick the current sqrt price is at // if oneForZeroStrategy, we look to the right of the tick the current sqrt price is at // if no ticks are initialized (no users have created liquidity positions) then we return an error - nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick.Int64()) + nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick) if !ok { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap") + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap") } // Utilizing the next initialized tick, we find the corresponding nextPrice (the target price) _, nextTickSqrtPrice, err := math.TickToSqrtPrice(nextTick) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick) + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick) } // If nextSqrtPrice exceeds the price limit, we set the nextSqrtPrice to the price limit. @@ -371,9 +371,9 @@ func (k Keeper) computeOutAmtGivenIn( // tick has been consumed and we must move on to the next tick to complete the swap if nextTickSqrtPrice.Equal(sqrtPrice) { // Retrieve the liquidity held in the next closest initialized tick - liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick.Int64(), sdk.NewDecCoinFromDec(tokenInMin.Denom, swapState.feeGrowthGlobal)) + liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick, sdk.NewDecCoinFromDec(tokenInMin.Denom, swapState.feeGrowthGlobal)) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet) // Update the swapState's liquidity with the new tick's liquidity @@ -388,13 +388,13 @@ func (k Keeper) computeOutAmtGivenIn( price := sqrtPrice.Mul(sqrtPrice) swapState.tick, err = math.PriceToTickRoundDown(price, p.GetTickSpacing()) if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } } } if err := k.chargeFee(ctx, poolId, sdk.NewDecCoinFromDec(tokenInMin.Denom, swapState.feeGrowthGlobal)); err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } // Coin amounts require int values @@ -423,11 +423,11 @@ func (k Keeper) calcInAmtGivenOut( swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64, -) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { +) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick int64, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) { ctx, writeCtx = ctx.CacheContext() p, err := k.getPoolById(ctx, poolId) if err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } asset0 := p.GetToken0() asset1 := p.GetToken1() @@ -445,7 +445,7 @@ func (k Keeper) calcInAmtGivenOut( // take provided price limit and turn this into a sqrt price limit since formulas use sqrtPrice sqrtPriceLimit, err := priceLimit.ApproxSqrt() if err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit") + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit") } // set the swap strategy @@ -455,20 +455,20 @@ func (k Keeper) calcInAmtGivenOut( curSqrtPrice := p.GetCurrentSqrtPrice() if err := swapStrategy.ValidateSqrtPrice(sqrtPriceLimit, curSqrtPrice); err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } // check that the specified tokenOut matches one of the assets in the specified pool if desiredTokenOut.Denom != asset0 && desiredTokenOut.Denom != asset1 { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: desiredTokenOut.Denom} + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: desiredTokenOut.Denom} } // check that the specified tokenIn matches one of the assets in the specified pool if tokenInDenom != asset0 && tokenInDenom != asset1 { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInDenom} + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInDenom} } // check that token in and token out are different denominations if desiredTokenOut.Denom == tokenInDenom { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInDenom, TokenOutDenom: desiredTokenOut.Denom} + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInDenom, TokenOutDenom: desiredTokenOut.Denom} } // initialize swap state with the following parameters: @@ -477,7 +477,7 @@ func (k Keeper) calcInAmtGivenOut( amountSpecifiedRemaining: desiredTokenOut.Amount.ToDec(), // tokenOut amountCalculated: sdk.ZeroDec(), // tokenIn sqrtPrice: curSqrtPrice, - tick: swapStrategy.InitializeTickValue(p.GetCurrentTick()), + tick: swapStrategy.InitializeTickValue(p.GetCurrentTick().Int64()), liquidity: p.GetLiquidity(), feeGrowthGlobal: sdk.ZeroDec(), } @@ -492,15 +492,15 @@ func (k Keeper) calcInAmtGivenOut( // if zeroForOne is false, we look to the left of the tick the current sqrt price is at // if zeroForOne is true, we look to the right of the tick the current sqrt price is at // if no ticks are initialized (no users have created liquidity positions) then we return an error - nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick.Int64()) + nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick) if !ok { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap") + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap") } // utilizing the next initialized tick, we find the corresponding nextPrice (the target price) _, sqrtPriceNextTick, err := math.TickToSqrtPrice(nextTick) if err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick) + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick) } sqrtPriceTarget := swapStrategy.GetSqrtTargetPrice(sqrtPriceNextTick) @@ -533,9 +533,9 @@ func (k Keeper) calcInAmtGivenOut( // tick has been consumed and we must move on to the next tick to complete the swap if sqrtPriceNextTick.Equal(sqrtPrice) { // retrieve the liquidity held in the next closest initialized tick - liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick.Int64(), sdk.NewDecCoinFromDec(desiredTokenOut.Denom, swapState.feeGrowthGlobal)) + liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick, sdk.NewDecCoinFromDec(desiredTokenOut.Denom, swapState.feeGrowthGlobal)) if err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet) // update the swapState's liquidity with the new tick's liquidity @@ -550,13 +550,13 @@ func (k Keeper) calcInAmtGivenOut( price := sqrtPrice.Mul(sqrtPrice) swapState.tick, err = math.PriceToTickRoundDown(price, p.GetTickSpacing()) if err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } } } if err := k.chargeFee(ctx, poolId, sdk.NewDecCoinFromDec(tokenInDenom, swapState.feeGrowthGlobal)); err != nil { - return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + return writeCtx, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, sdk.Dec{}, err } // coin amounts require int values @@ -591,7 +591,7 @@ func (k Keeper) updatePoolForSwap( sender sdk.AccAddress, tokenIn sdk.Coin, tokenOut sdk.Coin, - newCurrentTick sdk.Int, + newCurrentTick int64, newLiquidity sdk.Dec, newSqrtPrice sdk.Dec, ) error { @@ -617,7 +617,7 @@ func (k Keeper) updatePoolForSwap( return types.InsufficientPoolBalanceError{Err: err} } - err = pool.ApplySwap(newLiquidity, newCurrentTick, newSqrtPrice) + err = pool.ApplySwap(newLiquidity, sdk.NewInt(newCurrentTick), newSqrtPrice) if err != nil { return fmt.Errorf("error applying swap: %w", err) } diff --git a/x/concentrated-liquidity/swaps_test.go b/x/concentrated-liquidity/swaps_test.go index f59e3049730..765325e455b 100644 --- a/x/concentrated-liquidity/swaps_test.go +++ b/x/concentrated-liquidity/swaps_test.go @@ -38,7 +38,7 @@ type SwapTest struct { expectedTokenIn sdk.Coin expectedTokenOut sdk.Coin - expectedTick sdk.Int + expectedTick int64 expectedSqrtPrice sdk.Dec expectedLowerTickFeeGrowth sdk.DecCoins expectedUpperTickFeeGrowth sdk.DecCoins @@ -82,7 +82,7 @@ var ( // expectedTokenOut: 8396.71424216 rounded down https://www.wolframalpha.com/input?i=%281517882343.751510418088349649+*+%2870.738348247484497717+-+70.710678118654752440+%29%29+%2F+%2870.710678118654752440+*+70.738348247484497717%29 expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(42000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(8396)), - expectedTick: sdk.NewInt(31003900), + expectedTick: 31003900, expectedSqrtPrice: sdk.MustNewDecFromStr("70.738348247484497717"), // https://www.wolframalpha.com/input?i=70.710678118654752440+%2B+42000000+%2F+1517882343.751510418088349649 // tick's accum coins stay same since crossing tick does not occur in this case expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, @@ -101,7 +101,7 @@ var ( // expectedTokenOut: 66808388.8901 rounded down https://www.wolframalpha.com/input?i=1517882343.751510418088349649+*+%2870.710678118654752440+-+70.6666639108571443311%29 expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(13370)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(66808388)), - expectedTick: sdk.NewInt(30993700), + expectedTick: 30993700, expectedSqrtPrice: sdk.MustNewDecFromStr("70.666663910857144332"), // https://www.wolframalpha.com/input?i=%28%281517882343.751510418088349649%29%29+%2F+%28%28%281517882343.751510418088349649%29+%2F+%2870.710678118654752440%29%29+%2B+%2813370%29%29 expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -126,7 +126,7 @@ var ( // expectedTokenOut: 8398.3567 rounded down https://www.wolframalpha.com/input?i=%283035764687.503020836176699298+*+%2870.724513183069625078+-+70.710678118654752440+%29%29+%2F+%2870.710678118654752440+*+70.724513183069625078%29 expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(42000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(8398)), - expectedTick: sdk.NewInt(31001900), + expectedTick: 31001900, expectedSqrtPrice: sdk.MustNewDecFromStr("70.724513183069625078"), // https://www.wolframalpha.com/input?i=70.710678118654752440+%2B++++%2842000000++%2F+3035764687.503020836176699298%29 // two positions with same liquidity entered poolLiqAmount0: sdk.NewInt(1000000).MulRaw(2), @@ -149,7 +149,7 @@ var ( // expectedTokenOut: 66829187.9678 rounded down https://www.wolframalpha.com/input?i=3035764687.503020836176699298+*+%2870.710678118654752440+-+70.688664163408836319%29 expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(13370)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(66829187)), - expectedTick: sdk.NewInt(30996800), + expectedTick: 30996800, expectedSqrtPrice: sdk.MustNewDecFromStr("70.688664163408836320"), // https://www.wolframalpha.com/input?i=%28%283035764687.503020836176699298%29%29+%2F+%28%28%283035764687.503020836176699298%29+%2F+%2870.710678118654752440%29%29+%2B+%2813370.0000%29%29 // two positions with same liquidity entered poolLiqAmount0: sdk.NewInt(1000000).MulRaw(2), @@ -186,7 +186,7 @@ var ( // expectedTokenOut: 998976.6183474263883566299269 + 821653.4522259 = 1820630.070 round down = 1.820630 eth expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(10000000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(1820630)), - expectedTick: sdk.NewInt(32105400), + expectedTick: 32105400, expectedSqrtPrice: sdk.MustNewDecFromStr("78.137149196095607129"), // https://www.wolframalpha.com/input?i=74.16198487095662948711397441+%2B+4761322417+%2F+1197767444.955508123222985080 expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -219,7 +219,7 @@ var ( expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2000000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(9103422788)), // crosses one tick with fee growth outside - expectedTick: sdk.NewInt(30095100), + expectedTick: 30095100, expectedSqrtPrice: sdk.MustNewDecFromStr("63.993489023323078693"), // https://www.wolframalpha.com/input?i=%28%281198735489.597250295669959397%29%29+%2F+%28%28%281198735489.597250295669959397%29+%2F+%28+67.41661516273269559379442134%29%29+%2B+%28951138.000000000000000000%29%29 // crossing tick happens single time for each upper tick and lower tick. // Thus the tick's fee growth is DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins @@ -259,7 +259,7 @@ var ( // expectedTokenOut: 998976.6183474263883566299269692777 + 865185.2591363751404579873403641 = 1864161.877 round down = 1.864161 eth expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(10000000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(1864161)), - expectedTick: sdk.NewInt(32055900), + expectedTick: 32055900, expectedSqrtPrice: sdk.MustNewDecFromStr("77.819789636800169392"), // https://www.wolframalpha.com/input?i=74.16198487095662948711397441+%2B++++%282452251164.000000000000000000+%2F+670416088.605668727039240782%29 expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -294,7 +294,7 @@ var ( expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, expectedSecondLowerTickFeeGrowth: secondPosition{tickIndex: 310010, expectedFeeGrowth: cl.EmptyCoins}, expectedSecondUpperTickFeeGrowth: secondPosition{tickIndex: 322500, expectedFeeGrowth: cl.EmptyCoins}, - expectedTick: sdk.NewInt(31712600), + expectedTick: 31712600, expectedSqrtPrice: sdk.MustNewDecFromStr("75.582373164412551491"), // https://www.wolframalpha.com/input?i=74.16198487095662948711397441++%2B+%28+952251164.000000000000000000++%2F+670416088.605668727039240782%29 newLowerPrice: sdk.NewDec(5001), newUpperPrice: sdk.NewDec(6250), @@ -321,7 +321,7 @@ var ( secondPositionUpperPrice: sdk.NewDec(4999), expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2000000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(9321276930)), - expectedTick: sdk.NewInt(30129000), + expectedTick: 30129000, expectedSqrtPrice: sdk.MustNewDecFromStr("64.257943794993248954"), // https://www.wolframalpha.com/input?i=%28%28670416215.71882744366040059300%29%29+%2F+%28%28%28670416215.71882744366040059300%29+%2F+%2867.41661516273269559379442134%29%29+%2B+%28488827.000000000000000000%29%29 // Started from DefaultFeeAccumCoins * 3, crossed tick once, thus becoming // DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins = DefaultFeeAccumCoins * 2 @@ -351,7 +351,7 @@ var ( secondPositionUpperPrice: sdk.NewDec(4999), expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(1800000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(8479320318)), - expectedTick: sdk.NewInt(30292000), + expectedTick: 30292000, expectedSqrtPrice: sdk.MustNewDecFromStr("65.513815285481060960"), // https://www.wolframalpha.com/input?i=%28%28670416215.718827443660400593000%29%29+%2F+%28%28%28670416215.718827443660400593000%29+%2F+%2867.41661516273269559379442134%29%29+%2B+%28288827.000000000000000000%29%29 // Started from DefaultFeeAccumCoins * 3, crossed tick once, thus becoming // DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins = DefaultFeeAccumCoins * 2 @@ -390,7 +390,7 @@ var ( // expectedTokenOut: 998976.61834742638835 + 821569.240826953837970 = 1820545.85917438022632 round down = 1.820545 eth expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(10000000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(1820545)), - expectedTick: sdk.NewInt(32105500), + expectedTick: 32105500, expectedSqrtPrice: sdk.MustNewDecFromStr("78.138055169663761658"), // https://www.wolframalpha.com/input?i=74.16872656315463530313879691++%2B+%28+4761322417.000000000000000000++%2F+1199528406.187413669220037261%29 expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -415,7 +415,7 @@ var ( // expectedTokenOut: 64417624.98716495170 rounded down https://www.wolframalpha.com/input?key=&i=1517882343.751510418088349649+*+%2870.710678118654752440+-+70.668238976219012614%29 expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(12892)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(64417624)), - expectedTick: func() sdk.Int { + expectedTick: func() int64 { tick, _ := math.PriceToTickRoundDown(sdk.NewDec(4994), DefaultTickSpacing) return tick }(), @@ -445,7 +445,7 @@ var ( // expectedFeeGrowthAccumulatorValue: 0.000276701288297452 expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(42000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(8312)), - expectedTick: sdk.NewInt(31003800), + expectedTick: 31003800, expectedSqrtPrice: sdk.MustNewDecFromStr("70.738071546196200264"), // https://www.wolframalpha.com/input?i=70.71067811865475244008443621+%2B++++%2841580000.000000000000000000+%2F+1517882343.751510418088349649%29 expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.000276701288297452"), }, @@ -470,7 +470,7 @@ var ( // expectedFeeGrowthAccumulatorValue: 0.000000132124865162033700093060000008 expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(13370)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(64824917)), - expectedTick: sdk.NewInt(30996900), + expectedTick: 30996900, expectedSqrtPrice: sdk.MustNewDecFromStr("70.689324382628080102"), // https://www.wolframalpha.com/input?i=%28%283035764687.503020836176699298%29%29+%2F+%28%28%283035764687.503020836176699298%29+%2F+%2870.71067811865475244008443621%29%29+%2B+%2812968.900000000000000000%29%29 expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.000000132091924532"), // two positions with same liquidity entered @@ -496,7 +496,7 @@ var ( expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2000000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(8691708221)), expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.000073738597832046"), - expectedTick: sdk.NewInt(30139200), + expectedTick: 30139200, expectedSqrtPrice: sdk.MustNewDecFromStr("64.336946417392457832"), // https://www.wolframalpha.com/input?i=%28%281198735489.597250295669959397%29%29+%2F+%28%28%281198735489.597250295669959397%29+%2F+%28+67.41661516273269559379442134%29%29+%2B+%28851137.999999999999999999%29%29 newLowerPrice: sdk.NewDec(4000), newUpperPrice: sdk.NewDec(4545), @@ -519,7 +519,7 @@ var ( expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(10000000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(1695807)), expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.624166726347032857"), - expectedTick: sdk.NewInt(31825900), + expectedTick: 31825900, expectedSqrtPrice: sdk.MustNewDecFromStr("76.328178655208424124"), // https://www.wolframalpha.com/input?i=+74.16198487095662948711397441+%2B++++%281452251164.000000000000000001+%2F+670416088.605668727039240782%29 newLowerPrice: sdk.NewDec(5001), newUpperPrice: sdk.NewDec(6250), @@ -539,7 +539,7 @@ var ( expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(1800000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(8440657775)), expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.000005569829831408"), - expectedTick: sdk.NewInt(30299600), + expectedTick: 30299600, expectedSqrtPrice: sdk.MustNewDecFromStr("65.571484748647169032"), // https://www.wolframalpha.com/input?i=%28%28670416215.718827443660400593000%29%29+%2F+%28%28%28670416215.718827443660400593000%29+%2F+%28+67.41661516273269559379442134%29%29+%2B+%28279827.000000000000000001%29%29 newLowerPrice: sdk.NewDec(4000), newUpperPrice: sdk.NewDec(4999), @@ -559,7 +559,7 @@ var ( expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(10000000000)), expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(1771252)), expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.221769187794051751"), - expectedTick: sdk.NewInt(32066500), + expectedTick: 32066500, expectedSqrtPrice: sdk.MustNewDecFromStr("77.887956882326389372"), // https://www.wolframalpha.com/input?i=74.16872656315463530313879691+%2B++++%284461322417.000000000000000001+%2F+1199528406.187413669220037261%29 newLowerPrice: sdk.NewDec(5501), newUpperPrice: sdk.NewDec(6250), @@ -580,7 +580,7 @@ var ( expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(13023)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(64417624)), expectedFeeGrowthAccumulatorValue: sdk.MustNewDecFromStr("0.000000085792039652"), - expectedTick: func() sdk.Int { + expectedTick: func() int64 { tick, _ := math.PriceToTickRoundDown(sdk.NewDec(4994), DefaultTickSpacing) return tick }(), @@ -627,7 +627,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin(USDC, sdk.NewInt(42000000)), expectedTokenIn: sdk.NewCoin(ETH, sdk.NewInt(8404)), - expectedTick: sdk.NewInt(30996000), + expectedTick: 30996000, expectedSqrtPrice: sdk.MustNewDecFromStr("70.683007989825007162"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -648,7 +648,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(13370)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(66891663)), - expectedTick: sdk.NewInt(31006200), + expectedTick: 31006200, expectedSqrtPrice: sdk.MustNewDecFromStr("70.754747188468900467"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -676,7 +676,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(66829187)), expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(13370)), - expectedTick: sdk.NewInt(30996800), + expectedTick: 30996800, expectedSqrtPrice: sdk.MustNewDecFromStr("70.688664163727643650"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -702,7 +702,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin("eth", sdk.NewInt(8398)), expectedTokenIn: sdk.NewCoin("usdc", sdk.NewInt(41998216)), - expectedTick: sdk.NewInt(31001900), + expectedTick: 31001900, expectedSqrtPrice: sdk.MustNewDecFromStr("70.724512595179305566"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -747,7 +747,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(9103422788)), expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2000000)), - expectedTick: sdk.NewInt(30095100), + expectedTick: 30095100, expectedSqrtPrice: sdk.MustNewDecFromStr("63.993489023888951975"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins.MulDec(sdk.NewDec(2)), @@ -796,7 +796,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(1820630)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(9999999570)), - expectedTick: sdk.NewInt(32105400), + expectedTick: 32105400, expectedSqrtPrice: sdk.MustNewDecFromStr("78.137148837036751553"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -853,7 +853,7 @@ var ( // print(token_in) expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2000000)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(9321276930)), - expectedTick: sdk.NewInt(30129000), + expectedTick: 30129000, expectedSqrtPrice: sdk.MustNewDecFromStr("64.257943796086567725"), // Started from DefaultFeeAccumCoins * 3, crossed tick once, thus becoming // DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins = DefaultFeeAccumCoins * 2 @@ -909,7 +909,7 @@ var ( // print(token_in) expectedTokenIn: sdk.NewCoin(ETH, sdk.NewInt(1800000)), expectedTokenOut: sdk.NewCoin(USDC, sdk.NewInt(8479320318)), - expectedTick: sdk.NewInt(30292000), + expectedTick: 30292000, expectedSqrtPrice: sdk.MustNewDecFromStr("65.513815286452064191"), // Started from DefaultFeeAccumCoins * 3, crossed tick once, thus becoming // DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins = DefaultFeeAccumCoins * 2 @@ -968,7 +968,7 @@ var ( // print(token_in) expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(9999994688)), expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(1864161)), - expectedTick: sdk.NewInt(32055900), + expectedTick: 32055900, expectedSqrtPrice: sdk.MustNewDecFromStr("77.819781711876553576"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1023,7 +1023,7 @@ var ( expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, expectedSecondLowerTickFeeGrowth: secondPosition{tickIndex: 310010, expectedFeeGrowth: cl.EmptyCoins}, expectedSecondUpperTickFeeGrowth: secondPosition{tickIndex: 322500, expectedFeeGrowth: cl.EmptyCoins}, - expectedTick: sdk.NewInt(31712600), + expectedTick: 31712600, expectedSqrtPrice: sdk.MustNewDecFromStr("75.582372355128594341"), newLowerPrice: sdk.NewDec(5001), newUpperPrice: sdk.NewDec(6250), @@ -1068,7 +1068,7 @@ var ( // print(token_in) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(1820545)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(9999994756)), - expectedTick: sdk.NewInt(32105500), + expectedTick: 32105500, expectedSqrtPrice: sdk.MustNewDecFromStr("78.138050797173647031"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1099,7 +1099,7 @@ var ( // print(token_in_1) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(4291)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(21463952)), - expectedTick: sdk.NewInt(31002000), + expectedTick: 31002000, expectedSqrtPrice: sdk.MustNewDecFromStr("70.724818840347693039"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1131,7 +1131,7 @@ var ( // print(fee_growth) expectedTokenOut: sdk.NewCoin(USDC, sdk.NewInt(42000000)), expectedTokenIn: sdk.NewCoin(ETH, sdk.NewInt(8489)), - expectedTick: sdk.NewInt(30996000), + expectedTick: 30996000, expectedSqrtPrice: sdk.MustNewDecFromStr("70.683007989825007162"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1163,7 +1163,7 @@ var ( // print(fee_growth) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(8398)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(43297130)), - expectedTick: sdk.NewInt(31001900), + expectedTick: 31001900, expectedSqrtPrice: sdk.MustNewDecFromStr("70.724512595179305566"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1210,7 +1210,7 @@ var ( // print(fee_growth) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(1820630)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(10010009580)), - expectedTick: sdk.NewInt(32105400), + expectedTick: 32105400, expectedSqrtPrice: sdk.MustNewDecFromStr("78.137148837036751553"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1268,7 +1268,7 @@ var ( // print(fee_growth) expectedTokenIn: sdk.NewCoin("eth", sdk.NewInt(2222223)), expectedTokenOut: sdk.NewCoin("usdc", sdk.NewInt(9321276930)), - expectedTick: sdk.NewInt(30129000), + expectedTick: 30129000, expectedSqrtPrice: sdk.MustNewDecFromStr("64.257943796086567725"), // Started from DefaultFeeAccumCoins * 3, crossed tick once, thus becoming // DefaultFeeAccumCoins * 3 - DefaultFeeAccumCoins = DefaultFeeAccumCoins * 2 @@ -1332,7 +1332,7 @@ var ( expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, expectedSecondLowerTickFeeGrowth: secondPosition{tickIndex: 310010, expectedFeeGrowth: cl.EmptyCoins}, expectedSecondUpperTickFeeGrowth: secondPosition{tickIndex: 322500, expectedFeeGrowth: cl.EmptyCoins}, - expectedTick: sdk.NewInt(31712600), + expectedTick: 31712600, expectedSqrtPrice: sdk.MustNewDecFromStr("75.582372355128594341"), newLowerPrice: sdk.NewDec(5001), newUpperPrice: sdk.NewDec(6250), @@ -1375,7 +1375,7 @@ var ( // print(fee_growth) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(1820545)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(10002995655)), - expectedTick: sdk.NewInt(32105500), + expectedTick: 32105500, expectedSqrtPrice: sdk.MustNewDecFromStr("78.138050797173647031"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1411,7 +1411,7 @@ var ( // print(fee_growth) expectedTokenOut: sdk.NewCoin(ETH, sdk.NewInt(4291)), expectedTokenIn: sdk.NewCoin(USDC, sdk.NewInt(21680760)), - expectedTick: sdk.NewInt(31002000), + expectedTick: 31002000, expectedSqrtPrice: sdk.MustNewDecFromStr("70.724818840347693039"), expectedLowerTickFeeGrowth: DefaultFeeAccumCoins, expectedUpperTickFeeGrowth: DefaultFeeAccumCoins, @@ -1477,7 +1477,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -1502,7 +1502,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { s.Require().NoError(err) // check that tokenIn, tokenOut, tick, and sqrtPrice from CalcOut are all what we expected - s.Require().Equal(test.expectedTick.String(), updatedTick.String()) + s.Require().Equal(test.expectedTick, updatedTick) s.Require().Equal(test.expectedTokenIn.String(), tokenIn.String()) s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) s.Require().Equal(test.expectedSqrtPrice, sqrtPrice) @@ -1555,7 +1555,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { s.Require().Equal(test.expectedTokenIn.String(), tokenIn.String()) s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) - s.Require().Equal(test.expectedTick.String(), updatedTick.String()) + s.Require().Equal(test.expectedTick, updatedTick) s.Require().Equal(test.expectedSqrtPrice, sqrtPrice) if test.newLowerPrice.IsNil() && test.newUpperPrice.IsNil() { @@ -1633,7 +1633,7 @@ func (s *KeeperTestSuite) TestSwapOutAmtGivenIn_TickUpdates() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -1715,7 +1715,7 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -1736,7 +1736,7 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() { s.Require().Equal(test.expectedSqrtPrice, sqrtPrice) s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) s.Require().Equal(test.expectedTokenIn.String(), tokenIn.String()) - s.Require().Equal(test.expectedTick.String(), updatedTick.String()) + s.Require().Equal(test.expectedTick, updatedTick) if test.newLowerPrice.IsNil() && test.newUpperPrice.IsNil() { test.newLowerPrice = DefaultLowerPrice @@ -1787,12 +1787,12 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() { s.Require().NoError(err) // check that tokenIn, tokenOut, tick, and sqrtPrice from SwapOut are all what we expected - s.Require().Equal(test.expectedTick.String(), updatedTick.String()) + s.Require().Equal(test.expectedTick, updatedTick) s.Require().Equal(test.expectedTokenIn.String(), tokenIn.String()) s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) s.Require().Equal(test.expectedSqrtPrice, sqrtPrice) // also ensure the pool's currentTick and currentSqrtPrice was updated due to calling a mutative method - s.Require().Equal(test.expectedTick.String(), pool.GetCurrentTick().String()) + s.Require().Equal(test.expectedTick, pool.GetCurrentTick().Int64()) if test.newLowerPrice.IsNil() && test.newUpperPrice.IsNil() { test.newLowerPrice = DefaultLowerPrice @@ -1879,7 +1879,7 @@ func (s *KeeperTestSuite) TestSwapInAmtGivenOut_TickUpdates() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2314,7 +2314,7 @@ func (s *KeeperTestSuite) TestComputeOutAmtGivenIn() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2382,7 +2382,7 @@ func (s *KeeperTestSuite) TestCalcOutAmtGivenIn_NonMutative() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2451,7 +2451,7 @@ func (s *KeeperTestSuite) TestCalcInAmtGivenOutWriteCtx() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2527,7 +2527,7 @@ func (s *KeeperTestSuite) TestInverseRelationshipSwapOutAmtGivenIn() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2625,7 +2625,7 @@ func (s *KeeperTestSuite) TestInverseRelationshipSwapInAmtGivenOut() { newUpperTick, err := math.PriceToTickRoundDown(test.secondPositionUpperPrice, pool.GetTickSpacing()) s.Require().NoError(err) - _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick.Int64(), newUpperTick.Int64()) + _, _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } @@ -2667,7 +2667,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { poolInitialBalance sdk.Coins tokenIn sdk.Coin tokenOut sdk.Coin - newCurrentTick sdk.Int + newCurrentTick int64 newLiquidity sdk.Dec newSqrtPrice sdk.Dec expectError error @@ -2677,7 +2677,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { poolInitialBalance: defaultInitialBalance, tokenIn: oneHundredETH, tokenOut: oneHundredUSDC, - newCurrentTick: sdk.NewInt(2), + newCurrentTick: 2, newLiquidity: sdk.NewDec(2), newSqrtPrice: sdk.NewDec(2), }, @@ -2686,7 +2686,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { poolInitialBalance: defaultInitialBalance, tokenIn: oneHundredETH.Add(oneHundredETH), tokenOut: oneHundredUSDC, - newCurrentTick: sdk.NewInt(8), + newCurrentTick: 8, newLiquidity: sdk.NewDec(37), newSqrtPrice: sdk.NewDec(91), }, @@ -2695,7 +2695,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { poolInitialBalance: defaultInitialBalance, tokenIn: oneHundredETH.Add(oneHundredETH), tokenOut: oneHundredUSDC, - newCurrentTick: sdk.NewInt(2), + newCurrentTick: 2, newLiquidity: sdk.NewDec(2), newSqrtPrice: sdk.NewDec(2), expectError: types.InsufficientUserBalanceError{}, @@ -2705,7 +2705,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { poolInitialBalance: defaultInitialBalance, tokenIn: oneHundredETH, tokenOut: oneHundredUSDC.Add(oneHundredUSDC), - newCurrentTick: sdk.NewInt(2), + newCurrentTick: 2, newLiquidity: sdk.NewDec(2), newSqrtPrice: sdk.NewDec(2), expectError: types.InsufficientPoolBalanceError{}, @@ -2752,7 +2752,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { } suite.Require().NoError(err) - suite.Require().Equal(tc.newCurrentTick, poolAfterUpdate.GetCurrentTick()) + suite.Require().Equal(tc.newCurrentTick, poolAfterUpdate.GetCurrentTick().Int64()) suite.Require().Equal(tc.newLiquidity, poolAfterUpdate.GetLiquidity()) suite.Require().Equal(tc.newSqrtPrice, poolAfterUpdate.GetCurrentSqrtPrice()) diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero.go b/x/concentrated-liquidity/swapstrategy/one_for_zero.go index d61278481ad..bcc0c7c803b 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero.go @@ -156,8 +156,8 @@ func (s oneForZeroStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric // Therefore, this method is, essentially a no-op. The logic is reversed for // zeroForOneStrategy where we use reverse iterator and have to add one to // the input. Therefore, we define this method to account for different strategies. -func (s oneForZeroStrategy) InitializeTickValue(currentTick sdk.Int) sdk.Int { - return currentTick +func (s oneForZeroStrategy) InitializeTickValue(currentTick int64) int64 { + return currentTick + 1 } // NextInitializedTick returns the next initialized tick index based on the @@ -165,7 +165,7 @@ func (s oneForZeroStrategy) InitializeTickValue(currentTick sdk.Int) sdk.Int { // will be returned. // // oneForZerostrategy searches for the next tick to the right of the current tickIndex. -func (s oneForZeroStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next sdk.Int, initialized bool) { +func (s oneForZeroStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next int64, initialized bool) { store := ctx.KVStore(s.storeKey) // Construct a prefix store with a prefix of , allowing @@ -186,10 +186,10 @@ func (s oneForZeroStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, } if tick > tickIndex { - return sdk.NewInt(tick), true + return tick, true } } - return sdk.ZeroInt(), false + return 0, false } // SetLiquidityDeltaSign sets the liquidity delta sign for the given liquidity delta. diff --git a/x/concentrated-liquidity/swapstrategy/swap_strategy.go b/x/concentrated-liquidity/swapstrategy/swap_strategy.go index 367e88319c2..2f8acad24f1 100644 --- a/x/concentrated-liquidity/swapstrategy/swap_strategy.go +++ b/x/concentrated-liquidity/swapstrategy/swap_strategy.go @@ -52,12 +52,12 @@ type swapStrategy interface { // InitializeTickValue returns the initial tick value for computing swaps based // on the actual current tick. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. - InitializeTickValue(currentTick sdk.Int) sdk.Int + InitializeTickValue(currentTick int64) int64 // NextInitializedTick returns the next initialized tick index based on the // provided tickindex. If no initialized tick exists, <0, false> // will be returned. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. - NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next sdk.Int, initialized bool) + NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next int64, initialized bool) // SetLiquidityDeltaSign sets the liquidity delta sign for the given liquidity delta. // This is called when consuming all liquidity. // When a position is created, we add liquidity to lower tick diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one.go b/x/concentrated-liquidity/swapstrategy/zero_for_one.go index adec4e781e3..25d3f4f4472 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one.go @@ -151,8 +151,8 @@ func (s zeroForOneStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric // As a result, we use reverse iterator in NextInitializedTick to find the next // tick to the left of current. The end cursor for reverse iteration is non-inclusive // so must add one here to make sure that the current tick is included in the search. -func (s zeroForOneStrategy) InitializeTickValue(currentTick sdk.Int) sdk.Int { - return currentTick.Add(sdk.OneInt()) +func (s zeroForOneStrategy) InitializeTickValue(currentTick int64) int64 { + return currentTick + 1 } // NextInitializedTick returns the next initialized tick index based on the @@ -160,7 +160,7 @@ func (s zeroForOneStrategy) InitializeTickValue(currentTick sdk.Int) sdk.Int { // will be returned. // // zeroForOneStrategy searches for the next tick to the left of the current tickIndex. -func (s zeroForOneStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next sdk.Int, initialized bool) { +func (s zeroForOneStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64) (next int64, initialized bool) { store := ctx.KVStore(s.storeKey) // Construct a prefix store with a prefix of , allowing @@ -181,10 +181,10 @@ func (s zeroForOneStrategy) NextInitializedTick(ctx sdk.Context, poolId uint64, panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) } if tick <= tickIndex { - return sdk.NewInt(tick), true + return tick, true } } - return sdk.ZeroInt(), false + return 0, false } // SetLiquidityDeltaSign sets the liquidity delta sign for the given liquidity delta. diff --git a/x/concentrated-liquidity/tick.go b/x/concentrated-liquidity/tick.go index c84ece6d0d6..c9521ddcb07 100644 --- a/x/concentrated-liquidity/tick.go +++ b/x/concentrated-liquidity/tick.go @@ -209,17 +209,14 @@ func roundTickToCanonicalPriceTick(lowerTick, upperTick int64, priceTickLower, p return 0, 0, err } - newLowerTickInt64 := newLowerTick.Int64() - newUpperTickInt64 := newUpperTick.Int64() - // If the lower or upper tick has changed, we need to re-validate the tick range. - if lowerTick != newLowerTickInt64 || upperTick != newUpperTickInt64 { - err := validateTickRangeIsValid(tickSpacing, newLowerTickInt64, newUpperTickInt64) + if lowerTick != newLowerTick || upperTick != newUpperTick { + err := validateTickRangeIsValid(tickSpacing, newLowerTick, newUpperTick) if err != nil { return 0, 0, err } } - return newLowerTickInt64, newUpperTickInt64, nil + return newLowerTick, newUpperTick, nil } // GetTickLiquidityForFullRange returns an array of liquidity depth for all ticks existing from min tick ~ max tick. @@ -251,7 +248,7 @@ func (k Keeper) GetTickLiquidityForFullRange(ctx sdk.Context, poolId uint64) ([] // use the smallest tick initialized as the starting point for calculating liquidity. currentLiquidity := tick.LiquidityNet - currentTick = nextTick.Int64() + currentTick = nextTick totalLiquidityWithinRange := currentLiquidity // iterator assignments @@ -363,7 +360,7 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t swapStrategy := swapstrategy.New(zeroForOne, sdk.ZeroDec(), k.storeKey, sdk.ZeroDec(), p.GetTickSpacing()) currentTick := p.GetCurrentTick() - _, currentTickSqrtPrice, err := math.TickToSqrtPrice(currentTick) + _, currentTickSqrtPrice, err := math.TickToSqrtPrice(currentTick.Int64()) if err != nil { return []queryproto.TickLiquidityNet{}, err } @@ -373,7 +370,7 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t // function to validate that start tick and bound tick are // between current tick and the min/max tick depending on the swap direction. validateTickIsInValidRange := func(validateTick sdk.Int) error { - _, validateSqrtPrice, err := math.TickToSqrtPrice(validateTick) + _, validateSqrtPrice, err := math.TickToSqrtPrice(validateTick.Int64()) if err != nil { return err } @@ -434,16 +431,16 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t return liquidityDepths, nil } -func (k Keeper) getTickByTickIndex(ctx sdk.Context, poolId uint64, tickIndex sdk.Int) (model.TickInfo, error) { +func (k Keeper) getTickByTickIndex(ctx sdk.Context, poolId uint64, tickIndex int64) (model.TickInfo, error) { store := ctx.KVStore(k.storeKey) - keyTick := types.KeyTick(poolId, tickIndex.Int64()) + keyTick := types.KeyTick(poolId, tickIndex) tickStruct := model.TickInfo{} found, err := osmoutils.Get(store, keyTick, &tickStruct) if err != nil { return model.TickInfo{}, err } if !found { - return model.TickInfo{}, types.TickNotFoundError{Tick: tickIndex.Int64()} + return model.TickInfo{}, types.TickNotFoundError{Tick: tickIndex} } return tickStruct, nil } diff --git a/x/concentrated-liquidity/tick_test.go b/x/concentrated-liquidity/tick_test.go index 21a802e7099..5df29365a8c 100644 --- a/x/concentrated-liquidity/tick_test.go +++ b/x/concentrated-liquidity/tick_test.go @@ -793,7 +793,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { // testing params poolId uint64 tokenIn string - currentPoolTick sdk.Int + currentPoolTick int64 startTick sdk.Int boundTick sdk.Int @@ -998,7 +998,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: ETH, - currentPoolTick: sdk.NewInt(10), + currentPoolTick: 10, startTick: sdk.NewInt(10), boundTick: sdk.NewInt(-15), expectedLiquidityDepths: []queryproto.TickLiquidityNet{ @@ -1017,7 +1017,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: ETH, - currentPoolTick: sdk.NewInt(21), + currentPoolTick: 21, startTick: sdk.NewInt(10), boundTick: sdk.NewInt(-15), expectedLiquidityDepths: []queryproto.TickLiquidityNet{ @@ -1036,7 +1036,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: USDC, - currentPoolTick: sdk.NewInt(5), + currentPoolTick: 5, startTick: sdk.NewInt(5), boundTick: sdk.NewInt(15), expectedLiquidityDepths: []queryproto.TickLiquidityNet{ @@ -1055,7 +1055,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: USDC, - currentPoolTick: sdk.NewInt(-50), + currentPoolTick: -50, startTick: sdk.NewInt(5), boundTick: sdk.NewInt(15), expectedLiquidityDepths: []queryproto.TickLiquidityNet{ @@ -1138,7 +1138,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: ETH, - currentPoolTick: sdk.NewInt(10), + currentPoolTick: 10, startTick: sdk.NewInt(21), boundTick: sdk.NewInt(-15), expectedError: true, @@ -1152,7 +1152,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { poolId: defaultPoolId, tokenIn: USDC, - currentPoolTick: sdk.NewInt(5), + currentPoolTick: 5, startTick: sdk.NewInt(-50), boundTick: sdk.NewInt(15), expectedError: true, @@ -1179,7 +1179,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { // with tick spacing > 1, requiring price to tick conversion with rounding. curTick, err := math.PriceToTick(curPrice) s.Require().NoError(err) - if !test.currentPoolTick.IsNil() { + if test.currentPoolTick > 0 { _, sqrtPrice, err := math.TickToSqrtPrice(test.currentPoolTick) s.Require().NoError(err) @@ -1187,7 +1187,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { curPrice = sqrtPrice } pool.SetCurrentSqrtPrice(curPrice) - pool.SetCurrentTick(curTick) + pool.SetCurrentTick(sdk.NewInt(curTick)) err = s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, pool) s.Require().NoError(err) @@ -1474,9 +1474,9 @@ func (s *KeeperTestSuite) TestRoundTickToCanonicalPriceTick() { s.Run(test.name, func() { s.SetupTest() - priceTickLower, _, err := cl.TickToSqrtPrice(sdk.NewInt(test.lowerTick)) + priceTickLower, _, err := math.TickToSqrtPrice(test.lowerTick) s.Require().NoError(err) - priceTickUpper, _, err := cl.TickToSqrtPrice(sdk.NewInt(test.upperTick)) + priceTickUpper, _, err := math.TickToSqrtPrice(test.upperTick) s.Require().NoError(err) // System Under Test diff --git a/x/concentrated-liquidity/types/constants.go b/x/concentrated-liquidity/types/constants.go index a7d6faabd2f..3c8549431f1 100644 --- a/x/concentrated-liquidity/types/constants.go +++ b/x/concentrated-liquidity/types/constants.go @@ -18,10 +18,10 @@ var ( MaxSqrtPrice, _ = MaxSpotPrice.ApproxRoot(2) MinSqrtPrice, _ = MinSpotPrice.ApproxRoot(2) // Supported uptimes preset to 1 ns, 1 min, 1 hr, 1D, 1W - SupportedUptimes = []time.Duration{time.Nanosecond, time.Minute, time.Hour, time.Hour * 24, time.Hour * 24 * 7} - ExponentAtPriceOne = sdk.NewInt(-6) - AuthorizedTickSpacing = []uint64{1, 10, 100, 1000} - AuthorizedSwapFees = []sdk.Dec{ + SupportedUptimes = []time.Duration{time.Nanosecond, time.Minute, time.Hour, time.Hour * 24, time.Hour * 24 * 7} + ExponentAtPriceOne int64 = -6 + AuthorizedTickSpacing = []uint64{1, 10, 100, 1000} + AuthorizedSwapFees = []sdk.Dec{ sdk.ZeroDec(), sdk.MustNewDecFromStr("0.0001"), // 0.01% sdk.MustNewDecFromStr("0.0005"), // 0.05% From adaaa15d3ffc1124fd6f2ccb1db23a17482c38b6 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 01:15:41 -0400 Subject: [PATCH 02/14] updates --- tests/cl-genesis-positions/convert.go | 14 +++++++------- tests/e2e/e2e_test.go | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/cl-genesis-positions/convert.go b/tests/cl-genesis-positions/convert.go index b4b7698769b..b5f44b8a5d8 100644 --- a/tests/cl-genesis-positions/convert.go +++ b/tests/cl-genesis-positions/convert.go @@ -156,15 +156,15 @@ func ConvertSubgraphToOsmosisGenesis(positionCreatorAddresses []sdk.AccAddress, panic(err) } - if lowerTickOsmosis.GT(upperTickOsmosis) { + if lowerTickOsmosis > upperTickOsmosis { fmt.Printf("lowerTickOsmosis (%s) > upperTickOsmosis (%s), skipping", lowerTickOsmosis, upperTickOsmosis) continue } - if lowerTickOsmosis.Equal(upperTickOsmosis) { + if lowerTickOsmosis == upperTickOsmosis { // bump up the upper tick by one. We don't care about having exactly the same tick range // Just a roughly similar breakdown - upperTickOsmosis = upperTickOsmosis.Add(sdk.OneInt()) + upperTickOsmosis = upperTickOsmosis + 1 } depositedAmount0, failedParsing := parseStringToInt(uniV3Position.DepositedToken0) @@ -186,8 +186,8 @@ func ConvertSubgraphToOsmosisGenesis(positionCreatorAddresses []sdk.AccAddress, position, err := clMsgServer.CreatePosition(sdk.WrapSDKContext(osmosis.Ctx), &cltypes.MsgCreatePosition{ PoolId: poolId, Sender: randomCreator.String(), - LowerTick: lowerTickOsmosis.Int64(), - UpperTick: upperTickOsmosis.Int64(), + LowerTick: lowerTickOsmosis, + UpperTick: upperTickOsmosis, TokensProvided: tokensProvided, TokenMinAmount0: sdk.ZeroInt(), TokenMinAmount1: sdk.ZeroInt(), @@ -208,8 +208,8 @@ func ConvertSubgraphToOsmosisGenesis(positionCreatorAddresses []sdk.AccAddress, JoinTime: osmosis.Ctx.BlockTime().Format("2006-01-02T15:04:05Z"), // ISO 8601 Liquidity: position.LiquidityCreated.String(), PositionID: strconv.FormatUint(position.PositionId, 10), - LowerTick: lowerTickOsmosis.String(), - UpperTick: upperTickOsmosis.String(), + LowerTick: strconv.FormatInt(lowerTickOsmosis, 10), + UpperTick: strconv.FormatInt(upperTickOsmosis, 10), }) } diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 63f60d3ee92..df3ef201922 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -30,7 +30,7 @@ import ( v16 "github.com/osmosis-labs/osmosis/v15/app/upgrades/v16" "github.com/osmosis-labs/osmosis/v15/tests/e2e/configurer/config" "github.com/osmosis-labs/osmosis/v15/tests/e2e/initialization" - cl "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity" + clmath "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/math" cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" ) @@ -365,15 +365,15 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { // * Uncollected fees from multiple swaps are correctly summed up and collected // tickOffset is a tick index after the next initialized tick to which this swap needs to move the current price - tickOffset := sdk.NewInt(300) + tickOffset := int64(300) sqrtPriceBeforeSwap = concentratedPool.GetCurrentSqrtPrice() liquidityBeforeSwap = concentratedPool.GetLiquidity() - nextInitTick := sdk.NewInt(40000) // address1 position1's upper tick + nextInitTick := int64(40000) // address1 position1's upper tick // Calculate sqrtPrice after and at the next initialized tick (upperTick of address1 position1 - 40000) - _, sqrtPriceAfterNextInitializedTick, err := cl.TickToSqrtPrice(nextInitTick.Add(tickOffset)) + _, sqrtPriceAfterNextInitializedTick, err := clmath.TickToSqrtPrice(nextInitTick + tickOffset) s.Require().NoError(err) - _, sqrtPriceAtNextInitializedTick, err := cl.TickToSqrtPrice(nextInitTick) + _, sqrtPriceAtNextInitializedTick, err := clmath.TickToSqrtPrice(nextInitTick) s.Require().NoError(err) // Calculate Δ(sqrtPrice): @@ -502,10 +502,10 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { // * liquidity of positions that come in range are correctly kicked in // tickOffset is a tick index after the next initialized tick to which this swap needs to move the current price - tickOffset = sdk.NewInt(300) + tickOffset = 300 sqrtPriceBeforeSwap = concentratedPool.GetCurrentSqrtPrice() liquidityBeforeSwap = concentratedPool.GetLiquidity() - nextInitTick = sdk.NewInt(40000) + nextInitTick = 40000 // Calculate amount required to get to // 1) next initialized tick @@ -513,9 +513,9 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { // Using: CalcAmount0Delta = liquidity * ((sqrtPriceB - sqrtPriceA) / (sqrtPriceB * sqrtPriceA)) // Calculate sqrtPrice after and at the next initialized tick (which is upperTick of address1 position1 - 40000) - _, sqrtPricebBelowNextInitializedTick, err := cl.TickToSqrtPrice(nextInitTick.Sub(tickOffset)) + _, sqrtPricebBelowNextInitializedTick, err := clmath.TickToSqrtPrice(nextInitTick - tickOffset) s.Require().NoError(err) - _, sqrtPriceAtNextInitializedTick, err = cl.TickToSqrtPrice(nextInitTick) + _, sqrtPriceAtNextInitializedTick, err = clmath.TickToSqrtPrice(nextInitTick) s.Require().NoError(err) // Calculate numerators From b8af418dced5d0e0ddc1fc4bfed17f6563fb3e79 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 01:40:45 -0400 Subject: [PATCH 03/14] perf: conver tick and exponent at price one to int64 --- .../osmosis/concentrated-liquidity/pool.proto | 13 +- x/concentrated-liquidity/bench_test.go | 16 +- .../client/query_proto_wrap.go | 2 +- x/concentrated-liquidity/fees.go | 4 +- x/concentrated-liquidity/fees_test.go | 32 ++-- x/concentrated-liquidity/incentives.go | 4 +- x/concentrated-liquidity/incentives_test.go | 36 ++-- x/concentrated-liquidity/keeper_test.go | 66 +++---- x/concentrated-liquidity/lp.go | 6 +- x/concentrated-liquidity/lp_test.go | 26 +-- x/concentrated-liquidity/model/pool.go | 20 +-- x/concentrated-liquidity/model/pool.pb.go | 165 +++++++----------- x/concentrated-liquidity/model/pool_test.go | 56 +++--- x/concentrated-liquidity/pool_test.go | 4 +- x/concentrated-liquidity/swaps.go | 6 +- x/concentrated-liquidity/swaps_test.go | 6 +- x/concentrated-liquidity/tick.go | 16 +- x/concentrated-liquidity/tick_test.go | 34 ++-- x/concentrated-liquidity/types/pool.go | 8 +- 19 files changed, 237 insertions(+), 283 deletions(-) diff --git a/proto/osmosis/concentrated-liquidity/pool.proto b/proto/osmosis/concentrated-liquidity/pool.proto index 81eea146973..6c0b47ef047 100644 --- a/proto/osmosis/concentrated-liquidity/pool.proto +++ b/proto/osmosis/concentrated-liquidity/pool.proto @@ -40,19 +40,12 @@ message Pool { (gogoproto.moretags) = "yaml:\"spot_price\"", (gogoproto.nullable) = false ]; - string current_tick = 8 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.moretags) = "yaml:\"current_tick\"", - (gogoproto.nullable) = false - ]; + int64 current_tick = 8 [ (gogoproto.moretags) = "yaml:\"current_tick\"" ]; // tick_spacing must be one of the authorized_tick_spacing values set in the // concentrated-liquidity parameters uint64 tick_spacing = 9 [ (gogoproto.moretags) = "yaml:\"tick_spacing\"" ]; - string exponent_at_price_one = 10 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.moretags) = "yaml:\"exponent_at_price_one\"", - (gogoproto.nullable) = false - ]; + int64 exponent_at_price_one = 10 + [ (gogoproto.moretags) = "yaml:\"exponent_at_price_one\"" ]; // swap_fee is the ratio that is charged on the amount of token in. string swap_fee = 11 [ diff --git a/x/concentrated-liquidity/bench_test.go b/x/concentrated-liquidity/bench_test.go index 3720e78c7b7..95cec986ea6 100644 --- a/x/concentrated-liquidity/bench_test.go +++ b/x/concentrated-liquidity/bench_test.go @@ -120,14 +120,14 @@ func BenchmarkSwapExactAmountIn(b *testing.B) { // Decreasing price so want to be below current tick // minTick <= lowerTick <= currentTick - lowerTick = rand.Int63n(currentTick.Int64()-types.MinTick+1) + types.MinTick + lowerTick = rand.Int63n(currentTick-types.MinTick+1) + types.MinTick // lowerTick <= upperTick <= currentTick - upperTick = currentTick.Int64() - rand.Int63n(int64(math.Abs(float64(currentTick.Int64()-lowerTick)))) + upperTick = currentTick - rand.Int63n(int64(math.Abs(float64(currentTick-lowerTick)))) } else { // Increasing price so want to be above current tick // currentTick <= lowerTick <= maxTick - lowerTick := rand.Int63n(types.MaxTick-currentTick.Int64()+1) + currentTick.Int64() + lowerTick := rand.Int63n(types.MaxTick-currentTick+1) + currentTick // lowerTick <= upperTick <= maxTick upperTick = types.MaxTick - rand.Int63n(int64(math.Abs(float64(types.MaxTick-lowerTick)))) } @@ -171,8 +171,8 @@ func BenchmarkSwapExactAmountIn(b *testing.B) { // Within 10 ticks of the current if tickSpacing <= 10 { for i := 0; i < numberOfPositions; i++ { - lowerTick := currentTick.Int64() - 10 - upperTick := currentTick.Int64() + 10 + lowerTick := currentTick - 10 + upperTick := currentTick + 10 tokenDesired0 := sdk.NewCoin(denom0, sdk.NewInt(maxAmountDeposited).MulRaw(5)) tokenDesired1 := sdk.NewCoin(denom1, sdk.NewInt(maxAmountDeposited).MulRaw(5)) @@ -190,8 +190,8 @@ func BenchmarkSwapExactAmountIn(b *testing.B) { // Within 100 ticks of the current for i := 0; i < numberOfPositions; i++ { - lowerTick := currentTick.Int64() - 100 - upperTick := currentTick.Int64() + 100 + lowerTick := currentTick - 100 + upperTick := currentTick + 100 // Normalize lowerTick to be a multiple of tickSpacing lowerTick = lowerTick + (tickSpacing - lowerTick%tickSpacing) // Normalize upperTick to be a multiple of tickSpacing @@ -214,7 +214,7 @@ func BenchmarkSwapExactAmountIn(b *testing.B) { swapAmountIn := sdk.MustNewDecFromStr(amountIn).TruncateInt() largeSwapInCoin := sdk.NewCoin(denomIn, swapAmountIn) - liquidityNet, err := clKeeper.GetTickLiquidityNetInDirection(s.Ctx, pool.GetId(), largeSwapInCoin.Denom, currentTick, sdk.Int{}) + liquidityNet, err := clKeeper.GetTickLiquidityNetInDirection(s.Ctx, pool.GetId(), largeSwapInCoin.Denom, sdk.NewInt(currentTick), sdk.Int{}) noError(err) fmt.Println("num_ticks_traversed", len(liquidityNet)) diff --git a/x/concentrated-liquidity/client/query_proto_wrap.go b/x/concentrated-liquidity/client/query_proto_wrap.go index 7e1a3b1dcb3..caf8d9c2252 100644 --- a/x/concentrated-liquidity/client/query_proto_wrap.go +++ b/x/concentrated-liquidity/client/query_proto_wrap.go @@ -153,7 +153,7 @@ func (q Querier) LiquidityNetInDirection(ctx sdk.Context, req clquery.LiquidityN return nil, err } - return &clquery.LiquidityNetInDirectionResponse{LiquidityDepths: liquidityDepths, CurrentLiquidity: pool.GetLiquidity(), CurrentTick: pool.GetCurrentTick().Int64()}, nil + return &clquery.LiquidityNetInDirectionResponse{LiquidityDepths: liquidityDepths, CurrentLiquidity: pool.GetLiquidity(), CurrentTick: pool.GetCurrentTick()}, nil } func (q Querier) ClaimableFees(ctx sdk.Context, req clquery.ClaimableFeesRequest) (*clquery.ClaimableFeesResponse, error) { diff --git a/x/concentrated-liquidity/fees.go b/x/concentrated-liquidity/fees.go index 1f9cc119f1e..cc271b84869 100644 --- a/x/concentrated-liquidity/fees.go +++ b/x/concentrated-liquidity/fees.go @@ -128,7 +128,7 @@ func (k Keeper) getFeeGrowthOutside(ctx sdk.Context, poolId uint64, lowerTick, u if err != nil { return sdk.DecCoins{}, err } - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() // get lower, upper tick info lowerTickInfo, err := k.GetTickInfo(ctx, poolId, lowerTick) @@ -164,7 +164,7 @@ func (k Keeper) getInitialFeeGrowthOppositeDirectionOfLastTraversalForTick(ctx s return sdk.DecCoins{}, err } - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() if currentTick >= tick { feeAccumulator, err := k.GetFeeAccumulator(ctx, poolId) if err != nil { diff --git a/x/concentrated-liquidity/fees_test.go b/x/concentrated-liquidity/fees_test.go index 295184239c6..0836c91a9fa 100644 --- a/x/concentrated-liquidity/fees_test.go +++ b/x/concentrated-liquidity/fees_test.go @@ -401,11 +401,11 @@ func (s *KeeperTestSuite) TestGetFeeGrowthOutside() { var pool types.ConcentratedPoolExtension if tc.poolSetup { pool = s.PrepareConcentratedPool() - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() s.initializeTick(s.Ctx, currentTick, tc.lowerTick, defaultInitialLiquidity, tc.lowerTickFeeGrowthOutside, emptyUptimeTrackers, false) s.initializeTick(s.Ctx, currentTick, tc.upperTick, defaultInitialLiquidity, tc.upperTickFeeGrowthOutside, emptyUptimeTrackers, true) - pool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + pool.SetCurrentTick(tc.currentTick) err := s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, pool) s.Require().NoError(err) err = s.App.ConcentratedLiquidityKeeper.ChargeFee(s.Ctx, validPoolId, tc.globalFeeGrowth) @@ -916,7 +916,7 @@ func (s *KeeperTestSuite) TestQueryAndCollectFees() { s.initializeTick(ctx, tc.currentTick, tc.upperTick, tc.initialLiquidity, tc.upperTickFeeGrowthOutside, emptyUptimeTrackers, true) - validPool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + validPool.SetCurrentTick(tc.currentTick) err = clKeeper.SetPool(ctx, validPool) s.Require().NoError(err) @@ -1179,7 +1179,7 @@ func (s *KeeperTestSuite) TestPrepareClaimableFees() { s.initializeFeeAccumulatorPositionWithLiquidity(ctx, validPoolId, tc.lowerTick, tc.upperTick, DefaultPositionId, tc.initialLiquidity) s.initializeTick(ctx, tc.currentTick, tc.lowerTick, tc.initialLiquidity, tc.lowerTickFeeGrowthOutside, emptyUptimeTrackers, false) s.initializeTick(ctx, tc.currentTick, tc.upperTick, tc.initialLiquidity, tc.upperTickFeeGrowthOutside, emptyUptimeTrackers, true) - validPool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + validPool.SetCurrentTick(tc.currentTick) _ = clKeeper.SetPool(ctx, validPool) @@ -1287,10 +1287,10 @@ func (s *KeeperTestSuite) TestInitOrUpdateFeeAccumulatorPosition_UpdatingPositio s.crossTickAndChargeFee(poolId, DefaultLowerTick) } - err := s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, poolId, pool.GetCurrentTick().Int64(), DefaultLowerTick, DefaultLiquidityAmt, false) + err := s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, poolId, pool.GetCurrentTick(), DefaultLowerTick, DefaultLiquidityAmt, false) s.Require().NoError(err) - err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, poolId, pool.GetCurrentTick().Int64(), DefaultUpperTick, DefaultLiquidityAmt, true) + err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, poolId, pool.GetCurrentTick(), DefaultUpperTick, DefaultLiquidityAmt, true) s.Require().NoError(err) // InitOrUpdateFeeAccumulatorPosition #1 lower tick to upper tick @@ -1456,11 +1456,11 @@ func (s *KeeperTestSuite) TestFunctional_Fees_Swaps() { // Swap multiple times USDC for ETH, therefore increasing the spot price ticksActivatedAfterEachSwap, totalFeesExpected, _, _ := s.swapAndTrackXTimesInARow(clPool.GetId(), DefaultCoin1, ETH, types.MaxSpotPrice, positions.numSwaps) - s.CollectAndAssertFees(s.Ctx, clPool.GetId(), totalFeesExpected, positionIds, [][]sdk.Int{ticksActivatedAfterEachSwap}, onlyUSDC, positions) + s.CollectAndAssertFees(s.Ctx, clPool.GetId(), totalFeesExpected, positionIds, [][]int64{ticksActivatedAfterEachSwap}, onlyUSDC, positions) // Swap multiple times ETH for USDC, therefore decreasing the spot price ticksActivatedAfterEachSwap, totalFeesExpected, _, _ = s.swapAndTrackXTimesInARow(clPool.GetId(), DefaultCoin0, USDC, types.MinSpotPrice, positions.numSwaps) - s.CollectAndAssertFees(s.Ctx, clPool.GetId(), totalFeesExpected, positionIds, [][]sdk.Int{ticksActivatedAfterEachSwap}, onlyETH, positions) + s.CollectAndAssertFees(s.Ctx, clPool.GetId(), totalFeesExpected, positionIds, [][]int64{ticksActivatedAfterEachSwap}, onlyETH, positions) // Do the same swaps as before, however this time we collect fees after both swap directions are complete. ticksActivatedAfterEachSwapUp, totalFeesExpectedUp, _, _ := s.swapAndTrackXTimesInARow(clPool.GetId(), DefaultCoin1, ETH, types.MaxSpotPrice, positions.numSwaps) @@ -1469,7 +1469,7 @@ func (s *KeeperTestSuite) TestFunctional_Fees_Swaps() { // We expect all positions to have both denoms in their fee accumulators except USDC for the overlapping range position since // it was not activated during the USDC -> ETH swap direction but was activated during the ETH -> USDC swap direction. - ticksActivatedAfterEachSwapTest := [][]sdk.Int{ticksActivatedAfterEachSwapUp, ticksActivatedAfterEachSwapDown} + ticksActivatedAfterEachSwapTest := [][]int64{ticksActivatedAfterEachSwapUp, ticksActivatedAfterEachSwapDown} denomsExpected := [][]string{{USDC, ETH}, {USDC, ETH}, {USDC, ETH}, {NoUSDCExpected, ETH}} s.CollectAndAssertFees(s.Ctx, clPool.GetId(), totalFeesExpected, positionIds, ticksActivatedAfterEachSwapTest, denomsExpected, positions) @@ -1514,7 +1514,7 @@ func (s *KeeperTestSuite) TestFunctional_Fees_LP() { s.Require().NoError(err) // Collect fees. - feesCollected := s.collectFeesAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{USDC}, [][]sdk.Int{ticksActivatedAfterEachSwap}) + feesCollected := s.collectFeesAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{USDC}, [][]int64{ticksActivatedAfterEachSwap}) expectedFeesTruncated := totalFeesExpected for i, feeToken := range totalFeesExpected { // We run expected fees through a cycle of divison and multiplication by liquidity to capture appropriate rounding behavior @@ -1547,7 +1547,7 @@ func (s *KeeperTestSuite) TestFunctional_Fees_LP() { _, err = s.App.ConcentratedLiquidityKeeper.CollectFees(ctx, owner, positionIdTwo) s.Require().Error(err) - feesCollected = s.collectFeesAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{ETH}, [][]sdk.Int{ticksActivatedAfterEachSwap}) + feesCollected = s.collectFeesAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{ETH}, [][]int64{ticksActivatedAfterEachSwap}) // total fees * half liquidity / (full liquidity + half liquidity) expectesFeesCollected := totalFeesExpected.AmountOf(ETH).ToDec().Mul(halfLiquidity.Quo(fullLiquidity.Add(halfLiquidity))).TruncateInt() @@ -1565,7 +1565,7 @@ func (s *KeeperTestSuite) TestFunctional_Fees_LP() { // CollectAndAssertFees collects fees from a given pool for all positions and verifies that the total fees collected match the expected total fees. // The method also checks that if the ticks that were active during the swap lie within the range of a position, then the position's fee accumulators // are not empty. The total fees collected are compared to the expected total fees within an additive tolerance defined by an error tolerance struct. -func (s *KeeperTestSuite) CollectAndAssertFees(ctx sdk.Context, poolId uint64, totalFees sdk.Coins, positionIds [][]uint64, activeTicks [][]sdk.Int, expectedFeeDenoms [][]string, positions Positions) { +func (s *KeeperTestSuite) CollectAndAssertFees(ctx sdk.Context, poolId uint64, totalFees sdk.Coins, positionIds [][]uint64, activeTicks [][]int64, expectedFeeDenoms [][]string, positions Positions) { var totalFeesCollected sdk.Coins // Claim full range position fees across all four accounts for i := 0; i < positions.numFullRange; i++ { @@ -1602,12 +1602,12 @@ func (s *KeeperTestSuite) CollectAndAssertFees(ctx sdk.Context, poolId uint64, t // tickStatusInvariance tests if the swap position was active during the given tick range and // checks that the fees collected are non-zero if the position was active, or zero otherwise. -func (s *KeeperTestSuite) tickStatusInvariance(ticksActivatedAfterEachSwap [][]sdk.Int, lowerTick, upperTick int64, coins sdk.Coins, expectedFeeDenoms []string) { +func (s *KeeperTestSuite) tickStatusInvariance(ticksActivatedAfterEachSwap [][]int64, lowerTick, upperTick int64, coins sdk.Coins, expectedFeeDenoms []string) { var positionWasActive bool // Check if the position was active during the swap for i, ticks := range ticksActivatedAfterEachSwap { for _, tick := range ticks { - if tick.GTE(sdk.NewInt(lowerTick)) && tick.LTE(sdk.NewInt(upperTick)) { + if tick >= lowerTick && tick <= upperTick { positionWasActive = true break } @@ -1626,7 +1626,7 @@ func (s *KeeperTestSuite) tickStatusInvariance(ticksActivatedAfterEachSwap [][]s // swapAndTrackXTimesInARow performs `numSwaps` swaps and tracks the tick activated after each swap. // It also returns the total fees collected, the total token in, and the total token out. -func (s *KeeperTestSuite) swapAndTrackXTimesInARow(poolId uint64, coinIn sdk.Coin, coinOutDenom string, priceLimit sdk.Dec, numSwaps int) (ticksActivatedAfterEachSwap []sdk.Int, totalFees sdk.Coins, totalTokenIn sdk.Coin, totalTokenOut sdk.Coin) { +func (s *KeeperTestSuite) swapAndTrackXTimesInARow(poolId uint64, coinIn sdk.Coin, coinOutDenom string, priceLimit sdk.Dec, numSwaps int) (ticksActivatedAfterEachSwap []int64, totalFees sdk.Coins, totalTokenIn sdk.Coin, totalTokenOut sdk.Coin) { // Retrieve pool clPool, err := s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, poolId) s.Require().NoError(err) @@ -1656,7 +1656,7 @@ func (s *KeeperTestSuite) swapAndTrackXTimesInARow(poolId uint64, coinIn sdk.Coi } // collectFeesAndCheckInvariance collects fees from the concentrated liquidity pool and checks the resulting tick status invariance. -func (s *KeeperTestSuite) collectFeesAndCheckInvariance(ctx sdk.Context, accountIndex int, minTick, maxTick int64, positionId uint64, feesCollected sdk.Coins, expectedFeeDenoms []string, activeTicks [][]sdk.Int) (totalFeesCollected sdk.Coins) { +func (s *KeeperTestSuite) collectFeesAndCheckInvariance(ctx sdk.Context, accountIndex int, minTick, maxTick int64, positionId uint64, feesCollected sdk.Coins, expectedFeeDenoms []string, activeTicks [][]int64) (totalFeesCollected sdk.Coins) { coins, err := s.App.ConcentratedLiquidityKeeper.CollectFees(ctx, s.TestAccs[accountIndex], positionId) s.Require().NoError(err) totalFeesCollected = feesCollected.Add(coins...) diff --git a/x/concentrated-liquidity/incentives.go b/x/concentrated-liquidity/incentives.go index 43af2160a30..17f9097c64a 100644 --- a/x/concentrated-liquidity/incentives.go +++ b/x/concentrated-liquidity/incentives.go @@ -84,7 +84,7 @@ func (k Keeper) getInitialUptimeGrowthOppositeDirectionOfLastTraversalForTick(ct return []sdk.DecCoins{}, err } - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() if currentTick >= tick { uptimeAccumulatorValues, err := k.getUptimeAccumulatorValues(ctx, poolId) if err != nil { @@ -566,7 +566,7 @@ func (k Keeper) GetUptimeGrowthInsideRange(ctx sdk.Context, poolId uint64, lower } // Get current, lower, and upper ticks - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() lowerTickInfo, err := k.GetTickInfo(ctx, poolId, lowerTick) if err != nil { return []sdk.DecCoins{}, err diff --git a/x/concentrated-liquidity/incentives_test.go b/x/concentrated-liquidity/incentives_test.go index 68e2ed667b4..4fb8d5456e4 100644 --- a/x/concentrated-liquidity/incentives_test.go +++ b/x/concentrated-liquidity/incentives_test.go @@ -940,7 +940,7 @@ func (s *KeeperTestSuite) TestUpdateUptimeAccumulatorsToNow() { if !tc.isInvalidBalancerPool { depositedCoins := sdk.NewCoins(sdk.NewCoin(clPool.GetToken0(), testQualifyingDepositsOne), sdk.NewCoin(clPool.GetToken1(), testQualifyingDepositsOne)) s.FundAcc(testAddressOne, depositedCoins) - _, _, _, qualifyingLiquidity, _, _, _, err = clKeeper.CreatePosition(s.Ctx, clPool.GetId(), testAddressOne, depositedCoins, sdk.ZeroInt(), sdk.ZeroInt(), clPool.GetCurrentTick().Int64()-100, clPool.GetCurrentTick().Int64()+100) + _, _, _, qualifyingLiquidity, _, _, _, err = clKeeper.CreatePosition(s.Ctx, clPool.GetId(), testAddressOne, depositedCoins, sdk.ZeroInt(), sdk.ZeroInt(), clPool.GetCurrentTick()-100, clPool.GetCurrentTick()+100) s.Require().NoError(err) // If a canonical balancer pool exists, we add its respective shares to the qualifying amount as well. @@ -1463,7 +1463,7 @@ func (s *KeeperTestSuite) TestGetUptimeGrowthInsideRange() { var pool types.ConcentratedPoolExtension if tc.poolSetup { pool = s.PrepareConcentratedPool() - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() // Update global uptime accums err := addToUptimeAccums(s.Ctx, pool.GetId(), s.App.ConcentratedLiquidityKeeper, tc.globalUptimeGrowth) @@ -1472,7 +1472,7 @@ func (s *KeeperTestSuite) TestGetUptimeGrowthInsideRange() { // Update tick-level uptime trackers s.initializeTick(s.Ctx, currentTick, tc.lowerTick, defaultInitialLiquidity, cl.EmptyCoins, wrapUptimeTrackers(tc.lowerTickUptimeGrowthOutside), true) s.initializeTick(s.Ctx, currentTick, tc.upperTick, defaultInitialLiquidity, cl.EmptyCoins, wrapUptimeTrackers(tc.upperTickUptimeGrowthOutside), false) - pool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + pool.SetCurrentTick(tc.currentTick) err = s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, pool) s.Require().NoError(err) } @@ -1788,7 +1788,7 @@ func (s *KeeperTestSuite) TestGetUptimeGrowthOutsideRange() { var pool types.ConcentratedPoolExtension if tc.poolSetup { pool = s.PrepareConcentratedPool() - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() // Update global uptime accums err := addToUptimeAccums(s.Ctx, pool.GetId(), s.App.ConcentratedLiquidityKeeper, tc.globalUptimeGrowth) @@ -1797,7 +1797,7 @@ func (s *KeeperTestSuite) TestGetUptimeGrowthOutsideRange() { // Update tick-level uptime trackers s.initializeTick(s.Ctx, currentTick, tc.lowerTick, defaultInitialLiquidity, cl.EmptyCoins, wrapUptimeTrackers(tc.lowerTickUptimeGrowthOutside), true) s.initializeTick(s.Ctx, currentTick, tc.upperTick, defaultInitialLiquidity, cl.EmptyCoins, wrapUptimeTrackers(tc.upperTickUptimeGrowthOutside), false) - pool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + pool.SetCurrentTick(tc.currentTick) err = s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, pool) s.Require().NoError(err) } @@ -1830,7 +1830,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { lowerTick tick upperTick tick positionId uint64 - currentTickIndex sdk.Int + currentTickIndex int64 globalUptimeAccumValues []sdk.DecCoins // For testing updates on existing liquidity @@ -1857,7 +1857,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { uptimeTrackers: wrapUptimeTrackers(uptimeHelper.hundredTokensMultiDenom), }, positionId: DefaultPositionId, - currentTickIndex: sdk.ZeroInt(), + currentTickIndex: 0, globalUptimeAccumValues: uptimeHelper.threeHundredTokensMultiDenom, expectedInitAccumValue: uptimeHelper.hundredTokensMultiDenom, expectedUnclaimedRewards: uptimeHelper.emptyExpectedAccumValues, @@ -1874,7 +1874,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { uptimeTrackers: wrapUptimeTrackers(uptimeHelper.threeHundredTokensMultiDenom), }, positionId: DefaultPositionId, - currentTickIndex: sdk.NewInt(51), + currentTickIndex: 51, globalUptimeAccumValues: uptimeHelper.fourHundredTokensMultiDenom, expectedInitAccumValue: uptimeHelper.twoHundredTokensMultiDenom, expectedUnclaimedRewards: uptimeHelper.emptyExpectedAccumValues, @@ -1891,7 +1891,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { uptimeTrackers: wrapUptimeTrackers(uptimeHelper.hundredTokensMultiDenom), }, positionId: DefaultPositionId, - currentTickIndex: sdk.NewInt(-51), + currentTickIndex: -51, globalUptimeAccumValues: uptimeHelper.fourHundredTokensMultiDenom, expectedInitAccumValue: uptimeHelper.twoHundredTokensMultiDenom, expectedUnclaimedRewards: uptimeHelper.emptyExpectedAccumValues, @@ -1908,7 +1908,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { uptimeTrackers: wrapUptimeTrackers(uptimeHelper.hundredTokensMultiDenom), }, positionId: DefaultPositionId, - currentTickIndex: sdk.ZeroInt(), + currentTickIndex: 0, // We set up the global accum values such that the growth inside is equal to 100 of each denom // for each uptime tracker. Let the uptime growth inside (UGI) = 100 @@ -1960,7 +1960,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { uptimeTrackers: wrapUptimeTrackers(uptimeHelper.hundredTokensMultiDenom), }, positionId: DefaultPositionId, - currentTickIndex: sdk.ZeroInt(), + currentTickIndex: 0, globalUptimeAccumValues: uptimeHelper.threeHundredTokensMultiDenom, expectedErr: types.NonPositiveLiquidityForNewPositionError{PositionId: DefaultPositionId, LiquidityDelta: DefaultLiquidityAmt.Neg()}, @@ -1980,8 +1980,8 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { clPool := s.PrepareConcentratedPool() // Initialize lower, upper, and current ticks - s.initializeTick(s.Ctx, test.currentTickIndex.Int64(), test.lowerTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.lowerTick.uptimeTrackers, true) - s.initializeTick(s.Ctx, test.currentTickIndex.Int64(), test.upperTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.upperTick.uptimeTrackers, false) + s.initializeTick(s.Ctx, test.currentTickIndex, test.lowerTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.lowerTick.uptimeTrackers, true) + s.initializeTick(s.Ctx, test.currentTickIndex, test.upperTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.upperTick.uptimeTrackers, false) clPool.SetCurrentTick(test.currentTickIndex) err := s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, clPool) s.Require().NoError(err) @@ -1997,8 +1997,8 @@ func (s *KeeperTestSuite) TestInitOrUpdatePositionUptimeAccumulators() { err = s.App.ConcentratedLiquidityKeeper.SetPosition(s.Ctx, clPool.GetId(), s.TestAccs[0], test.lowerTick.tickIndex, test.upperTick.tickIndex, DefaultJoinTime, test.positionLiquidity, DefaultPositionId, DefaultUnderlyingLockId) s.Require().NoError(err) - s.initializeTick(s.Ctx, test.currentTickIndex.Int64(), test.newLowerTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.newLowerTick.uptimeTrackers, true) - s.initializeTick(s.Ctx, test.currentTickIndex.Int64(), test.newUpperTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.newUpperTick.uptimeTrackers, false) + s.initializeTick(s.Ctx, test.currentTickIndex, test.newLowerTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.newLowerTick.uptimeTrackers, true) + s.initializeTick(s.Ctx, test.currentTickIndex, test.newUpperTick.tickIndex, sdk.ZeroDec(), cl.EmptyCoins, test.newUpperTick.uptimeTrackers, false) clPool.SetCurrentTick(test.currentTickIndex) err = s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, clPool) s.Require().NoError(err) @@ -2891,7 +2891,7 @@ func (s *KeeperTestSuite) TestQueryAndCollectIncentives() { } } - validPool.SetCurrentTick(sdk.NewInt(tc.currentTick)) + validPool.SetCurrentTick(tc.currentTick) err := clKeeper.SetPool(ctx, validPool) s.Require().NoError(err) @@ -3432,11 +3432,11 @@ func (s *KeeperTestSuite) TestQueryAndClaimAllIncentives() { clPool.SetCurrentTick(DefaultCurrTick) if tc.growthOutside != nil { - s.addUptimeGrowthOutsideRange(s.Ctx, validPoolId, defaultSender, DefaultCurrTick.Int64(), DefaultLowerTick, DefaultUpperTick, tc.growthOutside) + s.addUptimeGrowthOutsideRange(s.Ctx, validPoolId, defaultSender, DefaultCurrTick, DefaultLowerTick, DefaultUpperTick, tc.growthOutside) } if tc.growthInside != nil { - s.addUptimeGrowthInsideRange(s.Ctx, validPoolId, defaultSender, DefaultCurrTick.Int64(), DefaultLowerTick, DefaultUpperTick, tc.growthInside) + s.addUptimeGrowthInsideRange(s.Ctx, validPoolId, defaultSender, DefaultCurrTick, DefaultLowerTick, DefaultUpperTick, tc.growthInside) } err = clKeeper.SetPool(s.Ctx, clPool) diff --git a/x/concentrated-liquidity/keeper_test.go b/x/concentrated-liquidity/keeper_test.go index 14e541bd4bc..25704c53e48 100644 --- a/x/concentrated-liquidity/keeper_test.go +++ b/x/concentrated-liquidity/keeper_test.go @@ -21,39 +21,39 @@ import ( ) var ( - DefaultMinTick, DefaultMaxTick = types.MinTick, types.MaxTick - DefaultLowerPrice = sdk.NewDec(4545) - DefaultLowerTick = int64(30545000) - DefaultUpperPrice = sdk.NewDec(5500) - DefaultUpperTick = int64(31500000) - DefaultCurrPrice = sdk.NewDec(5000) - DefaultCurrTick = sdk.NewInt(31000000) - DefaultCurrSqrtPrice, _ = DefaultCurrPrice.ApproxSqrt() // 70.710678118654752440 - DefaultZeroSwapFee = sdk.ZeroDec() - DefaultFeeAccumCoins = sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(50))) - DefaultPositionId = uint64(1) - DefaultUnderlyingLockId = uint64(0) - DefaultJoinTime = time.Unix(0, 0).UTC() - ETH = "eth" - DefaultAmt0 = sdk.NewInt(1000000) - DefaultAmt0Expected = sdk.NewInt(998976) - DefaultCoin0 = sdk.NewCoin(ETH, DefaultAmt0) - USDC = "usdc" - DefaultAmt1 = sdk.NewInt(5000000000) - DefaultAmt1Expected = sdk.NewInt(5000000000) - DefaultCoin1 = sdk.NewCoin(USDC, DefaultAmt1) - DefaultCoins = sdk.NewCoins(DefaultCoin0, DefaultCoin1) - DefaultLiquidityAmt = sdk.MustNewDecFromStr("1517882343.751510418088349649") - FullRangeLiquidityAmt = sdk.MustNewDecFromStr("70710678.118654752940000000") - DefaultTickSpacing = uint64(100) - PoolCreationFee = poolmanagertypes.DefaultParams().PoolCreationFee - DefaultExponentConsecutivePositionLowerTick, _ = math.PriceToTickRoundDown(sdk.NewDec(5500), DefaultTickSpacing) - DefaultExponentConsecutivePositionUpperTick, _ = math.PriceToTickRoundDown(sdk.NewDec(6250), DefaultTickSpacing) - DefaultExponentOverlappingPositionLowerTick, _ = math.PriceToTickRoundDown(sdk.NewDec(4000), DefaultTickSpacing) - DefaultExponentOverlappingPositionUpperTick, _ = math.PriceToTickRoundDown(sdk.NewDec(4999), DefaultTickSpacing) - BAR = "bar" - FOO = "foo" - InsufficientFundsError = fmt.Errorf("insufficient funds") + DefaultMinTick, DefaultMaxTick = types.MinTick, types.MaxTick + DefaultLowerPrice = sdk.NewDec(4545) + DefaultLowerTick = int64(30545000) + DefaultUpperPrice = sdk.NewDec(5500) + DefaultUpperTick = int64(31500000) + DefaultCurrPrice = sdk.NewDec(5000) + DefaultCurrTick int64 = 31000000 + DefaultCurrSqrtPrice, _ = DefaultCurrPrice.ApproxSqrt() // 70.710678118654752440 + DefaultZeroSwapFee = sdk.ZeroDec() + DefaultFeeAccumCoins = sdk.NewDecCoins(sdk.NewDecCoin("foo", sdk.NewInt(50))) + DefaultPositionId = uint64(1) + DefaultUnderlyingLockId = uint64(0) + DefaultJoinTime = time.Unix(0, 0).UTC() + ETH = "eth" + DefaultAmt0 = sdk.NewInt(1000000) + DefaultAmt0Expected = sdk.NewInt(998976) + DefaultCoin0 = sdk.NewCoin(ETH, DefaultAmt0) + USDC = "usdc" + DefaultAmt1 = sdk.NewInt(5000000000) + DefaultAmt1Expected = sdk.NewInt(5000000000) + DefaultCoin1 = sdk.NewCoin(USDC, DefaultAmt1) + DefaultCoins = sdk.NewCoins(DefaultCoin0, DefaultCoin1) + DefaultLiquidityAmt = sdk.MustNewDecFromStr("1517882343.751510418088349649") + FullRangeLiquidityAmt = sdk.MustNewDecFromStr("70710678.118654752940000000") + DefaultTickSpacing = uint64(100) + PoolCreationFee = poolmanagertypes.DefaultParams().PoolCreationFee + DefaultExponentConsecutivePositionLowerTick, _ = math.PriceToTickRoundDown(sdk.NewDec(5500), DefaultTickSpacing) + DefaultExponentConsecutivePositionUpperTick, _ = math.PriceToTickRoundDown(sdk.NewDec(6250), DefaultTickSpacing) + DefaultExponentOverlappingPositionLowerTick, _ = math.PriceToTickRoundDown(sdk.NewDec(4000), DefaultTickSpacing) + DefaultExponentOverlappingPositionUpperTick, _ = math.PriceToTickRoundDown(sdk.NewDec(4999), DefaultTickSpacing) + BAR = "bar" + FOO = "foo" + InsufficientFundsError = fmt.Errorf("insufficient funds") ) type KeeperTestSuite struct { diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 388aef77b64..9f42bde0e47 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -342,7 +342,7 @@ func (k Keeper) UpdatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr return sdk.Int{}, sdk.Int{}, err } - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() // update tickInfo state for lower tick and upper tick err = k.initOrUpdateTick(ctx, poolId, currentTick, lowerTick, liquidityDelta, false) @@ -438,7 +438,7 @@ func (k Keeper) initializeInitialPositionForPool(ctx sdk.Context, pool types.Con // In such a case, we do not want to round the sqrt price to 100_000_000 X/Y, but rather // let it float within the possible tick range. pool.SetCurrentSqrtPrice(initialCurSqrtPrice) - pool.SetCurrentTick(sdk.NewInt(initialTick)) + pool.SetCurrentTick(initialTick) err = k.setPool(ctx, pool) if err != nil { return err @@ -466,7 +466,7 @@ func (k Keeper) uninitializePool(ctx sdk.Context, poolId uint64) error { } pool.SetCurrentSqrtPrice(sdk.ZeroDec()) - pool.SetCurrentTick(sdk.ZeroInt()) + pool.SetCurrentTick(0) if err := k.setPool(ctx, pool); err != nil { return err diff --git a/x/concentrated-liquidity/lp_test.go b/x/concentrated-liquidity/lp_test.go index d613081ad01..fa1fbc61008 100644 --- a/x/concentrated-liquidity/lp_test.go +++ b/x/concentrated-liquidity/lp_test.go @@ -16,7 +16,7 @@ import ( type lpTest struct { poolId uint64 - currentTick sdk.Int + currentTick int64 lowerTick int64 expectedLowerTick int64 upperTick int64 @@ -93,7 +93,7 @@ var ( "lower tick < upper tick < current tick -> both tick's fee accumulators are updated with one eth": { lowerTick: DefaultLowerTick, upperTick: DefaultUpperTick, - currentTick: sdk.NewInt(DefaultUpperTick + 100), + currentTick: DefaultUpperTick + 100, preSetChargeFee: oneEth, expectedFeeGrowthOutsideLower: oneEthCoins, @@ -105,7 +105,7 @@ var ( "lower tick < upper tick < current tick -> the fee is not charged so tick accumulators are unset": { lowerTick: DefaultLowerTick, upperTick: DefaultUpperTick, - currentTick: sdk.NewInt(DefaultUpperTick + 100), + currentTick: DefaultUpperTick + 100, preSetChargeFee: sdk.NewDecCoin(ETH, sdk.ZeroInt()), // zero fee expectedFeeGrowthOutsideLower: oneEthCoins, @@ -117,7 +117,7 @@ var ( "current tick < lower tick < upper tick -> both tick's fee accumulators are unitilialized": { lowerTick: DefaultLowerTick, upperTick: DefaultUpperTick, - currentTick: sdk.NewInt(DefaultLowerTick - 100), + currentTick: DefaultLowerTick - 100, preSetChargeFee: oneEth, expectedFeeGrowthOutsideLower: oneEthCoins, @@ -129,7 +129,7 @@ var ( "lower tick < upper tick == current tick -> both tick's fee accumulators are updated with one eth": { lowerTick: DefaultLowerTick, upperTick: DefaultUpperTick, - currentTick: sdk.NewInt(DefaultUpperTick), + currentTick: DefaultUpperTick, preSetChargeFee: oneEth, expectedFeeGrowthOutsideLower: oneEthCoins, @@ -141,7 +141,7 @@ var ( "second position: lower tick < upper tick == current tick -> both tick's fee accumulators are updated with one eth": { lowerTick: DefaultLowerTick, upperTick: DefaultUpperTick, - currentTick: sdk.NewInt(DefaultUpperTick), + currentTick: DefaultUpperTick, isNotFirstPositionWithSameAccount: true, positionId: 2, @@ -159,7 +159,7 @@ var ( expectedLowerTick: -161000000, upperTick: -160009800, expectedUpperTick: -160000000, - currentTick: sdk.NewInt(DefaultUpperTick), + currentTick: DefaultUpperTick, isNotFirstPositionWithSameAccount: true, positionId: 2, @@ -1444,7 +1444,7 @@ func (s *KeeperTestSuite) TestInitializeInitialPositionForPool() { amount1Desired sdk.Int tickSpacing uint64 expectedCurrSqrtPrice sdk.Dec - expectedTick sdk.Int + expectedTick int64 expectedError error } tests := map[string]sendTest{ @@ -1460,21 +1460,21 @@ func (s *KeeperTestSuite) TestInitializeInitialPositionForPool() { amount1Desired: sdk.NewInt(100_000_050), tickSpacing: DefaultTickSpacing, expectedCurrSqrtPrice: sqrt(100_000_050), - expectedTick: sdk.NewInt(72000000), + expectedTick: 72000000, }, "100_000_051 and tick spacing 100, price level where curr sqrt price does not translate to allowed tick (assumes exponent at price one of -6 and tick spacing of 100)": { amount0Desired: sdk.OneInt(), amount1Desired: sdk.NewInt(100_000_051), tickSpacing: DefaultTickSpacing, expectedCurrSqrtPrice: sqrt(100_000_051), - expectedTick: sdk.NewInt(72000000), + expectedTick: 72000000, }, "100_000_051 and tick spacing 1, price level where curr sqrt price translates to allowed tick (assumes exponent at price one of -6 and tick spacing of 1)": { amount0Desired: sdk.OneInt(), amount1Desired: sdk.NewInt(100_000_051), tickSpacing: 1, expectedCurrSqrtPrice: sqrt(100_000_051), - expectedTick: sdk.NewInt(72000001), + expectedTick: 72000001, }, "error: amount0Desired is zero": { amount0Desired: sdk.ZeroInt(), @@ -1517,7 +1517,7 @@ func (s *KeeperTestSuite) TestInitializeInitialPositionForPool() { s.Require().NoError(err) s.Require().Equal(tc.expectedCurrSqrtPrice.String(), pool.GetCurrentSqrtPrice().String()) - s.Require().Equal(tc.expectedTick.String(), pool.GetCurrentTick().String()) + s.Require().Equal(tc.expectedTick, pool.GetCurrentTick()) } }) } @@ -1691,7 +1691,7 @@ func (s *KeeperTestSuite) TestUninitializePool() { actualSqrtPrice := pool.GetCurrentSqrtPrice() actualTick := pool.GetCurrentTick() s.Require().Equal(sdk.ZeroDec(), actualSqrtPrice) - s.Require().Equal(sdk.ZeroInt(), actualTick) + s.Require().Equal(int64(0), actualTick) }) } } diff --git a/x/concentrated-liquidity/model/pool.go b/x/concentrated-liquidity/model/pool.go index d1693043631..5869ba60f09 100644 --- a/x/concentrated-liquidity/model/pool.go +++ b/x/concentrated-liquidity/model/pool.go @@ -41,12 +41,12 @@ func NewConcentratedLiquidityPool(poolId uint64, denom0, denom1 string, tickSpac IncentivesAddress: osmoutils.NewModuleAddressWithPrefix(types.ModuleName, incentivesAddressPrefix, sdk.Uint64ToBigEndian(poolId)).String(), Id: poolId, CurrentSqrtPrice: sdk.ZeroDec(), - CurrentTick: sdk.ZeroInt(), + CurrentTick: 0, CurrentTickLiquidity: sdk.ZeroDec(), Token0: denom0, Token1: denom1, TickSpacing: tickSpacing, - ExponentAtPriceOne: sdk.NewInt(types.ExponentAtPriceOne), + ExponentAtPriceOne: types.ExponentAtPriceOne, SwapFee: swapFee, } return pool, nil @@ -129,7 +129,7 @@ func (p Pool) GetCurrentSqrtPrice() sdk.Dec { } // GetCurrentTick returns the current tick of the pool -func (p Pool) GetCurrentTick() sdk.Int { +func (p Pool) GetCurrentTick() int64 { return p.CurrentTick } @@ -139,7 +139,7 @@ func (p Pool) GetTickSpacing() uint64 { } // GetExponentAtPriceOne returns the precision factor at price one of the pool -func (p Pool) GetExponentAtPriceOne() sdk.Int { +func (p Pool) GetExponentAtPriceOne() int64 { return p.ExponentAtPriceOne } @@ -168,7 +168,7 @@ func (p *Pool) SetCurrentSqrtPrice(newSqrtPrice sdk.Dec) { } // SetCurrentTick updates the current tick of the pool when the first position is created. -func (p *Pool) SetCurrentTick(newTick sdk.Int) { +func (p *Pool) SetCurrentTick(newTick int64) { p.CurrentTick = newTick } @@ -241,7 +241,7 @@ func (p Pool) CalcActualAmounts(ctx sdk.Context, lowerTick, upperTick int64, liq currentSqrtPrice := p.CurrentSqrtPrice actualAmountDenom0 = math.CalcAmount0Delta(liquidityDelta, currentSqrtPrice, sqrtPriceUpperTick, roundUp) actualAmountDenom1 = math.CalcAmount1Delta(liquidityDelta, currentSqrtPrice, sqrtPriceLowerTick, roundUp) - } else if p.CurrentTick.LT(sdk.NewInt(lowerTick)) { + } else if p.CurrentTick < lowerTick { // outcome two: position is below current price // this means position is solely made up of asset0 actualAmountDenom1 = sdk.ZeroDec() @@ -259,12 +259,12 @@ func (p Pool) CalcActualAmounts(ctx sdk.Context, lowerTick, upperTick int64, liq // isCurrentTickInRange returns true if pool's current tick is within // the range of the lower and upper ticks. False otherwise. func (p Pool) IsCurrentTickInRange(lowerTick, upperTick int64) bool { - return p.CurrentTick.GTE(sdk.NewInt(lowerTick)) && p.CurrentTick.LTE(sdk.NewInt(upperTick)) + return p.CurrentTick >= lowerTick && p.CurrentTick <= upperTick } // ApplySwap state of pool after swap. // It specifically overwrites the pool's liquidity, curr tick and the curr sqrt price -func (p *Pool) ApplySwap(newLiquidity sdk.Dec, newCurrentTick sdk.Int, newCurrentSqrtPrice sdk.Dec) error { +func (p *Pool) ApplySwap(newLiquidity sdk.Dec, newCurrentTick int64, newCurrentSqrtPrice sdk.Dec) error { // Check if the new liquidity provided is not negative. if newLiquidity.IsNegative() { return types.NegativeLiquidityError{Liquidity: newLiquidity} @@ -276,11 +276,11 @@ func (p *Pool) ApplySwap(newLiquidity sdk.Dec, newCurrentTick sdk.Int, newCurren } // Check if the new tick provided is within boundaries of the pool's precision factor. - if newCurrentTick.LT(sdk.NewInt(types.MinTick)) || newCurrentTick.GT(sdk.NewInt(types.MaxTick)) { + if newCurrentTick < types.MinTick || newCurrentTick > types.MaxTick { return types.TickIndexNotWithinBoundariesError{ MaxTick: types.MaxTick, MinTick: types.MinTick, - ActualTick: newCurrentTick.Int64(), + ActualTick: newCurrentTick, } } diff --git a/x/concentrated-liquidity/model/pool.pb.go b/x/concentrated-liquidity/model/pool.pb.go index 99375479d94..fcce45b1a57 100644 --- a/x/concentrated-liquidity/model/pool.pb.go +++ b/x/concentrated-liquidity/model/pool.pb.go @@ -45,11 +45,11 @@ type Pool struct { Token0 string `protobuf:"bytes,5,opt,name=token0,proto3" json:"token0,omitempty"` Token1 string `protobuf:"bytes,6,opt,name=token1,proto3" json:"token1,omitempty"` CurrentSqrtPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=current_sqrt_price,json=currentSqrtPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"current_sqrt_price" yaml:"spot_price"` - CurrentTick github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,8,opt,name=current_tick,json=currentTick,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"current_tick" yaml:"current_tick"` + CurrentTick int64 `protobuf:"varint,8,opt,name=current_tick,json=currentTick,proto3" json:"current_tick,omitempty" yaml:"current_tick"` // tick_spacing must be one of the authorized_tick_spacing values set in the // concentrated-liquidity parameters - TickSpacing uint64 `protobuf:"varint,9,opt,name=tick_spacing,json=tickSpacing,proto3" json:"tick_spacing,omitempty" yaml:"tick_spacing"` - ExponentAtPriceOne github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,10,opt,name=exponent_at_price_one,json=exponentAtPriceOne,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"exponent_at_price_one" yaml:"exponent_at_price_one"` + TickSpacing uint64 `protobuf:"varint,9,opt,name=tick_spacing,json=tickSpacing,proto3" json:"tick_spacing,omitempty" yaml:"tick_spacing"` + ExponentAtPriceOne int64 `protobuf:"varint,10,opt,name=exponent_at_price_one,json=exponentAtPriceOne,proto3" json:"exponent_at_price_one,omitempty" yaml:"exponent_at_price_one"` // swap_fee is the ratio that is charged on the amount of token in. SwapFee github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=swap_fee,json=swapFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"swap_fee" yaml:"swap_fee"` // last_liquidity_update is the last time either the pool liquidity or the @@ -98,47 +98,46 @@ func init() { } var fileDescriptor_3526ea5373d96c9a = []byte{ - // 626 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x4e, 0xdb, 0x40, - 0x10, 0xb6, 0x29, 0x10, 0xd8, 0x20, 0x5a, 0x96, 0x9f, 0x1a, 0x54, 0x6c, 0x64, 0xa9, 0x55, 0x2a, - 0x35, 0x76, 0xd3, 0xaa, 0x17, 0x6e, 0xa4, 0x3f, 0x12, 0x12, 0x2a, 0xc8, 0xd0, 0x4b, 0x85, 0x64, - 0x39, 0xf6, 0x62, 0x56, 0xb1, 0xbd, 0x8e, 0x77, 0x43, 0xc9, 0xb1, 0x87, 0x4a, 0x3d, 0x72, 0xec, - 0x91, 0x87, 0xe8, 0x43, 0xa0, 0x9e, 0x50, 0x4f, 0x55, 0x0f, 0x6e, 0x95, 0xbc, 0x41, 0x9e, 0xa0, - 0xf2, 0x7a, 0x9d, 0x58, 0x22, 0x3d, 0xe4, 0x64, 0xcf, 0x37, 0x33, 0xdf, 0x7c, 0x33, 0xbb, 0xb3, - 0xe0, 0x29, 0xa1, 0x21, 0xa1, 0x98, 0x9a, 0x2e, 0x89, 0x5c, 0x14, 0xb1, 0xc4, 0x61, 0xc8, 0xab, - 0x07, 0xb8, 0xd3, 0xc5, 0x1e, 0x66, 0x3d, 0x33, 0x26, 0x24, 0x30, 0xe2, 0x84, 0x30, 0x02, 0x1f, - 0x8b, 0x50, 0xa3, 0x1c, 0x3a, 0x8a, 0x34, 0x2e, 0x1a, 0x2d, 0xc4, 0x9c, 0xc6, 0xd6, 0xa6, 0xcb, - 0xe3, 0x6c, 0x9e, 0x64, 0xe6, 0x46, 0xce, 0xb0, 0xb5, 0xe6, 0x13, 0x9f, 0xe4, 0x78, 0xf6, 0x27, - 0x50, 0xcd, 0x27, 0xc4, 0x0f, 0x90, 0xc9, 0xad, 0x56, 0xf7, 0xcc, 0x64, 0x38, 0x44, 0x94, 0x39, - 0x61, 0x9c, 0x07, 0xe8, 0x3f, 0x2b, 0x60, 0xf6, 0x88, 0x90, 0x00, 0x3e, 0x03, 0x15, 0xc7, 0xf3, - 0x12, 0x44, 0xa9, 0x22, 0xef, 0xc8, 0xb5, 0xc5, 0x26, 0x1c, 0xa6, 0xda, 0x72, 0xcf, 0x09, 0x83, - 0x5d, 0x5d, 0x38, 0x74, 0xab, 0x08, 0x81, 0x07, 0x00, 0x62, 0x2e, 0x14, 0x5f, 0x20, 0x6a, 0x17, - 0x89, 0x33, 0x3c, 0x71, 0x7b, 0x98, 0x6a, 0x9b, 0x79, 0xe2, 0xdd, 0x18, 0xdd, 0x5a, 0x19, 0x83, - 0x7b, 0x82, 0x6d, 0x19, 0xcc, 0x60, 0x4f, 0xb9, 0xb7, 0x23, 0xd7, 0x66, 0xad, 0x19, 0xec, 0xc1, - 0x2f, 0x32, 0xd8, 0x70, 0xbb, 0x49, 0x82, 0x22, 0x66, 0x33, 0xec, 0xb6, 0xed, 0xd1, 0x24, 0x94, - 0x59, 0x5e, 0xe2, 0xf0, 0x26, 0xd5, 0xa4, 0xdf, 0xa9, 0xf6, 0xc4, 0xc7, 0xec, 0xbc, 0xdb, 0x32, - 0x5c, 0x12, 0x8a, 0x69, 0x88, 0x4f, 0x9d, 0x7a, 0x6d, 0x93, 0xf5, 0x62, 0x44, 0x8d, 0x37, 0xc8, - 0x1d, 0xa6, 0xda, 0x76, 0x2e, 0x68, 0x32, 0xab, 0x6e, 0xad, 0x09, 0xc7, 0x09, 0x76, 0xdb, 0x07, - 0x05, 0x0c, 0x37, 0xc0, 0x3c, 0x23, 0x6d, 0x14, 0x3d, 0x57, 0xe6, 0xb2, 0xb2, 0x96, 0xb0, 0x46, - 0x78, 0x43, 0x99, 0x2f, 0xe1, 0x0d, 0xd8, 0x01, 0xb0, 0x28, 0x40, 0x3b, 0x09, 0xb3, 0xe3, 0x04, - 0xbb, 0x48, 0xa9, 0x70, 0xc9, 0xaf, 0xa7, 0x96, 0xbc, 0x92, 0x4b, 0xa6, 0x31, 0x11, 0x4c, 0xba, - 0xf5, 0x40, 0xd0, 0x1f, 0x77, 0x12, 0x76, 0x94, 0x41, 0xf0, 0x1c, 0x2c, 0x95, 0x7b, 0x52, 0x16, - 0x78, 0xb1, 0xb7, 0x53, 0x14, 0xdb, 0x8f, 0xd8, 0x30, 0xd5, 0x56, 0xef, 0xce, 0x47, 0xb7, 0xaa, - 0xa5, 0xa9, 0xc0, 0x5d, 0xb0, 0xc4, 0xa7, 0x46, 0x63, 0xc7, 0xc5, 0x91, 0xaf, 0x2c, 0x66, 0xc7, - 0xd5, 0x7c, 0x38, 0xce, 0x2d, 0x7b, 0x75, 0xab, 0x9a, 0x99, 0xc7, 0xb9, 0x05, 0x3f, 0xcb, 0x60, - 0x1d, 0x5d, 0xc6, 0x24, 0xca, 0xb8, 0x1d, 0xd1, 0x8e, 0x4d, 0x22, 0xa4, 0x00, 0xae, 0xf7, 0xfd, - 0xd4, 0x7a, 0x1f, 0xe5, 0x35, 0x27, 0x92, 0xea, 0x16, 0x2c, 0xf0, 0xbd, 0x7c, 0x4c, 0x87, 0x11, - 0x82, 0xa7, 0x60, 0x81, 0x7e, 0x72, 0x62, 0xfb, 0x0c, 0x21, 0xa5, 0xca, 0xab, 0xee, 0x4d, 0x7d, - 0x24, 0xf7, 0xc5, 0x91, 0x08, 0x1e, 0xdd, 0xaa, 0x64, 0xbf, 0xef, 0x10, 0x82, 0x97, 0x60, 0x3d, - 0x70, 0x28, 0x1b, 0xdf, 0x29, 0xbb, 0x1b, 0x7b, 0x0e, 0x43, 0xca, 0xd2, 0x8e, 0x5c, 0xab, 0xbe, - 0xd8, 0x32, 0xf2, 0x45, 0x34, 0x8a, 0x45, 0x34, 0x4e, 0x8a, 0x45, 0x6c, 0xd6, 0x32, 0x19, 0xe3, - 0x96, 0x26, 0xd2, 0xe8, 0x57, 0x7f, 0x34, 0xd9, 0x5a, 0xcd, 0x7c, 0xa3, 0xeb, 0xf9, 0x81, 0x7b, - 0x76, 0x57, 0xbe, 0x5e, 0x6b, 0xd2, 0xb7, 0x6b, 0x4d, 0xfa, 0xf1, 0xbd, 0x3e, 0x97, 0xad, 0xf2, - 0x7e, 0xf3, 0xf4, 0xa6, 0xaf, 0xca, 0xb7, 0x7d, 0x55, 0xfe, 0xdb, 0x57, 0xe5, 0xab, 0x81, 0x2a, - 0xdd, 0x0e, 0x54, 0xe9, 0xd7, 0x40, 0x95, 0x3e, 0x36, 0x4b, 0xad, 0x8a, 0x27, 0xa7, 0x1e, 0x38, - 0x2d, 0x5a, 0x18, 0xe6, 0x45, 0xe3, 0x95, 0x79, 0xf9, 0xbf, 0x07, 0x2b, 0x24, 0x1e, 0x0a, 0x5a, - 0xf3, 0xbc, 0x87, 0x97, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xcb, 0xdc, 0x32, 0xdf, 0x04, - 0x00, 0x00, + // 617 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xb6, 0xfb, 0x93, 0xb6, 0x9b, 0xaa, 0xd0, 0xed, 0x0f, 0x6e, 0x45, 0xed, 0xc8, 0x12, 0x28, + 0x48, 0xc4, 0x26, 0x20, 0x2e, 0xbd, 0x35, 0x20, 0x24, 0xa4, 0x4a, 0xad, 0xdc, 0x72, 0x41, 0x95, + 0x2c, 0xc7, 0xde, 0x9a, 0x55, 0x6c, 0xaf, 0xe3, 0xdd, 0x84, 0xe4, 0x01, 0x90, 0x38, 0xf6, 0xc8, + 0xb1, 0x0f, 0xc1, 0x43, 0x54, 0x9c, 0x7a, 0x44, 0x1c, 0x0c, 0x4a, 0xde, 0x20, 0x12, 0x77, 0xe4, + 0xf5, 0x3a, 0xb1, 0xd4, 0x70, 0xe8, 0x29, 0x9e, 0x6f, 0xbe, 0xf9, 0xf6, 0x9b, 0xd9, 0xcc, 0x82, + 0x67, 0x84, 0x86, 0x84, 0x62, 0x6a, 0xba, 0x24, 0x72, 0x51, 0xc4, 0x12, 0x87, 0x21, 0xaf, 0x11, + 0xe0, 0x6e, 0x0f, 0x7b, 0x98, 0x0d, 0xcd, 0x98, 0x90, 0xc0, 0x88, 0x13, 0xc2, 0x08, 0x7c, 0x22, + 0xa8, 0x46, 0x99, 0x3a, 0x65, 0x1a, 0xfd, 0x66, 0x1b, 0x31, 0xa7, 0xb9, 0xbf, 0xe7, 0x72, 0x9e, + 0xcd, 0x8b, 0xcc, 0x3c, 0xc8, 0x15, 0xf6, 0xb7, 0x7d, 0xe2, 0x93, 0x1c, 0xcf, 0xbe, 0x04, 0xaa, + 0xf9, 0x84, 0xf8, 0x01, 0x32, 0x79, 0xd4, 0xee, 0x5d, 0x9a, 0x0c, 0x87, 0x88, 0x32, 0x27, 0x8c, + 0x73, 0x82, 0xfe, 0xb7, 0x02, 0x96, 0x4e, 0x09, 0x09, 0xe0, 0x73, 0xb0, 0xe2, 0x78, 0x5e, 0x82, + 0x28, 0x55, 0xe4, 0x9a, 0x5c, 0x5f, 0x6b, 0xc1, 0x49, 0xaa, 0x6d, 0x0c, 0x9d, 0x30, 0x38, 0xd4, + 0x45, 0x42, 0xb7, 0x0a, 0x0a, 0x3c, 0x06, 0x10, 0x73, 0xa3, 0xb8, 0x8f, 0xa8, 0x5d, 0x14, 0x2e, + 0xf0, 0xc2, 0x83, 0x49, 0xaa, 0xed, 0xe5, 0x85, 0x77, 0x39, 0xba, 0xb5, 0x39, 0x03, 0x8f, 0x84, + 0xda, 0x06, 0x58, 0xc0, 0x9e, 0xb2, 0x58, 0x93, 0xeb, 0x4b, 0xd6, 0x02, 0xf6, 0xe0, 0x17, 0x19, + 0xec, 0xba, 0xbd, 0x24, 0x41, 0x11, 0xb3, 0x19, 0x76, 0x3b, 0xf6, 0x74, 0x12, 0xca, 0x12, 0x3f, + 0xe2, 0xe4, 0x26, 0xd5, 0xa4, 0x5f, 0xa9, 0xf6, 0xd4, 0xc7, 0xec, 0x53, 0xaf, 0x6d, 0xb8, 0x24, + 0x14, 0xd3, 0x10, 0x3f, 0x0d, 0xea, 0x75, 0x4c, 0x36, 0x8c, 0x11, 0x35, 0xde, 0x22, 0x77, 0x92, + 0x6a, 0x07, 0xb9, 0xa1, 0xf9, 0xaa, 0xba, 0xb5, 0x2d, 0x12, 0xe7, 0xd8, 0xed, 0x1c, 0x17, 0x30, + 0xdc, 0x05, 0x15, 0x46, 0x3a, 0x28, 0x7a, 0xa1, 0x2c, 0x67, 0xc7, 0x5a, 0x22, 0x9a, 0xe2, 0x4d, + 0xa5, 0x52, 0xc2, 0x9b, 0xb0, 0x0b, 0x60, 0x71, 0x00, 0xed, 0x26, 0xcc, 0x8e, 0x13, 0xec, 0x22, + 0x65, 0x85, 0x5b, 0x7e, 0x73, 0x6f, 0xcb, 0x9b, 0xb9, 0x65, 0x1a, 0x13, 0xa1, 0xa4, 0x5b, 0x0f, + 0x85, 0xfc, 0x59, 0x37, 0x61, 0xa7, 0x19, 0x04, 0x0f, 0xc1, 0x7a, 0xb9, 0x27, 0x65, 0xb5, 0x26, + 0xd7, 0x17, 0x5b, 0x8f, 0x26, 0xa9, 0xb6, 0x75, 0xb7, 0x63, 0xdd, 0xaa, 0x96, 0xfa, 0xcc, 0x6a, + 0xf9, 0x1c, 0x68, 0xec, 0xb8, 0x38, 0xf2, 0x95, 0xb5, 0xec, 0x02, 0xca, 0xb5, 0xe5, 0xac, 0x6e, + 0x55, 0xb3, 0xf0, 0x2c, 0x8f, 0xe0, 0x19, 0xd8, 0x41, 0x83, 0x98, 0x44, 0x99, 0xb4, 0x23, 0xfc, + 0xd9, 0x24, 0x42, 0x0a, 0xe0, 0x06, 0x6a, 0x93, 0x54, 0x7b, 0x9c, 0x8b, 0xcc, 0xa5, 0xe9, 0x16, + 0x2c, 0xf0, 0xa3, 0xbc, 0x93, 0x93, 0x08, 0xc1, 0x0b, 0xb0, 0x4a, 0x3f, 0x3b, 0xb1, 0x7d, 0x89, + 0x90, 0x52, 0xe5, 0x53, 0x3b, 0xba, 0xf7, 0xd4, 0x1e, 0x88, 0xa9, 0x09, 0x1d, 0xdd, 0x5a, 0xc9, + 0x3e, 0xdf, 0x21, 0x04, 0x07, 0x60, 0x27, 0x70, 0x28, 0x9b, 0x5d, 0xbb, 0xdd, 0x8b, 0x3d, 0x87, + 0x21, 0x65, 0xbd, 0x26, 0xd7, 0xab, 0x2f, 0xf7, 0x8d, 0x7c, 0x57, 0x8c, 0x62, 0x57, 0x8c, 0xf3, + 0x62, 0x57, 0x5a, 0xf5, 0xcc, 0xc6, 0xac, 0xa5, 0xb9, 0x32, 0xfa, 0xd5, 0x6f, 0x4d, 0xb6, 0xb6, + 0xb2, 0xdc, 0xf4, 0x1f, 0xf4, 0x81, 0x67, 0x0e, 0x37, 0xbf, 0x5e, 0x6b, 0xd2, 0xb7, 0x6b, 0x4d, + 0xfa, 0xf1, 0xbd, 0xb1, 0x9c, 0x6d, 0xdb, 0xfb, 0xd6, 0xc5, 0xcd, 0x48, 0x95, 0x6f, 0x47, 0xaa, + 0xfc, 0x67, 0xa4, 0xca, 0x57, 0x63, 0x55, 0xba, 0x1d, 0xab, 0xd2, 0xcf, 0xb1, 0x2a, 0x7d, 0x6c, + 0x95, 0x5a, 0x15, 0xaf, 0x42, 0x23, 0x70, 0xda, 0xb4, 0x08, 0xcc, 0x7e, 0xf3, 0xb5, 0x39, 0xf8, + 0xdf, 0x9b, 0x12, 0x12, 0x0f, 0x05, 0xed, 0x0a, 0xef, 0xe1, 0xd5, 0xbf, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x17, 0x07, 0xb8, 0x83, 0x82, 0x04, 0x00, 0x00, } func (m *Pool) Marshal() (dAtA []byte, err error) { @@ -179,31 +178,21 @@ func (m *Pool) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x5a - { - size := m.ExponentAtPriceOne.Size() - i -= size - if _, err := m.ExponentAtPriceOne.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintPool(dAtA, i, uint64(size)) + if m.ExponentAtPriceOne != 0 { + i = encodeVarintPool(dAtA, i, uint64(m.ExponentAtPriceOne)) + i-- + dAtA[i] = 0x50 } - i-- - dAtA[i] = 0x52 if m.TickSpacing != 0 { i = encodeVarintPool(dAtA, i, uint64(m.TickSpacing)) i-- dAtA[i] = 0x48 } - { - size := m.CurrentTick.Size() - i -= size - if _, err := m.CurrentTick.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintPool(dAtA, i, uint64(size)) + if m.CurrentTick != 0 { + i = encodeVarintPool(dAtA, i, uint64(m.CurrentTick)) + i-- + dAtA[i] = 0x40 } - i-- - dAtA[i] = 0x42 { size := m.CurrentSqrtPrice.Size() i -= size @@ -300,13 +289,15 @@ func (m *Pool) Size() (n int) { } l = m.CurrentSqrtPrice.Size() n += 1 + l + sovPool(uint64(l)) - l = m.CurrentTick.Size() - n += 1 + l + sovPool(uint64(l)) + if m.CurrentTick != 0 { + n += 1 + sovPool(uint64(m.CurrentTick)) + } if m.TickSpacing != 0 { n += 1 + sovPool(uint64(m.TickSpacing)) } - l = m.ExponentAtPriceOne.Size() - n += 1 + l + sovPool(uint64(l)) + if m.ExponentAtPriceOne != 0 { + n += 1 + sovPool(uint64(m.ExponentAtPriceOne)) + } l = m.SwapFee.Size() n += 1 + l + sovPool(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.LastLiquidityUpdate) @@ -565,10 +556,10 @@ func (m *Pool) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 8: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field CurrentTick", wireType) } - var stringLen uint64 + m.CurrentTick = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPool @@ -578,26 +569,11 @@ func (m *Pool) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.CurrentTick |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPool - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPool - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.CurrentTick.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TickSpacing", wireType) @@ -618,10 +594,10 @@ func (m *Pool) Unmarshal(dAtA []byte) error { } } case 10: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ExponentAtPriceOne", wireType) } - var stringLen uint64 + m.ExponentAtPriceOne = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPool @@ -631,26 +607,11 @@ func (m *Pool) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ExponentAtPriceOne |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPool - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPool - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.ExponentAtPriceOne.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SwapFee", wireType) diff --git a/x/concentrated-liquidity/model/pool_test.go b/x/concentrated-liquidity/model/pool_test.go index 820baef8656..030c520b46b 100644 --- a/x/concentrated-liquidity/model/pool_test.go +++ b/x/concentrated-liquidity/model/pool_test.go @@ -23,14 +23,14 @@ const ( ) var ( - DefaultSpotPrice = sdk.MustNewDecFromStr("0.2") - DefaultReverseSpotPrice = sdk.NewDec(1).Quo(DefaultSpotPrice) - DefaultSqrtSpotPrice, _ = DefaultSpotPrice.ApproxSqrt() - DefaultLiquidityAmt = sdk.MustNewDecFromStr("1517882343.751510418088349649") - DefaultCurrTick = sdk.NewInt(310000) - DefaultCurrPrice = sdk.NewDec(5000) - DefaultCurrSqrtPrice, _ = DefaultCurrPrice.ApproxSqrt() // 70.710678118654752440 - DefaultSwapFee = sdk.MustNewDecFromStr("0.01") + DefaultSpotPrice = sdk.MustNewDecFromStr("0.2") + DefaultReverseSpotPrice = sdk.NewDec(1).Quo(DefaultSpotPrice) + DefaultSqrtSpotPrice, _ = DefaultSpotPrice.ApproxSqrt() + DefaultLiquidityAmt = sdk.MustNewDecFromStr("1517882343.751510418088349649") + DefaultCurrTick int64 = 310000 + DefaultCurrPrice = sdk.NewDec(5000) + DefaultCurrSqrtPrice, _ = DefaultCurrPrice.ApproxSqrt() // 70.710678118654752440 + DefaultSwapFee = sdk.MustNewDecFromStr("0.01") ) type ConcentratedPoolTestSuite struct { @@ -150,26 +150,26 @@ func (s *ConcentratedPoolTestSuite) TestIsCurrentTickInRange() { }{ { "given lower tick tick is within range of pool tick", - DefaultCurrTick.Int64() - 1, - DefaultCurrTick.Int64() + 1, + DefaultCurrTick - 1, + DefaultCurrTick + 1, true, }, { "lower tick and upper tick are equal to pool tick", - DefaultCurrTick.Int64(), - DefaultCurrTick.Int64(), + DefaultCurrTick, + DefaultCurrTick, true, }, { "lower tick is greater then pool tick", - DefaultCurrTick.Int64() + 1, - DefaultCurrTick.Int64() + 3, + DefaultCurrTick + 1, + DefaultCurrTick + 3, false, }, { "upper tick is lower then pool tick", - DefaultCurrTick.Int64() - 3, - DefaultCurrTick.Int64() - 1, + DefaultCurrTick - 3, + DefaultCurrTick - 1, false, }, } @@ -200,10 +200,10 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { tests := []struct { name string currentLiquidity sdk.Dec - currentTick sdk.Int + currentTick int64 currentSqrtPrice sdk.Dec newLiquidity sdk.Dec - newTick sdk.Int + newTick int64 newSqrtPrice sdk.Dec expectErr error }{ @@ -213,7 +213,7 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { currentTick: DefaultCurrTick, currentSqrtPrice: DefaultCurrSqrtPrice, newLiquidity: DefaultLiquidityAmt.Mul(sdk.NewDec(2)), - newTick: DefaultCurrTick.Mul(sdk.NewInt(2)), + newTick: DefaultCurrTick * 2, newSqrtPrice: DefaultCurrSqrtPrice.Mul(sdk.NewDec(2)), expectErr: nil, }, @@ -240,10 +240,10 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { { name: "upper tick too big", currentLiquidity: DefaultLiquidityAmt, - currentTick: sdk.NewInt(1), + currentTick: 1, currentSqrtPrice: DefaultCurrSqrtPrice, newLiquidity: DefaultLiquidityAmt, - newTick: sdk.NewInt(math.MaxInt64), + newTick: math.MaxInt64, newSqrtPrice: DefaultCurrSqrtPrice, expectErr: types.TickIndexNotWithinBoundariesError{ MaxTick: types.MaxTick, @@ -254,10 +254,10 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { { name: "lower tick too small", currentLiquidity: DefaultLiquidityAmt, - currentTick: sdk.NewInt(1), + currentTick: 1, currentSqrtPrice: DefaultCurrSqrtPrice, newLiquidity: DefaultLiquidityAmt, - newTick: sdk.NewInt(math.MinInt64), + newTick: math.MinInt64, newSqrtPrice: DefaultCurrSqrtPrice, expectErr: types.TickIndexNotWithinBoundariesError{ MaxTick: types.MaxTick, @@ -271,7 +271,7 @@ func (s *ConcentratedPoolTestSuite) TestApplySwap() { s.Run(tt.name, func() { // Create a concentrated liquidity pool struct instance mock_pool := model.Pool{ - ExponentAtPriceOne: sdk.NewInt(types.ExponentAtPriceOne), + ExponentAtPriceOne: types.ExponentAtPriceOne, CurrentTickLiquidity: tt.currentLiquidity, CurrentTick: tt.currentTick, CurrentSqrtPrice: tt.currentSqrtPrice, @@ -515,9 +515,9 @@ func (suite *ConcentratedPoolTestSuite) TestCalcActualAmounts() { suite.Setup() pool := model.Pool{ - CurrentTick: sdk.NewInt(tc.currentTick), + CurrentTick: tc.currentTick, } - _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick.Int64()) + _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick) actualAmount0, actualAmount1, err := pool.CalcActualAmounts(suite.Ctx, tc.lowerTick, tc.upperTick, tc.liquidityDelta) @@ -608,10 +608,10 @@ func (suite *ConcentratedPoolTestSuite) TestUpdateLiquidityIfActivePosition() { suite.Setup() pool := model.Pool{ - CurrentTick: sdk.NewInt(tc.currentTick), + CurrentTick: tc.currentTick, CurrentTickLiquidity: defaultLiquidityAmt, } - _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick.Int64()) + _, pool.CurrentSqrtPrice, _ = clmath.TickToSqrtPrice(pool.CurrentTick) wasUpdated := pool.UpdateLiquidityIfActivePosition(suite.Ctx, tc.lowerTick, tc.upperTick, tc.liquidityDelta) if tc.lowerTick <= tc.currentTick && tc.currentTick <= tc.upperTick { diff --git a/x/concentrated-liquidity/pool_test.go b/x/concentrated-liquidity/pool_test.go index 1a5a2a2e1e4..dbd12441169 100644 --- a/x/concentrated-liquidity/pool_test.go +++ b/x/concentrated-liquidity/pool_test.go @@ -347,9 +347,9 @@ func (s *KeeperTestSuite) TestSetPool() { Token0: ETH, Token1: USDC, CurrentSqrtPrice: sdk.OneDec(), - CurrentTick: sdk.ZeroInt(), + CurrentTick: 0, TickSpacing: DefaultTickSpacing, - ExponentAtPriceOne: sdk.NewInt(-6), + ExponentAtPriceOne: -6, SwapFee: sdk.MustNewDecFromStr("0.003"), LastLiquidityUpdate: s.Ctx.BlockTime(), } diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 932c6e5b2a6..3c01760e509 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -309,7 +309,7 @@ func (k Keeper) computeOutAmtGivenIn( amountCalculated: sdk.ZeroDec(), // tokenOut sqrtPrice: curSqrtPrice, // Pad (or don't pad) current tick based on swap direction to avoid off-by-one errors - tick: swapStrategy.InitializeTickValue(p.GetCurrentTick().Int64()), + tick: swapStrategy.InitializeTickValue(p.GetCurrentTick()), liquidity: p.GetLiquidity(), feeGrowthGlobal: sdk.ZeroDec(), } @@ -477,7 +477,7 @@ func (k Keeper) calcInAmtGivenOut( amountSpecifiedRemaining: desiredTokenOut.Amount.ToDec(), // tokenOut amountCalculated: sdk.ZeroDec(), // tokenIn sqrtPrice: curSqrtPrice, - tick: swapStrategy.InitializeTickValue(p.GetCurrentTick().Int64()), + tick: swapStrategy.InitializeTickValue(p.GetCurrentTick()), liquidity: p.GetLiquidity(), feeGrowthGlobal: sdk.ZeroDec(), } @@ -617,7 +617,7 @@ func (k Keeper) updatePoolForSwap( return types.InsufficientPoolBalanceError{Err: err} } - err = pool.ApplySwap(newLiquidity, sdk.NewInt(newCurrentTick), newSqrtPrice) + err = pool.ApplySwap(newLiquidity, newCurrentTick, newSqrtPrice) if err != nil { return fmt.Errorf("error applying swap: %w", err) } diff --git a/x/concentrated-liquidity/swaps_test.go b/x/concentrated-liquidity/swaps_test.go index 765325e455b..66b2b707f77 100644 --- a/x/concentrated-liquidity/swaps_test.go +++ b/x/concentrated-liquidity/swaps_test.go @@ -1792,7 +1792,7 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() { s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) s.Require().Equal(test.expectedSqrtPrice, sqrtPrice) // also ensure the pool's currentTick and currentSqrtPrice was updated due to calling a mutative method - s.Require().Equal(test.expectedTick, pool.GetCurrentTick().Int64()) + s.Require().Equal(test.expectedTick, pool.GetCurrentTick()) if test.newLowerPrice.IsNil() && test.newUpperPrice.IsNil() { test.newLowerPrice = DefaultLowerPrice @@ -2726,7 +2726,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { suite.FundAcc(sender, tc.senderInitialBalance) // Default pool values are initialized to one. - err := pool.ApplySwap(sdk.OneDec(), sdk.OneInt(), sdk.OneDec()) + err := pool.ApplySwap(sdk.OneDec(), 1, sdk.OneDec()) suite.Require().NoError(err) // Write default pool to state. @@ -2752,7 +2752,7 @@ func (suite *KeeperTestSuite) TestUpdatePoolForSwap() { } suite.Require().NoError(err) - suite.Require().Equal(tc.newCurrentTick, poolAfterUpdate.GetCurrentTick().Int64()) + suite.Require().Equal(tc.newCurrentTick, poolAfterUpdate.GetCurrentTick()) suite.Require().Equal(tc.newLiquidity, poolAfterUpdate.GetLiquidity()) suite.Require().Equal(tc.newSqrtPrice, poolAfterUpdate.GetCurrentSqrtPrice()) diff --git a/x/concentrated-liquidity/tick.go b/x/concentrated-liquidity/tick.go index c9521ddcb07..79411c27eed 100644 --- a/x/concentrated-liquidity/tick.go +++ b/x/concentrated-liquidity/tick.go @@ -324,13 +324,13 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t return []queryproto.TickLiquidityNet{}, err } - ctx.Logger().Debug(fmt.Sprintf("userGivenStartTick %s, boundTick %s, currentTick %s\n", userGivenStartTick, boundTick, p.GetCurrentTick())) + ctx.Logger().Debug(fmt.Sprintf("userGivenStartTick %s, boundTick %s, currentTick %d\n", userGivenStartTick, boundTick, p.GetCurrentTick())) startTick := p.GetCurrentTick() // If start tick is set, use it as the current tick for grabbing liquidities from. if !userGivenStartTick.IsNil() { - startTick = userGivenStartTick - ctx.Logger().Debug(fmt.Sprintf("startTick %s set to user given\n", startTick)) + startTick = userGivenStartTick.Int64() + ctx.Logger().Debug(fmt.Sprintf("startTick %d set to user given\n", startTick)) } // sanity check that given tokenIn is an asset in pool. @@ -360,12 +360,12 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t swapStrategy := swapstrategy.New(zeroForOne, sdk.ZeroDec(), k.storeKey, sdk.ZeroDec(), p.GetTickSpacing()) currentTick := p.GetCurrentTick() - _, currentTickSqrtPrice, err := math.TickToSqrtPrice(currentTick.Int64()) + _, currentTickSqrtPrice, err := math.TickToSqrtPrice(currentTick) if err != nil { return []queryproto.TickLiquidityNet{}, err } - ctx.Logger().Debug(fmt.Sprintf("currentTick %s; current tick's sqrt price%s\n", currentTick, currentTickSqrtPrice)) + ctx.Logger().Debug(fmt.Sprintf("currentTick %d; current tick's sqrt price%s\n", currentTick, currentTickSqrtPrice)) // function to validate that start tick and bound tick are // between current tick and the min/max tick depending on the swap direction. @@ -389,15 +389,15 @@ func (k Keeper) GetTickLiquidityNetInDirection(ctx sdk.Context, poolId uint64, t } ctx.Logger().Debug("validating start tick") - if err := validateTickIsInValidRange(startTick); err != nil { - return []queryproto.TickLiquidityNet{}, fmt.Errorf("failed validating start tick (%s) with current sqrt price of (%s): %w", startTick, currentTickSqrtPrice, err) + if err := validateTickIsInValidRange(sdk.NewInt(startTick)); err != nil { + return []queryproto.TickLiquidityNet{}, fmt.Errorf("failed validating start tick (%d) with current sqrt price of (%s): %w", startTick, currentTickSqrtPrice, err) } // iterator assignments store := ctx.KVStore(k.storeKey) prefixBz := types.KeyTickPrefixByPoolId(poolId) prefixStore := prefix.NewStore(store, prefixBz) - startTickKey := types.TickIndexToBytes(startTick.Int64()) + startTickKey := types.TickIndexToBytes(startTick) boundTickKey := types.TickIndexToBytes(boundTick.Int64()) // define iterator depending on swap strategy diff --git a/x/concentrated-liquidity/tick_test.go b/x/concentrated-liquidity/tick_test.go index 5df29365a8c..8e95e6d22e3 100644 --- a/x/concentrated-liquidity/tick_test.go +++ b/x/concentrated-liquidity/tick_test.go @@ -262,7 +262,7 @@ func (s *KeeperTestSuite) TestInitOrUpdateTick() { // Create a default CL pool pool := s.PrepareConcentratedPool() - currentTick := pool.GetCurrentTick().Int64() + currentTick := pool.GetCurrentTick() _, err := s.App.ConcentratedLiquidityKeeper.GetFeeAccumulator(s.Ctx, 1) s.Require().NoError(err) @@ -282,7 +282,7 @@ func (s *KeeperTestSuite) TestInitOrUpdateTick() { s.Require().NoError(err) err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, test.param.poolId, currentTick, test.param.tickIndex, DefaultLiquidityAmt, test.param.upper) s.Require().NoError(err) - if tickInfoBefore.LiquidityGross.IsZero() && test.param.tickIndex <= pool.GetCurrentTick().Int64() { + if tickInfoBefore.LiquidityGross.IsZero() && test.param.tickIndex <= pool.GetCurrentTick() { tickInfoAfter, err := s.App.ConcentratedLiquidityKeeper.GetTickInfo(s.Ctx, 1, test.param.tickIndex) s.Require().NoError(err) s.Require().Equal(tickInfoAfter.FeeGrowthOppositeDirectionOfLastTraversal, feeAccum.GetValue()) @@ -299,7 +299,7 @@ func (s *KeeperTestSuite) TestInitOrUpdateTick() { // Initialize or update the tick according to the test case err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, test.param.poolId, currentTick, test.param.tickIndex, test.param.liquidityIn, test.param.upper) - if tickInfoAfter.LiquidityGross.IsZero() && test.param.tickIndex <= pool.GetCurrentTick().Int64() { + if tickInfoAfter.LiquidityGross.IsZero() && test.param.tickIndex <= pool.GetCurrentTick() { tickInfoAfter, err := s.App.ConcentratedLiquidityKeeper.GetTickInfo(s.Ctx, 1, test.param.tickIndex) s.Require().NoError(err) s.Require().Equal(tickInfoAfter.FeeGrowthOppositeDirectionOfLastTraversal, feeAccum.GetValue()) @@ -333,7 +333,7 @@ func (s *KeeperTestSuite) TestInitOrUpdateTick() { func (s *KeeperTestSuite) TestGetTickInfo() { var ( - preInitializedTickIndex = DefaultCurrTick.Int64() + 2 + preInitializedTickIndex = DefaultCurrTick + 2 expectedUptimes = getExpectedUptimes() emptyUptimeTrackers = wrapUptimeTrackers(expectedUptimes.emptyExpectedAccumValues) varyingTokensAndDenoms = wrapUptimeTrackers(expectedUptimes.varyingTokensMultiDenom) @@ -375,7 +375,7 @@ func (s *KeeperTestSuite) TestGetTickInfo() { { name: "Get tick info for active tick on existing pool with existing tick", poolToGet: validPoolId, - tickToGet: DefaultCurrTick.Int64(), + tickToGet: DefaultCurrTick, preInitUptimeAccumValues: expectedUptimes.varyingTokensMultiDenom, // Both fee growth and uptime trackers are set to global since tickToGet <= current tick expectedTickInfo: model.TickInfo{LiquidityGross: sdk.ZeroDec(), LiquidityNet: sdk.ZeroDec(), FeeGrowthOppositeDirectionOfLastTraversal: sdk.NewDecCoins(oneEth), UptimeTrackers: varyingTokensAndDenoms}, @@ -383,21 +383,21 @@ func (s *KeeperTestSuite) TestGetTickInfo() { { name: "Get tick info on existing pool with no existing tick (cur pool tick > tick)", poolToGet: validPoolId, - tickToGet: DefaultCurrTick.Int64() + 1, + tickToGet: DefaultCurrTick + 1, // Note that FeeGrowthOutside and UptimeGrowthOutside(s) are not initialized. expectedTickInfo: model.TickInfo{LiquidityGross: sdk.ZeroDec(), LiquidityNet: sdk.ZeroDec(), UptimeTrackers: emptyUptimeTrackers}, }, { name: "Get tick info on existing pool with no existing tick (cur pool tick == tick), initialized fee growth outside", poolToGet: validPoolId, - tickToGet: DefaultCurrTick.Int64(), + tickToGet: DefaultCurrTick, // Note that FeeGrowthOutside and UptimeGrowthOutside(s) are initialized. expectedTickInfo: model.TickInfo{LiquidityGross: sdk.ZeroDec(), LiquidityNet: sdk.ZeroDec(), FeeGrowthOppositeDirectionOfLastTraversal: sdk.NewDecCoins(oneEth), UptimeTrackers: emptyUptimeTrackers}, }, { name: "Get tick info on a non-existing pool with no existing tick", poolToGet: 2, - tickToGet: DefaultCurrTick.Int64() + 1, + tickToGet: DefaultCurrTick + 1, expectedErr: types.PoolNotFoundError{PoolId: 2}, }, } @@ -417,7 +417,7 @@ func (s *KeeperTestSuite) TestGetTickInfo() { } // Set up an initialized tick - err := clKeeper.InitOrUpdateTick(s.Ctx, validPoolId, DefaultCurrTick.Int64(), preInitializedTickIndex, DefaultLiquidityAmt, true) + err := clKeeper.InitOrUpdateTick(s.Ctx, validPoolId, DefaultCurrTick, preInitializedTickIndex, DefaultLiquidityAmt, true) s.Require().NoError(err) // Charge fee to make sure that the global fee accumulator is always updated. @@ -446,7 +446,7 @@ func (s *KeeperTestSuite) TestGetTickInfo() { func (s *KeeperTestSuite) TestCrossTick() { var ( - preInitializedTickIndex = DefaultCurrTick.Int64() - 2 + preInitializedTickIndex = DefaultCurrTick - 2 expectedUptimes = getExpectedUptimes() emptyUptimeTrackers = wrapUptimeTrackers(expectedUptimes.emptyExpectedAccumValues) defaultAdditiveFee = sdk.NewDecCoinFromDec(USDC, sdk.NewDec(1000)) @@ -494,8 +494,8 @@ func (s *KeeperTestSuite) TestCrossTick() { { name: "Get tick info of an existing tick above current tick (nonzero uptime trackers)", poolToGet: validPoolId, - preInitializedTickIndex: DefaultCurrTick.Int64() + 1, - tickToGet: DefaultCurrTick.Int64() + 1, + preInitializedTickIndex: DefaultCurrTick + 1, + tickToGet: DefaultCurrTick + 1, additiveFee: defaultAdditiveFee, // Global uptime accums remain unchanged after tick init initGlobalUptimeAccumValues: expectedUptimes.twoHundredTokensMultiDenom, @@ -511,7 +511,7 @@ func (s *KeeperTestSuite) TestCrossTick() { name: "Get tick info of new tick with a separate existing tick below current tick (nonzero uptime trackers)", poolToGet: validPoolId, preInitializedTickIndex: preInitializedTickIndex, - tickToGet: DefaultCurrTick.Int64() + 1, + tickToGet: DefaultCurrTick + 1, additiveFee: defaultAdditiveFee, // Global uptime accums remain unchanged after tick init initGlobalUptimeAccumValues: expectedUptimes.twoHundredTokensMultiDenom, @@ -527,8 +527,8 @@ func (s *KeeperTestSuite) TestCrossTick() { // Note that this test case covers technically undefined behavior (crossing into the current tick). name: "Get tick info of existing tick at current tick (nonzero uptime trackers)", poolToGet: validPoolId, - preInitializedTickIndex: DefaultCurrTick.Int64(), - tickToGet: DefaultCurrTick.Int64(), + preInitializedTickIndex: DefaultCurrTick, + tickToGet: DefaultCurrTick, additiveFee: defaultAdditiveFee, // Global uptime accums remain unchanged after tick init initGlobalUptimeAccumValues: expectedUptimes.twoHundredTokensMultiDenom, @@ -588,7 +588,7 @@ func (s *KeeperTestSuite) TestCrossTick() { } // Set up an initialized tick - err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, validPoolId, DefaultCurrTick.Int64(), test.preInitializedTickIndex, DefaultLiquidityAmt, true) + err = s.App.ConcentratedLiquidityKeeper.InitOrUpdateTick(s.Ctx, validPoolId, DefaultCurrTick, test.preInitializedTickIndex, DefaultLiquidityAmt, true) s.Require().NoError(err) // Update global uptime accums for edge case testing @@ -1187,7 +1187,7 @@ func (s *KeeperTestSuite) TestGetTickLiquidityNetInDirection() { curPrice = sqrtPrice } pool.SetCurrentSqrtPrice(curPrice) - pool.SetCurrentTick(sdk.NewInt(curTick)) + pool.SetCurrentTick(curTick) err = s.App.ConcentratedLiquidityKeeper.SetPool(s.Ctx, pool) s.Require().NoError(err) diff --git a/x/concentrated-liquidity/types/pool.go b/x/concentrated-liquidity/types/pool.go index 51332d67a5e..f4496c6e5ac 100644 --- a/x/concentrated-liquidity/types/pool.go +++ b/x/concentrated-liquidity/types/pool.go @@ -15,18 +15,18 @@ type ConcentratedPoolExtension interface { GetToken0() string GetToken1() string GetCurrentSqrtPrice() sdk.Dec - GetCurrentTick() sdk.Int - GetExponentAtPriceOne() sdk.Int + GetCurrentTick() int64 + GetExponentAtPriceOne() int64 GetTickSpacing() uint64 GetLiquidity() sdk.Dec GetLastLiquidityUpdate() time.Time SetCurrentSqrtPrice(newSqrtPrice sdk.Dec) - SetCurrentTick(newTick sdk.Int) + SetCurrentTick(newTick int64) SetTickSpacing(newTickSpacing uint64) SetLastLiquidityUpdate(newTime time.Time) UpdateLiquidity(newLiquidity sdk.Dec) - ApplySwap(newLiquidity sdk.Dec, newCurrentTick sdk.Int, newCurrentSqrtPrice sdk.Dec) error + ApplySwap(newLiquidity sdk.Dec, newCurrentTick int64, newCurrentSqrtPrice sdk.Dec) error CalcActualAmounts(ctx sdk.Context, lowerTick, upperTick int64, liquidityDelta sdk.Dec) (actualAmountDenom0 sdk.Dec, actualAmountDenom1 sdk.Dec, err error) UpdateLiquidityIfActivePosition(ctx sdk.Context, lowerTick, upperTick int64, liquidityDelta sdk.Dec) bool } From 93c2f99a56f4062bc9fe89e5f3c23440ff182a78 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 01:45:30 -0400 Subject: [PATCH 04/14] fix test --- .../swapstrategy/swap_strategy_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go b/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go index 2c217227515..e29a1f2b584 100644 --- a/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go +++ b/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go @@ -60,35 +60,35 @@ func (suite *StrategyTestSuite) TestNextInitializedTick() { swapStrategy := swapstrategy.New(false, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(ctx, 1, 78) - suite.Require().Equal(sdk.NewInt(84), n) + suite.Require().Equal(int64(84), n) suite.Require().True(initd) }) suite.Run("returns tick to right if at initialized tick", func() { swapStrategy := swapstrategy.New(false, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, -55) - suite.Require().Equal(sdk.NewInt(-4), n) + suite.Require().Equal(int64(-4), n) suite.Require().True(initd) }) suite.Run("returns the tick directly to the right", func() { swapStrategy := swapstrategy.New(false, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, 77) - suite.Require().Equal(sdk.NewInt(78), n) + suite.Require().Equal(int64(78), n) suite.Require().True(initd) }) suite.Run("returns the tick directly to the right", func() { swapStrategy := swapstrategy.New(false, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, -56) - suite.Require().Equal(sdk.NewInt(-55), n) + suite.Require().Equal(int64(-55), n) suite.Require().True(initd) }) suite.Run("returns the next words initialized tick if on the right boundary", func() { swapStrategy := swapstrategy.New(false, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, -257) - suite.Require().Equal(sdk.NewInt(-200), n) + suite.Require().Equal(int64(-200), n) suite.Require().True(initd) }) suite.Run("returns the next initialized tick from the next word", func() { @@ -97,7 +97,7 @@ func (suite *StrategyTestSuite) TestNextInitializedTick() { suite.App.ConcentratedLiquidityKeeper.SetTickInfo(suite.Ctx, 1, 340, model.TickInfo{}) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, 328) - suite.Require().Equal(sdk.NewInt(340), n) + suite.Require().Equal(int64(340), n) suite.Require().True(initd) }) }) @@ -107,21 +107,21 @@ func (suite *StrategyTestSuite) TestNextInitializedTick() { swapStrategy := swapstrategy.New(true, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, 79) - suite.Require().Equal(sdk.NewInt(78), n) + suite.Require().Equal(int64(78), n) suite.Require().True(initd) }) suite.Run("returns previous tick even though given is initialized", func() { swapStrategy := swapstrategy.New(true, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, 78) - suite.Require().Equal(sdk.NewInt(70), n) + suite.Require().Equal(int64(70), n) suite.Require().True(initd) }) suite.Run("returns next initialized tick far away", func() { swapStrategy := swapstrategy.New(true, sdk.ZeroDec(), clStoreKey, sdk.ZeroDec(), defaultTickSpacing) n, initd := swapStrategy.NextInitializedTick(suite.Ctx, 1, 100) - suite.Require().Equal(sdk.NewInt(84), n) + suite.Require().Equal(int64(84), n) suite.Require().True(initd) }) }) From 73fa58e0715820475dfb1e86717f8413acacbc6b Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 02:12:29 -0400 Subject: [PATCH 05/14] updates --- tests/e2e/e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index df3ef201922..5ad1b14daba 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -222,7 +222,7 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { concentratedPool := s.updatedPool(chainANode, poolID) // Sanity check that pool initialized with valid parameters (the ones that we haven't explicitly specified) - s.Require().Equal(concentratedPool.GetCurrentTick(), sdk.ZeroInt()) + s.Require().Equal(concentratedPool.GetCurrentTick(), int64(0)) s.Require().Equal(concentratedPool.GetCurrentSqrtPrice(), sdk.ZeroDec()) s.Require().Equal(concentratedPool.GetLiquidity(), sdk.ZeroDec()) From 66f5f1d45ade442400660025d73f175d7affef57 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 12:15:17 -0400 Subject: [PATCH 06/14] updates --- tests/e2e/e2e_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 5ad1b14daba..15df18bc7d3 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -222,7 +222,7 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { concentratedPool := s.updatedPool(chainANode, poolID) // Sanity check that pool initialized with valid parameters (the ones that we haven't explicitly specified) - s.Require().Equal(concentratedPool.GetCurrentTick(), int64(0)) + s.Require().Equal(concentratedPool.GetCurrentTick().Int64(), int64(0)) s.Require().Equal(concentratedPool.GetCurrentSqrtPrice(), sdk.ZeroDec()) s.Require().Equal(concentratedPool.GetLiquidity(), sdk.ZeroDec()) @@ -231,7 +231,7 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { s.Require().Equal(concentratedPool.GetToken0(), denom0) s.Require().Equal(concentratedPool.GetToken1(), denom1) s.Require().Equal(concentratedPool.GetTickSpacing(), tickSpacing) - s.Require().Equal(concentratedPool.GetExponentAtPriceOne(), cltypes.ExponentAtPriceOne) + s.Require().Equal(concentratedPool.GetExponentAtPriceOne().Int64(), cltypes.ExponentAtPriceOne) s.Require().Equal(concentratedPool.GetSwapFee(sdk.Context{}), sdk.MustNewDecFromStr(swapFee)) fundTokens := []string{"100000000uosmo", "100000000uion", "100000000stake"} From 2504d822f7458aab0998ab75bc2db82fd448dfc1 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 12:17:21 -0400 Subject: [PATCH 07/14] updates --- tests/e2e/e2e_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 15df18bc7d3..5ad1b14daba 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -222,7 +222,7 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { concentratedPool := s.updatedPool(chainANode, poolID) // Sanity check that pool initialized with valid parameters (the ones that we haven't explicitly specified) - s.Require().Equal(concentratedPool.GetCurrentTick().Int64(), int64(0)) + s.Require().Equal(concentratedPool.GetCurrentTick(), int64(0)) s.Require().Equal(concentratedPool.GetCurrentSqrtPrice(), sdk.ZeroDec()) s.Require().Equal(concentratedPool.GetLiquidity(), sdk.ZeroDec()) @@ -231,7 +231,7 @@ func (s *IntegrationTestSuite) TestConcentratedLiquidity() { s.Require().Equal(concentratedPool.GetToken0(), denom0) s.Require().Equal(concentratedPool.GetToken1(), denom1) s.Require().Equal(concentratedPool.GetTickSpacing(), tickSpacing) - s.Require().Equal(concentratedPool.GetExponentAtPriceOne().Int64(), cltypes.ExponentAtPriceOne) + s.Require().Equal(concentratedPool.GetExponentAtPriceOne(), cltypes.ExponentAtPriceOne) s.Require().Equal(concentratedPool.GetSwapFee(sdk.Context{}), sdk.MustNewDecFromStr(swapFee)) fundTokens := []string{"100000000uosmo", "100000000uion", "100000000stake"} From 24671b06c1d4884dcce292de35f58344db64a776 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 13:34:31 -0400 Subject: [PATCH 08/14] Update x/concentrated-liquidity/math/tick.go Co-authored-by: Dev Ojha --- x/concentrated-liquidity/math/tick.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 50623ad256c..3f16530838f 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -59,7 +59,7 @@ func TickToPrice(tickIndex int64) (price sdk.Dec, err error) { // The formula is as follows: geometricExponentIncrementDistanceInTicks = 9 * 10**(-exponentAtPriceOne) // Due to sdk.Power restrictions, if the resulting power is negative, we take 9 * (1/10**exponentAtPriceOne) exponentAtPriceOne := types.ExponentAtPriceOne - geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne * -1)).TruncateInt64() + geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(-exponentAtPriceOne)).TruncateInt64() // Check that the tick index is between min and max value if tickIndex < types.MinTick { From 876970d9e6d9349999df3eca5cca1e6f1fad6975 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 13:35:12 -0400 Subject: [PATCH 09/14] nit --- x/concentrated-liquidity/math/tick_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/math/tick_test.go b/x/concentrated-liquidity/math/tick_test.go index e0b4e9e47d8..c1998271bb3 100644 --- a/x/concentrated-liquidity/math/tick_test.go +++ b/x/concentrated-liquidity/math/tick_test.go @@ -14,7 +14,7 @@ const ( var ( // spot price - (10^(spot price exponent - 6 - 1)) // Note we get spot price exponent by counting the number of digits in the max spot price and subtracting 1. - closestPriceBelowMaxPriceDefaultTickSpacing = types.MaxSpotPrice.Sub(sdk.NewDec(10).PowerMut(uint64(len(types.MaxSpotPrice.TruncateInt().String()) - 1 - int(types.ExponentAtPriceOne*-1) - 1))) + closestPriceBelowMaxPriceDefaultTickSpacing = types.MaxSpotPrice.Sub(sdk.NewDec(10).PowerMut(uint64(len(types.MaxSpotPrice.TruncateInt().String()) - 1 - int(-types.ExponentAtPriceOne) - 1))) // min tick + 10 ^ -expoentAtPriceOne closestTickAboveMinPriceDefaultTickSpacing = sdk.NewInt(types.MinTick).Add(sdk.NewInt(10).ToDec().Power(uint64(types.ExponentAtPriceOne * -1)).TruncateInt()) ) From 8a6a3015ee30af2e9fa0d77749cd6df5ab31f23d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 13:42:57 -0400 Subject: [PATCH 10/14] comment --- x/concentrated-liquidity/math/tick.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 3f16530838f..4b3d926de72 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -120,6 +120,9 @@ func PriceToTick(price sdk.Dec) (int64, error) { // PriceToTickRoundDown takes a price and returns the corresponding tick index. // If tickSpacing is provided, the tick index will be rounded down to the nearest multiple of tickSpacing. +// CONTRACT: tickSpacing must be smaller or equal to the max of 1 << 63 - 1. +// This is not a concern because we have authroized tick spacings that are smaller than this max, +// and we don't expect to ever require it to be this large. func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (int64, error) { tickIndex, err := PriceToTick(price) if err != nil { From 16a45203fcc6cbd49954b3f4a9f922aa184eb711 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 14:07:27 -0400 Subject: [PATCH 11/14] comment --- x/concentrated-liquidity/math/tick.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 4b3d926de72..6174f303a48 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -131,6 +131,12 @@ func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (int64, error) { // Round the tick index down to the nearest tick spacing if the tickIndex is in between authorized tick values // Note that this is Euclidean modulus. + // The difference from default Go modulus is that Go default results + // in a negative remainder when the dividend is negative. + // Consider example tickIndex = -17, tickSpacing = 10 + // tickIndexModulus = tickIndex % tickSpacing = -7 + // tickIndexModulus = -7 + 10 = 3 + // tickIndex = -17 - 3 = -20 tickIndexModulus := tickIndex % int64(tickSpacing) if tickIndexModulus < 0 { tickIndexModulus += int64(tickSpacing) From a6ed719364e61d506ce92e95ee88ed18e73ce864 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 14:17:04 -0400 Subject: [PATCH 12/14] >= --- x/concentrated-liquidity/math/tick.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 6174f303a48..76815beefd5 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -158,14 +158,14 @@ func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (int64, error) { // powTen treats negative exponents as 1/(10**|exponent|) instead of 10**-exponent // This is because the sdk.Dec.Power function does not support negative exponents func PowTenInternal(exponent int64) sdk.Dec { - if exponent > 0 { + if exponent >= 0 { return sdkTenDec.Power(uint64(exponent)) } return sdk.OneDec().Quo(sdkTenDec.Power(uint64(exponent * -1))) } func powTenBigDec(exponent int64) osmomath.BigDec { - if exponent > 0 { + if exponent >= 0 { return osmomath.NewBigDec(10).PowerInteger(uint64(exponent)) } return osmomath.OneDec().Quo(osmomath.NewBigDec(10).PowerInteger(uint64(exponent * -1))) From 72ebeb66bbcc5da101f916a5bef8dca4effd1885 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 14:41:49 -0400 Subject: [PATCH 13/14] lint --- x/concentrated-liquidity/math/tick.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 76815beefd5..188998211af 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -121,7 +121,7 @@ func PriceToTick(price sdk.Dec) (int64, error) { // PriceToTickRoundDown takes a price and returns the corresponding tick index. // If tickSpacing is provided, the tick index will be rounded down to the nearest multiple of tickSpacing. // CONTRACT: tickSpacing must be smaller or equal to the max of 1 << 63 - 1. -// This is not a concern because we have authroized tick spacings that are smaller than this max, +// This is not a concern because we have authorized tick spacings that are smaller than this max, // and we don't expect to ever require it to be this large. func PriceToTickRoundDown(price sdk.Dec, tickSpacing uint64) (int64, error) { tickIndex, err := PriceToTick(price) From ad59a605cc0727680393c4b6b2d4ccae55a8e3c1 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:50:19 -0400 Subject: [PATCH 14/14] lint --- x/concentrated-liquidity/math/precompute.go | 3 +-- x/concentrated-liquidity/math/tick.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x/concentrated-liquidity/math/precompute.go b/x/concentrated-liquidity/math/precompute.go index 7996ba3058e..8b2e3ebc46e 100644 --- a/x/concentrated-liquidity/math/precompute.go +++ b/x/concentrated-liquidity/math/precompute.go @@ -7,8 +7,7 @@ import ( ) var ( - sdkOneInt = sdk.OneInt() - sdkOneDec = sdk.NewDec(1) + sdkOneDec = sdk.OneDec() sdkNineDec = sdk.NewDec(9) sdkTenDec = sdk.NewDec(10) powersOfTen []sdk.Dec diff --git a/x/concentrated-liquidity/math/tick.go b/x/concentrated-liquidity/math/tick.go index 2331b0552c7..fb59bb8d5e4 100644 --- a/x/concentrated-liquidity/math/tick.go +++ b/x/concentrated-liquidity/math/tick.go @@ -175,7 +175,7 @@ func CalculatePriceToTick(price sdk.Dec) (tickIndex int64) { geometricExponentIncrementDistanceInTicks := sdkNineDec.Mul(PowTenInternal(exponentAtPriceOne * -1)).TruncateInt64() // Initialize the current price to 1, the current precision to exponentAtPriceOne, and the number of ticks passed to 0 - currentPrice := sdk.OneDec() + currentPrice := sdkOneDec ticksPassed := int64(0) exponentAtCurrentTick := exponentAtPriceOne