From 6d26e12c4b5869a0cc44f3f029575a39520f7af3 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Aug 2023 15:57:20 +0200 Subject: [PATCH] refactor(CL): replace 6 return values in CreatePosition with a struct (backport #5983) --- CHANGELOG.md | 4 +- go.sum | 1 - x/concentrated-liquidity/bench_test.go | 4 +- x/concentrated-liquidity/export_test.go | 4 -- x/concentrated-liquidity/fuzz_test.go | 8 +-- x/concentrated-liquidity/incentives_test.go | 19 +++--- x/concentrated-liquidity/keeper_test.go | 10 +-- x/concentrated-liquidity/lp.go | 67 ++++++++++++------- x/concentrated-liquidity/lp_test.go | 50 ++++++++++---- x/concentrated-liquidity/msg_server.go | 4 +- x/concentrated-liquidity/pool_test.go | 6 +- x/concentrated-liquidity/position.go | 4 +- x/concentrated-liquidity/position_test.go | 28 ++++---- x/concentrated-liquidity/range_test.go | 12 ++-- .../spread_rewards_test.go | 25 +++---- x/concentrated-liquidity/swaps_test.go | 4 +- .../swaps_tick_cross_test.go | 6 +- x/concentrated-liquidity/tick_test.go | 2 +- 18 files changed, 151 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93d31a98ce1..26b4ef1552c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -### State Breaking +### API breaks + +* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) refactor(CL): 6 return values in CL CreatePosition with a struct ### Bug Fixes diff --git a/go.sum b/go.sum index 05c3049eaa1..558cabd1625 100644 --- a/go.sum +++ b/go.sum @@ -950,7 +950,6 @@ github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:Ylmch github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI= github.com/osmosis-labs/osmosis/osmomath v0.0.5 h1:veOu4VvnqMbJyjx2MEEFW53I9h3m8Kd3WN4hVvUyeIU= github.com/osmosis-labs/osmosis/osmomath v0.0.5/go.mod h1:UlftwozB+QObT3o0YfkuuyL9fsVdgoWt0dm6J7MLYnU= -github.com/osmosis-labs/osmosis/osmoutils v0.0.6-0.20230709040235-cbf530ed88cc h1:NhjYKK0ADJCq5nmDfLMGRIAq8/QIhrStlt78+5xOZP4= github.com/osmosis-labs/osmosis/osmoutils v0.0.6-0.20230718110737-18371921cd51 h1:z7X7+p3CIxXoxo6264Pw3NBqAaeqEZyZ4euto/Si2x4= github.com/osmosis-labs/osmosis/osmoutils v0.0.6-0.20230718110737-18371921cd51/go.mod h1:Pl8Nzx6O6ow/+aqfMoMSz4hX+zz6RrnDYsooptECGxM= github.com/osmosis-labs/osmosis/x/epochs v0.0.1 h1:RCL3+W2s712dgtaKGgUHVt/6iJKfuPH63tkd3eiJeRo= diff --git a/x/concentrated-liquidity/bench_test.go b/x/concentrated-liquidity/bench_test.go index e78c8218e21..d2068fa0fd3 100644 --- a/x/concentrated-liquidity/bench_test.go +++ b/x/concentrated-liquidity/bench_test.go @@ -26,7 +26,7 @@ type BenchTestSuite struct { func (s *BenchTestSuite) createPosition(accountIndex int, poolId uint64, coin0, coin1 sdk.Coin, lowerTick, upperTick int64) { tokensDesired := sdk.NewCoins(coin0, coin1) - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[accountIndex], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[accountIndex], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) if err != nil { // This can happen for ticks that map to the very small prices // e.g 2 * 10^(-18) ends up mapping to the same sqrt price @@ -113,7 +113,7 @@ func runBenchmark(b *testing.B, testFunc func(b *testing.B, s *BenchTestSuite, p tokenDesired0 := sdk.NewCoin(denom0, sdk.NewInt(100)) tokenDesired1 := sdk.NewCoin(denom1, sdk.NewInt(100)) tokensDesired := sdk.NewCoins(tokenDesired0, tokenDesired1) - _, _, _, _, _, _, err = clKeeper.CreatePosition(s.Ctx, clPoolId, s.TestAccs[0], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) + _, err = clKeeper.CreatePosition(s.Ctx, clPoolId, s.TestAccs[0], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) noError(b, err) pool, err := clKeeper.GetPoolById(s.Ctx, clPoolId) diff --git a/x/concentrated-liquidity/export_test.go b/x/concentrated-liquidity/export_test.go index 079463cf5e9..caf99818625 100644 --- a/x/concentrated-liquidity/export_test.go +++ b/x/concentrated-liquidity/export_test.go @@ -207,10 +207,6 @@ func UpdatePositionToInitValuePlusGrowthOutside(accumulator *accum.AccumulatorOb return updatePositionToInitValuePlusGrowthOutside(accumulator, positionKey, growthOutside) } -func (k Keeper) CreatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, tokensProvided sdk.Coins, amount0Min, amount1Min sdk.Int, lowerTick, upperTick int64) (positionId uint64, actualAmount0 sdk.Int, actualAmount1 sdk.Int, liquidityDelta sdk.Dec, lowerTickResult int64, upperTickResult int64, err error) { - return k.createPosition(ctx, poolId, owner, tokensProvided, amount0Min, amount1Min, lowerTick, upperTick) -} - func (k Keeper) AddToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId uint64, amount0Added, amount1Added, amount0Min, amount1Min sdk.Int) (uint64, sdk.Int, sdk.Int, error) { return k.addToPosition(ctx, owner, positionId, amount0Added, amount1Added, amount0Min, amount1Min) } diff --git a/x/concentrated-liquidity/fuzz_test.go b/x/concentrated-liquidity/fuzz_test.go index e9684aebc91..2ed13bd27d8 100644 --- a/x/concentrated-liquidity/fuzz_test.go +++ b/x/concentrated-liquidity/fuzz_test.go @@ -490,13 +490,13 @@ func (s *KeeperTestSuite) addRandomPositon(r *rand.Rand, poolId uint64, minTick, fmt.Println("creating position: ", "accountName", "lowerTick", lowerTick, "upperTick", upperTick, "token0Desired", tokenDesired0, "tokenDesired1", tokenDesired1) - positionId, amt0, amt1, liq, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[accountIndex], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) + positionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[accountIndex], tokensDesired, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) s.Require().NoError(err) - fmt.Printf("actually created: %s%s %s%s \n", amt0, ETH, amt1, USDC) + fmt.Printf("actually created: %s%s %s%s \n", positionData.Amount0, ETH, positionData.Amount1, USDC) s.positionData = append(s.positionData, positionAndLiquidity{ - positionId: positionId, - liquidity: liq, + positionId: positionData.ID, + liquidity: positionData.Liquidity, accountIndex: accountIndex, }) } diff --git a/x/concentrated-liquidity/incentives_test.go b/x/concentrated-liquidity/incentives_test.go index a59f0d55bfd..d37242ddf92 100644 --- a/x/concentrated-liquidity/incentives_test.go +++ b/x/concentrated-liquidity/incentives_test.go @@ -1048,8 +1048,9 @@ 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()-100, clPool.GetCurrentTick()+100) + positionData, err := clKeeper.CreatePosition(s.Ctx, clPool.GetId(), testAddressOne, depositedCoins, sdk.ZeroInt(), sdk.ZeroInt(), clPool.GetCurrentTick()-100, clPool.GetCurrentTick()+100) s.Require().NoError(err) + qualifyingLiquidity = positionData.Liquidity // If a canonical balancer pool exists, we add its respective shares to the qualifying amount as well. clPool, err = clKeeper.GetPoolById(s.Ctx, clPool.GetId()) @@ -3132,7 +3133,7 @@ func (s *KeeperTestSuite) TestPrepareClaimAllIncentivesForPosition() { pool := s.PrepareConcentratedPool() // Set up position - positionIdOne, _, _, _, _, _, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], requiredBalances, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionOneData, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], requiredBalances, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) // Set incentives for pool to ensure accumulators work correctly @@ -3165,7 +3166,7 @@ func (s *KeeperTestSuite) TestPrepareClaimAllIncentivesForPosition() { // Determine what the expected forfeited incentives per share is, including the dust since we reinvest the dust when we forfeit. if tc.blockTimeElapsed < tc.minUptimeIncentiveRecord { for _, uptimeAccum := range uptimeAccumulatorsPreClaim { - newPositionName := string(types.KeyPositionId(positionIdOne)) + newPositionName := string(types.KeyPositionId(positionOneData.ID)) // Check if the accumulator contains the position. hasPosition := uptimeAccum.HasPosition(newPositionName) if hasPosition { @@ -3183,7 +3184,7 @@ func (s *KeeperTestSuite) TestPrepareClaimAllIncentivesForPosition() { } // System under test - collectedInc, forfeitedIncentives, err := s.clk.PrepareClaimAllIncentivesForPosition(s.Ctx, positionIdOne) + collectedInc, forfeitedIncentives, err := s.clk.PrepareClaimAllIncentivesForPosition(s.Ctx, positionOneData.ID) s.Require().NoError(err) s.Require().Equal(tc.expectedCoins.String(), collectedInc.String()) s.Require().Equal(expectedForfeitedIncentives.String(), forfeitedIncentives.String()) @@ -3268,14 +3269,14 @@ func (s *KeeperTestSuite) TestFunctional_ClaimIncentives_LiquidityChange_Varying s.Require().NoError(err) // Set up position - positionIdOne, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, defaultPoolId, defaultAddress, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionOneData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, defaultPoolId, defaultAddress, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) // Increase block time by the fully charged duration (first time) s.Ctx = s.Ctx.WithBlockTime(s.Ctx.BlockTime().Add(testFullChargeDuration)) // Claim incentives. - collected, _, err := s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionIdOne) + collected, _, err := s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionOneData.ID) s.Require().NoError(err) s.Require().Equal(expectedCoinsPerFullCharge.String(), collected.String()) @@ -3283,20 +3284,20 @@ func (s *KeeperTestSuite) TestFunctional_ClaimIncentives_LiquidityChange_Varying s.Ctx = s.Ctx.WithBlockTime(s.Ctx.BlockTime().Add(testFullChargeDuration)) // Create another position - positionIdTwo, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, defaultPoolId, defaultAddress, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionTwoData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, defaultPoolId, defaultAddress, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) // Increase block time by the fully charged duration (third time) s.Ctx = s.Ctx.WithBlockTime(s.Ctx.BlockTime().Add(testFullChargeDuration)) // Claim for second position. Must only claim half of the original expected amount since now there are 2 positions. - collected, _, err = s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionIdTwo) + collected, _, err = s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionTwoData.ID) s.Require().NoError(err) s.Require().Equal(expectedHalfOfExpectedCoinsPerFullCharge.String(), collected.String()) // Claim for first position and observe that claims full expected charge for the period between 1st claim and 2nd position creation // and half of the full charge amount since the 2nd position was created. - collected, _, err = s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionIdOne) + collected, _, err = s.App.ConcentratedLiquidityKeeper.CollectIncentives(s.Ctx, defaultAddress, positionOneData.ID) s.Require().NoError(err) // Note, adding one since both expected amounts already subtract one (-2 in total) s.Require().Equal(expectedCoinsPerFullCharge.Add(expectedHalfOfExpectedCoinsPerFullCharge.Add(oneUUSDCCoin)...).String(), collected.String()) diff --git a/x/concentrated-liquidity/keeper_test.go b/x/concentrated-liquidity/keeper_test.go index 28100974571..b796ee26e89 100644 --- a/x/concentrated-liquidity/keeper_test.go +++ b/x/concentrated-liquidity/keeper_test.go @@ -130,11 +130,11 @@ func (s *KeeperTestSuite) SetupPosition(poolId uint64, owner sdk.AccAddress, pro } s.FundAcc(owner, providedCoins.Add(roundingErrorCoins...)) - positionId, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, owner, providedCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) + positionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, owner, providedCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) s.Require().NoError(err) - liquidity, err := s.App.ConcentratedLiquidityKeeper.GetPositionLiquidity(s.Ctx, positionId) + liquidity, err := s.App.ConcentratedLiquidityKeeper.GetPositionLiquidity(s.Ctx, positionData.ID) s.Require().NoError(err) - return liquidity, positionId + return liquidity, positionData.ID } // SetupDefaultPositions sets up four different positions to the given pool with different accounts for each position./ @@ -467,9 +467,9 @@ func (s *KeeperTestSuite) runFungifySetup(address sdk.AccAddress, numPositions i // Set up fully charged positions totalLiquidity := sdk.ZeroDec() for i := 0; i < numPositions; i++ { - _, _, _, liquidityCreated, _, _, err := s.clk.CreatePosition(s.Ctx, defaultPoolId, address, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionData, err := s.clk.CreatePosition(s.Ctx, defaultPoolId, address, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) - totalLiquidity = totalLiquidity.Add(liquidityCreated) + totalLiquidity = totalLiquidity.Add(positionData.Liquidity) } return pool, expectedPositionIds, totalLiquidity diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 2f10d53e918..91ebee4407a 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -15,6 +15,16 @@ import ( const noUnderlyingLockId = uint64(0) +// CreatePositionData represents the return data from CreatePosition. +type CreatePositionData struct { + ID uint64 + Amount0 sdk.Int + Amount1 sdk.Int + Liquidity sdk.Dec + LowerTick int64 + UpperTick int64 +} + // createPosition creates a concentrated liquidity position in range between lowerTick and upperTick // in a given poolId with the desired amount of each token. Since LPs are only allowed to provide // liquidity proportional to the existing reserves, the actual amount of tokens used might differ from requested. @@ -32,92 +42,92 @@ const noUnderlyingLockId = uint64(0) // - the liquidity delta is zero // - the amount0 or amount1 returned from the position update is less than the given minimums // - the pool or user does not have enough tokens to satisfy the requested amount -func (k Keeper) createPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, tokensProvided sdk.Coins, amount0Min, amount1Min sdk.Int, lowerTick, upperTick int64) (positionId uint64, actualAmount0 sdk.Int, actualAmount1 sdk.Int, liquidityDelta sdk.Dec, lowerTickResult int64, upperTickResult int64, err error) { +func (k Keeper) CreatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, tokensProvided sdk.Coins, amount0Min, amount1Min sdk.Int, lowerTick, upperTick int64) (positionDate CreatePositionData, err error) { // Use the current blockTime as the position's join time. joinTime := ctx.BlockTime() // Retrieve the pool associated with the given pool ID. pool, err := k.getPoolById(ctx, poolId) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } for _, token := range tokensProvided { if token.Denom != pool.GetToken0() && token.Denom != pool.GetToken1() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, errors.New("token provided is not one of the pool tokens") + return CreatePositionData{}, errors.New("token provided is not one of the pool tokens") } } // Check if the provided tick range is valid according to the pool's tick spacing and module parameters. if err := validateTickRangeIsValid(pool.GetTickSpacing(), lowerTick, upperTick); err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } amount0Desired := tokensProvided.AmountOf(pool.GetToken0()) amount1Desired := tokensProvided.AmountOf(pool.GetToken1()) if amount0Desired.IsZero() && amount1Desired.IsZero() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, errors.New("cannot create a position with zero amounts of both pool tokens") + return CreatePositionData{}, errors.New("cannot create a position with zero amounts of both pool tokens") } // sanity check that both given minimum accounts are not negative amounts. if amount0Min.IsNegative() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, types.NotPositiveRequireAmountError{Amount: amount0Min.String()} + return CreatePositionData{}, types.NotPositiveRequireAmountError{Amount: amount0Min.String()} } if amount1Min.IsNegative() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, types.NotPositiveRequireAmountError{Amount: amount1Min.String()} + return CreatePositionData{}, types.NotPositiveRequireAmountError{Amount: amount1Min.String()} } // Transform the provided ticks into their corresponding sqrtPrices. _, _, sqrtPriceLowerTick, sqrtPriceUpperTick, err := math.TicksToSqrtPrice(lowerTick, upperTick) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } // If multiple ticks can represent the same spot price, ensure we are using the largest of those ticks. lowerTick, upperTick, err = roundTickToCanonicalPriceTick(lowerTick, upperTick, sqrtPriceLowerTick, sqrtPriceUpperTick, pool.GetTickSpacing()) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } - positionId = k.getNextPositionIdAndIncrement(ctx) + positionId := k.getNextPositionIdAndIncrement(ctx) // If this is the first position created in this pool, ensure that the position includes both asset0 and asset1 // in order to assign an initial spot price. hasPositions, err := k.HasAnyPositionForPool(ctx, poolId) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } if !hasPositions { err := k.initializeInitialPositionForPool(ctx, pool, amount0Desired, amount1Desired) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } } // Calculate the amount of liquidity that will be added to the pool when this position is created. - liquidityDelta = math.GetLiquidityFromAmounts(pool.GetCurrentSqrtPrice(), sqrtPriceLowerTick, sqrtPriceUpperTick, amount0Desired, amount1Desired) + liquidityDelta := math.GetLiquidityFromAmounts(pool.GetCurrentSqrtPrice(), sqrtPriceLowerTick, sqrtPriceUpperTick, amount0Desired, amount1Desired) if liquidityDelta.IsZero() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, errors.New("liquidityDelta calculated equals zero") + return CreatePositionData{}, errors.New("liquidityDelta calculated equals zero") } // Initialize / update the position in the pool based on the provided tick range and liquidity delta. - actualAmount0, actualAmount1, err = k.UpdatePosition(ctx, poolId, owner, lowerTick, upperTick, liquidityDelta, joinTime, positionId) + actualAmount0, actualAmount1, err := k.UpdatePosition(ctx, poolId, owner, lowerTick, upperTick, liquidityDelta, joinTime, positionId) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } // Check if the actual amounts of tokens 0 and 1 are greater than or equal to the given minimum amounts. if actualAmount0.LT(amount0Min) { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, types.InsufficientLiquidityCreatedError{Actual: actualAmount0, Minimum: amount0Min, IsTokenZero: true} + return CreatePositionData{}, types.InsufficientLiquidityCreatedError{Actual: actualAmount0, Minimum: amount0Min, IsTokenZero: true} } if actualAmount1.LT(amount1Min) { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, types.InsufficientLiquidityCreatedError{Actual: actualAmount1, Minimum: amount1Min} + return CreatePositionData{}, types.InsufficientLiquidityCreatedError{Actual: actualAmount1, Minimum: amount1Min} } // Transfer the actual amounts of tokens 0 and 1 from the position owner to the pool. err = k.sendCoinsBetweenPoolAndUser(ctx, pool.GetToken0(), pool.GetToken1(), actualAmount0, actualAmount1, owner, pool.GetAddress()) if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, 0, err + return CreatePositionData{}, err } event := &liquidityChangeEvent{ @@ -151,7 +161,14 @@ func (k Keeper) createPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr } k.RecordTotalLiquidityIncrease(ctx, tokensAdded) - return positionId, actualAmount0, actualAmount1, liquidityDelta, lowerTick, upperTick, nil + return CreatePositionData{ + ID: positionId, + Amount0: actualAmount0, + Amount1: actualAmount1, + Liquidity: liquidityDelta, + LowerTick: lowerTick, + UpperTick: upperTick, + }, nil } // WithdrawPosition attempts to withdraw liquidityAmount from a position with the given pool id in the given tick range. @@ -367,7 +384,7 @@ func (k Keeper) addToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId if !amount1MinGiven.IsZero() { minimumAmount1 = amount1Withdrawn.Add(amount1MinGiven) } - newPositionId, actualAmount0, actualAmount1, _, _, _, err := k.createPosition(ctx, position.PoolId, owner, tokensProvided, minimumAmount0, minimumAmount1, position.LowerTick, position.UpperTick) + newPositionData, err := k.CreatePosition(ctx, position.PoolId, owner, tokensProvided, minimumAmount0, minimumAmount1, position.LowerTick, position.UpperTick) if err != nil { return 0, sdk.Int{}, sdk.Int{}, err } @@ -379,13 +396,13 @@ func (k Keeper) addToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), sdk.NewAttribute(sdk.AttributeKeySender, owner.String()), sdk.NewAttribute(types.AttributeKeyPositionId, strconv.FormatUint(positionId, 10)), - sdk.NewAttribute(types.AttributeKeyNewPositionId, strconv.FormatUint(newPositionId, 10)), - sdk.NewAttribute(types.AttributeAmount0, actualAmount0.String()), - sdk.NewAttribute(types.AttributeAmount1, actualAmount1.String()), + sdk.NewAttribute(types.AttributeKeyNewPositionId, strconv.FormatUint(newPositionData.ID, 10)), + sdk.NewAttribute(types.AttributeAmount0, newPositionData.Amount0.String()), + sdk.NewAttribute(types.AttributeAmount1, newPositionData.Amount1.String()), ), }) - return newPositionId, actualAmount0, actualAmount1, nil + return newPositionData.ID, newPositionData.Amount0, newPositionData.Amount1, nil } // UpdatePosition updates the position in the given pool id and in the given tick range and liquidityAmount. diff --git a/x/concentrated-liquidity/lp_test.go b/x/concentrated-liquidity/lp_test.go index eba4db093ee..b9bafb14781 100644 --- a/x/concentrated-liquidity/lp_test.go +++ b/x/concentrated-liquidity/lp_test.go @@ -294,7 +294,16 @@ func (s *KeeperTestSuite) TestCreatePosition() { poolBalancePrePositionCreation := s.App.BankKeeper.GetAllBalances(s.Ctx, pool.GetAddress()) // System under test. - positionId, asset0, asset1, liquidityCreated, newLowerTick, newUpperTick, err := clKeeper.CreatePosition(s.Ctx, tc.poolId, s.TestAccs[0], tc.tokensProvided, tc.amount0Minimum, tc.amount1Minimum, tc.lowerTick, tc.upperTick) + positionData, err := clKeeper.CreatePosition(s.Ctx, tc.poolId, s.TestAccs[0], tc.tokensProvided, tc.amount0Minimum, tc.amount1Minimum, tc.lowerTick, tc.upperTick) + + var ( + positionId = positionData.ID + newLowerTick = positionData.LowerTick + newUpperTick = positionData.UpperTick + liquidityCreated = positionData.Liquidity + asset0 = positionData.Amount0 + asset1 = positionData.Amount1 + ) // Note user and pool account balances to compare after create position is called userBalancePostPositionCreation := s.App.BankKeeper.GetAllBalances(s.Ctx, s.TestAccs[0]) @@ -381,9 +390,13 @@ const ( ) func (s *KeeperTestSuite) createPositionWithLockState(ls lockState, poolId uint64, owner sdk.AccAddress, providedCoins sdk.Coins, dur time.Duration) (uint64, sdk.Dec) { - var liquidityCreated sdk.Dec - var positionId uint64 - var err error + var ( + positionData cl.CreatePositionData + liquidityCreated sdk.Dec + positionId uint64 + err error + ) + if ls == locked { positionId, _, _, liquidityCreated, _, err = s.clk.CreateFullRangePositionLocked(s.Ctx, poolId, owner, providedCoins, dur) } else if ls == unlocking { @@ -391,7 +404,9 @@ func (s *KeeperTestSuite) createPositionWithLockState(ls lockState, poolId uint6 } else if ls == unlocked { positionId, _, _, liquidityCreated, _, err = s.clk.CreateFullRangePositionUnlocking(s.Ctx, poolId, owner, providedCoins, dur-time.Hour) } else { - positionId, _, _, liquidityCreated, _, _, err = s.clk.CreatePosition(s.Ctx, poolId, owner, providedCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionData, err = s.clk.CreatePosition(s.Ctx, poolId, owner, providedCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionId = positionData.ID + liquidityCreated = positionData.Liquidity } s.Require().NoError(err) return positionId, liquidityCreated @@ -721,7 +736,7 @@ func (s *KeeperTestSuite) TestWithdrawPosition() { if expectedRemainingLiquidity.IsZero() { // Add one USDC because we withdraw one less than originally funded due to truncation in favor of the pool. s.FundAcc(owner, sdk.NewCoins(sdk.NewCoin(USDC, sdk.OneInt()))) - _, _, _, _, _, _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), owner, config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), owner, config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) } }) @@ -1049,7 +1064,7 @@ func (s *KeeperTestSuite) TestAddToPosition() { if !tc.lastPositionInPool { s.FundAcc(s.TestAccs[1], fundCoins) - _, _, _, _, _, _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) } @@ -1196,7 +1211,7 @@ func (s *KeeperTestSuite) TestSingleSidedAddToPosition() { // Create a position from the parameters in the test case. testCoins := sdk.NewCoins(sdk.NewCoin(ETH, tc.amount0ToAdd), sdk.NewCoin(USDC, tc.amount1ToAdd)) - positionId, _, _, _, _, _, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), owner, testCoins, sdk.ZeroInt(), sdk.ZeroInt(), config.lowerTick, config.upperTick) + positionData, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), owner, testCoins, sdk.ZeroInt(), sdk.ZeroInt(), config.lowerTick, config.upperTick) s.Require().NoError(err) // Move the block time forward @@ -1208,7 +1223,7 @@ func (s *KeeperTestSuite) TestSingleSidedAddToPosition() { if !tc.lastPositionInPool { s.FundAcc(s.TestAccs[0], fundCoins) - _, _, _, _, _, _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + _, err = concentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], config.tokensProvided, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) } @@ -1222,7 +1237,7 @@ func (s *KeeperTestSuite) TestSingleSidedAddToPosition() { } // --- System under test --- - newPosId, newAmt0, newAmt1, err := concentratedLiquidityKeeper.AddToPosition(s.Ctx, owner, positionId, tc.amount0ToAdd, tc.amount1ToAdd, config.amount0Minimum, config.amount1Minimum) + newPosId, newAmt0, newAmt1, err := concentratedLiquidityKeeper.AddToPosition(s.Ctx, owner, positionData.ID, tc.amount0ToAdd, tc.amount1ToAdd, config.amount0Minimum, config.amount1Minimum) if config.expectedError != nil { s.Require().Error(err) s.Require().Equal(sdk.Int{}, newAmt0) @@ -1247,7 +1262,7 @@ func (s *KeeperTestSuite) TestSingleSidedAddToPosition() { s.Require().Equal(0, errToleranceOneRoundDown.Compare(postBalanceToken1.Amount.Sub(preBalanceToken1.Amount), sdk.ZeroInt())) // now check that old position id has been successfully deleted - _, err = s.App.ConcentratedLiquidityKeeper.GetPosition(s.Ctx, positionId) + _, err = s.App.ConcentratedLiquidityKeeper.GetPosition(s.Ctx, positionData.ID) s.Require().Error(err) }) } @@ -1591,7 +1606,7 @@ func (s *KeeperTestSuite) TestUpdatePosition() { // create position // Fund test account and create the desired position s.FundAcc(s.TestAccs[0], DefaultCoins) - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition( + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition( s.Ctx, 1, s.TestAccs[0], @@ -1810,9 +1825,18 @@ func (s *KeeperTestSuite) TestInverseRelation_CreatePosition_WithdrawPosition() poolBalancePrePositionCreation := s.App.BankKeeper.GetAllBalances(s.Ctx, poolBefore.GetAddress()) // System under test. - positionId, amtDenom0CreatePosition, amtDenom1CreatePosition, liquidityCreated, newLowerTick, newUpperTick, err := clKeeper.CreatePosition(s.Ctx, tc.poolId, s.TestAccs[0], tc.tokensProvided, tc.amount0Minimum, tc.amount1Minimum, tc.lowerTick, tc.upperTick) + positionData, err := clKeeper.CreatePosition(s.Ctx, tc.poolId, s.TestAccs[0], tc.tokensProvided, tc.amount0Minimum, tc.amount1Minimum, tc.lowerTick, tc.upperTick) s.Require().NoError(err) + var ( + positionId = positionData.ID + newLowerTick = positionData.LowerTick + newUpperTick = positionData.UpperTick + liquidityCreated = positionData.Liquidity + amtDenom0CreatePosition = positionData.Amount0 + amtDenom1CreatePosition = positionData.Amount1 + ) + if tc.expectedLowerTick != 0 { s.Require().Equal(tc.expectedLowerTick, newLowerTick) tc.lowerTick = newLowerTick diff --git a/x/concentrated-liquidity/msg_server.go b/x/concentrated-liquidity/msg_server.go index 2997bb7b8f8..b7e2e3cb320 100644 --- a/x/concentrated-liquidity/msg_server.go +++ b/x/concentrated-liquidity/msg_server.go @@ -52,7 +52,7 @@ func (server msgServer) CreatePosition(goCtx context.Context, msg *types.MsgCrea return nil, err } - positionId, actualAmount0, actualAmount1, liquidityCreated, lowerTick, upperTick, err := server.keeper.createPosition(ctx, msg.PoolId, sender, msg.TokensProvided, msg.TokenMinAmount0, msg.TokenMinAmount1, msg.LowerTick, msg.UpperTick) + positionData, err := server.keeper.CreatePosition(ctx, msg.PoolId, sender, msg.TokensProvided, msg.TokenMinAmount0, msg.TokenMinAmount1, msg.LowerTick, msg.UpperTick) if err != nil { return nil, err } @@ -67,7 +67,7 @@ func (server msgServer) CreatePosition(goCtx context.Context, msg *types.MsgCrea // Note: create position event is emitted in keeper.createPosition(...) - return &types.MsgCreatePositionResponse{PositionId: positionId, Amount0: actualAmount0, Amount1: actualAmount1, LiquidityCreated: liquidityCreated, LowerTick: lowerTick, UpperTick: upperTick}, nil + return &types.MsgCreatePositionResponse{PositionId: positionData.ID, Amount0: positionData.Amount0, Amount1: positionData.Amount1, LiquidityCreated: positionData.Liquidity, LowerTick: positionData.LowerTick, UpperTick: positionData.UpperTick}, nil } func (server msgServer) AddToPosition(goCtx context.Context, msg *types.MsgAddToPosition) (*types.MsgAddToPositionResponse, error) { diff --git a/x/concentrated-liquidity/pool_test.go b/x/concentrated-liquidity/pool_test.go index b3e748425e4..54281c95fbe 100644 --- a/x/concentrated-liquidity/pool_test.go +++ b/x/concentrated-liquidity/pool_test.go @@ -469,11 +469,11 @@ func (s *KeeperTestSuite) TestDecreaseConcentratedPoolTickSpacing() { concentratedPool := s.PrepareConcentratedPoolWithCoinsAndFullRangePosition(ETH, USDC) // Create a position in the pool that is divisible by the tick spacing - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), -100, 100) + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), -100, 100) s.Require().NoError(err) // Attempt to create a position that is not divisible by the tick spacing - _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.position.lowerTick, test.position.upperTick) + _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.position.lowerTick, test.position.upperTick) s.Require().Error(err) // Alter the tick spacing of the pool @@ -486,7 +486,7 @@ func (s *KeeperTestSuite) TestDecreaseConcentratedPoolTickSpacing() { s.Require().NoError(err) // Attempt to create a position that was previously not divisible by the tick spacing but now is - _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.position.lowerTick, test.position.upperTick) + _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, concentratedPool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.position.lowerTick, test.position.upperTick) if test.expectedCreatePositionErr != nil { s.Require().Error(err) s.Require().ErrorContains(err, test.expectedCreatePositionErr.Error()) diff --git a/x/concentrated-liquidity/position.go b/x/concentrated-liquidity/position.go index b0c26ae0b05..7827600a674 100644 --- a/x/concentrated-liquidity/position.go +++ b/x/concentrated-liquidity/position.go @@ -413,12 +413,12 @@ func (k Keeper) CreateFullRangePosition(ctx sdk.Context, poolId uint64, owner sd } // Create a full range (min to max tick) concentrated liquidity position. - positionId, amount0, amount1, liquidity, _, _, err = k.createPosition(ctx, concentratedPool.GetId(), owner, coins, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) + positionData, err := k.CreatePosition(ctx, concentratedPool.GetId(), owner, coins, sdk.ZeroInt(), sdk.ZeroInt(), types.MinInitializedTick, types.MaxTick) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, err } - return positionId, amount0, amount1, liquidity, nil + return positionData.ID, positionData.Amount0, positionData.Amount1, positionData.Liquidity, nil } // CreateFullRangePositionLocked creates a full range (min to max tick) concentrated liquidity position for the given pool ID, owner, and coins. diff --git a/x/concentrated-liquidity/position_test.go b/x/concentrated-liquidity/position_test.go index d989cf26312..7075470300b 100644 --- a/x/concentrated-liquidity/position_test.go +++ b/x/concentrated-liquidity/position_test.go @@ -824,20 +824,20 @@ func (s *KeeperTestSuite) TestCalculateUnderlyingAssetsFromPosition() { // prepare concentrated pool with a default position s.PrepareConcentratedPool() s.FundAcc(s.TestAccs[0], sdk.NewCoins(sdk.NewCoin(ETH, DefaultAmt0), sdk.NewCoin(USDC, DefaultAmt1))) - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, 1, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, 1, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) // create a position from the test case s.FundAcc(s.TestAccs[1], sdk.NewCoins(sdk.NewCoin(ETH, DefaultAmt0), sdk.NewCoin(USDC, DefaultAmt1))) - _, actualAmount0, actualAmount1, liquidity, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, tc.position.PoolId, s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), tc.position.LowerTick, tc.position.UpperTick) + positionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, tc.position.PoolId, s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), tc.position.LowerTick, tc.position.UpperTick) s.Require().NoError(err) - tc.position.Liquidity = liquidity + tc.position.Liquidity = positionData.Liquidity if tc.isZeroLiquidity { // set the position liquidity to zero tc.position.Liquidity = sdk.ZeroDec() - actualAmount0 = sdk.ZeroInt() - actualAmount1 = sdk.ZeroInt() + positionData.Amount0 = sdk.ZeroInt() + positionData.Amount1 = sdk.ZeroInt() } // calculate underlying assets from the position @@ -846,8 +846,8 @@ func (s *KeeperTestSuite) TestCalculateUnderlyingAssetsFromPosition() { calculatedCoin0, calculatedCoin1, err := cl.CalculateUnderlyingAssetsFromPosition(s.Ctx, tc.position, clPool) s.Require().NoError(err) - s.Require().Equal(calculatedCoin0.String(), sdk.NewCoin(clPool.GetToken0(), actualAmount0).String()) - s.Require().Equal(calculatedCoin1.String(), sdk.NewCoin(clPool.GetToken1(), actualAmount1).String()) + s.Require().Equal(calculatedCoin0.String(), sdk.NewCoin(clPool.GetToken0(), positionData.Amount0).String()) + s.Require().Equal(calculatedCoin1.String(), sdk.NewCoin(clPool.GetToken1(), positionData.Amount1).String()) }) } } @@ -1033,13 +1033,15 @@ func (s *KeeperTestSuite) TestValidateAndFungifyChargedPositions() { var ( liquidityCreated sdk.Dec err error + positionData cl.CreatePositionData ) if pos.isLocked { _, _, _, liquidityCreated, _, err = s.clk.CreateFullRangePositionUnlocking(s.Ctx, pos.poolId, pos.acc, pos.coins, lockDuration) s.Require().NoError(err) } else { - _, _, _, liquidityCreated, _, _, err = s.clk.CreatePosition(s.Ctx, pos.poolId, pos.acc, pos.coins, sdk.ZeroInt(), sdk.ZeroInt(), pos.lowerTick, pos.upperTick) + positionData, err = s.clk.CreatePosition(s.Ctx, pos.poolId, pos.acc, pos.coins, sdk.ZeroInt(), sdk.ZeroInt(), pos.lowerTick, pos.upperTick) s.Require().NoError(err) + liquidityCreated = positionData.Liquidity } totalLiquidity = totalLiquidity.Add(liquidityCreated) @@ -1050,7 +1052,7 @@ func (s *KeeperTestSuite) TestValidateAndFungifyChargedPositions() { // Set up uncharged positions for _, pos := range test.setupUnchargedPositions { - _, _, _, _, _, _, err := s.clk.CreatePosition(s.Ctx, pos.poolId, pos.acc, pos.coins, sdk.ZeroInt(), sdk.ZeroInt(), pos.lowerTick, pos.upperTick) + _, err := s.clk.CreatePosition(s.Ctx, pos.poolId, pos.acc, pos.coins, sdk.ZeroInt(), sdk.ZeroInt(), pos.lowerTick, pos.upperTick) s.Require().NoError(err) } @@ -1769,8 +1771,10 @@ func (s *KeeperTestSuite) TestMintSharesAndLock() { s.Require().NoError(err) } else { var err error - positionId, _, _, liquidity, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPool.GetId(), test.owner, defaultPositionCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.lowerTick, test.upperTick) + positionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPool.GetId(), test.owner, defaultPositionCoins, sdk.ZeroInt(), sdk.ZeroInt(), test.lowerTick, test.upperTick) s.Require().NoError(err) + positionId = positionData.ID + liquidity = positionData.Liquidity } lockupModuleAccountBalancePre := s.App.LockupKeeper.GetModuleBalance(s.Ctx) @@ -2277,7 +2281,7 @@ func (s *KeeperTestSuite) TestGetAndUpdateFullRangeLiquidity() { // Create a new position that overlaps with the min tick, but is not full range and therefore should not count towards the full range liquidity. s.FundAcc(owner, tc.positionCoins) - _, _, _, _, _, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPoolId, owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), tc.lowerTick, tc.upperTick) + _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPoolId, owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), tc.lowerTick, tc.upperTick) s.Require().NoError(err) clPool, err = s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, clPoolId) @@ -2616,7 +2620,7 @@ func (s *KeeperTestSuite) TestNegativeTickRange_SpreadFactor() { // Initialize position at a higher range s.FundAcc(s.TestAccs[0], DefaultCoins) - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultCurrTick+50, DefaultCurrTick+100) + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultCurrTick+50, DefaultCurrTick+100) s.Require().NoError(err) // Refetch pool diff --git a/x/concentrated-liquidity/range_test.go b/x/concentrated-liquidity/range_test.go index 56a0fde4b14..80584072fd2 100644 --- a/x/concentrated-liquidity/range_test.go +++ b/x/concentrated-liquidity/range_test.go @@ -204,12 +204,12 @@ func (s *KeeperTestSuite) setupRangesAndAssertInvariants(pool types.Concentrated cumulativeEmittedIncentives, lastIncentiveTrackerUpdate = s.trackEmittedIncentives(cumulativeEmittedIncentives, lastIncentiveTrackerUpdate) // Set up position - curPositionId, actualAmt0, actualAmt1, curLiquidity, actualLowerTick, actualUpperTick, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), curAddr, curAssets, sdk.ZeroInt(), sdk.ZeroInt(), ranges[curRange][0], ranges[curRange][1]) + positionData, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), curAddr, curAssets, sdk.ZeroInt(), sdk.ZeroInt(), ranges[curRange][0], ranges[curRange][1]) s.Require().NoError(err) // Ensure position was set up correctly and didn't break global invariants - s.Require().Equal(ranges[curRange][0], actualLowerTick) - s.Require().Equal(ranges[curRange][1], actualUpperTick) + s.Require().Equal(ranges[curRange][0], positionData.LowerTick) + s.Require().Equal(ranges[curRange][1], positionData.UpperTick) s.assertGlobalInvariants(ExpectedGlobalRewardValues{}) // Let time elapse after join if applicable @@ -220,14 +220,14 @@ func (s *KeeperTestSuite) setupRangesAndAssertInvariants(pool types.Concentrated s.assertGlobalInvariants(ExpectedGlobalRewardValues{}) // Track changes to state - actualAddedCoins := sdk.NewCoins(sdk.NewCoin(pool.GetToken0(), actualAmt0), sdk.NewCoin(pool.GetToken1(), actualAmt1)) + actualAddedCoins := sdk.NewCoins(sdk.NewCoin(pool.GetToken0(), positionData.Amount0), sdk.NewCoin(pool.GetToken1(), positionData.Amount1)) totalAssets = totalAssets.Add(actualAddedCoins...) if testParams.baseSwapAmount != (sdk.Int{}) { totalAssets = totalAssets.Add(swappedIn).Sub(sdk.NewCoins(swappedOut)) } - totalLiquidity = totalLiquidity.Add(curLiquidity) + totalLiquidity = totalLiquidity.Add(positionData.Liquidity) totalTimeElapsed = totalTimeElapsed + timeElapsed - allPositionIds = append(allPositionIds, curPositionId) + allPositionIds = append(allPositionIds, positionData.ID) curBlock++ } endNumPositions := len(allPositionIds) diff --git a/x/concentrated-liquidity/spread_rewards_test.go b/x/concentrated-liquidity/spread_rewards_test.go index 14ee54614d9..5284433442d 100644 --- a/x/concentrated-liquidity/spread_rewards_test.go +++ b/x/concentrated-liquidity/spread_rewards_test.go @@ -1460,39 +1460,40 @@ func (s *KeeperTestSuite) TestFunctional_SpreadRewards_LP() { s.Require().Error(err) // Create position in the default range 1. - positionIdOne, _, _, liquidity, _, _, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionDataOne, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) // Swap once. ticksActivatedAfterEachSwap, totalSpreadRewardsExpected, _, _ := s.swapAndTrackXTimesInARow(pool.GetId(), DefaultCoin1, ETH, types.MaxSpotPrice, 1) // Withdraw half. - halfLiquidity := liquidity.Mul(sdk.NewDecWithPrec(5, 1)) - _, _, err = concentratedLiquidityKeeper.WithdrawPosition(ctx, owner, positionIdOne, halfLiquidity) + halfLiquidity := positionDataOne.Liquidity.Mul(sdk.NewDecWithPrec(5, 1)) + _, _, err = concentratedLiquidityKeeper.WithdrawPosition(ctx, owner, positionDataOne.ID, halfLiquidity) s.Require().NoError(err) // Collect spread rewards. - spreadRewardsCollected := s.collectSpreadRewardsAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{USDC}, [][]int64{ticksActivatedAfterEachSwap}) + spreadRewardsCollected := s.collectSpreadRewardsAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionDataOne.ID, sdk.NewCoins(), []string{USDC}, [][]int64{ticksActivatedAfterEachSwap}) expectedSpreadRewardsTruncated := totalSpreadRewardsExpected for i, spreadRewardToken := range totalSpreadRewardsExpected { // We run expected spread rewards through a cycle of divison and multiplication by liquidity to capture appropriate rounding behavior - expectedSpreadRewardsTruncated[i] = sdk.NewCoin(spreadRewardToken.Denom, spreadRewardToken.Amount.ToDec().QuoTruncate(liquidity).MulTruncate(liquidity).TruncateInt()) + expectedSpreadRewardsTruncated[i] = sdk.NewCoin(spreadRewardToken.Denom, spreadRewardToken.Amount.ToDec().QuoTruncate(positionDataOne.Liquidity).MulTruncate(positionDataOne.Liquidity).TruncateInt()) } s.Require().Equal(expectedSpreadRewardsTruncated, spreadRewardsCollected) // Unclaimed rewards should be emptied since spread rewards were collected. - s.validatePositionSpreadRewardGrowth(pool.GetId(), positionIdOne, cl.EmptyCoins) + s.validatePositionSpreadRewardGrowth(pool.GetId(), positionDataOne.ID, cl.EmptyCoins) // Create position in the default range 2. - positionIdTwo, _, _, fullLiquidity, _, _, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionDataTwo, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) + fullLiquidity := positionDataTwo.Liquidity // Swap once in the other direction. ticksActivatedAfterEachSwap, totalSpreadRewardsExpected, _, _ = s.swapAndTrackXTimesInARow(pool.GetId(), DefaultCoin0, USDC, types.MinSpotPrice, 1) // This should claim under the hood for position 2 since full liquidity is removed. balanceBeforeWithdraw := s.App.BankKeeper.GetBalance(ctx, owner, ETH) - amtDenom0, _, err := concentratedLiquidityKeeper.WithdrawPosition(ctx, owner, positionIdTwo, fullLiquidity) + amtDenom0, _, err := concentratedLiquidityKeeper.WithdrawPosition(ctx, owner, positionDataTwo.ID, positionDataTwo.Liquidity) s.Require().NoError(err) balanceAfterWithdraw := s.App.BankKeeper.GetBalance(ctx, owner, ETH) @@ -1502,20 +1503,20 @@ func (s *KeeperTestSuite) TestFunctional_SpreadRewards_LP() { s.Require().Equal(expectedPositionToWithdraw.String(), balanceAfterWithdraw.Sub(balanceBeforeWithdraw).Amount.Sub(amtDenom0).String()) // Validate cannot claim for withdrawn position. - _, err = s.App.ConcentratedLiquidityKeeper.CollectSpreadRewards(ctx, owner, positionIdTwo) + _, err = s.App.ConcentratedLiquidityKeeper.CollectSpreadRewards(ctx, owner, positionDataTwo.ID) s.Require().Error(err) - spreadRewardsCollected = s.collectSpreadRewardsAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionIdOne, sdk.NewCoins(), []string{ETH}, [][]int64{ticksActivatedAfterEachSwap}) + spreadRewardsCollected = s.collectSpreadRewardsAndCheckInvariance(ctx, 0, DefaultMinTick, DefaultMaxTick, positionDataOne.ID, sdk.NewCoins(), []string{ETH}, [][]int64{ticksActivatedAfterEachSwap}) // total spread rewards * half liquidity / (full liquidity + half liquidity) expectesSpreadRewardsCollected := totalSpreadRewardsExpected.AmountOf(ETH).ToDec().Mul(halfLiquidity.Quo(fullLiquidity.Add(halfLiquidity))).TruncateInt() s.Require().Equal(expectesSpreadRewardsCollected.String(), spreadRewardsCollected.AmountOf(ETH).String()) // Create position in the default range 3. - positionIdThree, _, _, fullLiquidity, _, _, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + positionDataThree, err := concentratedLiquidityKeeper.CreatePosition(ctx, pool.GetId(), owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) - collectedThree, err := s.App.ConcentratedLiquidityKeeper.CollectSpreadRewards(ctx, owner, positionIdThree) + collectedThree, err := s.App.ConcentratedLiquidityKeeper.CollectSpreadRewards(ctx, owner, positionDataThree.ID) s.Require().NoError(err) s.Require().Equal(sdk.Coins(nil), collectedThree) } diff --git a/x/concentrated-liquidity/swaps_test.go b/x/concentrated-liquidity/swaps_test.go index c8f8178e85c..5b2fa8c05ad 100644 --- a/x/concentrated-liquidity/swaps_test.go +++ b/x/concentrated-liquidity/swaps_test.go @@ -2761,7 +2761,7 @@ func (s *KeeperTestSuite) setupSecondPosition(test SwapTest, pool types.Concentr if !test.secondPositionLowerPrice.IsNil() { newLowerTick, newUpperTick := s.lowerUpperPricesToTick(test.secondPositionLowerPrice, test.secondPositionUpperPrice, pool.GetTickSpacing()) - _, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) + _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[1], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), newLowerTick, newUpperTick) s.Require().NoError(err) } } @@ -3396,7 +3396,7 @@ func (s *KeeperTestSuite) TestInfiniteSwapLoop_OutGivenIn() { // Create position near min tick s.FundAcc(positionOwner, DefaultRangeTestParams.baseAssets.Add(DefaultRangeTestParams.baseAssets...)) - _, _, _, _, _, _, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), positionOwner, DefaultRangeTestParams.baseAssets, sdk.ZeroInt(), sdk.ZeroInt(), -108000000, -107999900) + _, err := s.clk.CreatePosition(s.Ctx, pool.GetId(), positionOwner, DefaultRangeTestParams.baseAssets, sdk.ZeroInt(), sdk.ZeroInt(), -108000000, -107999900) s.Require().NoError(err) // Swap small amount to get current tick to position above, triggering the problematic function/branch (CalcAmount0Delta) diff --git a/x/concentrated-liquidity/swaps_tick_cross_test.go b/x/concentrated-liquidity/swaps_tick_cross_test.go index ee3a517a418..8d4ed73bf5a 100644 --- a/x/concentrated-liquidity/swaps_tick_cross_test.go +++ b/x/concentrated-liquidity/swaps_tick_cross_test.go @@ -45,14 +45,14 @@ func (s *KeeperTestSuite) CreatePositionTickSpacingsFromCurrentTick(poolId uint6 lowerTick := currentTick - int64(tickSpacingsAwayFromCurrentTick)*tickSpacing upperTick := currentTick + int64(tickSpacingsAwayFromCurrentTick)*tickSpacing s.FundAcc(s.TestAccs[0], DefaultCoins) - positionId, _, _, liquidityNarrowRangeTwo, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) + positionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, pool.GetId(), s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) s.Require().NoError(err) return positionMeta{ - positionId: positionId, + positionId: positionData.ID, lowerTick: lowerTick, upperTick: upperTick, - liquidity: liquidityNarrowRangeTwo, + liquidity: positionData.Liquidity, } } diff --git a/x/concentrated-liquidity/tick_test.go b/x/concentrated-liquidity/tick_test.go index f20e8ca3762..6c42d54ce0b 100644 --- a/x/concentrated-liquidity/tick_test.go +++ b/x/concentrated-liquidity/tick_test.go @@ -603,7 +603,7 @@ func (s *KeeperTestSuite) TestCrossTick() { if test.poolToGet == validPoolId { s.FundAcc(s.TestAccs[0], sdk.NewCoins(DefaultCoin0, DefaultCoin1)) - _, _, _, _, _, _, err := s.clk.CreatePosition(s.Ctx, test.poolToGet, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) + _, err := s.clk.CreatePosition(s.Ctx, test.poolToGet, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) }