From 4ed40506ac45a08d0860186653e02d7fe98c8e21 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 00:04:09 -0400 Subject: [PATCH 01/10] refactor: prototype reducing iterator overhead in swaps --- x/concentrated-liquidity/swaps.go | 31 ++++++++++++++----- .../swapstrategy/one_for_zero.go | 25 +++++++++++++++ .../swapstrategy/swap_strategy.go | 5 +++ .../swapstrategy/zero_for_one.go | 25 +++++++++++++++ 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 1cba311d2a3..fbf855247d1 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -314,6 +314,12 @@ func (k Keeper) computeOutAmtGivenIn( feeGrowthGlobal: sdk.ZeroDec(), } + iter := swapStrategy.InitializeTickIterator(ctx, poolId, swapState.tick.Int64()) + defer iter.Close() + if !iter.Valid() { + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no ticks found for pool %d", poolId) + } + // Iterate and update swapState until we swap all tokenIn or we reach the specific sqrtPriceLimit // TODO: for now, we check if amountSpecifiedRemaining is GT 0.0000001. This is because there are times when the remaining // amount may be extremely small, and that small amount cannot generate and amountIn/amountOut and we are therefore left @@ -322,17 +328,21 @@ func (k Keeper) computeOutAmtGivenIn( // Log the sqrtPrice we start the iteration with sqrtPriceStart := swapState.sqrtPrice + if !iter.Valid() { + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no more ticks found for pool %d", poolId) + } + // We first check to see what the position of the nearest initialized tick is // 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()) - 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") + nextTick, err := types.TickIndexFromBytes(iter.Key()) + if err != nil { + panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) } - // Utilizing the next initialized tick, we find the corresponding nextPrice (the target price) - _, nextTickSqrtPrice, err := math.TickToSqrtPrice(nextTick) + // Utilizing the next initialized tick, we find the corresponding nextPrice (the target price). + _, nextTickSqrtPrice, err := math.TickToSqrtPrice(sdk.NewInt(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) } @@ -371,17 +381,24 @@ 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 } + + if !iter.Valid() { + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no more ticks found for pool %d", poolId) + } + + iter.Next() + liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet) // Update the swapState's liquidity with the new tick's liquidity newLiquidity := math.AddLiquidity(swapState.liquidity, liquidityNet) swapState.liquidity = newLiquidity // Update the swapState's tick with the tick we retrieved liquidity from - swapState.tick = nextTick + swapState.tick = sdk.NewInt(nextTick) } else if !sqrtPriceStart.Equal(sqrtPrice) { // Otherwise if the sqrtPrice calculated from computeSwapStep does not equal the sqrtPrice we started with at the // beginning of this iteration, we set the swapState tick to the corresponding tick of the sqrtPrice calculated from computeSwapStep diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero.go b/x/concentrated-liquidity/swapstrategy/one_for_zero.go index d61278481ad..e5c06287ce3 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + dbm "github.com/tendermint/tm-db" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/math" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" @@ -147,6 +148,30 @@ func (s oneForZeroStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountZeroOut, amountOneIn, feeChargeTotal } +// TODO: spec +func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { + store := ctx.KVStore(s.storeKey) + prefixBz := types.KeyTickPrefixByPoolId(poolId) + prefixStore := prefix.NewStore(store, prefixBz) + startKey := types.TickIndexToBytes(tickIndex) + iter := prefixStore.Iterator(startKey, nil) + + for ; iter.Valid(); iter.Next() { + // Since, we constructed our prefix store with , the + // key is the encoding of a tick index. + tick, err := types.TickIndexFromBytes(iter.Key()) + if err != nil { + iter.Close() + panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) + } + + if tick > tickIndex { + break + } + } + return iter +} + // InitializeTickValue returns the initial tick value for computing swaps based // on the actual current tick. // diff --git a/x/concentrated-liquidity/swapstrategy/swap_strategy.go b/x/concentrated-liquidity/swapstrategy/swap_strategy.go index 367e88319c2..622de796ae0 100644 --- a/x/concentrated-liquidity/swapstrategy/swap_strategy.go +++ b/x/concentrated-liquidity/swapstrategy/swap_strategy.go @@ -2,6 +2,7 @@ package swapstrategy import ( sdk "github.com/cosmos/cosmos-sdk/types" + dbm "github.com/tendermint/tm-db" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" ) @@ -49,6 +50,10 @@ type swapStrategy interface { // * feeChargeTotal is the total fee charge. The fee is charged on the amount of token in. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPriceTarget, liquidity, amountRemainingOut sdk.Dec) (sqrtPriceNext, amountOutConsumed, amountInComputed, feeChargeTotal sdk.Dec) + // InitializeTickIterator returns iterator that seeks to the given tickIndex. + // If tick index does not exist in the store, it will return an invalid iterator. + // See oneForZeroStrategy or zeroForOneStrategy for implementation details. + InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator // InitializeTickValue returns the initial tick value for computing swaps based // on the actual current tick. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one.go b/x/concentrated-liquidity/swapstrategy/zero_for_one.go index adec4e781e3..358969473a9 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one.go @@ -5,6 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + dbm "github.com/tendermint/tm-db" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/math" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" @@ -144,6 +145,30 @@ func (s zeroForOneStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountOneOut, amountZeroIn, feeChargeTotal } +// TODO: spec +func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { + store := ctx.KVStore(s.storeKey) + prefixBz := types.KeyTickPrefixByPoolId(poolId) + prefixStore := prefix.NewStore(store, prefixBz) + startKey := types.TickIndexToBytes(tickIndex) + + iter := prefixStore.ReverseIterator(nil, startKey) + + for ; iter.Valid(); iter.Next() { + // Since, we constructed our prefix store with , the + // key is the encoding of a tick index. + tick, err := types.TickIndexFromBytes(iter.Key()) + if err != nil { + iter.Close() + panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) + } + if tick <= tickIndex { + break + } + } + return iter +} + // InitializeTickValue returns the initial tick value for computing swaps based // on the actual current tick. // From 3c2c53c6ff33c4f0cccd19b70896543d33559a9f Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 15:15:17 -0400 Subject: [PATCH 02/10] updates --- x/concentrated-liquidity/swaps.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index fbf855247d1..634e5eee5ef 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -302,6 +302,14 @@ func (k Keeper) computeOutAmtGivenIn( return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom} } + hasPositionInPool, err := k.HasAnyPositionForPool(ctx, poolId) + if err != nil { + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err + } + if !hasPositionInPool { + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("cannot swap since no positions found in pool %d", poolId) + } + // initialize swap state with the following parameters: // as we iterate through the following for loop, this swap state will get updated after each required iteration swapState := SwapState{ From fd589fc94cb0c8527b5cd9d168e50544d14477bb Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 18:45:37 -0400 Subject: [PATCH 03/10] updates --- x/concentrated-liquidity/math/math.go | 6 +- x/concentrated-liquidity/swaps.go | 8 -- .../swapstrategy/one_for_zero_test.go | 110 ++++++++++++++++++ .../swapstrategy/swap_strategy_test.go | 14 +++ .../swapstrategy/zero_for_one_test.go | 106 +++++++++++++++++ 5 files changed, 235 insertions(+), 9 deletions(-) diff --git a/x/concentrated-liquidity/math/math.go b/x/concentrated-liquidity/math/math.go index bb6fdcd808b..d526f8d71d8 100644 --- a/x/concentrated-liquidity/math/math.go +++ b/x/concentrated-liquidity/math/math.go @@ -27,6 +27,10 @@ func Liquidity0(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec { product := sqrtPriceABigDec.Mul(sqrtPriceBBigDec) diff := sqrtPriceBBigDec.Sub(sqrtPriceABigDec) + if diff.Equal(osmomath.ZeroDec()) { + panic(fmt.Sprintf("liquidity0 diff is zero: sqrtPriceA %s sqrtPriceB %s", sqrtPriceA, sqrtPriceB)) + } + return amountBigDec.Mul(product).Quo(diff).SDKDec() } @@ -47,7 +51,7 @@ func Liquidity1(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec { diff := sqrtPriceBBigDec.Sub(sqrtPriceABigDec) if diff.Equal(osmomath.ZeroDec()) { - panic(fmt.Sprintf("diff is zero: sqrtPriceA %s sqrtPriceB %s", sqrtPriceA, sqrtPriceB)) + panic(fmt.Sprintf("liquidity1 diff is zero: sqrtPriceA %s sqrtPriceB %s", sqrtPriceA, sqrtPriceB)) } return amountBigDec.Quo(diff).SDKDec() diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 634e5eee5ef..fbf855247d1 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -302,14 +302,6 @@ func (k Keeper) computeOutAmtGivenIn( return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom} } - hasPositionInPool, err := k.HasAnyPositionForPool(ctx, poolId) - if err != nil { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err - } - if !hasPositionInPool { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("cannot swap since no positions found in pool %d", poolId) - } - // initialize swap state with the following parameters: // as we iterate through the following for loop, this swap state will get updated after each required iteration swapState := SwapState{ diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go index ced6d67eb9b..6425f7a9c89 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go @@ -3,6 +3,7 @@ package swapstrategy_test import ( sdk "github.com/cosmos/cosmos-sdk/types" + cl "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/math" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/swapstrategy" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" @@ -268,3 +269,112 @@ func (suite *StrategyTestSuite) TestComputeSwapStepInGivenOut_OneForZero() { }) } } + +func (suite *StrategyTestSuite) TestInitializeTickIterator_OneForZero() { + tests := map[string]struct { + currentTick int64 + preSetPositions []position + + expectIsValid bool + expectNextTick int64 + expectError error + }{ + "1 position, one for zero": { + preSetPositions: []position{ + { + lowerTick: -100, + upperTick: 100, + }, + }, + expectIsValid: true, + expectNextTick: 100, + }, + "2 positions, one for zero": { + preSetPositions: []position{ + { + lowerTick: -400, + upperTick: 300, + }, + { + lowerTick: -200, + upperTick: 200, + }, + }, + expectIsValid: true, + expectNextTick: 200, + }, + "lower tick lands on current tick, one for zero": { + preSetPositions: []position{ + { + lowerTick: 0, + upperTick: 100, + }, + }, + expectIsValid: true, + expectNextTick: 100, + }, + "upper tick lands on current tick, one for zero": { + preSetPositions: []position{ + { + lowerTick: -100, + upperTick: 0, + }, + { + lowerTick: 100, + upperTick: 200, + }, + }, + expectIsValid: true, + expectNextTick: 100, + }, + "no ticks, one for zero": { + preSetPositions: []position{}, + expectIsValid: false, + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + suite.SetupTest() + strategy := swapstrategy.New(false, types.MaxSqrtPrice, suite.App.GetKey(types.ModuleName), sdk.ZeroDec(), defaultTickSpacing) + + pool := suite.PrepareConcentratedPool() + + clMsgServer := cl.NewMsgServerImpl(suite.App.ConcentratedLiquidityKeeper) + + for _, pos := range tc.preSetPositions { + suite.FundAcc(suite.TestAccs[0], DefaultCoins.Add(DefaultCoins...)) + _, err := clMsgServer.CreatePosition(sdk.WrapSDKContext(suite.Ctx), &types.MsgCreatePosition{ + PoolId: pool.GetId(), + Sender: suite.TestAccs[0].String(), + LowerTick: pos.lowerTick, + UpperTick: pos.upperTick, + TokensProvided: DefaultCoins.Add(sdk.NewCoin(USDC, sdk.OneInt())), + TokenMinAmount0: sdk.ZeroInt(), + TokenMinAmount1: sdk.ZeroInt(), + }) + suite.Require().NoError(err) + } + + // refetch pool + pool, err := suite.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(suite.Ctx, pool.GetId()) + suite.Require().NoError(err) + + currentTick := pool.GetCurrentTick() + suite.Require().Equal(int64(0), currentTick.Int64()) + + tickIndex := strategy.InitializeTickValue(currentTick) + + iter := strategy.InitializeTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + defer iter.Close() + + suite.Require().Equal(tc.expectIsValid, iter.Valid()) + if tc.expectIsValid { + actualNextTick, err := types.TickIndexFromBytes(iter.Key()) + suite.Require().NoError(err) + suite.Require().Equal(tc.expectNextTick, actualNextTick) + } + }) + } +} diff --git a/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go b/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go index 2c217227515..ec91ca80563 100644 --- a/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go +++ b/x/concentrated-liquidity/swapstrategy/swap_strategy_test.go @@ -18,6 +18,18 @@ type StrategyTestSuite struct { apptesting.KeeperTestHelper } +type position struct { + lowerTick int64 + upperTick int64 +} + +const ( + defaultPoolId = uint64(1) + initialCurrentTick = int64(0) + ETH = "eth" + USDC = "usdc" +) + var ( two = sdk.NewDec(2) three = sdk.NewDec(2) @@ -30,6 +42,8 @@ var ( defaultLiquidity = sdk.MustNewDecFromStr("3035764687.503020836176699298") defaultFee = sdk.MustNewDecFromStr("0.03") defaultTickSpacing = uint64(100) + defaultAmountReserves = sdk.NewInt(1_000_000_000) + DefaultCoins = sdk.NewCoins(sdk.NewCoin(ETH, defaultAmountReserves), sdk.NewCoin(USDC, defaultAmountReserves)) ) func TestStrategyTestSuite(t *testing.T) { diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go index 0e49e347776..e595396a2b1 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go @@ -3,6 +3,7 @@ package swapstrategy_test import ( sdk "github.com/cosmos/cosmos-sdk/types" + cl "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/swapstrategy" "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" ) @@ -254,3 +255,108 @@ func (suite *StrategyTestSuite) TestComputeSwapStepInGivenOut_ZeroForOne() { }) } } + +func (suite *StrategyTestSuite) TestInitializeTickIterator_ZeroForOne() { + tests := map[string]struct { + currentTick int64 + preSetPositions []position + + expectIsValid bool + expectNextTick int64 + expectError error + }{ + "1 position, zero for one": { + preSetPositions: []position{ + { + lowerTick: -100, + upperTick: 100, + }, + }, + expectIsValid: true, + expectNextTick: -100, + }, + "2 positions, zero for one": { + preSetPositions: []position{ + { + lowerTick: -400, + upperTick: 300, + }, + { + lowerTick: -200, + upperTick: 200, + }, + }, + expectIsValid: true, + expectNextTick: -200, + }, + "lower tick lands on current tick, zero for one": { + preSetPositions: []position{ + { + lowerTick: 0, + upperTick: 100, + }, + }, + expectIsValid: true, + expectNextTick: 0, + }, + "upper tick lands on current tick, zero for one": { + preSetPositions: []position{ + { + lowerTick: -100, + upperTick: 0, + }, + }, + expectIsValid: true, + expectNextTick: 0, + }, + "no ticks, zero for one": { + preSetPositions: []position{}, + expectIsValid: false, + }, + } + + for name, tc := range tests { + tc := tc + suite.Run(name, func() { + suite.SetupTest() + strategy := swapstrategy.New(true, types.MaxSqrtPrice, suite.App.GetKey(types.ModuleName), sdk.ZeroDec(), defaultTickSpacing) + + pool := suite.PrepareConcentratedPool() + + clMsgServer := cl.NewMsgServerImpl(suite.App.ConcentratedLiquidityKeeper) + + for _, pos := range tc.preSetPositions { + suite.FundAcc(suite.TestAccs[0], DefaultCoins.Add(DefaultCoins...)) + _, err := clMsgServer.CreatePosition(sdk.WrapSDKContext(suite.Ctx), &types.MsgCreatePosition{ + PoolId: pool.GetId(), + Sender: suite.TestAccs[0].String(), + LowerTick: pos.lowerTick, + UpperTick: pos.upperTick, + TokensProvided: DefaultCoins.Add(sdk.NewCoin(USDC, sdk.OneInt())), + TokenMinAmount0: sdk.ZeroInt(), + TokenMinAmount1: sdk.ZeroInt(), + }) + suite.Require().NoError(err) + } + + // refetch pool + pool, err := suite.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(suite.Ctx, pool.GetId()) + suite.Require().NoError(err) + + currentTick := pool.GetCurrentTick() + suite.Require().Equal(int64(0), currentTick.Int64()) + + tickIndex := strategy.InitializeTickValue(currentTick) + + iter := strategy.InitializeTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + defer iter.Close() + + suite.Require().Equal(tc.expectIsValid, iter.Valid()) + if tc.expectIsValid { + actualNextTick, err := types.TickIndexFromBytes(iter.Key()) + suite.Require().NoError(err) + suite.Require().Equal(tc.expectNextTick, actualNextTick) + } + }) + } +} From 8ccf5d2ede0097c56812baa03ed4a400c69985d5 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:14:24 -0400 Subject: [PATCH 04/10] clean up --- x/concentrated-liquidity/swaps.go | 6 +++--- x/concentrated-liquidity/types/errors.go | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index f66a27ec9bf..38d323ddc6c 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -329,7 +329,7 @@ func (k Keeper) computeOutAmtGivenIn( sqrtPriceStart := swapState.sqrtPrice if !iter.Valid() { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no more ticks found for pool %d", poolId) + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } // We first check to see what the position of the nearest initialized tick is @@ -338,7 +338,7 @@ func (k Keeper) computeOutAmtGivenIn( // if no ticks are initialized (no users have created liquidity positions) then we return an error nextTick, err := types.TickIndexFromBytes(iter.Key()) if err != nil { - panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err } // Utilizing the next initialized tick, we find the corresponding nextPrice (the target price). @@ -387,7 +387,7 @@ func (k Keeper) computeOutAmtGivenIn( } if !iter.Valid() { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no more ticks found for pool %d", poolId) + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } iter.Next() diff --git a/x/concentrated-liquidity/types/errors.go b/x/concentrated-liquidity/types/errors.go index 0230e1a5a1a..2a450cb5e0d 100644 --- a/x/concentrated-liquidity/types/errors.go +++ b/x/concentrated-liquidity/types/errors.go @@ -807,3 +807,11 @@ type CoinLengthError struct { func (e CoinLengthError) Error() string { return fmt.Sprintf("coin length (%d) must be less than or equal to max length (%d)", e.Length, e.MaxLength) } + +type RanOutOfTicksForPoolError struct { + PoolId uint64 +} + +func (e RanOutOfTicksForPoolError) Error() string { + return fmt.Sprintf("ran out of ticks for pool (%d) during swap", e.PoolId) +} From 0d72bca76c108765baac50db67f6dd7b4064d73d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:21:28 -0400 Subject: [PATCH 05/10] godoc updates --- .../swapstrategy/one_for_zero.go | 13 +++++++++++-- .../swapstrategy/zero_for_one.go | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero.go b/x/concentrated-liquidity/swapstrategy/one_for_zero.go index e5c06287ce3..2bdadf60a83 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero.go @@ -148,7 +148,16 @@ func (s oneForZeroStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountZeroOut, amountOneIn, feeChargeTotal } -// TODO: spec +// InitializeTickIterator returns iterator that seeks to the given tickIndex. +// If tick index does not exist in the store, it will return an invalid iterator. +// +// oneForZeroStrategy assumes moving to the right of the current square root price. +// As a result, we use forward iterator in InitializeTickIterator to find the next +// tick to the left of current. The end cursor for forward iteration is inclusive. +// Therefore, it searches directly from the tickIndex forwards in increasing lexicographic order. +// Returns an invalid iterator if tickIndex is not in the store. +// Panics if fails to parse tick index from bytes. +// The caller is responsible for closing the iterator on success. func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { store := ctx.KVStore(s.storeKey) prefixBz := types.KeyTickPrefixByPoolId(poolId) @@ -176,7 +185,7 @@ func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 // on the actual current tick. // // oneForZeroStrategy assumes moving to the right of the current square root price. -// As a result, we use forward iterator in NextInitializedTick to find the next +// As a result, we use forward iterator in InitializeTickIterator to find the next // tick to the left of current. The end cursor for forward iteration is inclusive. // 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 diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one.go b/x/concentrated-liquidity/swapstrategy/zero_for_one.go index 358969473a9..9a91738decc 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one.go @@ -145,7 +145,16 @@ func (s zeroForOneStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountOneOut, amountZeroIn, feeChargeTotal } -// TODO: spec +// InitializeTickIterator returns iterator that seeks to the given tickIndex. +// If tick index does not exist in the store, it will return an invalid iterator. +// +// zeroForOneStrategy assumes moving to the left of the current square root price. +// 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 the search starts from the tickIndex - 1. The caller must handle this case. +// Returns an invalid iterator if tickIndex is not in the store. +// Panics if fails to parse tick index from bytes. +// The caller is responsible for closing the iterator on success. func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { store := ctx.KVStore(s.storeKey) prefixBz := types.KeyTickPrefixByPoolId(poolId) @@ -173,7 +182,7 @@ func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 // on the actual current tick. // // zeroForOneStrategy assumes moving to the left of the current square root price. -// As a result, we use reverse iterator in NextInitializedTick to find the next +// As a result, we use reverse iterator in InitializeTickIterator 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 { From 61d3c0efc46936f5737d93fb93a6b5505bc9a7cf Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:22:36 -0400 Subject: [PATCH 06/10] updates --- x/concentrated-liquidity/swaps.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 38d323ddc6c..b8903054e85 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -317,7 +317,7 @@ func (k Keeper) computeOutAmtGivenIn( iter := swapStrategy.InitializeTickIterator(ctx, poolId, swapState.tick.Int64()) defer iter.Close() if !iter.Valid() { - return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("no ticks found for pool %d", poolId) + return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } // Iterate and update swapState until we swap all tokenIn or we reach the specific sqrtPriceLimit From 34848d3e2c482c9624942988fa29aa5e7137ad55 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:25:17 -0400 Subject: [PATCH 07/10] updates --- x/concentrated-liquidity/swaps.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index b8903054e85..121f1340b72 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -314,9 +314,9 @@ func (k Keeper) computeOutAmtGivenIn( feeGrowthGlobal: sdk.ZeroDec(), } - iter := swapStrategy.InitializeTickIterator(ctx, poolId, swapState.tick.Int64()) - defer iter.Close() - if !iter.Valid() { + nextTickIter := swapStrategy.InitializeTickIterator(ctx, poolId, swapState.tick.Int64()) + defer nextTickIter.Close() + if !nextTickIter.Valid() { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } @@ -328,7 +328,7 @@ func (k Keeper) computeOutAmtGivenIn( // Log the sqrtPrice we start the iteration with sqrtPriceStart := swapState.sqrtPrice - if !iter.Valid() { + if !nextTickIter.Valid() { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } @@ -336,7 +336,7 @@ 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, err := types.TickIndexFromBytes(iter.Key()) + nextTick, err := types.TickIndexFromBytes(nextTickIter.Key()) if err != nil { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err } @@ -386,11 +386,11 @@ func (k Keeper) computeOutAmtGivenIn( return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err } - if !iter.Valid() { + // Move next tick iterator to the next tick as the tick is crossed. + if !nextTickIter.Valid() { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } - - iter.Next() + nextTickIter.Next() liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet) // Update the swapState's liquidity with the new tick's liquidity From 2b6548d5311c260d4039ce1a5f64524bf54631ae Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:25:22 -0400 Subject: [PATCH 08/10] updates --- x/concentrated-liquidity/swaps.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 121f1340b72..0606c571a59 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -328,6 +328,7 @@ func (k Keeper) computeOutAmtGivenIn( // Log the sqrtPrice we start the iteration with sqrtPriceStart := swapState.sqrtPrice + // Iterator must be valid to be able to retrieve the next tick from it below. if !nextTickIter.Valid() { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} } From 9386fa9b0e58298407d01d1a923d9462f8d58b2c Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 16 May 2023 19:47:22 -0400 Subject: [PATCH 09/10] clean up --- x/concentrated-liquidity/swaps.go | 2 +- .../swapstrategy/one_for_zero.go | 18 +++++++-------- .../swapstrategy/one_for_zero_test.go | 4 ++-- .../swapstrategy/swap_strategy.go | 6 ++--- .../swapstrategy/zero_for_one.go | 22 +++++++++---------- .../swapstrategy/zero_for_one_test.go | 4 ++-- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 0606c571a59..a07f3a40681 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -314,7 +314,7 @@ func (k Keeper) computeOutAmtGivenIn( feeGrowthGlobal: sdk.ZeroDec(), } - nextTickIter := swapStrategy.InitializeTickIterator(ctx, poolId, swapState.tick.Int64()) + nextTickIter := swapStrategy.InitializeNextTickIterator(ctx, poolId, swapState.tick.Int64()) defer nextTickIter.Close() if !nextTickIter.Valid() { return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.RanOutOfTicksForPoolError{PoolId: poolId} diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero.go b/x/concentrated-liquidity/swapstrategy/one_for_zero.go index 2bdadf60a83..48c2b96c653 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero.go @@ -148,21 +148,21 @@ func (s oneForZeroStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountZeroOut, amountOneIn, feeChargeTotal } -// InitializeTickIterator returns iterator that seeks to the given tickIndex. -// If tick index does not exist in the store, it will return an invalid iterator. +// InitializeNextTickIterator returns iterator that seeks to the next tick from the given tickIndex. +// If nex tick relative to tickINdex does not exist in the store, it will return an invalid iterator. // // oneForZeroStrategy assumes moving to the right of the current square root price. -// As a result, we use forward iterator in InitializeTickIterator to find the next -// tick to the left of current. The end cursor for forward iteration is inclusive. -// Therefore, it searches directly from the tickIndex forwards in increasing lexicographic order. +// As a result, we use forward iterator to seek to the next tick index relative to the currentTickIndex. +// Since start key of the forward iterator is inclusive, we search directly from the tickIndex +// forwards in increasing lexicographic order until a tick greater than currentTickIndex is found. // Returns an invalid iterator if tickIndex is not in the store. // Panics if fails to parse tick index from bytes. // The caller is responsible for closing the iterator on success. -func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { +func (s oneForZeroStrategy) InitializeNextTickIterator(ctx sdk.Context, poolId uint64, currentTickIndex int64) dbm.Iterator { store := ctx.KVStore(s.storeKey) prefixBz := types.KeyTickPrefixByPoolId(poolId) prefixStore := prefix.NewStore(store, prefixBz) - startKey := types.TickIndexToBytes(tickIndex) + startKey := types.TickIndexToBytes(currentTickIndex) iter := prefixStore.Iterator(startKey, nil) for ; iter.Valid(); iter.Next() { @@ -174,7 +174,7 @@ func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) } - if tick > tickIndex { + if tick > currentTickIndex { break } } @@ -185,7 +185,7 @@ func (s oneForZeroStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 // on the actual current tick. // // oneForZeroStrategy assumes moving to the right of the current square root price. -// As a result, we use forward iterator in InitializeTickIterator to find the next +// As a result, we use forward iterator in InitializeNextTickIterator to find the next // tick to the left of current. The end cursor for forward iteration is inclusive. // 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 diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go index 6425f7a9c89..cf00673e61e 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go @@ -270,7 +270,7 @@ func (suite *StrategyTestSuite) TestComputeSwapStepInGivenOut_OneForZero() { } } -func (suite *StrategyTestSuite) TestInitializeTickIterator_OneForZero() { +func (suite *StrategyTestSuite) TestInitializeNextTickIterator_OneForZero() { tests := map[string]struct { currentTick int64 preSetPositions []position @@ -366,7 +366,7 @@ func (suite *StrategyTestSuite) TestInitializeTickIterator_OneForZero() { tickIndex := strategy.InitializeTickValue(currentTick) - iter := strategy.InitializeTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) defer iter.Close() suite.Require().Equal(tc.expectIsValid, iter.Valid()) diff --git a/x/concentrated-liquidity/swapstrategy/swap_strategy.go b/x/concentrated-liquidity/swapstrategy/swap_strategy.go index 622de796ae0..269d9ea3978 100644 --- a/x/concentrated-liquidity/swapstrategy/swap_strategy.go +++ b/x/concentrated-liquidity/swapstrategy/swap_strategy.go @@ -50,10 +50,10 @@ type swapStrategy interface { // * feeChargeTotal is the total fee charge. The fee is charged on the amount of token in. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPriceTarget, liquidity, amountRemainingOut sdk.Dec) (sqrtPriceNext, amountOutConsumed, amountInComputed, feeChargeTotal sdk.Dec) - // InitializeTickIterator returns iterator that seeks to the given tickIndex. - // If tick index does not exist in the store, it will return an invalid iterator. + // InitializeNextTickIterator returns iterator that seeks to the next tick from the given tickIndex. + // If nex tick relative to tickINdex does not exist in the store, it will return an invalid iterator. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. - InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator + InitializeNextTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator // InitializeTickValue returns the initial tick value for computing swaps based // on the actual current tick. // See oneForZeroStrategy or zeroForOneStrategy for implementation details. diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one.go b/x/concentrated-liquidity/swapstrategy/zero_for_one.go index 9a91738decc..1903d0305e9 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one.go @@ -145,21 +145,21 @@ func (s zeroForOneStrategy) ComputeSwapStepInGivenOut(sqrtPriceCurrent, sqrtPric return sqrtPriceNext, amountOneOut, amountZeroIn, feeChargeTotal } -// InitializeTickIterator returns iterator that seeks to the given tickIndex. -// If tick index does not exist in the store, it will return an invalid iterator. +// InitializeNextTickIterator returns iterator that seeks to the next tick from the given tickIndex. +// If nex tick relative to tickINdex does not exist in the store, it will return an invalid iterator. // -// zeroForOneStrategy assumes moving to the left of the current square root price. -// 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 the search starts from the tickIndex - 1. The caller must handle this case. -// Returns an invalid iterator if tickIndex is not in the store. +// oneForZeroStrategy assumes moving to the left of the current square root price. +// As a result, we use a reverse iterator to seek to the next tick index relative to the currentTickIndexPlusOne. +// Since end key of the reverse iterator is exclusive, we search from current + 1 tick index. +// in decrasing lexicographic order until a tick one smaller than current is found. +// Returns an invalid iterator if currentTickIndexPlusOne is not in the store. // Panics if fails to parse tick index from bytes. // The caller is responsible for closing the iterator on success. -func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint64, tickIndex int64) dbm.Iterator { +func (s zeroForOneStrategy) InitializeNextTickIterator(ctx sdk.Context, poolId uint64, currentTickIndexPlusOne int64) dbm.Iterator { store := ctx.KVStore(s.storeKey) prefixBz := types.KeyTickPrefixByPoolId(poolId) prefixStore := prefix.NewStore(store, prefixBz) - startKey := types.TickIndexToBytes(tickIndex) + startKey := types.TickIndexToBytes(currentTickIndexPlusOne) iter := prefixStore.ReverseIterator(nil, startKey) @@ -171,7 +171,7 @@ func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 iter.Close() panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err)) } - if tick <= tickIndex { + if tick < currentTickIndexPlusOne { break } } @@ -182,7 +182,7 @@ func (s zeroForOneStrategy) InitializeTickIterator(ctx sdk.Context, poolId uint6 // on the actual current tick. // // zeroForOneStrategy assumes moving to the left of the current square root price. -// As a result, we use reverse iterator in InitializeTickIterator to find the next +// As a result, we use reverse iterator in InitializeNextTickIterator 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 { diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go index e595396a2b1..85607cef5d3 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go @@ -256,7 +256,7 @@ func (suite *StrategyTestSuite) TestComputeSwapStepInGivenOut_ZeroForOne() { } } -func (suite *StrategyTestSuite) TestInitializeTickIterator_ZeroForOne() { +func (suite *StrategyTestSuite) TestInitializeNextTickIterator_ZeroForOne() { tests := map[string]struct { currentTick int64 preSetPositions []position @@ -348,7 +348,7 @@ func (suite *StrategyTestSuite) TestInitializeTickIterator_ZeroForOne() { tickIndex := strategy.InitializeTickValue(currentTick) - iter := strategy.InitializeTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) defer iter.Close() suite.Require().Equal(tc.expectIsValid, iter.Valid()) From e81c3c4f385b9d6b0f1894ea416f6202d4350df5 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 17 May 2023 17:18:39 -0400 Subject: [PATCH 10/10] updates --- x/concentrated-liquidity/swapstrategy/one_for_zero_test.go | 4 ++-- x/concentrated-liquidity/swapstrategy/zero_for_one_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go index cf00673e61e..48c7cd3bf2d 100644 --- a/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go +++ b/x/concentrated-liquidity/swapstrategy/one_for_zero_test.go @@ -362,11 +362,11 @@ func (suite *StrategyTestSuite) TestInitializeNextTickIterator_OneForZero() { suite.Require().NoError(err) currentTick := pool.GetCurrentTick() - suite.Require().Equal(int64(0), currentTick.Int64()) + suite.Require().Equal(int64(0), currentTick) tickIndex := strategy.InitializeTickValue(currentTick) - iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex) defer iter.Close() suite.Require().Equal(tc.expectIsValid, iter.Valid()) diff --git a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go index 85607cef5d3..c1295f36fdd 100644 --- a/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go +++ b/x/concentrated-liquidity/swapstrategy/zero_for_one_test.go @@ -344,11 +344,11 @@ func (suite *StrategyTestSuite) TestInitializeNextTickIterator_ZeroForOne() { suite.Require().NoError(err) currentTick := pool.GetCurrentTick() - suite.Require().Equal(int64(0), currentTick.Int64()) + suite.Require().Equal(int64(0), currentTick) tickIndex := strategy.InitializeTickValue(currentTick) - iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex.Int64()) + iter := strategy.InitializeNextTickIterator(suite.Ctx, defaultPoolId, tickIndex) defer iter.Close() suite.Require().Equal(tc.expectIsValid, iter.Valid())