From 617dd99398d5180f18dd29ee3d9ea2e11ff23df1 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 10 May 2023 16:41:26 -0400 Subject: [PATCH 01/19] [InternalReview] MsgAddToConcentratedLiquiditySuperfluidPosition --- app/apptesting/concentrated_liquidity.go | 2 +- proto/osmosis/superfluid/tx.proto | 5 + tests/cl-genesis-positions/convert.go | 2 +- .../client/query_proto_wrap.go | 6 +- x/concentrated-liquidity/export_test.go | 4 +- x/concentrated-liquidity/lp.go | 8 +- x/concentrated-liquidity/pool.go | 6 +- x/concentrated-liquidity/position.go | 39 +--- x/concentrated-liquidity/position_test.go | 11 +- x/concentrated-liquidity/types/cl.go | 2 +- x/concentrated-liquidity/types/cl_test.go | 6 +- x/concentrated-liquidity/types/keys.go | 4 +- x/gamm/keeper/migrate.go | 4 +- x/gamm/types/expected_keepers.go | 2 +- x/incentives/types/expected_keepers.go | 2 +- x/lockup/keeper/lock.go | 2 +- x/lockup/keeper/lock_test.go | 6 +- x/superfluid/client/cli/tx.go | 2 +- x/superfluid/keeper/concentrated_liquidity.go | 42 ++-- .../keeper/concentrated_liquidity_test.go | 2 +- x/superfluid/keeper/epoch.go | 3 +- x/superfluid/keeper/gov/gov.go | 2 +- x/superfluid/keeper/migrate.go | 4 +- x/superfluid/keeper/msg_server.go | 4 +- x/superfluid/keeper/slash.go | 7 +- x/superfluid/keeper/slash_test.go | 2 +- x/superfluid/keeper/stake.go | 9 +- x/superfluid/keeper/stake_test.go | 4 +- x/superfluid/types/errors.go | 11 + x/superfluid/types/expected_keepers.go | 2 +- x/superfluid/types/gov.go | 2 +- x/superfluid/types/tx.pb.go | 207 +++++++++++------- 32 files changed, 241 insertions(+), 173 deletions(-) diff --git a/app/apptesting/concentrated_liquidity.go b/app/apptesting/concentrated_liquidity.go index 41502974c9a..11cce8facd4 100644 --- a/app/apptesting/concentrated_liquidity.go +++ b/app/apptesting/concentrated_liquidity.go @@ -49,7 +49,7 @@ func (s *KeeperTestHelper) PrepareConcentratedPoolWithCoinsAndLockedFullRangePos s.FundAcc(s.TestAccs[0], fundCoins) positionId, _, _, _, _, concentratedLockId, err := s.App.ConcentratedLiquidityKeeper.CreateFullRangePositionLocked(s.Ctx, clPool.GetId(), s.TestAccs[0], fundCoins, time.Hour*24*14) s.Require().NoError(err) - clPool, err = s.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(s.Ctx, clPool.GetId()) + clPool, err = s.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(s.Ctx, clPool.GetId()) s.Require().NoError(err) return clPool, concentratedLockId, positionId } diff --git a/proto/osmosis/superfluid/tx.proto b/proto/osmosis/superfluid/tx.proto index a30df7a5299..eb2e46cdea2 100644 --- a/proto/osmosis/superfluid/tx.proto +++ b/proto/osmosis/superfluid/tx.proto @@ -204,5 +204,10 @@ message MsgAddToConcentratedLiquiditySuperfluidPositionResponse { (gogoproto.moretags) = "yaml:\"amount1\"", (gogoproto.nullable) = false ]; + string new_liquidity = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.moretags) = "yaml:\"new_liquidity\"", + (gogoproto.nullable) = false + ]; uint64 lock_id = 4 [ (gogoproto.moretags) = "yaml:\"lock_id\"" ]; } \ No newline at end of file diff --git a/tests/cl-genesis-positions/convert.go b/tests/cl-genesis-positions/convert.go index ea5c3fca813..b4b7698769b 100644 --- a/tests/cl-genesis-positions/convert.go +++ b/tests/cl-genesis-positions/convert.go @@ -115,7 +115,7 @@ func ConvertSubgraphToOsmosisGenesis(positionCreatorAddresses []sdk.AccAddress, fmt.Println("Created pool id of: ", poolId) - pool, err := osmosis.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(osmosis.Ctx, poolId) + pool, err := osmosis.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(osmosis.Ctx, poolId) if err != nil { panic(err) } diff --git a/x/concentrated-liquidity/client/query_proto_wrap.go b/x/concentrated-liquidity/client/query_proto_wrap.go index 15608c10d36..7e1a3b1dcb3 100644 --- a/x/concentrated-liquidity/client/query_proto_wrap.go +++ b/x/concentrated-liquidity/client/query_proto_wrap.go @@ -37,7 +37,7 @@ func (q Querier) UserPositions(ctx sdk.Context, req clquery.UserPositionsRequest for _, position := range userPositions { // get the pool from the position - pool, err := q.Keeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, position.PoolId) + pool, err := q.Keeper.GetConcentratedPoolById(ctx, position.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -67,7 +67,7 @@ func (q Querier) PositionById(ctx sdk.Context, req clquery.PositionByIdRequest) return nil, status.Error(codes.Internal, err.Error()) } - positionPool, err := q.Keeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, position.PoolId) + positionPool, err := q.Keeper.GetConcentratedPoolById(ctx, position.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -148,7 +148,7 @@ func (q Querier) LiquidityNetInDirection(ctx sdk.Context, req clquery.LiquidityN return nil, err } - pool, err := q.Keeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, req.PoolId) + pool, err := q.Keeper.GetConcentratedPoolById(ctx, req.PoolId) if err != nil { return nil, err } diff --git a/x/concentrated-liquidity/export_test.go b/x/concentrated-liquidity/export_test.go index 5607964841b..2ca2dc6c367 100644 --- a/x/concentrated-liquidity/export_test.go +++ b/x/concentrated-liquidity/export_test.go @@ -135,8 +135,8 @@ func (k Keeper) UpdateFullRangeLiquidityInPool(ctx sdk.Context, poolId uint64, l return k.updateFullRangeLiquidityInPool(ctx, poolId, liquidity) } -func (k Keeper) MintSharesLockAndUpdate(ctx sdk.Context, concentratedPoolId, positionId uint64, owner sdk.AccAddress, remainingLockDuration time.Duration) (concentratedLockID uint64, underlyingLiquidityTokenized sdk.Coins, err error) { - return k.mintSharesLockAndUpdate(ctx, concentratedPoolId, positionId, owner, remainingLockDuration) +func (k Keeper) MintSharesAndLock(ctx sdk.Context, concentratedPoolId, positionId uint64, owner sdk.AccAddress, remainingLockDuration time.Duration) (concentratedLockID uint64, underlyingLiquidityTokenized sdk.Coins, err error) { + return k.mintSharesAndLock(ctx, concentratedPoolId, positionId, owner, remainingLockDuration) } func (k Keeper) SetPositionIdToLock(ctx sdk.Context, positionId, underlyingLockId uint64) { diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 9ba93126a48..0eb309617cb 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -45,6 +45,12 @@ func (k Keeper) createPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr if err := validateTickRangeIsValid(pool.GetTickSpacing(), lowerTick, upperTick); err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, err } + + // Check that exactly two coins are provided. + if len(tokensProvided) != 2 { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(tokensProvided)} + } + amount0Desired := tokensProvided.AmountOf(pool.GetToken0()) amount1Desired := tokensProvided.AmountOf(pool.GetToken1()) if amount0Desired.IsZero() && amount1Desired.IsZero() { @@ -293,7 +299,7 @@ func (k Keeper) addToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId // Create new position with updated liquidity. amount0Desired := amount0Withdrawn.Add(amount0Added) amount1Desired := amount1Withdrawn.Add(amount1Added) - pool, err := k.GetPoolFromPoolIdAndConvertToConcentrated(ctx, position.PoolId) + pool, err := k.GetConcentratedPoolById(ctx, position.PoolId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, err } diff --git a/x/concentrated-liquidity/pool.go b/x/concentrated-liquidity/pool.go index 2b8de40ad91..64612d40282 100644 --- a/x/concentrated-liquidity/pool.go +++ b/x/concentrated-liquidity/pool.go @@ -225,7 +225,9 @@ func convertPoolInterfaceToConcentrated(poolI poolmanagertypes.PoolI) (types.Con return concentratedPool, nil } -func (k Keeper) GetPoolFromPoolIdAndConvertToConcentrated(ctx sdk.Context, poolId uint64) (types.ConcentratedPoolExtension, error) { +// GetConcentratedPoolById returns a concentrated pool interface associated with the given id. +// Returns error if fails to fetch the pool from the store. +func (k Keeper) GetConcentratedPoolById(ctx sdk.Context, poolId uint64) (types.ConcentratedPoolExtension, error) { poolI, err := k.GetPool(ctx, poolId) if err != nil { return nil, err @@ -271,7 +273,7 @@ func (k Keeper) GetSerializedPools(ctx sdk.Context, pagination *query.PageReques // It returns an error if the tick spacing is not one of the authorized tick spacings or is not less than the current tick spacing of the respective pool. func (k Keeper) DecreaseConcentratedPoolTickSpacing(ctx sdk.Context, poolIdToTickSpacingRecord []types.PoolIdToTickSpacingRecord) error { for _, poolIdToTickSpacingRecord := range poolIdToTickSpacingRecord { - pool, err := k.GetPoolFromPoolIdAndConvertToConcentrated(ctx, poolIdToTickSpacingRecord.PoolId) + pool, err := k.GetConcentratedPoolById(ctx, poolIdToTickSpacingRecord.PoolId) if err != nil { return err } diff --git a/x/concentrated-liquidity/position.go b/x/concentrated-liquidity/position.go index 81b471c440f..b87dfc23d22 100644 --- a/x/concentrated-liquidity/position.go +++ b/x/concentrated-liquidity/position.go @@ -286,30 +286,9 @@ func (k Keeper) deletePosition(ctx sdk.Context, // CreateFullRangePosition creates a full range (min to max tick) concentrated liquidity position for the given pool ID, owner, and coins. // The function returns the amounts of token 0 and token 1, and the liquidity created from the position. -func (k Keeper) CreateFullRangePosition(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, err error) { - // Check that exactly two coins are provided. - if len(coins) != 2 { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(coins)} - } - - concentratedPool, err := k.GetPoolFromPoolIdAndConvertToConcentrated(ctx, clPoolId) - if err != nil { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, err - } - - // Defense in depth, ensure coins provided match the pool's token denominations. - if coins.AmountOf(concentratedPool.GetToken0()).LTE(sdk.ZeroInt()) { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.Amount0IsNegativeError{Amount0: coins.AmountOf(concentratedPool.GetToken0())} - } - if coins.AmountOf(concentratedPool.GetToken1()).LTE(sdk.ZeroInt()) { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.Amount1IsNegativeError{Amount1: coins.AmountOf(concentratedPool.GetToken1())} - } - if len(coins) != 2 { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(coins)} - } - +func (k Keeper) CreateFullRangePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, coins sdk.Coins) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, err error) { // Create a full range (min to max tick) concentrated liquidity position. - positionId, amount0, amount1, liquidity, joinTime, err = k.createPosition(ctx, concentratedPool.GetId(), owner, coins, sdk.ZeroInt(), sdk.ZeroInt(), types.MinTick, types.MaxTick) + positionId, amount0, amount1, liquidity, joinTime, err = k.createPosition(ctx, poolId, owner, coins, sdk.ZeroInt(), sdk.ZeroInt(), types.MinTick, types.MaxTick) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, err } @@ -329,7 +308,7 @@ func (k Keeper) CreateFullRangePositionLocked(ctx sdk.Context, clPoolId uint64, // Mint cl shares for the position and lock them for the remaining lock duration. // Also sets the position ID to underlying lock ID mapping. - concentratedLockId, _, err := k.mintSharesLockAndUpdate(ctx, clPoolId, positionId, owner, remainingLockDuration) + concentratedLockId, _, err := k.mintSharesAndLock(ctx, clPoolId, positionId, owner, remainingLockDuration) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, 0, err } @@ -349,7 +328,7 @@ func (k Keeper) CreateFullRangePositionUnlocking(ctx sdk.Context, clPoolId uint6 // Mint cl shares for the position and lock them for the remaining lock duration. // Also sets the position ID to underlying lock ID mapping. - concentratedLockId, underlyingLiquidityTokenized, err := k.mintSharesLockAndUpdate(ctx, clPoolId, positionId, owner, remainingLockDuration) + concentratedLockId, underlyingLiquidityTokenized, err := k.mintSharesAndLock(ctx, clPoolId, positionId, owner, remainingLockDuration) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, 0, err } @@ -363,11 +342,11 @@ func (k Keeper) CreateFullRangePositionUnlocking(ctx sdk.Context, clPoolId uint6 return positionId, amount0, amount1, liquidity, joinTime, concentratedLockID, nil } -// mintSharesLockAndUpdate mints the shares for the full range concentrated liquidity position and locks them for the given duration. It also updates the position ID to underlying lock ID mapping. +// mintSharesAndLock mints the shares for the full range concentrated liquidity position and locks them for the given duration. It also updates the position ID to underlying lock ID mapping. // In the context of concentrated liquidity, shares need to be minted in order for a lock in its current form to be utilized (we cannot lock non-coin objects). // In turn, the locks are a prerequisite for superfluid to be enabled. // Additionally, the cl share gets sent to the lockup module account, which, in order to be sent via bank, must be minted. -func (k Keeper) mintSharesLockAndUpdate(ctx sdk.Context, concentratedPoolId, positionId uint64, owner sdk.AccAddress, remainingLockDuration time.Duration) (concentratedLockID uint64, underlyingLiquidityTokenized sdk.Coins, err error) { +func (k Keeper) mintSharesAndLock(ctx sdk.Context, concentratedPoolId, positionId uint64, owner sdk.AccAddress, remainingLockDuration time.Duration) (concentratedLockID uint64, underlyingLiquidityTokenized sdk.Coins, err error) { // Ensure the provided position is full range. position, err := k.GetPosition(ctx, positionId) if err != nil { @@ -378,6 +357,8 @@ func (k Keeper) mintSharesLockAndUpdate(ctx sdk.Context, concentratedPoolId, pos } // Create a coin object to represent the underlying liquidity for the cl position. + // Q: what is the impact of this on slashing or anything else. I think truncating liqudiity even slightly might cause the final token amount difference + // to end up being quite large. I think the risk of this is offset but superfluid risk factor but would like to confirm. underlyingLiquidityTokenized = sdk.NewCoins(sdk.NewCoin(types.GetConcentratedLockupDenomFromPoolId(concentratedPoolId), position.Liquidity.TruncateInt())) // Mint the underlying liquidity as a token and send to the owner. @@ -392,7 +373,9 @@ func (k Keeper) mintSharesLockAndUpdate(ctx sdk.Context, concentratedPoolId, pos // Lock the position for the specified duration. // Note, the end blocker for the lockup module contains an exception for this CL denom. When a lock with a denom of cl/pool/{poolId} is mature, - // it does not send the coins to the owner account and instead burns them. This is strictly to use well tested pre-existing methods rather than potentially introducing bugs with new logic and methods. + // it does not send the coins to the owner account but instead burns them. + // This is implemented in such a way to use well-tested pre-existing methods rather than + // completely re-implementing concentrated liquidity superfluid infrastructure that has a riks of introducing bugs with new logic and methods. concentratedLock, err := k.lockupKeeper.CreateLock(ctx, owner, underlyingLiquidityTokenized, remainingLockDuration) if err != nil { return 0, sdk.Coins{}, err diff --git a/x/concentrated-liquidity/position_test.go b/x/concentrated-liquidity/position_test.go index a96238c904c..c19ce972247 100644 --- a/x/concentrated-liquidity/position_test.go +++ b/x/concentrated-liquidity/position_test.go @@ -1457,9 +1457,8 @@ func (s *KeeperTestSuite) TestCreateFullRangePosition() { } } -func (s *KeeperTestSuite) TestMintSharesLockAndUpdate() { +func (s *KeeperTestSuite) TestMintSharesAndLock() { defaultAddress := s.TestAccs[0] - defaultPositionCoins := sdk.NewCoins(DefaultCoin0, DefaultCoin1) tests := []struct { name string @@ -1500,25 +1499,25 @@ func (s *KeeperTestSuite) TestMintSharesLockAndUpdate() { clPool := s.PrepareConcentratedPool() // Fund the owner account - s.FundAcc(test.owner, defaultPositionCoins) + s.FundAcc(test.owner, DefaultCoins) // Create a position positionId := uint64(0) liquidity := sdk.ZeroDec() if test.createFullRangePosition { var err error - positionId, _, _, liquidity, _, err = s.App.ConcentratedLiquidityKeeper.CreateFullRangePosition(s.Ctx, clPool.GetId(), test.owner, defaultPositionCoins) + positionId, _, _, liquidity, _, err = s.App.ConcentratedLiquidityKeeper.CreateFullRangePosition(s.Ctx, clPool.GetId(), test.owner, DefaultCoins) 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(), DefaultLowerTick, DefaultUpperTick) + positionId, _, _, liquidity, _, err = s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, clPool.GetId(), test.owner, DefaultCoins, sdk.ZeroInt(), sdk.ZeroInt(), DefaultLowerTick, DefaultUpperTick) s.Require().NoError(err) } lockupModuleAccountBalancePre := s.App.LockupKeeper.GetModuleBalance(s.Ctx) // System under test - concentratedLockId, underlyingLiquidityTokenized, err := s.App.ConcentratedLiquidityKeeper.MintSharesLockAndUpdate(s.Ctx, clPool.GetId(), positionId, test.owner, test.remainingLockDuration) + concentratedLockId, underlyingLiquidityTokenized, err := s.App.ConcentratedLiquidityKeeper.MintSharesAndLock(s.Ctx, clPool.GetId(), positionId, test.owner, test.remainingLockDuration) if test.expectedErr != nil { s.Require().Error(err) s.Require().ErrorIs(err, test.expectedErr) diff --git a/x/concentrated-liquidity/types/cl.go b/x/concentrated-liquidity/types/cl.go index 547bfd1933e..eb09e8260ac 100644 --- a/x/concentrated-liquidity/types/cl.go +++ b/x/concentrated-liquidity/types/cl.go @@ -17,5 +17,5 @@ func OrderInitialPoolDenoms(denom0, denom1 string) (string, string, error) { // GetConcentratedLockupDenomFromPoolId returns the concentrated lockup denom for a given pool. func GetConcentratedLockupDenomFromPoolId(poolId uint64) string { - return fmt.Sprintf("%s/%d", ClTokenPrefix, poolId) + return fmt.Sprintf("%s/%d", ConcentratedLiquidityTokenPrefix, poolId) } diff --git a/x/concentrated-liquidity/types/cl_test.go b/x/concentrated-liquidity/types/cl_test.go index 89cefc7e48e..855cee672a4 100644 --- a/x/concentrated-liquidity/types/cl_test.go +++ b/x/concentrated-liquidity/types/cl_test.go @@ -16,17 +16,17 @@ func TestGetConcentratedLockupDenomFromPoolId(t *testing.T) { { name: "poolId 1", poolId: 1, - expectedDenom: fmt.Sprintf("%s/%d", types.ClTokenPrefix, 1), + expectedDenom: fmt.Sprintf("%s/%d", types.ConcentratedLiquidityTokenPrefix, 1), }, { name: "poolId 0", poolId: 0, - expectedDenom: fmt.Sprintf("%s/%d", types.ClTokenPrefix, 0), + expectedDenom: fmt.Sprintf("%s/%d", types.ConcentratedLiquidityTokenPrefix, 0), }, { name: "poolId 1000", poolId: 1000, - expectedDenom: fmt.Sprintf("%s/%d", types.ClTokenPrefix, 1000), + expectedDenom: fmt.Sprintf("%s/%d", types.ConcentratedLiquidityTokenPrefix, 1000), }, } diff --git a/x/concentrated-liquidity/types/keys.go b/x/concentrated-liquidity/types/keys.go index 3e334e113c6..48b7b060b77 100644 --- a/x/concentrated-liquidity/types/keys.go +++ b/x/concentrated-liquidity/types/keys.go @@ -18,7 +18,7 @@ const ( uint64ByteSize = 8 uintBase = 10 - ClTokenPrefix = "cl/pool" + ConcentratedLiquidityTokenPrefix = "cl/pool" ) // Key prefixes @@ -239,7 +239,7 @@ func KeyBalancerFullRange(clPoolId, balancerPoolId, uptimeIndex uint64) []byte { // Helper Functions func GetPoolIdFromShareDenom(denom string) (uint64, error) { - if !strings.HasPrefix(denom, ClTokenPrefix) { + if !strings.HasPrefix(denom, ConcentratedLiquidityTokenPrefix) { return 0, fmt.Errorf("denom does not start with the cl token prefix") } parts := strings.Split(denom, "/") diff --git a/x/gamm/keeper/migrate.go b/x/gamm/keeper/migrate.go index 471df1df65e..0805ab7d6af 100644 --- a/x/gamm/keeper/migrate.go +++ b/x/gamm/keeper/migrate.go @@ -32,7 +32,7 @@ func (k Keeper) MigrateUnlockedPositionFromBalancerToConcentrated(ctx sdk.Contex } // Get the concentrated pool from the message and type cast it to ConcentratedPoolExtension. - concentratedPool, err := k.concentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, poolIdEntering) + concentratedPool, err := k.concentratedLiquidityKeeper.GetConcentratedPoolById(ctx, poolIdEntering) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, 0, 0, err } @@ -195,7 +195,7 @@ func (k Keeper) validateRecords(ctx sdk.Context, records []types.BalancerToConce var clPool cltypes.ConcentratedPoolExtension if record.ClPoolId != 0 { // Ensure the provided ClPoolId exists and that it is of type concentrated. - clPool, err = k.concentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, record.ClPoolId) + clPool, err = k.concentratedLiquidityKeeper.GetConcentratedPoolById(ctx, record.ClPoolId) if err != nil { return err } diff --git a/x/gamm/types/expected_keepers.go b/x/gamm/types/expected_keepers.go index 33142294bd0..2984d3cbedc 100644 --- a/x/gamm/types/expected_keepers.go +++ b/x/gamm/types/expected_keepers.go @@ -49,7 +49,7 @@ type CommunityPoolKeeper interface { // ConcentratedLiquidityKeeper defines the contract needed to be fulfilled for the concentrated liquidity keeper. type ConcentratedLiquidityKeeper interface { - GetPoolFromPoolIdAndConvertToConcentrated(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) + GetConcentratedPoolById(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) CreateFullRangePosition(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, err error) } diff --git a/x/incentives/types/expected_keepers.go b/x/incentives/types/expected_keepers.go index 76e84c1c684..4fd81e74d87 100644 --- a/x/incentives/types/expected_keepers.go +++ b/x/incentives/types/expected_keepers.go @@ -48,7 +48,7 @@ type TxFeesKeeper interface { type ConcentratedLiquidityKeeper interface { CreateIncentive(ctx sdk.Context, poolId uint64, sender sdk.AccAddress, incentiveCoin sdk.Coin, emissionRate sdk.Dec, startTime time.Time, minUptime time.Duration) (cltypes.IncentiveRecord, error) - GetPoolFromPoolIdAndConvertToConcentrated(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) + GetConcentratedPoolById(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) } type AccountKeeper interface { diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index da1ddb64569..076ed76537d 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -385,7 +385,7 @@ func (k Keeper) unlockMaturedLockInternalLogic(ctx sdk.Context, lock types.Perio coins := lock.Coins finalCoinsToSendBackToUser := sdk.NewCoins() for _, coin := range coins { - if strings.HasPrefix(coin.Denom, cltypes.ClTokenPrefix) { + if strings.HasPrefix(coin.Denom, cltypes.ConcentratedLiquidityTokenPrefix) { // If the coin is a CL liquidity token, we do not add it to the finalCoinsToSendBackToUser and instead burn it err := k.bk.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(coin)) if err != nil { diff --git a/x/lockup/keeper/lock_test.go b/x/lockup/keeper/lock_test.go index 6a803138a9f..63336318c58 100644 --- a/x/lockup/keeper/lock_test.go +++ b/x/lockup/keeper/lock_test.go @@ -913,7 +913,7 @@ func (suite *KeeperTestSuite) TestEndblockerWithdrawAllMaturedLockups() { // We expect that only non-CL locks (i.e. locks that do not have the CL token prefix) send tokens back to the user's balance when mature. This is because CL tokens get burned after the lock matures. expectedCoins := sdk.NewCoins() for _, coin := range totalCoins { - if !strings.HasPrefix(coin.Denom, cltypes.ClTokenPrefix) { + if !strings.HasPrefix(coin.Denom, cltypes.ConcentratedLiquidityTokenPrefix) { expectedCoins = expectedCoins.Add(coin) } } @@ -1068,7 +1068,7 @@ func (suite *KeeperTestSuite) TestSlashTokensFromLockByIDSendUnderlyingAndBurn() suite.Require().NoError(err) // Refetch the cl pool post full range position creation - clPool, err = suite.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(suite.Ctx, clPoolId) + clPool, err = suite.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(suite.Ctx, clPoolId) suite.Require().NoError(err) clPoolPositionDenom := cltypes.GetConcentratedLockupDenomFromPoolId(clPoolId) @@ -1096,7 +1096,7 @@ func (suite *KeeperTestSuite) TestSlashTokensFromLockByIDSendUnderlyingAndBurn() position, err := suite.App.ConcentratedLiquidityKeeper.GetPosition(suite.Ctx, positionID) suite.Require().NoError(err) - concentratedPool, err := suite.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(suite.Ctx, position.PoolId) + concentratedPool, err := suite.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(suite.Ctx, position.PoolId) suite.Require().NoError(err) tempPositionToCalculateUnderlyingAssets := position diff --git a/x/superfluid/client/cli/tx.go b/x/superfluid/client/cli/tx.go index 6f7e38137dd..9394ab92a47 100644 --- a/x/superfluid/client/cli/tx.go +++ b/x/superfluid/client/cli/tx.go @@ -221,7 +221,7 @@ func parseSetSuperfluidAssetsArgsToContent(cmd *cobra.Command) (govtypes.Content var assetType types.SuperfluidAssetType if strings.HasPrefix(asset, gammtypes.GAMMTokenPrefix) { assetType = types.SuperfluidAssetTypeLPShare - } else if strings.HasPrefix(asset, cltypes.ClTokenPrefix) { + } else if strings.HasPrefix(asset, cltypes.ConcentratedLiquidityTokenPrefix) { assetType = types.SuperfluidAssetTypeConcentratedShare } else { return nil, fmt.Errorf("Invalid asset prefix: %s", asset) diff --git a/x/superfluid/keeper/concentrated_liquidity.go b/x/superfluid/keeper/concentrated_liquidity.go index 0a2085831c8..bac8d9a3624 100644 --- a/x/superfluid/keeper/concentrated_liquidity.go +++ b/x/superfluid/keeper/concentrated_liquidity.go @@ -15,8 +15,8 @@ import ( // // Returns: // newPositionId: ID of the newly created concentrated liquidity position. -// actualAmount0: Actual amount of token 0 added. -// actualAmount1: Actual amount of token 1 added. +// actualAmount0: Actual amount of token 0 existing in the updated position. +// actualAmount1: Actual amount of token 1 existing in the updated position. // newLiquidity: The new liquidity value. // newLockId: ID of the lock associated with the new position. // error: Error, if any. @@ -24,10 +24,12 @@ import ( // An error is returned if: // - The position does not exist. // - The amount added is negative. -// - The function caller does not own the lock. +// - The provided sender does not own the lock. +// - The provided sender does not own the position. // - The position is not superfluid staked. // - The position is the last position in the pool. -func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, owner sdk.AccAddress, positionId uint64, amount0ToAdd, amount1ToAdd sdk.Int) (uint64, sdk.Int, sdk.Int, sdk.Dec, uint64, error) { +// - The lock duration does not match the unbonding duration. +func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, sender sdk.AccAddress, positionId uint64, amount0ToAdd, amount1ToAdd sdk.Int) (uint64, sdk.Int, sdk.Int, sdk.Dec, uint64, error) { position, err := k.clk.GetPosition(ctx, positionId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err @@ -46,6 +48,11 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, types.PositionNotSuperfluidStakedError{PositionId: position.PositionId} } + // Defense in depth making sure that the position is full-range. + if position.LowerTick != cltypes.MinTick || position.UpperTick != cltypes.MaxTick { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, types.ConcentratedTickRangeNotFullError{ActualLowerTick: position.LowerTick, ActualUpperTick: position.UpperTick} + } + lock, err := k.lk.GetLockByID(ctx, lockId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err @@ -59,8 +66,8 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow if lock.Owner != position.Address { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, types.LockOwnerMismatchError{LockId: lockId, LockOwner: lock.Owner, ProvidedOwner: position.Address} } - if lock.Owner != owner.String() { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, types.LockOwnerMismatchError{LockId: lockId, LockOwner: lock.Owner, ProvidedOwner: owner.String()} + if lock.Owner != sender.String() { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, types.LockOwnerMismatchError{LockId: lockId, LockOwner: lock.Owner, ProvidedOwner: sender.String()} } unbondingDuration := k.sk.UnbondingTime(ctx) if lock.Duration != unbondingDuration || !lock.EndTime.IsZero() { @@ -69,7 +76,7 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow // Superfluid undelegate the superfluid delegated position. // This deletes the connection between the lock and the intermediate account, deletes the synthetic lock, and burns the synthetic osmo. - intermediateAccount, err := k.SuperfluidUndelegateToConcentratedPosition(ctx, owner.String(), lockId) + intermediateAccount, err := k.SuperfluidForceUndelegate(ctx, sender.String(), lockId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } @@ -81,8 +88,8 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } - // Withdraw full position. - amount0Withdrawn, amount1Withdrawn, err := k.clk.WithdrawPosition(ctx, owner, positionId, position.Liquidity) + // Withdraw full liquidity from the position. + amount0Withdrawn, amount1Withdrawn, err := k.clk.WithdrawPosition(ctx, sender, positionId, position.Liquidity) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } @@ -97,18 +104,18 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow } // Create a coins object that includes the old position coins and the new position coins. - concentratedPool, err := k.clk.GetPoolFromPoolIdAndConvertToConcentrated(ctx, position.PoolId) + concentratedPool, err := k.clk.GetConcentratedPoolById(ctx, position.PoolId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } newPositionCoins := sdk.NewCoins(sdk.NewCoin(concentratedPool.GetToken0(), amount0Withdrawn.Add(amount0ToAdd)), sdk.NewCoin(concentratedPool.GetToken1(), amount1Withdrawn.Add(amount1ToAdd))) // Create a full range (min to max tick) concentrated liquidity position, lock it, and superfluid delegate it. - newPositionId, actualAmount0, actualAmount1, newLiquidity, _, newLockId, err := k.clk.CreateFullRangePositionLocked(ctx, position.PoolId, owner, newPositionCoins, unbondingDuration) + newPositionId, actualNewAmount0, actualNewAmount1, newLiquidity, _, newLockId, err := k.clk.CreateFullRangePositionLocked(ctx, position.PoolId, sender, newPositionCoins, unbondingDuration) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } - err = k.SuperfluidDelegate(ctx, owner.String(), newLockId, intermediateAccount.ValAddr) + err = k.SuperfluidDelegate(ctx, sender.String(), newLockId, intermediateAccount.ValAddr) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } @@ -117,17 +124,18 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, ow ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeySender, owner.String()), + sdk.NewAttribute(sdk.AttributeKeySender, sender.String()), ), sdk.NewEvent( types.TypeEvtAddToConcentratedLiquiditySuperfluidPosition, - sdk.NewAttribute(sdk.AttributeKeySender, owner.String()), + sdk.NewAttribute(sdk.AttributeKeySender, sender.String()), sdk.NewAttribute(types.AttributePositionId, strconv.FormatUint(newPositionId, 10)), - sdk.NewAttribute(types.AttributeAmount0, actualAmount0.String()), - sdk.NewAttribute(types.AttributeAmount1, actualAmount1.String()), + sdk.NewAttribute(types.AttributeAmount0, actualNewAmount0.String()), + sdk.NewAttribute(types.AttributeAmount1, actualNewAmount1.String()), sdk.NewAttribute(types.AttributeConcentratedLockId, strconv.FormatUint(newLockId, 10)), + sdk.NewAttribute(types.AttributeLiquidity, newLiquidity.String()), ), }) - return newPositionId, actualAmount0, actualAmount1, newLiquidity, newLockId, nil + return newPositionId, actualNewAmount0, actualNewAmount1, newLiquidity, newLockId, nil } diff --git a/x/superfluid/keeper/concentrated_liquidity_test.go b/x/superfluid/keeper/concentrated_liquidity_test.go index 9fc7f8b54e3..952b9820ad4 100644 --- a/x/superfluid/keeper/concentrated_liquidity_test.go +++ b/x/superfluid/keeper/concentrated_liquidity_test.go @@ -118,7 +118,7 @@ func (suite *KeeperTestSuite) TestAddToConcentratedLiquiditySuperfluidPosition() // Run test setup logic. positionId, lockId, amount0, amount1, valAddr, poolJoinAcc := suite.SetupSuperfluidConcentratedPosition(ctx, tc.superfluidDelegated, tc.superfluidUndelegating, tc.unlocking, owner) - clPool, err := concentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(ctx, 1) + clPool, err := concentratedLiquidityKeeper.GetConcentratedPoolById(ctx, 1) suite.Require().NoError(err) clPoolAddress := clPool.GetAddress() diff --git a/x/superfluid/keeper/epoch.go b/x/superfluid/keeper/epoch.go index 7ce22cda1b3..e97dfdd30ee 100644 --- a/x/superfluid/keeper/epoch.go +++ b/x/superfluid/keeper/epoch.go @@ -134,7 +134,7 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup } else if asset.AssetType == types.SuperfluidAssetTypeConcentratedShare { // LP_token_Osmo_equivalent = OSMO_amount_on_pool / LP_token_supply poolId := cltypes.MustGetPoolIdFromShareDenom(asset.Denom) - pool, err := k.clk.GetPoolFromPoolIdAndConvertToConcentrated(ctx, poolId) + pool, err := k.clk.GetConcentratedPoolById(ctx, poolId) if err != nil { k.Logger(ctx).Error(err.Error()) // Pool has unexpectedly removed Osmo from its assets. @@ -152,6 +152,7 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup UpperTick: cltypes.MaxTick, Liquidity: fullRangeLiquidity, } + // Note that the returned amounts are rounded up. This should be fine as they both are used for calculating the multiplier. asset0, asset1, err := cl.CalculateUnderlyingAssetsFromPosition(ctx, position, pool) if err != nil { k.Logger(ctx).Error(err.Error()) diff --git a/x/superfluid/keeper/gov/gov.go b/x/superfluid/keeper/gov/gov.go index 87e1ef0938b..eae3579832e 100644 --- a/x/superfluid/keeper/gov/gov.go +++ b/x/superfluid/keeper/gov/gov.go @@ -17,7 +17,7 @@ import ( func HandleSetSuperfluidAssetsProposal(ctx sdk.Context, k keeper.Keeper, ek types.EpochKeeper, p *types.SetSuperfluidAssetsProposal) error { for _, asset := range p.Assets { // Add check to ensure concentrated LP shares are formatted correctly - if strings.HasPrefix(asset.Denom, cltypes.ClTokenPrefix) { + if strings.HasPrefix(asset.Denom, cltypes.ConcentratedLiquidityTokenPrefix) { if asset.AssetType != types.SuperfluidAssetTypeConcentratedShare { return fmt.Errorf("concentrated LP share denom (%s) must have asset type %s", asset.Denom, types.SuperfluidAssetTypeConcentratedShare) } diff --git a/x/superfluid/keeper/migrate.go b/x/superfluid/keeper/migrate.go index b9a5ea10f60..d3ae969ad29 100644 --- a/x/superfluid/keeper/migrate.go +++ b/x/superfluid/keeper/migrate.go @@ -66,7 +66,7 @@ func (k Keeper) migrateSuperfluidBondedBalancerToConcentrated(ctx sdk.Context, // Superfluid undelegate the superfluid delegated position. // This deletes the connection between the lock and the intermediate account, deletes the synthetic lock, and burns the synthetic osmo. - intermediateAccount, err := k.SuperfluidUndelegateToConcentratedPosition(ctx, sender.String(), lockId) + intermediateAccount, err := k.SuperfluidForceUndelegate(ctx, sender.String(), lockId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, 0, 0, err } @@ -280,7 +280,7 @@ func (k Keeper) prepareMigration(ctx sdk.Context, sender sdk.AccAddress, lockId } // Get the concentrated pool from the provided ID and type cast it to ConcentratedPoolExtension. - concentratedPool, err = k.clk.GetPoolFromPoolIdAndConvertToConcentrated(ctx, poolIdEntering) + concentratedPool, err = k.clk.GetConcentratedPoolById(ctx, poolIdEntering) if err != nil { return 0, 0, nil, &lockuptypes.PeriodLock{}, 0, nil, false, false, err } diff --git a/x/superfluid/keeper/msg_server.go b/x/superfluid/keeper/msg_server.go index 7b9a8339ebf..7b9138b3ce5 100644 --- a/x/superfluid/keeper/msg_server.go +++ b/x/superfluid/keeper/msg_server.go @@ -237,10 +237,10 @@ func (server msgServer) AddToConcentratedLiquiditySuperfluidPosition(goCtx conte return nil, err } - newPositionId, actualAmount0, actualAmount1, _, newLockId, err := server.keeper.addToConcentratedLiquiditySuperfluidPosition(ctx, sender, msg.PositionId, msg.TokenDesired0.Amount, msg.TokenDesired1.Amount) + newPositionId, actualAmount0, actualAmount1, newLiquidity, newLockId, err := server.keeper.addToConcentratedLiquiditySuperfluidPosition(ctx, sender, msg.PositionId, msg.TokenDesired0.Amount, msg.TokenDesired1.Amount) if err != nil { return nil, err } - return &types.MsgAddToConcentratedLiquiditySuperfluidPositionResponse{PositionId: newPositionId, Amount0: actualAmount0, Amount1: actualAmount1, LockId: newLockId}, nil + return &types.MsgAddToConcentratedLiquiditySuperfluidPositionResponse{PositionId: newPositionId, Amount0: actualAmount0, Amount1: actualAmount1, LockId: newLockId, NewLiquidity: newLiquidity}, nil } diff --git a/x/superfluid/keeper/slash.go b/x/superfluid/keeper/slash.go index d08caf2ada3..88f1d7e0fa9 100644 --- a/x/superfluid/keeper/slash.go +++ b/x/superfluid/keeper/slash.go @@ -68,7 +68,7 @@ func (k Keeper) slashSynthLock(ctx sdk.Context, synthLock *lockuptypes.Synthetic // If the slashCoins contains a cl denom, we need to update the underlying cl position to reflect the slash. _ = osmoutils.ApplyFuncIfNoError(ctx, func(cacheCtx sdk.Context) error { - if strings.HasPrefix(lock.Coins[0].Denom, cltypes.ClTokenPrefix) { + if strings.HasPrefix(lock.Coins[0].Denom, cltypes.ConcentratedLiquidityTokenPrefix) { // Run prepare logic to get the underlying coins to slash. // We get the pool address here since the underlying coins will be sent directly from the pool to the community pool instead of the lock module account. // Additionally, we update the cl position's state entry to reflect the slash in the position's liquidity. @@ -109,6 +109,9 @@ func (k Keeper) prepareConcentratedLockForSlash(ctx sdk.Context, lock *lockuptyp if err != nil { return sdk.AccAddress{}, sdk.Coins{}, err } + + // Q: this would make the amounts calculated in alculateUnderlyingAssetsFromPosition + // be rounded down. Is this fine? I think yes, should be minimal impact. slashAmtNeg := slashAmt.Neg() // If slashAmt is not negative, return an error @@ -121,7 +124,7 @@ func (k Keeper) prepareConcentratedLockForSlash(ctx sdk.Context, lock *lockuptyp positionForCalculatingUnderlying := position positionForCalculatingUnderlying.Liquidity = slashAmt - concentratedPool, err := k.clk.GetPoolFromPoolIdAndConvertToConcentrated(ctx, position.PoolId) + concentratedPool, err := k.clk.GetConcentratedPoolById(ctx, position.PoolId) if err != nil { return sdk.AccAddress{}, sdk.Coins{}, err } diff --git a/x/superfluid/keeper/slash_test.go b/x/superfluid/keeper/slash_test.go index 0881819530b..8a312e67de1 100644 --- a/x/superfluid/keeper/slash_test.go +++ b/x/superfluid/keeper/slash_test.go @@ -287,7 +287,7 @@ func (suite *KeeperTestSuite) TestPrepareConcentratedLockForSlash() { upperTickInfoPostSlash, getTickErr := suite.App.ConcentratedLiquidityKeeper.GetTickInfo(suite.Ctx, clPoolId, positionPreSlash.UpperTick) suite.Require().NoError(getTickErr) - clPool, getPoolErr := suite.App.ConcentratedLiquidityKeeper.GetPoolFromPoolIdAndConvertToConcentrated(suite.Ctx, clPoolId) + clPool, getPoolErr := suite.App.ConcentratedLiquidityKeeper.GetConcentratedPoolById(suite.Ctx, clPoolId) suite.Require().NoError(getPoolErr) liquidityPostSlash := clPool.GetLiquidity() if tc.expectedErr { diff --git a/x/superfluid/keeper/stake.go b/x/superfluid/keeper/stake.go index d643ce94c9d..c2c9f6cca0a 100644 --- a/x/superfluid/keeper/stake.go +++ b/x/superfluid/keeper/stake.go @@ -300,10 +300,11 @@ func (k Keeper) SuperfluidUndelegate(ctx sdk.Context, sender string, lockID uint return k.createSyntheticLockup(ctx, lockID, intermediaryAcc, unlockingStatus) } -// SuperfluidUndelegateToConcentratedPosition starts undelegating superfluid delegated position for the given lock. It behaves similarly to SuperfluidUndelegate, -// however it does not create a new synthetic lockup representing the unstaking side. This is because at the time this function is called, the new concentrated liquidity side -// lock has not yet been created. Once the new cl side lock is created, the synthetic lockup representing the unstaking side is created. -func (k Keeper) SuperfluidUndelegateToConcentratedPosition(ctx sdk.Context, sender string, gammLockID uint64) (types.SuperfluidIntermediaryAccount, error) { +// SuperfluidForceUndelegate starts undelegating superfluid delegated position for the given lock. It behaves similarly to SuperfluidUndelegate, +// however it does not create a new synthetic lockup representing the unstaking side. This is because after the time this function is called, we might +// want to perform more operations prior to creating a lock. Once the actual lock is created, the synthetic lockup representing the unstaking side +// should eventually be created as well. Use thi function with caution to avoid accidentally missing synthetic lock creation. +func (k Keeper) SuperfluidForceUndelegate(ctx sdk.Context, sender string, gammLockID uint64) (types.SuperfluidIntermediaryAccount, error) { return k.undelegateCommon(ctx, sender, gammLockID) } diff --git a/x/superfluid/keeper/stake_test.go b/x/superfluid/keeper/stake_test.go index 7ab49d396c4..962e6300c06 100644 --- a/x/superfluid/keeper/stake_test.go +++ b/x/superfluid/keeper/stake_test.go @@ -529,7 +529,7 @@ func (suite *KeeperTestSuite) TestSuperfluidUndelegateToConcentratedPosition() { presupplyWithOffset := suite.App.BankKeeper.GetSupplyWithOffset(suite.Ctx, bondDenom) // superfluid undelegate - _, err = suite.App.SuperfluidKeeper.SuperfluidUndelegateToConcentratedPosition(suite.Ctx, lock.Owner, lockId) + _, err = suite.App.SuperfluidKeeper.SuperfluidForceUndelegate(suite.Ctx, lock.Owner, lockId) if tc.expSuperUnbondingErr[index] { suite.Require().Error(err) continue @@ -584,7 +584,7 @@ func (suite *KeeperTestSuite) TestSuperfluidUndelegateToConcentratedPosition() { lock, err := suite.App.LockupKeeper.GetLockByID(suite.Ctx, lockId) suite.Require().NoError(err) - _, err = suite.App.SuperfluidKeeper.SuperfluidUndelegateToConcentratedPosition(suite.Ctx, lock.Owner, lockId) + _, err = suite.App.SuperfluidKeeper.SuperfluidForceUndelegate(suite.Ctx, lock.Owner, lockId) suite.Require().Error(err) } }) diff --git a/x/superfluid/types/errors.go b/x/superfluid/types/errors.go index 45f8c886c8a..8fe89565f2c 100644 --- a/x/superfluid/types/errors.go +++ b/x/superfluid/types/errors.go @@ -4,6 +4,8 @@ import ( fmt "fmt" errorsmod "cosmossdk.io/errors" + + cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types" ) // x/superfluid module errors. @@ -51,3 +53,12 @@ type LockOwnerMismatchError struct { func (e LockOwnerMismatchError) Error() string { return fmt.Sprintf("lock ID %d owner %s does not match provided owner %s.", e.LockId, e.LockOwner, e.ProvidedOwner) } + +type ConcentratedTickRangeNotFullError struct { + ActualLowerTick int64 + ActualUpperTick int64 +} + +func (e ConcentratedTickRangeNotFullError) Error() string { + return fmt.Sprintf("position must be full range. Lower tick (%d) must be (%d). Upper tick (%d) must be (%d)", e.ActualLowerTick, e.ActualUpperTick, cltypes.MinTick, cltypes.MaxTick) +} diff --git a/x/superfluid/types/expected_keepers.go b/x/superfluid/types/expected_keepers.go index f82a4f74f04..3d5ffc0dcaa 100644 --- a/x/superfluid/types/expected_keepers.go +++ b/x/superfluid/types/expected_keepers.go @@ -106,7 +106,7 @@ type ConcentratedKeeper interface { GetPosition(ctx sdk.Context, positionId uint64) (model.Position, error) SetPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick, upperTick int64, joinTime time.Time, liquidity sdk.Dec, positionId uint64, underlyingLockId uint64) error UpdatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick, upperTick int64, liquidityDelta sdk.Dec, joinTime time.Time, positionId uint64) (sdk.Int, sdk.Int, error) - GetPoolFromPoolIdAndConvertToConcentrated(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) + GetConcentratedPoolById(ctx sdk.Context, poolId uint64) (cltypes.ConcentratedPoolExtension, error) CreateFullRangePositionLocked(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins, remainingLockDuration time.Duration) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, concentratedLockID uint64, err error) CreateFullRangePositionUnlocking(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins, remainingLockDuration time.Duration) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, concentratedLockID uint64, err error) GetPositionIdToLockId(ctx sdk.Context, underlyingLockId uint64) (uint64, error) diff --git a/x/superfluid/types/gov.go b/x/superfluid/types/gov.go index c34c3e8c066..1ad7dd8de97 100644 --- a/x/superfluid/types/gov.go +++ b/x/superfluid/types/gov.go @@ -71,7 +71,7 @@ func (p *SetSuperfluidAssetsProposal) ValidateBasic() error { return err } // Denom must be from CL - if !strings.HasPrefix(asset.Denom, cltypes.ClTokenPrefix) { + if !strings.HasPrefix(asset.Denom, cltypes.ConcentratedLiquidityTokenPrefix) { return fmt.Errorf("denom %s must be from CL", asset.Denom) } default: diff --git a/x/superfluid/types/tx.pb.go b/x/superfluid/types/tx.pb.go index 786cc740f9b..295f658c894 100644 --- a/x/superfluid/types/tx.pb.go +++ b/x/superfluid/types/tx.pb.go @@ -959,10 +959,11 @@ func (m *MsgAddToConcentratedLiquiditySuperfluidPosition) GetTokenDesired1() typ } type MsgAddToConcentratedLiquiditySuperfluidPositionResponse struct { - PositionId uint64 `protobuf:"varint,1,opt,name=position_id,json=positionId,proto3" json:"position_id,omitempty" yaml:"position_id"` - Amount0 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount0,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount0" yaml:"amount0"` - Amount1 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=amount1,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount1" yaml:"amount1"` - LockId uint64 `protobuf:"varint,4,opt,name=lock_id,json=lockId,proto3" json:"lock_id,omitempty" yaml:"lock_id"` + PositionId uint64 `protobuf:"varint,1,opt,name=position_id,json=positionId,proto3" json:"position_id,omitempty" yaml:"position_id"` + Amount0 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount0,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount0" yaml:"amount0"` + Amount1 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=amount1,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount1" yaml:"amount1"` + NewLiquidity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=new_liquidity,json=newLiquidity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_liquidity" yaml:"new_liquidity"` + LockId uint64 `protobuf:"varint,4,opt,name=lock_id,json=lockId,proto3" json:"lock_id,omitempty" yaml:"lock_id"` } func (m *MsgAddToConcentratedLiquiditySuperfluidPositionResponse) Reset() { @@ -1040,81 +1041,83 @@ func init() { func init() { proto.RegisterFile("osmosis/superfluid/tx.proto", fileDescriptor_55b645f187d22814) } var fileDescriptor_55b645f187d22814 = []byte{ - // 1173 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x41, 0x4f, 0x1b, 0x47, - 0x14, 0x66, 0x6d, 0x17, 0x92, 0xa1, 0x90, 0xb0, 0x0d, 0x89, 0x71, 0x89, 0xd7, 0x99, 0x46, 0x11, - 0x55, 0xc8, 0x2e, 0x26, 0x4d, 0x40, 0x3d, 0x81, 0xb1, 0x5a, 0x39, 0xc5, 0x2a, 0xda, 0x80, 0x2a, - 0x45, 0xaa, 0x56, 0x6b, 0xcf, 0x64, 0xd9, 0xb2, 0xde, 0x71, 0x76, 0xc6, 0x14, 0xd4, 0x1f, 0x90, - 0x6b, 0xfe, 0x41, 0xef, 0x3d, 0xf4, 0x37, 0xf4, 0xd6, 0xa8, 0xa7, 0xdc, 0x5a, 0xb5, 0x92, 0x53, - 0xc1, 0x3f, 0xe0, 0xd8, 0x53, 0x35, 0xbb, 0xb3, 0xeb, 0x35, 0x78, 0x31, 0xeb, 0x90, 0x43, 0x4e, - 0xec, 0xcc, 0xbc, 0xf7, 0x7d, 0xef, 0xbd, 0x79, 0xef, 0xcd, 0xc3, 0xe0, 0x53, 0x42, 0x5b, 0x84, - 0xda, 0x54, 0xa3, 0x9d, 0x36, 0xf6, 0x9e, 0x3b, 0x1d, 0x1b, 0x69, 0xec, 0x40, 0x6d, 0x7b, 0x84, - 0x11, 0x59, 0x16, 0x87, 0x6a, 0xef, 0xb0, 0x70, 0xc3, 0x22, 0x16, 0xf1, 0x8f, 0x35, 0xfe, 0x15, - 0x48, 0x16, 0x8a, 0x16, 0x21, 0x96, 0x83, 0x35, 0x7f, 0xd5, 0xe8, 0x3c, 0xd7, 0x50, 0xc7, 0x33, - 0x99, 0x4d, 0xdc, 0xf0, 0xbc, 0xe9, 0x43, 0x69, 0x0d, 0x93, 0x62, 0x6d, 0xbf, 0xdc, 0xc0, 0xcc, - 0x2c, 0x6b, 0x4d, 0x62, 0x87, 0xe7, 0xca, 0x69, 0x7d, 0x66, 0xb7, 0x30, 0x65, 0x66, 0xab, 0x2d, - 0x04, 0x3e, 0x1b, 0x60, 0x67, 0xef, 0x33, 0x10, 0x82, 0xfb, 0x60, 0xb6, 0x4e, 0xad, 0xa7, 0xd1, - 0x76, 0x15, 0x3b, 0xd8, 0x32, 0x19, 0x96, 0x3f, 0x07, 0xe3, 0x14, 0xbb, 0x08, 0x7b, 0x79, 0xa9, - 0x24, 0x2d, 0x5c, 0xad, 0xcc, 0x9c, 0x74, 0x95, 0xa9, 0x43, 0xb3, 0xe5, 0x7c, 0x09, 0x83, 0x7d, - 0xa8, 0x0b, 0x01, 0xf9, 0x16, 0x98, 0x70, 0x48, 0x73, 0xcf, 0xb0, 0x51, 0x3e, 0x53, 0x92, 0x16, - 0x72, 0xfa, 0x38, 0x5f, 0xd6, 0x90, 0x3c, 0x07, 0xae, 0xec, 0x9b, 0x8e, 0x61, 0x22, 0xe4, 0xe5, - 0xb3, 0x1c, 0x45, 0x9f, 0xd8, 0x37, 0x9d, 0x75, 0x84, 0x3c, 0xa8, 0x80, 0xdb, 0x03, 0x79, 0x75, - 0x4c, 0xdb, 0xc4, 0xa5, 0x18, 0x7e, 0x0f, 0x6e, 0xf5, 0x09, 0xec, 0xb8, 0xe8, 0x12, 0x4d, 0x83, - 0x77, 0x80, 0x92, 0x00, 0x7f, 0x8e, 0x05, 0x0d, 0xe2, 0xa2, 0x4d, 0xd2, 0xdc, 0x7b, 0x4f, 0x16, - 0x84, 0xf0, 0x91, 0x05, 0xbf, 0x4a, 0xe0, 0x6e, 0x82, 0x95, 0xeb, 0xee, 0x25, 0xdb, 0x23, 0x57, - 0x40, 0x8e, 0x67, 0x97, 0x7f, 0x51, 0x93, 0xcb, 0x73, 0x6a, 0x90, 0x7e, 0x2a, 0x4f, 0x3f, 0x55, - 0xa4, 0x9f, 0xba, 0x41, 0x6c, 0xb7, 0xf2, 0xc9, 0xeb, 0xae, 0x32, 0x76, 0xd2, 0x55, 0x26, 0x03, - 0x02, 0xae, 0x04, 0x75, 0x5f, 0x17, 0x7e, 0x0d, 0x16, 0x2f, 0x62, 0x6f, 0xe8, 0x60, 0xdc, 0x18, - 0xa9, 0x2f, 0x38, 0xbf, 0x4b, 0x60, 0xbe, 0x4e, 0x2d, 0x2e, 0xbc, 0xee, 0xa2, 0x77, 0x4b, 0x4f, - 0x13, 0x7c, 0xc4, 0x8d, 0xa3, 0xf9, 0x4c, 0x29, 0x7b, 0xbe, 0x67, 0x4b, 0xdc, 0xb3, 0x5f, 0xde, - 0x2a, 0x0b, 0x96, 0xcd, 0x76, 0x3b, 0x0d, 0xb5, 0x49, 0x5a, 0x9a, 0xa8, 0xc2, 0xe0, 0xcf, 0x03, - 0x8a, 0xf6, 0x34, 0x76, 0xd8, 0xc6, 0xd4, 0x57, 0xa0, 0x7a, 0x80, 0x7c, 0x5e, 0xa2, 0x3f, 0xf6, - 0xaf, 0x30, 0xd1, 0x91, 0x28, 0x14, 0xd3, 0x20, 0x53, 0xab, 0x8a, 0x28, 0x64, 0x6a, 0x55, 0xf8, - 0x32, 0x03, 0xb4, 0x3a, 0xb5, 0x36, 0x3c, 0x6c, 0x32, 0xfc, 0x55, 0xc7, 0x71, 0x74, 0xd3, 0xb5, - 0xf0, 0x16, 0xa1, 0x36, 0xef, 0x11, 0x1f, 0x76, 0x50, 0xe4, 0xfb, 0x60, 0xa2, 0x4d, 0x88, 0xc3, - 0xef, 0x3d, 0xc7, 0x3d, 0xae, 0xc8, 0x27, 0x5d, 0x65, 0x3a, 0xb0, 0x54, 0x1c, 0x40, 0x7d, 0x9c, - 0x7f, 0xd5, 0x10, 0x7c, 0x01, 0x56, 0x52, 0x06, 0x22, 0x0a, 0xea, 0x4d, 0x10, 0x24, 0x54, 0xb5, - 0x2f, 0xbd, 0xaa, 0x72, 0x11, 0x80, 0xb6, 0x00, 0xa8, 0x55, 0x45, 0x1d, 0xc4, 0x76, 0xa0, 0x07, - 0xf2, 0x75, 0x6a, 0xed, 0xb8, 0x5b, 0x84, 0x38, 0xdf, 0xed, 0xda, 0x0c, 0x3b, 0x36, 0x65, 0x18, - 0xf1, 0x65, 0x9a, 0x20, 0xc7, 0xdc, 0xcc, 0x0c, 0x75, 0xf3, 0x09, 0x28, 0x25, 0x71, 0x46, 0xfe, - 0xdc, 0x03, 0xd7, 0xf0, 0x81, 0xcd, 0x30, 0x32, 0x44, 0xd9, 0xd0, 0xbc, 0x54, 0xca, 0x2e, 0xe4, - 0xf4, 0xa9, 0x60, 0x7b, 0xd3, 0xaf, 0x1e, 0x0a, 0x8f, 0x32, 0x60, 0xd5, 0x07, 0x73, 0x82, 0xbc, - 0xab, 0xdb, 0x96, 0x67, 0x32, 0xfc, 0x74, 0xd7, 0xf4, 0x30, 0xdd, 0x26, 0x51, 0x14, 0x37, 0x88, - 0xdb, 0xc4, 0x2e, 0xe3, 0x67, 0x28, 0x8c, 0x68, 0x4a, 0x07, 0xfb, 0x9a, 0x49, 0xdc, 0x41, 0x71, - 0x00, 0xa3, 0x06, 0x63, 0x81, 0x19, 0xea, 0x1b, 0x60, 0x30, 0x62, 0xb4, 0x02, 0x8b, 0x86, 0x77, - 0x9b, 0x92, 0xe8, 0x36, 0x79, 0x61, 0xc1, 0x69, 0x04, 0xa8, 0x5f, 0xa3, 0xc2, 0x2d, 0xe1, 0xa5, - 0x8c, 0xc1, 0x34, 0x23, 0x7b, 0xd8, 0x35, 0x48, 0x87, 0x19, 0x2d, 0x9e, 0xe4, 0xb9, 0x61, 0x49, - 0x7e, 0x57, 0xb0, 0xcc, 0x07, 0x2c, 0x7d, 0xea, 0x86, 0xd9, 0x22, 0x1d, 0x97, 0x51, 0xa8, 0x7f, - 0xec, 0xef, 0x7f, 0xdb, 0x61, 0x75, 0xdb, 0xa5, 0xf0, 0x8f, 0x2c, 0x58, 0x1b, 0x35, 0xc8, 0xd1, - 0x8d, 0x3e, 0x03, 0x13, 0x01, 0xfc, 0x92, 0x88, 0xf6, 0x1a, 0xb7, 0xe4, 0xef, 0xae, 0x72, 0xef, - 0x02, 0xe5, 0x56, 0x73, 0x59, 0x2f, 0xde, 0x02, 0x06, 0xea, 0x21, 0x60, 0x0f, 0xbb, 0xec, 0xdf, - 0xce, 0x3b, 0x63, 0x97, 0x23, 0xec, 0xb2, 0xfc, 0x23, 0x98, 0x71, 0xec, 0x17, 0x1d, 0x1b, 0xd9, - 0xec, 0xd0, 0x68, 0xfa, 0xb5, 0x89, 0x82, 0x2a, 0xaf, 0x3c, 0x49, 0xc1, 0x52, 0xc5, 0xcd, 0xde, - 0xdd, 0x9e, 0x01, 0x84, 0xfa, 0xf5, 0x68, 0x2f, 0xa8, 0x7f, 0x24, 0xef, 0x80, 0xab, 0x3f, 0x10, - 0xdb, 0x35, 0xf8, 0xb4, 0xe3, 0x37, 0x8f, 0xc9, 0xe5, 0x82, 0x1a, 0x8c, 0x42, 0x6a, 0x38, 0x0a, - 0xa9, 0xdb, 0xe1, 0x28, 0x54, 0x99, 0x17, 0x17, 0x7b, 0x3d, 0xa0, 0x88, 0x54, 0xe1, 0xab, 0xb7, - 0x8a, 0xa4, 0x5f, 0xe1, 0x6b, 0x2e, 0x0c, 0xff, 0x0c, 0xda, 0xed, 0x3a, 0x42, 0xdb, 0x24, 0x7e, - 0x61, 0x9b, 0x21, 0x7f, 0xaf, 0xcb, 0x44, 0x85, 0xb2, 0x02, 0x26, 0xc3, 0x9e, 0x11, 0xbd, 0x60, - 0x95, 0x9b, 0x27, 0x5d, 0x45, 0x0e, 0x4b, 0x3c, 0x3a, 0x84, 0xb1, 0xf6, 0x82, 0x62, 0x15, 0x96, - 0x19, 0x56, 0x61, 0x46, 0x98, 0xcb, 0x08, 0x53, 0xdb, 0xc3, 0x68, 0x69, 0x78, 0xc5, 0xdc, 0x16, - 0x2e, 0xcf, 0xc6, 0x73, 0x39, 0x54, 0x87, 0xfa, 0x94, 0xbf, 0x51, 0x15, 0xeb, 0x33, 0x04, 0x65, - 0x11, 0xd4, 0x11, 0x09, 0xca, 0xa7, 0x08, 0xca, 0x3c, 0xb2, 0x2b, 0x29, 0x23, 0x1b, 0x55, 0xc7, - 0xc8, 0x11, 0x8e, 0x95, 0x55, 0xe6, 0x3d, 0x96, 0x55, 0xf6, 0xb2, 0xcb, 0x2a, 0xd6, 0x50, 0x73, - 0xc3, 0x1a, 0xea, 0xf2, 0x7f, 0x00, 0x64, 0xeb, 0xd4, 0x92, 0x3d, 0x20, 0x0f, 0x1a, 0x06, 0xd4, - 0xb3, 0xff, 0x8a, 0xa8, 0x03, 0x67, 0xee, 0x42, 0xf9, 0xc2, 0xa2, 0xd1, 0xcd, 0x1c, 0x80, 0x1b, - 0x03, 0x67, 0xf3, 0xfb, 0x43, 0xa1, 0x7a, 0xc2, 0x85, 0x87, 0x29, 0x84, 0x93, 0x98, 0xa3, 0x19, - 0xf8, 0x22, 0xcc, 0xa1, 0xf0, 0x85, 0x98, 0xcf, 0x4c, 0xab, 0x3f, 0x4b, 0xe0, 0xce, 0xf0, 0x59, - 0x7c, 0x35, 0x85, 0x53, 0x7d, 0x9a, 0x85, 0xb5, 0x51, 0x35, 0x23, 0x0b, 0x5f, 0x4a, 0x60, 0x2e, - 0x79, 0x66, 0x5e, 0x4a, 0xc0, 0x4f, 0xd4, 0x28, 0xac, 0xa6, 0xd5, 0x88, 0x2c, 0xf9, 0x4d, 0x02, - 0x8b, 0xa9, 0x66, 0xd7, 0x8d, 0x04, 0xaa, 0x34, 0x20, 0x85, 0x6f, 0x2e, 0x01, 0x24, 0x72, 0xe1, - 0x27, 0x30, 0x3b, 0x78, 0x02, 0x5c, 0x4c, 0x60, 0x19, 0x28, 0x5d, 0xf8, 0x22, 0x8d, 0x74, 0x44, - 0xfe, 0x8f, 0x04, 0x1e, 0x8d, 0x36, 0xbe, 0x6d, 0x26, 0xf2, 0x8d, 0x80, 0x56, 0xd8, 0xbe, 0x4c, - 0xb4, 0xbe, 0xec, 0x48, 0xf5, 0xd4, 0x26, 0x65, 0x47, 0x1a, 0x90, 0xc4, 0xec, 0x18, 0xe5, 0x69, - 0xaa, 0x6c, 0xbd, 0x3e, 0x2a, 0x4a, 0x6f, 0x8e, 0x8a, 0xd2, 0xbf, 0x47, 0x45, 0xe9, 0xd5, 0x71, - 0x71, 0xec, 0xcd, 0x71, 0x71, 0xec, 0xaf, 0xe3, 0xe2, 0xd8, 0xb3, 0xc7, 0xb1, 0x67, 0x40, 0x10, - 0x3e, 0x70, 0xcc, 0x06, 0x0d, 0x17, 0xda, 0x7e, 0xf9, 0x91, 0x76, 0xd0, 0xf7, 0xeb, 0x11, 0x7f, - 0x1a, 0x1a, 0xe3, 0xfe, 0xf8, 0xf2, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x23, 0xf9, - 0xff, 0x60, 0x12, 0x00, 0x00, + // 1204 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x36, 0x25, 0xc5, 0x4e, 0xd6, 0x71, 0x7e, 0xd8, 0x38, 0x91, 0x55, 0x47, 0x54, 0xb6, 0x41, + 0xe0, 0x22, 0x0e, 0x69, 0x39, 0x4d, 0x62, 0xf4, 0x64, 0xcb, 0x42, 0x0a, 0xa5, 0x16, 0x6a, 0x30, + 0x36, 0x0a, 0x04, 0x28, 0x08, 0x4a, 0xbb, 0xa1, 0x59, 0x53, 0x5c, 0x85, 0xbb, 0xf2, 0x0f, 0xfa, + 0x00, 0xb9, 0xe6, 0x0d, 0x7a, 0xef, 0xa1, 0xcf, 0xd0, 0x43, 0x81, 0x06, 0x3d, 0xe5, 0xd6, 0xa2, + 0x05, 0x94, 0xc2, 0x7e, 0x03, 0x1f, 0x7b, 0x2a, 0x48, 0x2e, 0x57, 0x94, 0x2d, 0x5a, 0xa6, 0xe2, + 0x1c, 0x7a, 0x32, 0x77, 0x77, 0xe6, 0xfb, 0x66, 0x66, 0x67, 0x66, 0x47, 0x06, 0x9f, 0x12, 0xda, + 0x22, 0xd4, 0xa6, 0x1a, 0xed, 0xb4, 0xb1, 0xf7, 0xd2, 0xe9, 0xd8, 0x48, 0x63, 0x7b, 0x6a, 0xdb, + 0x23, 0x8c, 0xc8, 0x32, 0x3f, 0x54, 0x7b, 0x87, 0x85, 0x1b, 0x16, 0xb1, 0x48, 0x70, 0xac, 0xf9, + 0x5f, 0xa1, 0x64, 0xa1, 0x68, 0x11, 0x62, 0x39, 0x58, 0x0b, 0x56, 0x8d, 0xce, 0x4b, 0x0d, 0x75, + 0x3c, 0x93, 0xd9, 0xc4, 0x8d, 0xce, 0x9b, 0x01, 0x94, 0xd6, 0x30, 0x29, 0xd6, 0x76, 0xca, 0x0d, + 0xcc, 0xcc, 0xb2, 0xd6, 0x24, 0x76, 0x74, 0xae, 0x1c, 0xd7, 0x67, 0x76, 0x0b, 0x53, 0x66, 0xb6, + 0xda, 0x5c, 0xe0, 0xb3, 0x01, 0x76, 0xf6, 0x3e, 0x43, 0x21, 0xb8, 0x03, 0xa6, 0xeb, 0xd4, 0x7a, + 0x2e, 0xb6, 0xab, 0xd8, 0xc1, 0x96, 0xc9, 0xb0, 0xfc, 0x39, 0x18, 0xa7, 0xd8, 0x45, 0xd8, 0xcb, + 0x4b, 0x25, 0x69, 0xee, 0x52, 0xe5, 0xfa, 0x51, 0x57, 0x99, 0xda, 0x37, 0x5b, 0xce, 0x97, 0x30, + 0xdc, 0x87, 0x3a, 0x17, 0x90, 0x6f, 0x81, 0x09, 0x87, 0x34, 0xb7, 0x0d, 0x1b, 0xe5, 0x33, 0x25, + 0x69, 0x2e, 0xa7, 0x8f, 0xfb, 0xcb, 0x1a, 0x92, 0x67, 0xc0, 0xc5, 0x1d, 0xd3, 0x31, 0x4c, 0x84, + 0xbc, 0x7c, 0xd6, 0x47, 0xd1, 0x27, 0x76, 0x4c, 0x67, 0x05, 0x21, 0x0f, 0x2a, 0xe0, 0xf6, 0x40, + 0x5e, 0x1d, 0xd3, 0x36, 0x71, 0x29, 0x86, 0xdf, 0x81, 0x5b, 0x7d, 0x02, 0x9b, 0x2e, 0x3a, 0x47, + 0xd3, 0xe0, 0x1d, 0xa0, 0x24, 0xc0, 0x9f, 0x62, 0x41, 0x83, 0xb8, 0x68, 0x8d, 0x34, 0xb7, 0x3f, + 0x92, 0x05, 0x11, 0xbc, 0xb0, 0xe0, 0x67, 0x09, 0xdc, 0x4d, 0xb0, 0x72, 0xc5, 0x3d, 0x67, 0x7b, + 0xe4, 0x0a, 0xc8, 0xf9, 0xd9, 0x15, 0x5c, 0xd4, 0xe4, 0xe2, 0x8c, 0x1a, 0xa6, 0x9f, 0xea, 0xa7, + 0x9f, 0xca, 0xd3, 0x4f, 0x5d, 0x25, 0xb6, 0x5b, 0xf9, 0xe4, 0x6d, 0x57, 0x19, 0x3b, 0xea, 0x2a, + 0x93, 0x21, 0x81, 0xaf, 0x04, 0xf5, 0x40, 0x17, 0x7e, 0x05, 0xe6, 0xcf, 0x62, 0x6f, 0xe4, 0x60, + 0xdc, 0x18, 0xa9, 0x2f, 0x38, 0xbf, 0x49, 0x60, 0xb6, 0x4e, 0x2d, 0x5f, 0x78, 0xc5, 0x45, 0x1f, + 0x96, 0x9e, 0x26, 0xb8, 0xe0, 0x1b, 0x47, 0xf3, 0x99, 0x52, 0xf6, 0x74, 0xcf, 0x16, 0x7c, 0xcf, + 0x7e, 0x7a, 0xaf, 0xcc, 0x59, 0x36, 0xdb, 0xea, 0x34, 0xd4, 0x26, 0x69, 0x69, 0xbc, 0x0a, 0xc3, + 0x3f, 0x0f, 0x28, 0xda, 0xd6, 0xd8, 0x7e, 0x1b, 0xd3, 0x40, 0x81, 0xea, 0x21, 0xf2, 0x69, 0x89, + 0xfe, 0x38, 0xb8, 0xc2, 0x44, 0x47, 0x44, 0x28, 0xae, 0x80, 0x4c, 0xad, 0xca, 0xa3, 0x90, 0xa9, + 0x55, 0xe1, 0xeb, 0x0c, 0xd0, 0xea, 0xd4, 0x5a, 0xf5, 0xb0, 0xc9, 0xf0, 0xd3, 0x8e, 0xe3, 0xe8, + 0xa6, 0x6b, 0xe1, 0x75, 0x42, 0x6d, 0xbf, 0x47, 0xfc, 0xbf, 0x83, 0x22, 0xdf, 0x07, 0x13, 0x6d, + 0x42, 0x1c, 0xff, 0xde, 0x73, 0xbe, 0xc7, 0x15, 0xf9, 0xa8, 0xab, 0x5c, 0x09, 0x2d, 0xe5, 0x07, + 0x50, 0x1f, 0xf7, 0xbf, 0x6a, 0x08, 0xbe, 0x02, 0x4f, 0x52, 0x06, 0x42, 0x04, 0xf5, 0x26, 0x08, + 0x13, 0xaa, 0xda, 0x97, 0x5e, 0x55, 0xb9, 0x08, 0x40, 0x9b, 0x03, 0xd4, 0xaa, 0xbc, 0x0e, 0x62, + 0x3b, 0xd0, 0x03, 0xf9, 0x3a, 0xb5, 0x36, 0xdd, 0x75, 0x42, 0x9c, 0x6f, 0xb7, 0x6c, 0x86, 0x1d, + 0x9b, 0x32, 0x8c, 0xfc, 0x65, 0x9a, 0x20, 0xc7, 0xdc, 0xcc, 0x0c, 0x75, 0xf3, 0x19, 0x28, 0x25, + 0x71, 0x0a, 0x7f, 0xee, 0x81, 0xab, 0x78, 0xcf, 0x66, 0x18, 0x19, 0xbc, 0x6c, 0x68, 0x5e, 0x2a, + 0x65, 0xe7, 0x72, 0xfa, 0x54, 0xb8, 0xbd, 0x16, 0x54, 0x0f, 0x85, 0x07, 0x19, 0xb0, 0x14, 0x80, + 0x39, 0x61, 0xde, 0xd5, 0x6d, 0xcb, 0x33, 0x19, 0x7e, 0xbe, 0x65, 0x7a, 0x98, 0x6e, 0x10, 0x11, + 0xc5, 0x55, 0xe2, 0x36, 0xb1, 0xcb, 0xfc, 0x33, 0x14, 0x45, 0x34, 0xa5, 0x83, 0x7d, 0xcd, 0x24, + 0xee, 0x20, 0x3f, 0x80, 0xa2, 0xc1, 0x58, 0xe0, 0x3a, 0x0d, 0x0c, 0x30, 0x18, 0x31, 0x5a, 0xa1, + 0x45, 0xc3, 0xbb, 0x4d, 0x89, 0x77, 0x9b, 0x3c, 0xb7, 0xe0, 0x38, 0x02, 0xd4, 0xaf, 0x52, 0xee, + 0x16, 0xf7, 0x52, 0xc6, 0xe0, 0x0a, 0x23, 0xdb, 0xd8, 0x35, 0x48, 0x87, 0x19, 0x2d, 0x3f, 0xc9, + 0x73, 0xc3, 0x92, 0xfc, 0x2e, 0x67, 0x99, 0x0d, 0x59, 0xfa, 0xd4, 0x0d, 0xb3, 0x45, 0x3a, 0x2e, + 0xa3, 0x50, 0xbf, 0x1c, 0xec, 0x7f, 0xd3, 0x61, 0x75, 0xdb, 0xa5, 0xf0, 0xf7, 0x2c, 0x58, 0x1e, + 0x35, 0xc8, 0xe2, 0x46, 0x5f, 0x80, 0x89, 0x10, 0x7e, 0x81, 0x47, 0x7b, 0xd9, 0xb7, 0xe4, 0xaf, + 0xae, 0x72, 0xef, 0x0c, 0xe5, 0x56, 0x73, 0x59, 0x2f, 0xde, 0x1c, 0x06, 0xea, 0x11, 0x60, 0x0f, + 0xbb, 0x1c, 0xdc, 0xce, 0x07, 0x63, 0x97, 0x05, 0x76, 0x59, 0xde, 0x05, 0xd7, 0x1d, 0xfb, 0x55, + 0xc7, 0x46, 0x36, 0xdb, 0x37, 0x9a, 0x41, 0x6d, 0xa2, 0xb0, 0xca, 0x2b, 0xcf, 0x52, 0xb0, 0x54, + 0x71, 0xb3, 0x77, 0xb7, 0x27, 0x00, 0xa1, 0x7e, 0x4d, 0xec, 0x85, 0xf5, 0x8f, 0xe4, 0x4d, 0x70, + 0xe9, 0x7b, 0x62, 0xbb, 0x86, 0x3f, 0xed, 0x04, 0xcd, 0x63, 0x72, 0xb1, 0xa0, 0x86, 0xa3, 0x90, + 0x1a, 0x8d, 0x42, 0xea, 0x46, 0x34, 0x0a, 0x55, 0x66, 0xf9, 0xc5, 0x5e, 0x0b, 0x29, 0x84, 0x2a, + 0x7c, 0xf3, 0x5e, 0x91, 0xf4, 0x8b, 0xfe, 0xda, 0x17, 0x86, 0x7f, 0x84, 0xed, 0x76, 0x05, 0xa1, + 0x0d, 0x12, 0xbf, 0xb0, 0xb5, 0x88, 0xbf, 0xd7, 0x65, 0x44, 0xa1, 0x3c, 0x01, 0x93, 0x51, 0xcf, + 0x10, 0x2f, 0x58, 0xe5, 0xe6, 0x51, 0x57, 0x91, 0xa3, 0x12, 0x17, 0x87, 0x30, 0xd6, 0x5e, 0x50, + 0xac, 0xc2, 0x32, 0xc3, 0x2a, 0xcc, 0x88, 0x72, 0x19, 0x61, 0x6a, 0x7b, 0x18, 0x2d, 0x0c, 0xaf, + 0x98, 0xdb, 0xdc, 0xe5, 0xe9, 0x78, 0x2e, 0x47, 0xea, 0x50, 0x9f, 0x0a, 0x36, 0xaa, 0x7c, 0x7d, + 0x82, 0xa0, 0xcc, 0x83, 0x3a, 0x22, 0x41, 0xf9, 0x18, 0x41, 0x19, 0xfe, 0x9a, 0x0d, 0xfa, 0x77, + 0x9a, 0xc8, 0x8a, 0xea, 0x18, 0x39, 0xc2, 0xb1, 0xb2, 0xca, 0x7c, 0xc4, 0xb2, 0xca, 0x9e, 0x77, + 0x59, 0x6d, 0x83, 0x29, 0x17, 0xef, 0x1a, 0x22, 0xeb, 0xf3, 0x17, 0x02, 0x86, 0xa7, 0xa9, 0x4b, + 0xea, 0x46, 0xc8, 0xd0, 0x07, 0x06, 0xf5, 0xcb, 0x2e, 0xde, 0x15, 0x71, 0x8f, 0x77, 0xef, 0xdc, + 0xb0, 0xee, 0xbd, 0xf8, 0x2f, 0x00, 0xd9, 0x3a, 0xb5, 0x64, 0x0f, 0xc8, 0x83, 0x26, 0x0f, 0xf5, + 0xe4, 0xef, 0x1e, 0x75, 0xe0, 0x80, 0x5f, 0x28, 0x9f, 0x59, 0x54, 0xa4, 0xc1, 0x1e, 0xb8, 0x31, + 0xf0, 0x87, 0xc0, 0xfd, 0xa1, 0x50, 0x3d, 0xe1, 0xc2, 0xc3, 0x14, 0xc2, 0x49, 0xcc, 0x62, 0xe0, + 0x3e, 0x0b, 0x73, 0x24, 0x7c, 0x26, 0xe6, 0x13, 0xa3, 0xf1, 0x8f, 0x12, 0xb8, 0x33, 0x7c, 0xf0, + 0x5f, 0x4a, 0xe1, 0x54, 0x9f, 0x66, 0x61, 0x79, 0x54, 0x4d, 0x61, 0xe1, 0x6b, 0x09, 0xcc, 0x24, + 0x0f, 0xe8, 0x0b, 0x09, 0xf8, 0x89, 0x1a, 0x85, 0xa5, 0xb4, 0x1a, 0xc2, 0x92, 0x5f, 0x24, 0x30, + 0x9f, 0x6a, 0x50, 0x5e, 0x4d, 0xa0, 0x4a, 0x03, 0x52, 0xf8, 0xfa, 0x1c, 0x40, 0x84, 0x0b, 0x3f, + 0x80, 0xe9, 0xc1, 0xe3, 0xe6, 0x7c, 0x02, 0xcb, 0x40, 0xe9, 0xc2, 0x17, 0x69, 0xa4, 0x05, 0xf9, + 0xdf, 0x12, 0x78, 0x34, 0xda, 0xac, 0xb8, 0x96, 0xc8, 0x37, 0x02, 0x5a, 0x61, 0xe3, 0x3c, 0xd1, + 0xfa, 0xb2, 0x23, 0xd5, 0xbb, 0x9e, 0x94, 0x1d, 0x69, 0x40, 0x12, 0xb3, 0x63, 0x94, 0x77, 0xb0, + 0xb2, 0xfe, 0xf6, 0xa0, 0x28, 0xbd, 0x3b, 0x28, 0x4a, 0xff, 0x1c, 0x14, 0xa5, 0x37, 0x87, 0xc5, + 0xb1, 0x77, 0x87, 0xc5, 0xb1, 0x3f, 0x0f, 0x8b, 0x63, 0x2f, 0x1e, 0xc7, 0x5e, 0x04, 0x4e, 0xf8, + 0xc0, 0x31, 0x1b, 0x34, 0x5a, 0x68, 0x3b, 0xe5, 0x47, 0xda, 0x5e, 0xdf, 0xbf, 0xaa, 0xfc, 0x57, + 0xa2, 0x31, 0x1e, 0xcc, 0x4a, 0x0f, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x77, 0x3e, 0xe2, 0x6e, + 0xcd, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2190,6 +2193,16 @@ func (m *MsgAddToConcentratedLiquiditySuperfluidPositionResponse) MarshalToSized _ = i var l int _ = l + { + size := m.NewLiquidity.Size() + i -= size + if _, err := m.NewLiquidity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a if m.LockId != 0 { i = encodeVarintTx(dAtA, i, uint64(m.LockId)) i-- @@ -2528,6 +2541,8 @@ func (m *MsgAddToConcentratedLiquiditySuperfluidPositionResponse) Size() (n int) if m.LockId != 0 { n += 1 + sovTx(uint64(m.LockId)) } + l = m.NewLiquidity.Size() + n += 1 + l + sovTx(uint64(l)) return n } @@ -4579,6 +4594,40 @@ func (m *MsgAddToConcentratedLiquiditySuperfluidPositionResponse) Unmarshal(dAtA break } } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewLiquidity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NewLiquidity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) From 0fd0f606890e9c1526d62394fcabb737705a5a07 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 10 May 2023 20:56:25 +0000 Subject: [PATCH 02/19] updates --- x/concentrated-liquidity/client/cli/tx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/concentrated-liquidity/client/cli/tx.go b/x/concentrated-liquidity/client/cli/tx.go index 35358950de8..05b8683fdae 100644 --- a/x/concentrated-liquidity/client/cli/tx.go +++ b/x/concentrated-liquidity/client/cli/tx.go @@ -49,9 +49,9 @@ func NewCreateConcentratedPoolCmd() (*osmocli.TxCliDesc, *clmodel.MsgCreateConce func NewCreatePositionCmd() (*osmocli.TxCliDesc, *types.MsgCreatePosition) { return &osmocli.TxCliDesc{ - Use: "create-position [pool-id] [lower-tick] [upper-tick] [token-0-amount] [token-1-amount] [token-0-min-amount] [token-1-min-amount]", + Use: "create-position [pool-id] [lower-tick] [upper-tick] [token-0-coin,token-1-coin] [token-0-min-amount] [token-1-min-amount]", Short: "create or add to existing concentrated liquidity position", - Example: "create-position 1 \"[-69082]\" 69082 1000000000 10000000 0 0 --from val --chain-id osmosis-1", + Example: "create-position 1 \"[-69082]\" 69082 1000000000uosmo,10000000uion 0 0 --from val --chain-id osmosis-1", }, &types.MsgCreatePosition{} } From c5580b4c8eb70da0b033dd217a9e0656d2908017 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 00:31:56 +0000 Subject: [PATCH 03/19] updates --- osmoutils/errors.go | 11 ++++ osmoutils/store_helper.go | 17 +++++- osmoutils/store_helper_test.go | 66 +++++++++++++++++++++++ x/concentrated-liquidity/lp.go | 5 -- x/concentrated-liquidity/position.go | 35 ++++++++++-- x/concentrated-liquidity/position_test.go | 6 ++- x/superfluid/keeper/epoch.go | 7 ++- x/superfluid/types/expected_keepers.go | 2 +- 8 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 osmoutils/errors.go diff --git a/osmoutils/errors.go b/osmoutils/errors.go new file mode 100644 index 00000000000..51dc951915c --- /dev/null +++ b/osmoutils/errors.go @@ -0,0 +1,11 @@ +package osmoutils + +import "fmt" + +type DecNotFoundError struct { + Key string +} + +func (e DecNotFoundError) Error() string { + return fmt.Sprintf("no sdk.Dec at key (%s)", e.Key) +} diff --git a/osmoutils/store_helper.go b/osmoutils/store_helper.go index 232815179fa..80299d1743d 100644 --- a/osmoutils/store_helper.go +++ b/osmoutils/store_helper.go @@ -85,7 +85,7 @@ func GetIterValuesWithStop[T any]( // HasAnyAtPrefix returns true if there is at least one value in the given prefix. func HasAnyAtPrefix[T any](storeObj store.KVStore, prefix []byte, parseValue func([]byte) (T, error)) (bool, error) { - _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix),false, parseValue) + _, err := GetFirstValueInRange(storeObj, prefix, sdk.PrefixEndBytes(prefix), false, parseValue) if err != nil { if err == ErrNoValuesInRange { return false, nil @@ -180,6 +180,21 @@ func MustGetDec(store store.KVStore, key []byte) sdk.Dec { return result.Dec } +// GetDec gets dec value from store at key. Returns error if: +// - database error occurs. +// - no value at given key is found. +func GetDec(store store.KVStore, key []byte) (sdk.Dec, error) { + result := &sdk.DecProto{} + isFound, err := Get(store, key, result) + if err != nil { + return sdk.Dec{}, err + } + if !isFound { + return sdk.Dec{}, DecNotFoundError{Key: string(key)} + } + return result.Dec, nil +} + // Get returns a value at key by mutating the result parameter. Returns true if the value was found and the // result mutated correctly. If the value is not in the store, returns false. Returns error only when database or serialization errors occur. (And when an error occurs, returns false) func Get(store store.KVStore, key []byte, result proto.Message) (found bool, err error) { diff --git a/osmoutils/store_helper_test.go b/osmoutils/store_helper_test.go index e153c6cf3cd..21d2a134cf5 100644 --- a/osmoutils/store_helper_test.go +++ b/osmoutils/store_helper_test.go @@ -1243,3 +1243,69 @@ func (s *TestSuite) TestHasAnyAtPrefix() { }) } } + +func (s *TestSuite) TestGetDec() { + tests := map[string]struct { + // keys and values to preset + preSetKeyValues map[string]sdk.Dec + + // keys and values to attempt to get and validate + expectedGetKeyValues map[string]sdk.Dec + + expectError error + }{ + "valid get": { + preSetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: sdk.OneDec().Add(sdk.OneDec()), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + + expectedGetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: sdk.OneDec().Add(sdk.OneDec()), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + }, + "error: attempt to get non-existent key": { + preSetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyC: sdk.OneDec().Add(sdk.OneDec()).Add(sdk.OneDec()), + }, + + expectedGetKeyValues: map[string]sdk.Dec{ + keyA: sdk.OneDec(), + keyB: {}, // this one errors + }, + + expectError: osmoutils.DecNotFoundError{Key: keyB}, + }, + } + + for name, tc := range tests { + s.Run(name, func() { + s.SetupTest() + // Setup + for key, value := range tc.preSetKeyValues { + osmoutils.MustSetDec(s.store, []byte(key), value) + } + + for key, expectedValue := range tc.expectedGetKeyValues { + // System under test. + actualDec, err := osmoutils.GetDec(s.store, []byte(key)) + + // Assertions. + + if tc.expectError != nil { + s.Require().Error(err) + s.Require().ErrorIs(err, tc.expectError) + return + } + + s.Require().NoError(err) + s.Require().Equal(expectedValue.String(), actualDec.String()) + } + }) + + } +} diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 0eb309617cb..f9059551e58 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -46,11 +46,6 @@ func (k Keeper) createPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, err } - // Check that exactly two coins are provided. - if len(tokensProvided) != 2 { - return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(tokensProvided)} - } - amount0Desired := tokensProvided.AmountOf(pool.GetToken0()) amount1Desired := tokensProvided.AmountOf(pool.GetToken1()) if amount0Desired.IsZero() && amount1Desired.IsZero() { diff --git a/x/concentrated-liquidity/position.go b/x/concentrated-liquidity/position.go index b87dfc23d22..eab02814bbf 100644 --- a/x/concentrated-liquidity/position.go +++ b/x/concentrated-liquidity/position.go @@ -287,6 +287,27 @@ func (k Keeper) deletePosition(ctx sdk.Context, // CreateFullRangePosition creates a full range (min to max tick) concentrated liquidity position for the given pool ID, owner, and coins. // The function returns the amounts of token 0 and token 1, and the liquidity created from the position. func (k Keeper) CreateFullRangePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, coins sdk.Coins) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, err error) { + // Check that exactly two coins are provided. + if len(coins) != 2 { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(coins)} + } + + concentratedPool, err := k.GetConcentratedPoolById(ctx, poolId) + if err != nil { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, err + } + + // Defense in depth, ensure coins provided match the pool's token denominations. + if coins.AmountOf(concentratedPool.GetToken0()).LTE(sdk.ZeroInt()) { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.Amount0IsNegativeError{Amount0: coins.AmountOf(concentratedPool.GetToken0())} + } + if coins.AmountOf(concentratedPool.GetToken1()).LTE(sdk.ZeroInt()) { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.Amount1IsNegativeError{Amount1: coins.AmountOf(concentratedPool.GetToken1())} + } + if len(coins) != 2 { + return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, types.NumCoinsError{NumCoins: len(coins)} + } + // Create a full range (min to max tick) concentrated liquidity position. positionId, amount0, amount1, liquidity, joinTime, err = k.createPosition(ctx, poolId, owner, coins, sdk.ZeroInt(), sdk.ZeroInt(), types.MinTick, types.MaxTick) if err != nil { @@ -705,12 +726,18 @@ func (k Keeper) positionHasActiveUnderlyingLockAndUpdate(ctx sdk.Context, positi return hasActiveUnderlyingLock, lockId, nil } -// MustGetFullRangeLiquidityInPool returns the total liquidity that is currently in the full range of the pool. -func (k Keeper) MustGetFullRangeLiquidityInPool(ctx sdk.Context, poolId uint64) sdk.Dec { +// GetFullRangeLiquidityInPool returns the total liquidity that is currently in the full range of the pool. +// Returns error if: +// - fails to retrieve data from the store. +// - there is no full range liquidity in the pool. +func (k Keeper) GetFullRangeLiquidityInPool(ctx sdk.Context, poolId uint64) (sdk.Dec, error) { store := ctx.KVStore(k.storeKey) poolIdLiquidityKey := types.KeyPoolIdForLiquidity(poolId) - currentTotalFullRangeLiquidity := osmoutils.MustGetDec(store, poolIdLiquidityKey) - return currentTotalFullRangeLiquidity + currentTotalFullRangeLiquidity, err := osmoutils.GetDec(store, poolIdLiquidityKey) + if err != nil { + return sdk.Dec{}, err + } + return currentTotalFullRangeLiquidity, nil } // updateFullRangeLiquidityInPool updates the total liquidity store that is currently in the full range of the pool. diff --git a/x/concentrated-liquidity/position_test.go b/x/concentrated-liquidity/position_test.go index c19ce972247..340ee3e784a 100644 --- a/x/concentrated-liquidity/position_test.go +++ b/x/concentrated-liquidity/position_test.go @@ -1980,7 +1980,8 @@ func (s *KeeperTestSuite) TestGetAndUpdateFullRangeLiquidity() { s.Require().NoError(err) // Get the full range liquidity for the pool. - expectedFullRangeLiquidity := s.App.ConcentratedLiquidityKeeper.MustGetFullRangeLiquidityInPool(s.Ctx, clPoolId) + expectedFullRangeLiquidity, err := s.App.ConcentratedLiquidityKeeper.GetFullRangeLiquidityInPool(s.Ctx, clPoolId) + s.Require().NoError(err) s.Require().Equal(expectedFullRangeLiquidity, actualFullRangeLiquidity) // 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. @@ -1994,7 +1995,8 @@ func (s *KeeperTestSuite) TestGetAndUpdateFullRangeLiquidity() { // Test updating the full range liquidity. err = s.App.ConcentratedLiquidityKeeper.UpdateFullRangeLiquidityInPool(s.Ctx, clPoolId, tc.updateLiquidity) s.Require().NoError(err) - actualFullRangeLiquidity = s.App.ConcentratedLiquidityKeeper.MustGetFullRangeLiquidityInPool(s.Ctx, clPoolId) + actualFullRangeLiquidity, err = s.App.ConcentratedLiquidityKeeper.GetFullRangeLiquidityInPool(s.Ctx, clPoolId) + s.Require().NoError(err) s.Require().Equal(expectedFullRangeLiquidity.Add(tc.updateLiquidity), actualFullRangeLiquidity) } } diff --git a/x/superfluid/keeper/epoch.go b/x/superfluid/keeper/epoch.go index e97dfdd30ee..270f12799e9 100644 --- a/x/superfluid/keeper/epoch.go +++ b/x/superfluid/keeper/epoch.go @@ -145,7 +145,12 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup // get underlying assets from all liquidity in a full range position // note: this is not the same as the total liquidity in the pool, as this includes positions not in the full range bondDenom := k.sk.BondDenom(ctx) - fullRangeLiquidity := k.clk.MustGetFullRangeLiquidityInPool(ctx, poolId) + fullRangeLiquidity, err := k.clk.GetFullRangeLiquidityInPool(ctx, poolId) + if err != nil { + k.Logger(ctx).Error(err.Error()) + k.BeginUnwindSuperfluidAsset(ctx, 0, asset) + return err + } position := model.Position{ LowerTick: cltypes.MinTick, diff --git a/x/superfluid/types/expected_keepers.go b/x/superfluid/types/expected_keepers.go index 3d5ffc0dcaa..24bba8eb954 100644 --- a/x/superfluid/types/expected_keepers.go +++ b/x/superfluid/types/expected_keepers.go @@ -110,7 +110,7 @@ type ConcentratedKeeper interface { CreateFullRangePositionLocked(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins, remainingLockDuration time.Duration) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, concentratedLockID uint64, err error) CreateFullRangePositionUnlocking(ctx sdk.Context, clPoolId uint64, owner sdk.AccAddress, coins sdk.Coins, remainingLockDuration time.Duration) (positionId uint64, amount0, amount1 sdk.Int, liquidity sdk.Dec, joinTime time.Time, concentratedLockID uint64, err error) GetPositionIdToLockId(ctx sdk.Context, underlyingLockId uint64) (uint64, error) - MustGetFullRangeLiquidityInPool(ctx sdk.Context, poolId uint64) sdk.Dec + GetFullRangeLiquidityInPool(ctx sdk.Context, poolId uint64) (sdk.Dec, error) PositionHasActiveUnderlyingLock(ctx sdk.Context, positionId uint64) (bool, uint64, error) HasAnyPositionForPool(ctx sdk.Context, poolId uint64) (bool, error) WithdrawPosition(ctx sdk.Context, owner sdk.AccAddress, positionId uint64, requestedLiquidityAmountToWithdraw sdk.Dec) (amtDenom0, amtDenom1 sdk.Int, err error) From 4f94481a2fe138e1af3ef3dc34dc2ef6b914e9ab Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 00:35:07 +0000 Subject: [PATCH 04/19] updates --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 74afeceadad..1e0a079b79b 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/ory/dockertest/v3 v3.10.0 github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c111 - github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230504190933-b174397f0bc5 + github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7 github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 15e1539e600..a60eb37d311 100644 --- a/go.sum +++ b/go.sum @@ -940,6 +940,8 @@ github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c11 github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c111/go.mod h1:a7lhiXRpn8QJ21OhFpaEnUNErTSIafaYpp02q6uI/Dk= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230504190933-b174397f0bc5 h1:fBzTtgZHxvZkpwlg6YtAsNaexEHYaFZDXsYfPQWu9GE= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230504190933-b174397f0bc5/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= +github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7 h1:HXP40MVuostO+baNgeUBvBu1YVR3SJGOzYVqg6AqsdM= +github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 h1:RIrWLzIiZN5Xd2JOfSOtGZaf6V3qEQYg6EaDTAkMnCo= github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304/go.mod h1:yPWoJTj5RKrXKUChAicp+G/4Ni/uVEpp27mi/FF/L9c= github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627 h1:A0SwZgp4bmJFbivYJc8mmVhMjrr3EdUZluBYFke11+w= From aa051c6020b0bb46584c051ebbda36d1f13bcb64 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 00:39:48 +0000 Subject: [PATCH 05/19] updates --- x/superfluid/keeper/epoch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/superfluid/keeper/epoch.go b/x/superfluid/keeper/epoch.go index 270f12799e9..4c4f461f7f3 100644 --- a/x/superfluid/keeper/epoch.go +++ b/x/superfluid/keeper/epoch.go @@ -149,7 +149,7 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup if err != nil { k.Logger(ctx).Error(err.Error()) k.BeginUnwindSuperfluidAsset(ctx, 0, asset) - return err + return fmt.Errorf("failed to retrieve full range liquidity from pool (%d): %w", poolId, err) } position := model.Position{ From e946c8ceae7aae1568e0ce5046335f758d68633f Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:00:26 +0000 Subject: [PATCH 06/19] revert me --- x/concentrated-liquidity/incentives.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/concentrated-liquidity/incentives.go b/x/concentrated-liquidity/incentives.go index 8613d7f7b89..7010700b4d7 100644 --- a/x/concentrated-liquidity/incentives.go +++ b/x/concentrated-liquidity/incentives.go @@ -330,6 +330,8 @@ func (k Keeper) updatePoolUptimeAccumulatorsToNow(ctx sdk.Context, poolId uint64 return err } + ctx.Logger().Error("HEEEREE") + uptimeAccums, err := k.GetUptimeAccumulators(ctx, poolId) if err != nil { return err From 24993a85500d2073d5fd26fa60351850debeeb59 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:02:09 +0000 Subject: [PATCH 07/19] updates --- x/concentrated-liquidity/incentives.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/concentrated-liquidity/incentives.go b/x/concentrated-liquidity/incentives.go index 7010700b4d7..0f9acaddfcb 100644 --- a/x/concentrated-liquidity/incentives.go +++ b/x/concentrated-liquidity/incentives.go @@ -330,8 +330,6 @@ func (k Keeper) updatePoolUptimeAccumulatorsToNow(ctx sdk.Context, poolId uint64 return err } - ctx.Logger().Error("HEEEREE") - uptimeAccums, err := k.GetUptimeAccumulators(ctx, poolId) if err != nil { return err @@ -352,6 +350,8 @@ func (k Keeper) updatePoolUptimeAccumulatorsToNow(ctx sdk.Context, poolId uint64 continue } + ctx.Logger().Error("uptime index", uptimeIndex) + incentivesToAddToCurAccum, updatedPoolRecords, err := calcAccruedIncentivesForAccum(ctx, curUptimeDuration, qualifyingLiquidity, timeElapsedSec, poolIncentiveRecords) if err != nil { return err From 21abb277a0482839f514def8d02201d66e6162d4 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:04:32 +0000 Subject: [PATCH 08/19] debug --- x/concentrated-liquidity/incentives.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/concentrated-liquidity/incentives.go b/x/concentrated-liquidity/incentives.go index 0f9acaddfcb..58b0e324da3 100644 --- a/x/concentrated-liquidity/incentives.go +++ b/x/concentrated-liquidity/incentives.go @@ -350,8 +350,6 @@ func (k Keeper) updatePoolUptimeAccumulatorsToNow(ctx sdk.Context, poolId uint64 continue } - ctx.Logger().Error("uptime index", uptimeIndex) - incentivesToAddToCurAccum, updatedPoolRecords, err := calcAccruedIncentivesForAccum(ctx, curUptimeDuration, qualifyingLiquidity, timeElapsedSec, poolIncentiveRecords) if err != nil { return err @@ -826,6 +824,8 @@ func (k Keeper) claimAllIncentivesForPosition(ctx sdk.Context, positionId uint64 return sdk.Coins{}, sdk.Coins{}, err } + ctx.Logger().Error("HEEERE", "uptimeIndex", uptimeIndex) + // If the accumulator contains the position, claim the position's incentives. if hasPosition { collectedIncentivesForUptime, dust, err := prepareAccumAndClaimRewards(uptimeAccum, positionName, uptimeGrowthOutside[uptimeIndex]) From b422ece2bc0c1546e796af64aa907fe18c75f67d Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:51:00 +0000 Subject: [PATCH 09/19] docs --- x/superfluid/README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/x/superfluid/README.md b/x/superfluid/README.md index 8ff1f497b9a..1eac015e602 100644 --- a/x/superfluid/README.md +++ b/x/superfluid/README.md @@ -376,6 +376,43 @@ It then mints concentrated liquidity shares and locks them up for the staking duration. From there, the normal superfluid delegation logic is executed. +## Add To Superfluid Concentrated Position + +This message allows a user to add liquidity to a concentrated liquidity position. + +```{.go} +type MsgAddToConcentratedLiquiditySuperfluidPosition struct { + PositionId uint64 + Sender string + TokenDesired0 types.Coin + TokenDesired1 types.Coin +} +``` + +It does so by performing the following steps: +- perform validation of the input parameters + * make sure that position is locked + * belongs to the sender + * lock duration is correct and belongs to the sender +- superfluid undelegate without synthetic lock creation +- withdraw old position +- make sure position isn't the last one in pool. Fail if so +- update tokens for a new position (added + withdrawn) +- created locked SF position +- SF delegate (also creates synth lock) + +Upon successful execution, the following response is given: + +```{.go} +type MsgAddToConcentratedLiquiditySuperfluidPositionResponse struct { + PositionId uint64 + Amount0 github_com_cosmos_cosmos_sdk_types.Int + Amount1 github_com_cosmos_cosmos_sdk_types.Int + NewLiquidity github_com_cosmos_cosmos_sdk_types.Dec + LockId uint64 +} +``` + ## Epochs Overall Epoch sequence From 615fa4fcbe56759d8b0744609989fb1c51652dd7 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:53:06 +0000 Subject: [PATCH 10/19] go sum --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index a60eb37d311..b4df7a78b6a 100644 --- a/go.sum +++ b/go.sum @@ -938,8 +938,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.3-dev.0.20230503232557-ba905586c111 h1:1ahWbf9iF9sxDOjxrHWFaBGLE0nWFdpiX1pqObUaJO8= github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c111/go.mod h1:a7lhiXRpn8QJ21OhFpaEnUNErTSIafaYpp02q6uI/Dk= -github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230504190933-b174397f0bc5 h1:fBzTtgZHxvZkpwlg6YtAsNaexEHYaFZDXsYfPQWu9GE= -github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230504190933-b174397f0bc5/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7 h1:HXP40MVuostO+baNgeUBvBu1YVR3SJGOzYVqg6AqsdM= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 h1:RIrWLzIiZN5Xd2JOfSOtGZaf6V3qEQYg6EaDTAkMnCo= From 5cd8956500f2d2182960c679ee1871f342a272ce Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:54:21 +0000 Subject: [PATCH 11/19] go mod --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1e0a079b79b..06504731330 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/ory/dockertest/v3 v3.10.0 github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c111 - github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7 + github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511015306-615fa4fcbe56 github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index b4df7a78b6a..407e0efb457 100644 --- a/go.sum +++ b/go.sum @@ -940,6 +940,8 @@ github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c11 github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230503232557-ba905586c111/go.mod h1:a7lhiXRpn8QJ21OhFpaEnUNErTSIafaYpp02q6uI/Dk= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7 h1:HXP40MVuostO+baNgeUBvBu1YVR3SJGOzYVqg6AqsdM= github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511003156-c5580b4c8eb7/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= +github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511015306-615fa4fcbe56 h1:27yWLC0uXSatRy8aRn0yinHU+K31bkjBRmNnQUDO0Ks= +github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230511015306-615fa4fcbe56/go.mod h1:hk/o9/kmTSZmZqwXcSrPuwj/gpRMCqbE/d3vj6teL2A= github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 h1:RIrWLzIiZN5Xd2JOfSOtGZaf6V3qEQYg6EaDTAkMnCo= github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304/go.mod h1:yPWoJTj5RKrXKUChAicp+G/4Ni/uVEpp27mi/FF/L9c= github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230331072320-5d6f6cfa2627 h1:A0SwZgp4bmJFbivYJc8mmVhMjrr3EdUZluBYFke11+w= From 9a3a9d564f7adeac211189ab73572b582010d2e3 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 11 May 2023 01:55:45 +0000 Subject: [PATCH 12/19] remove --- x/concentrated-liquidity/incentives.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/concentrated-liquidity/incentives.go b/x/concentrated-liquidity/incentives.go index 99029fa854c..43af2160a30 100644 --- a/x/concentrated-liquidity/incentives.go +++ b/x/concentrated-liquidity/incentives.go @@ -824,8 +824,6 @@ func (k Keeper) claimAllIncentivesForPosition(ctx sdk.Context, positionId uint64 return sdk.Coins{}, sdk.Coins{}, err } - ctx.Logger().Error("HEEERE", "uptimeIndex", uptimeIndex) - // If the accumulator contains the position, claim the position's incentives. if hasPosition { collectedIncentivesForUptime, dust, err := prepareAccumAndClaimRewards(uptimeAccum, positionName, uptimeGrowthOutside[uptimeIndex]) From 402eb2576ec9b299776f36a8be1663e574ac1201 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 10 May 2023 21:58:05 -0400 Subject: [PATCH 13/19] Update x/superfluid/README.md --- x/superfluid/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/superfluid/README.md b/x/superfluid/README.md index 1eac015e602..1f4c3a646d7 100644 --- a/x/superfluid/README.md +++ b/x/superfluid/README.md @@ -378,7 +378,7 @@ is executed. ## Add To Superfluid Concentrated Position -This message allows a user to add liquidity to a concentrated liquidity position. +This message allows a user to add liquidity to a concentrated liquidity superfluid position. ```{.go} type MsgAddToConcentratedLiquiditySuperfluidPosition struct { From ccc2d88b91311df20f2c7312deb0b70ed96f4ac6 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 10 May 2023 21:58:43 -0400 Subject: [PATCH 14/19] Update x/concentrated-liquidity/position.go --- x/concentrated-liquidity/position.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/position.go b/x/concentrated-liquidity/position.go index eab02814bbf..b7d50b2a5e5 100644 --- a/x/concentrated-liquidity/position.go +++ b/x/concentrated-liquidity/position.go @@ -396,7 +396,7 @@ func (k Keeper) mintSharesAndLock(ctx sdk.Context, concentratedPoolId, positionI // Note, the end blocker for the lockup module contains an exception for this CL denom. When a lock with a denom of cl/pool/{poolId} is mature, // it does not send the coins to the owner account but instead burns them. // This is implemented in such a way to use well-tested pre-existing methods rather than - // completely re-implementing concentrated liquidity superfluid infrastructure that has a riks of introducing bugs with new logic and methods. + // completely re-implementing concentrated liquidity superfluid infrastructure that has a risk of introducing bugs with new logic and methods. concentratedLock, err := k.lockupKeeper.CreateLock(ctx, owner, underlyingLiquidityTokenized, remainingLockDuration) if err != nil { return 0, sdk.Coins{}, err From 19c92c226489a16d290411ffafad536ab8d46876 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 May 2023 16:43:21 -0400 Subject: [PATCH 15/19] comment --- proto/osmosis/superfluid/tx.proto | 3 +++ x/superfluid/types/tx.pb.go | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/proto/osmosis/superfluid/tx.proto b/proto/osmosis/superfluid/tx.proto index eb2e46cdea2..1a4301eb6d4 100644 --- a/proto/osmosis/superfluid/tx.proto +++ b/proto/osmosis/superfluid/tx.proto @@ -204,6 +204,9 @@ message MsgAddToConcentratedLiquiditySuperfluidPositionResponse { (gogoproto.moretags) = "yaml:\"amount1\"", (gogoproto.nullable) = false ]; + // new_liquidity is the final liquidity after the add. + // It includes the liquidity that existed before in the position + // and the new liquidity that was added to the position. string new_liquidity = 5 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.moretags) = "yaml:\"new_liquidity\"", diff --git a/x/superfluid/types/tx.pb.go b/x/superfluid/types/tx.pb.go index 295f658c894..1d8fa701c2f 100644 --- a/x/superfluid/types/tx.pb.go +++ b/x/superfluid/types/tx.pb.go @@ -959,9 +959,12 @@ func (m *MsgAddToConcentratedLiquiditySuperfluidPosition) GetTokenDesired1() typ } type MsgAddToConcentratedLiquiditySuperfluidPositionResponse struct { - PositionId uint64 `protobuf:"varint,1,opt,name=position_id,json=positionId,proto3" json:"position_id,omitempty" yaml:"position_id"` - Amount0 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount0,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount0" yaml:"amount0"` - Amount1 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=amount1,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount1" yaml:"amount1"` + PositionId uint64 `protobuf:"varint,1,opt,name=position_id,json=positionId,proto3" json:"position_id,omitempty" yaml:"position_id"` + Amount0 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount0,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount0" yaml:"amount0"` + Amount1 github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=amount1,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount1" yaml:"amount1"` + // new_liquidity is the final liquidity after the add. + // It includes the liquidity that existed before in the position + // and the new liquidity that was added to the position. NewLiquidity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=new_liquidity,json=newLiquidity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"new_liquidity" yaml:"new_liquidity"` LockId uint64 `protobuf:"varint,4,opt,name=lock_id,json=lockId,proto3" json:"lock_id,omitempty" yaml:"lock_id"` } From facba8a1b9b814e9839f37b2abd458c8d343447b Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 May 2023 16:44:41 -0400 Subject: [PATCH 16/19] coins --- x/concentrated-liquidity/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/client/cli/tx.go b/x/concentrated-liquidity/client/cli/tx.go index 05b8683fdae..3f750d23c33 100644 --- a/x/concentrated-liquidity/client/cli/tx.go +++ b/x/concentrated-liquidity/client/cli/tx.go @@ -49,7 +49,7 @@ func NewCreateConcentratedPoolCmd() (*osmocli.TxCliDesc, *clmodel.MsgCreateConce func NewCreatePositionCmd() (*osmocli.TxCliDesc, *types.MsgCreatePosition) { return &osmocli.TxCliDesc{ - Use: "create-position [pool-id] [lower-tick] [upper-tick] [token-0-coin,token-1-coin] [token-0-min-amount] [token-1-min-amount]", + Use: "create-position [pool-id] [lower-tick] [upper-tick] [coins] [token-0-min-amount] [token-1-min-amount]", Short: "create or add to existing concentrated liquidity position", Example: "create-position 1 \"[-69082]\" 69082 1000000000uosmo,10000000uion 0 0 --from val --chain-id osmosis-1", }, &types.MsgCreatePosition{} From 09af62bd8827711201c68591906c5048aa1669cd Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 May 2023 16:45:22 -0400 Subject: [PATCH 17/19] remove Q --- x/concentrated-liquidity/position.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/concentrated-liquidity/position.go b/x/concentrated-liquidity/position.go index e20409a807d..420d14065d9 100644 --- a/x/concentrated-liquidity/position.go +++ b/x/concentrated-liquidity/position.go @@ -378,8 +378,6 @@ func (k Keeper) mintSharesAndLock(ctx sdk.Context, concentratedPoolId, positionI } // Create a coin object to represent the underlying liquidity for the cl position. - // Q: what is the impact of this on slashing or anything else. I think truncating liqudiity even slightly might cause the final token amount difference - // to end up being quite large. I think the risk of this is offset but superfluid risk factor but would like to confirm. underlyingLiquidityTokenized = sdk.NewCoins(sdk.NewCoin(types.GetConcentratedLockupDenomFromPoolId(concentratedPoolId), position.Liquidity.TruncateInt())) // Mint the underlying liquidity as a token and send to the owner. From 8599d6afab418b5ac0aba157f3dd10871ded09af Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 May 2023 16:47:18 -0400 Subject: [PATCH 18/19] remove Q --- x/superfluid/keeper/slash.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/superfluid/keeper/slash.go b/x/superfluid/keeper/slash.go index 88f1d7e0fa9..3c84844281c 100644 --- a/x/superfluid/keeper/slash.go +++ b/x/superfluid/keeper/slash.go @@ -110,8 +110,6 @@ func (k Keeper) prepareConcentratedLockForSlash(ctx sdk.Context, lock *lockuptyp return sdk.AccAddress{}, sdk.Coins{}, err } - // Q: this would make the amounts calculated in alculateUnderlyingAssetsFromPosition - // be rounded down. Is this fine? I think yes, should be minimal impact. slashAmtNeg := slashAmt.Neg() // If slashAmt is not negative, return an error From 183cf834b6eff83e095078c1f5f50a0cc768d5a6 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 May 2023 17:11:05 -0400 Subject: [PATCH 19/19] revert name --- x/superfluid/keeper/concentrated_liquidity.go | 2 +- x/superfluid/keeper/migrate.go | 2 +- x/superfluid/keeper/stake.go | 4 ++-- x/superfluid/keeper/stake_test.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/superfluid/keeper/concentrated_liquidity.go b/x/superfluid/keeper/concentrated_liquidity.go index bac8d9a3624..6669ec47f8e 100644 --- a/x/superfluid/keeper/concentrated_liquidity.go +++ b/x/superfluid/keeper/concentrated_liquidity.go @@ -76,7 +76,7 @@ func (k Keeper) addToConcentratedLiquiditySuperfluidPosition(ctx sdk.Context, se // Superfluid undelegate the superfluid delegated position. // This deletes the connection between the lock and the intermediate account, deletes the synthetic lock, and burns the synthetic osmo. - intermediateAccount, err := k.SuperfluidForceUndelegate(ctx, sender.String(), lockId) + intermediateAccount, err := k.SuperfluidUndelegateToConcentratedPosition(ctx, sender.String(), lockId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, 0, err } diff --git a/x/superfluid/keeper/migrate.go b/x/superfluid/keeper/migrate.go index d3ae969ad29..2e34469df40 100644 --- a/x/superfluid/keeper/migrate.go +++ b/x/superfluid/keeper/migrate.go @@ -66,7 +66,7 @@ func (k Keeper) migrateSuperfluidBondedBalancerToConcentrated(ctx sdk.Context, // Superfluid undelegate the superfluid delegated position. // This deletes the connection between the lock and the intermediate account, deletes the synthetic lock, and burns the synthetic osmo. - intermediateAccount, err := k.SuperfluidForceUndelegate(ctx, sender.String(), lockId) + intermediateAccount, err := k.SuperfluidUndelegateToConcentratedPosition(ctx, sender.String(), lockId) if err != nil { return 0, sdk.Int{}, sdk.Int{}, sdk.Dec{}, time.Time{}, 0, 0, err } diff --git a/x/superfluid/keeper/stake.go b/x/superfluid/keeper/stake.go index c2c9f6cca0a..8ead741735f 100644 --- a/x/superfluid/keeper/stake.go +++ b/x/superfluid/keeper/stake.go @@ -300,11 +300,11 @@ func (k Keeper) SuperfluidUndelegate(ctx sdk.Context, sender string, lockID uint return k.createSyntheticLockup(ctx, lockID, intermediaryAcc, unlockingStatus) } -// SuperfluidForceUndelegate starts undelegating superfluid delegated position for the given lock. It behaves similarly to SuperfluidUndelegate, +// SuperfluidUndelegateToConcentratedPosition starts undelegating superfluid delegated position for the given lock. It behaves similarly to SuperfluidUndelegate, // however it does not create a new synthetic lockup representing the unstaking side. This is because after the time this function is called, we might // want to perform more operations prior to creating a lock. Once the actual lock is created, the synthetic lockup representing the unstaking side // should eventually be created as well. Use thi function with caution to avoid accidentally missing synthetic lock creation. -func (k Keeper) SuperfluidForceUndelegate(ctx sdk.Context, sender string, gammLockID uint64) (types.SuperfluidIntermediaryAccount, error) { +func (k Keeper) SuperfluidUndelegateToConcentratedPosition(ctx sdk.Context, sender string, gammLockID uint64) (types.SuperfluidIntermediaryAccount, error) { return k.undelegateCommon(ctx, sender, gammLockID) } diff --git a/x/superfluid/keeper/stake_test.go b/x/superfluid/keeper/stake_test.go index 962e6300c06..7ab49d396c4 100644 --- a/x/superfluid/keeper/stake_test.go +++ b/x/superfluid/keeper/stake_test.go @@ -529,7 +529,7 @@ func (suite *KeeperTestSuite) TestSuperfluidUndelegateToConcentratedPosition() { presupplyWithOffset := suite.App.BankKeeper.GetSupplyWithOffset(suite.Ctx, bondDenom) // superfluid undelegate - _, err = suite.App.SuperfluidKeeper.SuperfluidForceUndelegate(suite.Ctx, lock.Owner, lockId) + _, err = suite.App.SuperfluidKeeper.SuperfluidUndelegateToConcentratedPosition(suite.Ctx, lock.Owner, lockId) if tc.expSuperUnbondingErr[index] { suite.Require().Error(err) continue @@ -584,7 +584,7 @@ func (suite *KeeperTestSuite) TestSuperfluidUndelegateToConcentratedPosition() { lock, err := suite.App.LockupKeeper.GetLockByID(suite.Ctx, lockId) suite.Require().NoError(err) - _, err = suite.App.SuperfluidKeeper.SuperfluidForceUndelegate(suite.Ctx, lock.Owner, lockId) + _, err = suite.App.SuperfluidKeeper.SuperfluidUndelegateToConcentratedPosition(suite.Ctx, lock.Owner, lockId) suite.Require().Error(err) } })