From 296544bd83eff2e8c8b10d559faa505e799c2ce0 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Aug 2023 14:58:46 +0200 Subject: [PATCH 1/6] refactor(CL): replace 6 return values in CreatePosition with a struct --- x/concentrated-liquidity/bench_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 | 32 +++++---- x/concentrated-liquidity/range_test.go | 12 ++-- .../spread_rewards_test.go | 25 +++---- x/concentrated-liquidity/swaps_test.go | 8 ++- .../swaps_tick_cross_test.go | 6 +- x/concentrated-liquidity/tick_test.go | 2 +- 15 files changed, 153 insertions(+), 104 deletions(-) diff --git a/x/concentrated-liquidity/bench_test.go b/x/concentrated-liquidity/bench_test.go index 50f27599cf8..1f0b7fcee20 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/fuzz_test.go b/x/concentrated-liquidity/fuzz_test.go index c72c7ba3cde..3aadfc58d4b 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 7b7ca068a62..5b9ab6b911f 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()) @@ -3127,7 +3128,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 @@ -3160,7 +3161,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 { @@ -3178,7 +3179,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()) @@ -3262,14 +3263,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()) @@ -3277,20 +3278,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 c68d4a25ec9..b43cb85a5a0 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 c28fe796cbe..3f71d03f94c 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -15,6 +15,16 @@ import ( const noUnderlyingLockId = uint64(0) +// CreatePositionData reprsents 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. @@ -375,7 +392,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 } @@ -387,13 +404,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 356cd5b8282..faaf21df50b 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 @@ -736,7 +751,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) } }) @@ -1064,7 +1079,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) } @@ -1211,7 +1226,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 @@ -1223,7 +1238,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) } @@ -1237,7 +1252,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) @@ -1262,7 +1277,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) }) } @@ -1606,7 +1621,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], @@ -1833,9 +1848,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 b00fe0dd5ff..4d56bd56ade 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 41c6ec3616c..76f820bd93f 100644 --- a/x/concentrated-liquidity/pool_test.go +++ b/x/concentrated-liquidity/pool_test.go @@ -470,11 +470,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 @@ -487,7 +487,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 8519c866d90..f0307051c65 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 9a3c33b5547..76b6185d89b 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) @@ -2696,7 +2700,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) // Estimate how much to swap in to approximately DefaultCurrTick - 50 @@ -2739,7 +2743,7 @@ func (s *KeeperTestSuite) TestNegativeTickRange_SpreadFactor() { // We initialized the lower tick's accumulator (DefaultCurrTick - 25) to be greater than the upper tick's accumulator (DefaultCurrTick + 50) // Whenever the current tick is above the position's range, we compute in range accumulator as upper tick accumulator - lower tick accumulator // In this case, it ends up being negative, which is now supported. - negativeIntervalAccumPositionId, _, _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultCurrTick-25, DefaultCurrTick+50) + negativeIntervalAccumPositionData, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultCurrTick-25, DefaultCurrTick+50) s.Require().NoError(err) // Increase block time @@ -2863,7 +2867,7 @@ func (s *KeeperTestSuite) TestNegativeTickRange_SpreadFactor() { spreadRewardAccumulator, err := s.clk.GetSpreadRewardAccumulator(s.Ctx, poolId) s.Require().NoError(err) - accum, err := spreadRewardAccumulator.GetPosition(types.KeySpreadRewardPositionAccumulator(negativeIntervalAccumPositionId)) + accum, err := spreadRewardAccumulator.GetPosition(types.KeySpreadRewardPositionAccumulator(negativeIntervalAccumPositionData.ID)) s.Require().NoError(err) // Validate that at least one accumulator is negative for the test to be valid. diff --git a/x/concentrated-liquidity/range_test.go b/x/concentrated-liquidity/range_test.go index 5efffa42263..e722315c7d0 100644 --- a/x/concentrated-liquidity/range_test.go +++ b/x/concentrated-liquidity/range_test.go @@ -216,12 +216,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 @@ -232,14 +232,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 7b33c1a88f4..de29d2af471 100644 --- a/x/concentrated-liquidity/spread_rewards_test.go +++ b/x/concentrated-liquidity/spread_rewards_test.go @@ -1417,39 +1417,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) @@ -1459,20 +1460,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 a5a30236155..668030b9616 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) @@ -3507,7 +3507,9 @@ func (s *KeeperTestSuite) TestComputeMaxInAmtGivenMaxTicksCrossed() { func (s *KeeperTestSuite) createPositionAndFundAcc(clPool types.ConcentratedPoolExtension, lowerTick, upperTick int64) (amt0, amt1 sdk.Int) { s.FundAcc(s.TestAccs[0], DefaultCoins) - _, amt0, amt1, _, _, _, _ = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPool.GetId(), s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) + positionData, _ := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPool.GetId(), s.TestAccs[0], DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick) + amt0 = positionData.Amount0 + amt1 = positionData.Amount1 return } diff --git a/x/concentrated-liquidity/swaps_tick_cross_test.go b/x/concentrated-liquidity/swaps_tick_cross_test.go index 254b9308a3d..72de8d56670 100644 --- a/x/concentrated-liquidity/swaps_tick_cross_test.go +++ b/x/concentrated-liquidity/swaps_tick_cross_test.go @@ -50,14 +50,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 f1ea8738629..ca0d3409e1e 100644 --- a/x/concentrated-liquidity/tick_test.go +++ b/x/concentrated-liquidity/tick_test.go @@ -610,7 +610,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) } From 4414546a67ecf9e05b0da333a0d0060d89d09fd8 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Aug 2023 15:10:39 +0200 Subject: [PATCH 2/6] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b76ad0edcaf..2a42fc35b3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#5964](https://github.com/osmosis-labs/osmosis/pull/5964) fix e2e test concurrency bugs * [#5948] (https://github.com/osmosis-labs/osmosis/pull/5948) Parameterizing Pool Type Information in Protorev +### API Breaking + +* [#5983] (https://github.com/osmosis-labs/osmosis/pull/5983) refactor(CL): replace 6 return values in CreatePosition with a struct + ### Minor improvements & Bug Fixes * [#5806](https://github.com/osmosis-labs/osmosis/issues/5806) ci: automatically close issues generated by the Broken Links Check action when a new run occurs. From 5a3441081ef3eb9d796058f7718b62355e2adec3 Mon Sep 17 00:00:00 2001 From: devbot-wizard <141283918+devbot-wizard@users.noreply.github.com> Date: Tue, 8 Aug 2023 14:14:36 +0000 Subject: [PATCH 3/6] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a42fc35b3f..2691363bab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#5890](https://github.com/osmosis-labs/osmosis/pull/5890) feat: CreateCLPool & LinkCFMMtoCL pool into one gov-prop * [#5964](https://github.com/osmosis-labs/osmosis/pull/5964) fix e2e test concurrency bugs * [#5948] (https://github.com/osmosis-labs/osmosis/pull/5948) Parameterizing Pool Type Information in Protorev +* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) allow testing with different chain-id's in E2E testing ### API Breaking From 10a82220a8af7e3a3b838647b0101669fba22129 Mon Sep 17 00:00:00 2001 From: devbot-wizard <141283918+devbot-wizard@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:05:08 +0000 Subject: [PATCH 4/6] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2691363bab5..f522851c51c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### API breaks + +* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) replace 6 return values in CL CreatePosition with a struct + ### Features * [#5072](https://github.com/osmosis-labs/osmosis/pull/5072) IBC-hooks: Add support for async acks when processing onRecvPacket From 0dd55c401ef2dd93e26abb5bbcf26dd81af8cd25 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 8 Aug 2023 17:06:30 +0200 Subject: [PATCH 5/6] Apply suggestions from code review --- CHANGELOG.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f522851c51c..d1ba7a8b0ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### API breaks -* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) replace 6 return values in CL CreatePosition with a struct +* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) refactor(CL): 6 return values in CL CreatePosition with a struct ### Features @@ -83,11 +83,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#5890](https://github.com/osmosis-labs/osmosis/pull/5890) feat: CreateCLPool & LinkCFMMtoCL pool into one gov-prop * [#5964](https://github.com/osmosis-labs/osmosis/pull/5964) fix e2e test concurrency bugs * [#5948] (https://github.com/osmosis-labs/osmosis/pull/5948) Parameterizing Pool Type Information in Protorev -* [#5983](https://github.com/osmosis-labs/osmosis/pull/5983) allow testing with different chain-id's in E2E testing - -### API Breaking - -* [#5983] (https://github.com/osmosis-labs/osmosis/pull/5983) refactor(CL): replace 6 return values in CreatePosition with a struct ### Minor improvements & Bug Fixes From 2f2f10a13434ac85c85fb5bc00bb9f70a7de5c5e Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 8 Aug 2023 17:11:23 +0200 Subject: [PATCH 6/6] Update x/concentrated-liquidity/lp.go --- x/concentrated-liquidity/lp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 3f71d03f94c..734f0d85499 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -15,7 +15,7 @@ import ( const noUnderlyingLockId = uint64(0) -// CreatePositionData reprsents the return data from CreatePosition. +// CreatePositionData represents the return data from CreatePosition. type CreatePositionData struct { ID uint64 Amount0 sdk.Int