From 5f84120c518eddce18a0c726d37ba7805a98e495 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Aug 2023 15:31:04 +0200 Subject: [PATCH 01/13] linter: max return values --- .golangci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index 4e92b01dbea..991c69e9ab1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -41,6 +41,15 @@ linters: - unused - whitespace - unparam + - revive + +linters-settings: + revive: + rules: + - name: function-result-limit + severity: warning + disabled: false + arguments: [4] issues: exclude-rules: From 7ba7746799ee6038dc505a51da7b6925b2c9e97d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 16 Aug 2023 15:03:30 +0200 Subject: [PATCH 02/13] updates --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 991c69e9ab1..3677e10d9c9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,7 +9,7 @@ linters: enable: - asciicheck - bidichk - - depguard + # - depguard - durationcheck - errcheck - errname From fc6cca97ff9cd535cfa5cac7ac176c119bfee27c Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 13:45:43 +0200 Subject: [PATCH 03/13] fix all linter errors --- .golangci.yml | 2 +- app/upgrades/v17/upgrades.go | 44 +++++--- tests/e2e/configurer/chain/queries.go | 24 +++- tests/e2e/e2e_test.go | 9 +- x/concentrated-liquidity/export_test.go | 4 +- .../simulation/sim_msgs.go | 80 +++++++++----- x/concentrated-liquidity/swaps.go | 104 ++++++++++-------- x/concentrated-liquidity/swaps_test.go | 34 +++--- x/gamm/simulation/sim_msgs.go | 54 +++++---- x/twap/client/cli/query.go | 54 +++++---- 10 files changed, 249 insertions(+), 160 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 3677e10d9c9..991c69e9ab1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,7 +9,7 @@ linters: enable: - asciicheck - bidichk - # - depguard + - depguard - durationcheck - errcheck - errname diff --git a/app/upgrades/v17/upgrades.go b/app/upgrades/v17/upgrades.go index 9e4e8718275..efe92b64fcd 100644 --- a/app/upgrades/v17/upgrades.go +++ b/app/upgrades/v17/upgrades.go @@ -26,6 +26,14 @@ import ( poolmanagertypes "github.com/osmosis-labs/osmosis/v19/x/poolmanager/types" ) +// clPoolCreationInfo encapsulates the returns from CL pool +// creation function. +type clPoolCreationInfo struct { + id uint64 + denom string + migrationLink gammmigration.BalancerToConcentratedPoolLink +} + const ( mainnetChainID = "osmosis-1" e2eChainA = "osmo-test-a" @@ -82,7 +90,7 @@ func CreateUpgradeHandler( fullRangeCoinsUsed := sdk.Coins{} for _, assetPair := range assetPairs { - clPoolDenom, clPoolId, poolLink, coinsUsed, err := createCLPoolWithCommunityPoolPosition(ctx, keepers, assetPair, communityPoolAddress) + clPoolCreationInfo, coinsUsed, err := createCLPoolWithCommunityPoolPosition(ctx, keepers, assetPair, communityPoolAddress) if errors.Is(err, notEnoughLiquidityForSwapErr) { continue } else if err != nil { @@ -90,18 +98,18 @@ func CreateUpgradeHandler( } // Track pool link created and coins used for the community pool. - poolLinks = append(poolLinks, poolLink) + poolLinks = append(poolLinks, clPoolCreationInfo.migrationLink) fullRangeCoinsUsed = fullRangeCoinsUsed.Add(coinsUsed...) if assetPair.Superfluid { - ctx.Logger().Info(fmt.Sprintf("gammPoolId %d is superfluid enabled, enabling %s as a superfluid asset", assetPair.LinkedClassicPool, clPoolDenom)) - err := authorizeSuperfluid(ctx, keepers, clPoolDenom) + ctx.Logger().Info(fmt.Sprintf("gammPoolId %d is superfluid enabled, enabling %s as a superfluid asset", assetPair.LinkedClassicPool, clPoolCreationInfo.denom)) + err := authorizeSuperfluid(ctx, keepers, clPoolCreationInfo.denom) if err != nil { return nil, err } } - err = manuallySetTWAPRecords(ctx, keepers, clPoolId) + err = manuallySetTWAPRecords(ctx, keepers, clPoolCreationInfo.id) if err != nil { return nil, err } @@ -138,7 +146,7 @@ func CreateUpgradeHandler( } // createCLPoolWithCommunityPoolPosition creates a CL pool for a given balancer pool and adds a full range position with the community pool. -func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.AppKeepers, assetPair AssetPair, communityPoolAddress sdk.AccAddress) (clPoolDenom string, clPoolId uint64, poolLink gammmigration.BalancerToConcentratedPoolLink, coinsUsed sdk.Coins, err error) { +func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.AppKeepers, assetPair AssetPair, communityPoolAddress sdk.AccAddress) (clPoolCreationInfo, sdk.Coins, error) { // Determine if base or quote asset is OSMO and save the non-OSMO asset. osmoIn := sdk.NewCoin(OSMO, sdk.NewInt(100000)) nonOsmoAsset := "" @@ -152,24 +160,24 @@ func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.App // If not, skip the pool. linkedClassicPool, err := keepers.PoolManagerKeeper.GetPool(ctx, assetPair.LinkedClassicPool) if err != nil { - return "", 0, gammmigration.BalancerToConcentratedPoolLink{}, nil, err + return clPoolCreationInfo{}, sdk.Coins{}, err } _, err = keepers.GAMMKeeper.CalcOutAmtGivenIn(ctx, linkedClassicPool, osmoIn, nonOsmoAsset, assetPair.SpreadFactor) if err != nil { - return "", 0, gammmigration.BalancerToConcentratedPoolLink{}, nil, err + return clPoolCreationInfo{}, sdk.Coins{}, err } // Create a concentrated liquidity pool for asset pair. ctx.Logger().Info(fmt.Sprintf("Creating CL pool from poolID (%d), baseAsset (%s), quoteAsset (%s) spreadFactor (%s), tickSpacing (%d)", assetPair.LinkedClassicPool, assetPair.BaseAsset, assetPair.QuoteAsset, assetPair.SpreadFactor, TickSpacing)) clPool, err := keepers.GAMMKeeper.CreateConcentratedPoolFromCFMM(ctx, assetPair.LinkedClassicPool, assetPair.BaseAsset, assetPair.SpreadFactor, TickSpacing) if err != nil { - return "", 0, gammmigration.BalancerToConcentratedPoolLink{}, nil, err + return clPoolCreationInfo{}, sdk.Coins{}, err } - clPoolId = clPool.GetId() - clPoolDenom = cltypes.GetConcentratedLockupDenomFromPoolId(clPoolId) + clPoolId := clPool.GetId() + clPoolDenom := cltypes.GetConcentratedLockupDenomFromPoolId(clPoolId) // Create pool link object. - poolLink = gammmigration.BalancerToConcentratedPoolLink{ + poolLink := gammmigration.BalancerToConcentratedPoolLink{ BalancerPoolId: assetPair.LinkedClassicPool, ClPoolId: clPoolId, } @@ -182,7 +190,7 @@ func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.App // Swap 0.1 OSMO for nonOsmoAsset from the community pool. respectiveNonOsmoAssetInt, err := keepers.GAMMKeeper.SwapExactAmountIn(ctx, communityPoolAddress, linkedClassicPool, osmoIn, nonOsmoAsset, sdk.ZeroInt(), linkedClassicPool.GetSpreadFactor(ctx)) if err != nil { - return "", 0, gammmigration.BalancerToConcentratedPoolLink{}, nil, err + return clPoolCreationInfo{}, sdk.Coins{}, err } ctx.Logger().Info(fmt.Sprintf("Swapped %s for %s%s from the community pool", osmoIn.String(), respectiveNonOsmoAssetInt.String(), nonOsmoAsset)) @@ -192,7 +200,7 @@ func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.App fullRangeCoins := sdk.NewCoins(respectiveNonOsmoAsset, osmoIn) _, err = keepers.ConcentratedLiquidityKeeper.CreateFullRangePosition(ctx, clPoolId, communityPoolAddress, fullRangeCoins) if err != nil { - return "", 0, gammmigration.BalancerToConcentratedPoolLink{}, nil, err + return clPoolCreationInfo{}, sdk.Coins{}, err } // Get community pool balance after swap and position creation @@ -203,9 +211,13 @@ func createCLPoolWithCommunityPoolPosition(ctx sdk.Context, keepers *keepers.App // While we can be fairly certain the diff between these two is 0.2 OSMO, if for whatever reason // some baseAsset dust remains in the community pool and we don't account for it, when updating the // fee pool balance later, we will be off by that amount and will cause a panic. - coinsUsed = commPoolBalancePre.Sub(commPoolBalancePost) + coinsUsed := commPoolBalancePre.Sub(commPoolBalancePost) - return clPoolDenom, clPoolId, poolLink, coinsUsed, nil + return clPoolCreationInfo{ + id: clPoolId, + denom: clPoolDenom, + migrationLink: poolLink, + }, coinsUsed, nil } // authorizeSuperfluid authorizes superfluid for the provided CL pool. diff --git a/tests/e2e/configurer/chain/queries.go b/tests/e2e/configurer/chain/queries.go index f2b6341aa52..d2bd0808a00 100644 --- a/tests/e2e/configurer/chain/queries.go +++ b/tests/e2e/configurer/chain/queries.go @@ -32,6 +32,14 @@ import ( epochstypes "github.com/osmosis-labs/osmosis/x/epochs/types" ) +// PropTallyResult is the result of a proposal tally. +type PropTallyResult struct { + Yes sdk.Int + No sdk.Int + Abstain sdk.Int + NoWithVeto sdk.Int +} + // QueryProtoRevNumberOfTrades gets the number of trades the protorev module has executed. func (n *NodeConfig) QueryProtoRevNumberOfTrades() (sdk.Int, error) { path := "/osmosis/protorev/number_of_trades" @@ -443,21 +451,31 @@ func (n *NodeConfig) QueryWasmSmartArray(contract string, msg string) (resultArr return resultArray, nil } -func (n *NodeConfig) QueryPropTally(proposalNumber int) (sdk.Int, sdk.Int, sdk.Int, sdk.Int, error) { +func (n *NodeConfig) QueryPropTally(proposalNumber int) (PropTallyResult, error) { path := fmt.Sprintf("cosmos/gov/v1beta1/proposals/%d/tally", proposalNumber) bz, err := n.QueryGRPCGateway(path) require.NoError(n.t, err) var balancesResp govtypes.QueryTallyResultResponse if err := util.Cdc.UnmarshalJSON(bz, &balancesResp); err != nil { - return sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt(), err + return PropTallyResult{ + Yes: sdk.ZeroInt(), + No: sdk.ZeroInt(), + Abstain: sdk.ZeroInt(), + NoWithVeto: sdk.ZeroInt(), + }, err } noTotal := balancesResp.Tally.No yesTotal := balancesResp.Tally.Yes noWithVetoTotal := balancesResp.Tally.NoWithVeto abstainTotal := balancesResp.Tally.Abstain - return noTotal, yesTotal, noWithVetoTotal, abstainTotal, nil + return PropTallyResult{ + Yes: yesTotal, + No: noTotal, + Abstain: abstainTotal, + NoWithVeto: noWithVetoTotal, + }, nil } func (n *NodeConfig) QueryPropStatus(proposalNumber int) (string, error) { diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 50cc840d3c4..13d0adefe17 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1038,11 +1038,11 @@ func (s *IntegrationTestSuite) SuperfluidVoting() { s.Eventually( func() bool { - noTotal, yesTotal, noWithVetoTotal, abstainTotal, err := chainABNode.QueryPropTally(propNumber) + propTally, err := chainABNode.QueryPropTally(propNumber) if err != nil { return false } - if abstainTotal.Int64()+noTotal.Int64()+noWithVetoTotal.Int64()+yesTotal.Int64() <= 0 { + if propTally.Abstain.Int64()+propTally.No.Int64()+propTally.NoWithVeto.Int64()+propTally.Yes.Int64() <= 0 { return false } return true @@ -1051,8 +1051,9 @@ func (s *IntegrationTestSuite) SuperfluidVoting() { 10*time.Millisecond, "Osmosis node failed to retrieve prop tally", ) - noTotal, _, _, _, _ := chainABNode.QueryPropTally(propNumber) - noTotalFinal, err := strconv.Atoi(noTotal.String()) + propTally, err := chainABNode.QueryPropTally(propNumber) + s.Require().NoError(err) + noTotalFinal, err := strconv.Atoi(propTally.No.String()) s.NoError(err) s.Eventually( diff --git a/x/concentrated-liquidity/export_test.go b/x/concentrated-liquidity/export_test.go index 505d70776a5..fa513af194e 100644 --- a/x/concentrated-liquidity/export_test.go +++ b/x/concentrated-liquidity/export_test.go @@ -72,7 +72,7 @@ func (k Keeper) ComputeOutAmtGivenIn( spreadFactor sdk.Dec, priceLimit sdk.Dec, -) (calcTokenIn, calcTokenOut sdk.Coin, poolUpdates PoolUpdates, totalSpreadRewards sdk.Dec, err error) { +) (swapResult SwapResult, poolUpdates PoolUpdates, err error) { return k.computeOutAmtGivenIn(ctx, poolId, tokenInMin, tokenOutDenom, spreadFactor, priceLimit) } @@ -95,7 +95,7 @@ func (k Keeper) ComputeInAmtGivenOut( priceLimit sdk.Dec, poolId uint64, -) (calcTokenIn, calcTokenOut sdk.Coin, poolUpdates PoolUpdates, totalSpreadRewards sdk.Dec, err error) { +) (swapResult SwapResult, poolUpdates PoolUpdates, err error) { return k.computeInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, spreadFactor, priceLimit, poolId) } diff --git a/x/concentrated-liquidity/simulation/sim_msgs.go b/x/concentrated-liquidity/simulation/sim_msgs.go index 757fa5df113..91d15706386 100644 --- a/x/concentrated-liquidity/simulation/sim_msgs.go +++ b/x/concentrated-liquidity/simulation/sim_msgs.go @@ -17,10 +17,25 @@ import ( minttypes "github.com/osmosis-labs/osmosis/v19/x/mint/types" ) +type preparePoolConfig struct { + creator sdk.AccAddress + coin0 sdk.Coin + coin1 sdk.Coin + tickSpacing uint64 + spreadFactor sdk.Dec +} + +type preparePositionConfig struct { + owner sdk.AccAddress + tokens sdk.Coins + lowerTick int64 + upperTick int64 +} + var PoolCreationFee = sdk.NewInt64Coin("stake", 10_000_000) func RandomMsgCreateConcentratedPool(k clkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk.Context) (*clmodeltypes.MsgCreateConcentratedPool, error) { - poolCreator, coin0, coin1, tickSpacing, spreadFactor, err := RandomPreparePoolFunc(sim, ctx, k) + preparePoolInfo, err := RandomPreparePoolFunc(sim, ctx, k) if err != nil { return nil, err } @@ -50,11 +65,11 @@ func RandomMsgCreateConcentratedPool(k clkeeper.Keeper, sim *osmosimtypes.SimCtx } return &clmodeltypes.MsgCreateConcentratedPool{ - Sender: poolCreator.String(), - Denom0: coin0.Denom, - Denom1: coin1.Denom, - TickSpacing: tickSpacing, - SpreadFactor: spreadFactor, + Sender: preparePoolInfo.creator.String(), + Denom0: preparePoolInfo.coin0.Denom, + Denom1: preparePoolInfo.coin1.Denom, + TickSpacing: preparePoolInfo.tickSpacing, + SpreadFactor: preparePoolInfo.spreadFactor, }, nil } @@ -65,28 +80,28 @@ func RandMsgCreatePosition(k clkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk. return nil, err } - positionCreator, tokens, lowerTick, upperTick, err := RandomPrepareCreatePositionFunc(sim, ctx, clPool, poolDenoms) + preparePositionConfig, err := RandomPrepareCreatePositionFunc(sim, ctx, clPool, poolDenoms) if err != nil { return nil, err } - token0Desired := tokens.AmountOf(clPool.GetToken0()) - token1Desired := tokens.AmountOf(clPool.GetToken1()) + token0Desired := preparePositionConfig.tokens.AmountOf(clPool.GetToken0()) + token1Desired := preparePositionConfig.tokens.AmountOf(clPool.GetToken1()) tokenMinAmount0, tokenMinAmount1 := RandomMinAmount(sim, token0Desired, token1Desired) - accountBalancePoolDenom0 := sim.BankKeeper().GetBalance(ctx, positionCreator, poolDenoms[0]) - accountBalancePoolDenom1 := sim.BankKeeper().GetBalance(ctx, positionCreator, poolDenoms[1]) - if accountBalancePoolDenom0.Amount.LT(tokens[0].Amount) || accountBalancePoolDenom1.Amount.LT(tokens[1].Amount) { + accountBalancePoolDenom0 := sim.BankKeeper().GetBalance(ctx, preparePositionConfig.owner, poolDenoms[0]) + accountBalancePoolDenom1 := sim.BankKeeper().GetBalance(ctx, preparePositionConfig.owner, poolDenoms[1]) + if accountBalancePoolDenom0.Amount.LT(preparePositionConfig.tokens[0].Amount) || accountBalancePoolDenom1.Amount.LT(preparePositionConfig.tokens[1].Amount) { return nil, fmt.Errorf("insufficient funds when creating a concentrated position") } return &cltypes.MsgCreatePosition{ PoolId: clPool.GetId(), - Sender: positionCreator.String(), - LowerTick: lowerTick, - UpperTick: upperTick, - TokensProvided: tokens, + Sender: preparePositionConfig.owner.String(), + LowerTick: preparePositionConfig.lowerTick, + UpperTick: preparePositionConfig.upperTick, + TokensProvided: preparePositionConfig.tokens, TokenMinAmount0: tokenMinAmount0, TokenMinAmount1: tokenMinAmount1, }, nil @@ -325,7 +340,7 @@ func RandomTickDivisibility(sim *osmosimtypes.SimCtx, minTick int64, maxTick int return int64(-1), nil } -func RandomPreparePoolFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, k clkeeper.Keeper) (sdk.AccAddress, sdk.Coin, sdk.Coin, uint64, sdk.Dec, error) { +func RandomPreparePoolFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, k clkeeper.Keeper) (preparePoolConfig, error) { rand := sim.GetRand() authorizedTickSpacing := cltypes.AuthorizedTickSpacing @@ -334,22 +349,22 @@ func RandomPreparePoolFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, k clkeeper // find an address with two or more distinct denoms in their wallet sender, senderExists := sim.RandomSimAccountWithConstraint(createPoolRestriction(sim, ctx)) if !senderExists { - return nil, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, fmt.Errorf("no sender with two different denoms & pool creation fee exists") + return preparePoolConfig{}, fmt.Errorf("no sender with two different denoms & pool creation fee exists") } // get random 3 coins, use 2 to create pool and 1 for fees (stake denom). poolCoins, ok := sim.GetRandSubsetOfKDenoms(ctx, sender, 3) if !ok { - return nil, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, fmt.Errorf("provided sender with requested number of denoms does not exist") + return preparePoolConfig{}, fmt.Errorf("provided sender with requested number of denoms does not exist") } // check if the sender has sufficient amount for fees if poolCoins.Add(PoolCreationFee).IsAnyGT(sim.BankKeeper().SpendableCoins(ctx, sender.Address)) { - return nil, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, errors.New("chose an account / creation amount that didn't pass fee limit") + return preparePoolConfig{}, errors.New("chose an account / creation amount that didn't pass fee limit") } if poolCoins[0].Denom == sdk.DefaultBondDenom || poolCoins[1].Denom == sdk.DefaultBondDenom { - return nil, sdk.Coin{}, sdk.Coin{}, 0, sdk.Dec{}, fmt.Errorf("poolCoins contains denom stake which contains invalid metadata") + return preparePoolConfig{}, fmt.Errorf("poolCoins contains denom stake which contains invalid metadata") } coin0 := poolCoins[0] @@ -357,20 +372,26 @@ func RandomPreparePoolFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, k clkeeper tickSpacing := authorizedTickSpacing[rand.Intn(len(authorizedTickSpacing))] spreadFactor := authorizedSpreadFactor[rand.Intn(len(authorizedSpreadFactor))] - return sender.Address, coin0, coin1, tickSpacing, spreadFactor, nil + return preparePoolConfig{ + creator: sender.Address, + coin0: coin0, + coin1: coin1, + tickSpacing: tickSpacing, + spreadFactor: spreadFactor, + }, nil } -func RandomPrepareCreatePositionFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, clPool cltypes.ConcentratedPoolExtension, poolDenoms []string) (sdk.AccAddress, sdk.Coins, int64, int64, error) { +func RandomPrepareCreatePositionFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, clPool cltypes.ConcentratedPoolExtension, poolDenoms []string) (preparePositionConfig, error) { // make sure that the position creator has the poolTokens positionCreator, tokens, senderExists := sim.SelAddrWithDenoms(ctx, poolDenoms) if !senderExists { - return nil, sdk.Coins{}, 0, 0, fmt.Errorf("no sender with denoms %s exists", poolDenoms) + return preparePositionConfig{}, fmt.Errorf("no sender with denoms %s exists", poolDenoms) } // ensure that we always have 2 tokens // Note: tokens returns a random subset of poolDenoms, so had to add this assertion if len(tokens) < 2 { - return nil, sdk.Coins{}, 0, 0, fmt.Errorf("user does not have pool tokens") + return preparePositionConfig{}, fmt.Errorf("user does not have pool tokens") } // Retrieve minTick and maxTick from kprecision factor @@ -379,8 +400,13 @@ func RandomPrepareCreatePositionFunc(sim *osmosimtypes.SimCtx, ctx sdk.Context, // Randomize lowerTick and upperTick from max values to create position lowerTick, upperTick, err := getRandomTickPositions(sim, minTick, maxTick, clPool.GetTickSpacing()) if err != nil { - return nil, sdk.Coins{}, 0, 0, err + return preparePositionConfig{}, err } - return positionCreator.Address, tokens, lowerTick, upperTick, nil + return preparePositionConfig{ + owner: positionCreator.Address, + tokens: tokens, + lowerTick: lowerTick, + upperTick: upperTick, + }, nil } diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index c06a9215730..2516585a2d7 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -61,6 +61,14 @@ type SwapState struct { swapStrategy swapstrategy.SwapStrategy } +// SwapResult represents the result from computing +// the swap state. +type SwapResult struct { + AmountIn sdk.Int + AmountOut sdk.Int + SpreadRewards sdk.Dec +} + // swapNoProgressLimit is the maximum number of iterations that can be performed // without progressing the swap state. If this limit is reached, the swap is // considered to have failed. @@ -210,18 +218,20 @@ func (k Keeper) swapOutAmtGivenIn( spreadFactor sdk.Dec, priceLimit sdk.Dec, ) (calcTokenIn, calcTokenOut sdk.Coin, poolUpdates PoolUpdates, err error) { - tokenIn, tokenOut, poolUpdates, totalSpreadFactors, err := k.computeOutAmtGivenIn(ctx, pool.GetId(), tokenIn, tokenOutDenom, spreadFactor, priceLimit) + swapResult, poolUpdates, err := k.computeOutAmtGivenIn(ctx, pool.GetId(), tokenIn, tokenOutDenom, spreadFactor, priceLimit) if err != nil { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, err } + tokenOut := sdk.NewCoin(tokenOutDenom, swapResult.AmountOut) + if !tokenOut.Amount.IsPositive() { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, types.InvalidAmountCalculatedError{Amount: tokenOut.Amount} } // Settles balances between the tx sender and the pool to match the swap that was executed earlier. // Also emits swap event and updates related liquidity metrics - if err := k.updatePoolForSwap(ctx, pool, SwapDetails{sender, tokenIn, tokenOut}, poolUpdates, totalSpreadFactors); err != nil { + if err := k.updatePoolForSwap(ctx, pool, SwapDetails{sender, tokenIn, tokenOut}, poolUpdates, swapResult.SpreadRewards); err != nil { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, err } @@ -239,10 +249,12 @@ func (k *Keeper) swapInAmtGivenOut( spreadFactor sdk.Dec, priceLimit sdk.Dec, ) (calcTokenIn, calcTokenOut sdk.Coin, poolUpdates PoolUpdates, err error) { - tokenIn, tokenOut, poolUpdates, totalSpreadFactors, err := k.computeInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, spreadFactor, priceLimit, pool.GetId()) + swapResult, poolUpdates, err := k.computeInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, spreadFactor, priceLimit, pool.GetId()) if err != nil { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, err } + tokenIn := sdk.NewCoin(tokenInDenom, swapResult.AmountIn) + tokenOut := sdk.NewCoin(desiredTokenOut.Denom, swapResult.AmountOut) // check that the tokenOut calculated is both valid and less than specified limit if !tokenIn.Amount.IsPositive() { @@ -251,7 +263,7 @@ func (k *Keeper) swapInAmtGivenOut( // Settles balances between the tx sender and the pool to match the swap that was executed earlier. // Also emits swap event and updates related liquidity metrics - if err := k.updatePoolForSwap(ctx, pool, SwapDetails{sender, tokenIn, tokenOut}, poolUpdates, totalSpreadFactors); err != nil { + if err := k.updatePoolForSwap(ctx, pool, SwapDetails{sender, tokenIn, tokenOut}, poolUpdates, swapResult.SpreadRewards); err != nil { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, err } @@ -266,11 +278,11 @@ func (k Keeper) CalcOutAmtGivenIn( spreadFactor sdk.Dec, ) (tokenOut sdk.Coin, err error) { cacheCtx, _ := ctx.CacheContext() - _, tokenOut, _, _, err = k.computeOutAmtGivenIn(cacheCtx, poolI.GetId(), tokenIn, tokenOutDenom, spreadFactor, sdk.ZeroDec()) + swapResult, _, err := k.computeOutAmtGivenIn(cacheCtx, poolI.GetId(), tokenIn, tokenOutDenom, spreadFactor, sdk.ZeroDec()) if err != nil { return sdk.Coin{}, err } - return tokenOut, nil + return sdk.NewCoin(tokenOutDenom, swapResult.AmountOut), nil } func (k Keeper) CalcInAmtGivenOut( @@ -279,13 +291,13 @@ func (k Keeper) CalcInAmtGivenOut( tokenOut sdk.Coin, tokenInDenom string, spreadFactor sdk.Dec, -) (tokenIn sdk.Coin, err error) { +) (sdk.Coin, error) { cacheCtx, _ := ctx.CacheContext() - tokenIn, _, _, _, err = k.computeInAmtGivenOut(cacheCtx, tokenOut, tokenInDenom, spreadFactor, sdk.ZeroDec(), poolI.GetId()) + swapResult, _, err := k.computeInAmtGivenOut(cacheCtx, tokenOut, tokenInDenom, spreadFactor, sdk.ZeroDec(), poolI.GetId()) if err != nil { return sdk.Coin{}, err } - return tokenIn, nil + return sdk.NewCoin(tokenInDenom, swapResult.AmountIn), nil } func (k Keeper) swapSetup(ctx sdk.Context, @@ -343,15 +355,15 @@ func (k Keeper) computeOutAmtGivenIn( tokenOutDenom string, spreadFactor sdk.Dec, priceLimit sdk.Dec, -) (tokenIn, tokenOut sdk.Coin, poolUpdates PoolUpdates, totalSpreadFactors sdk.Dec, err error) { +) (swapResult SwapResult, poolUpdates PoolUpdates, err error) { p, spreadRewardAccumulator, uptimeAccums, err := k.swapSetup(ctx, poolId, tokenInMin.Denom, tokenOutDenom) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } swapStrategy, sqrtPriceLimit, err := k.setupSwapStrategy(p, spreadFactor, tokenInMin.Denom, priceLimit) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } // initialize swap state with the following parameters: @@ -373,7 +385,7 @@ func (k Keeper) computeOutAmtGivenIn( // get next initialized tick, and its implied sqrtPriceTarget nextInitializedTick, nextInitializedTickSqrtPrice, sqrtPriceTarget, err := iteratorToNextInitializedTickSqrtPriceTarget(nextInitTickIter, poolId, swapStrategy) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } // Utilizing the bucket's liquidity and knowing the sqrt price target, we calculate how much tokenOut we get from the tokenIn @@ -386,7 +398,7 @@ func (k Keeper) computeOutAmtGivenIn( ) if err := validateSwapProgressAndAmountConsumption(computedSqrtPrice, sqrtPriceStart, amountIn, amountOut); err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } // Update the spread reward growth for the entire swap using the total spread factors charged. @@ -408,19 +420,19 @@ func (k Keeper) computeOutAmtGivenIn( swapState, err = k.swapCrossTickLogic(ctx, swapState, swapStrategy, nextInitializedTick, nextInitTickIter, p, spreadRewardAccumulator, uptimeAccums, tokenInMin.Denom) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } } else if edgeCaseInequalityBasedOnSwapStrategy(swapStrategy.ZeroForOne(), nextInitializedTickSqrtPrice, computedSqrtPrice) { // If, based on the swap strategy, the computedSqrtPrice matches the edge case inequality, we return an error. // This is an edge case that occurs when swapping at/near tick boundaries that will be fixed in the next release. // For now, we return an error and ask the user to try again with a different swap amount. - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPrice} + return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPriceBigDec} } else if !sqrtPriceStart.Equal(computedSqrtPrice) { // Otherwise if the sqrtPrice calculated from ComputeSwapWithinBucketOutGivenIn(...) does not equal the sqrtPriceStart we started with at the // beginning of this iteration, we set the swapState tick to the corresponding tick of the computedSqrtPrice calculated from ComputeSwapWithinBucketOutGivenIn(...) newTick, err := math.CalculateSqrtPriceToTick(computedSqrtPrice) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } swapState.tick = newTick } @@ -429,7 +441,7 @@ func (k Keeper) computeOutAmtGivenIn( // See definition of swapNoProgressLimit for more details. if amountIn.IsZero() { if swapNoProgressIterationCount >= swapNoProgressLimit { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, types.SwapNoProgressError{PoolId: poolId, UserProvidedCoin: tokenInMin} + return SwapResult{}, PoolUpdates{}, types.SwapNoProgressError{PoolId: poolId, UserProvidedCoin: tokenInMin} } swapNoProgressIterationCount++ } @@ -437,7 +449,7 @@ func (k Keeper) computeOutAmtGivenIn( // Note, this should be impossible to reach but we leave it as a defense-in-depth measure. if swapState.amountSpecifiedRemaining.IsNegative() { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, types.OverChargeSwapOutGivenInError{AmountSpecifiedRemaining: swapState.amountSpecifiedRemaining} + return SwapResult{}, PoolUpdates{}, types.OverChargeSwapOutGivenInError{AmountSpecifiedRemaining: swapState.amountSpecifiedRemaining} } // Add spread reward growth per share to the pool-global spread reward accumulator. @@ -446,17 +458,18 @@ func (k Keeper) computeOutAmtGivenIn( // Coin amounts require int values // Round amountIn up to avoid under charging - amt0 := (tokenInMin.Amount.ToDec().Sub(swapState.amountSpecifiedRemaining)).Ceil().TruncateInt() + amountIn := (tokenInMin.Amount.ToDec().Sub(swapState.amountSpecifiedRemaining)).Ceil().TruncateInt() // Round amountOut down to avoid over distributing. - amt1 := swapState.amountCalculated.TruncateInt() + amountOut := swapState.amountCalculated.TruncateInt() - ctx.Logger().Debug("final amount in", amt0) - ctx.Logger().Debug("final amount out", amt1) + ctx.Logger().Debug("final amount in", amountIn) + ctx.Logger().Debug("final amount out", amountOut) - tokenIn = sdk.NewCoin(tokenInMin.Denom, amt0) - tokenOut = sdk.NewCoin(tokenOutDenom, amt1) - - return tokenIn, tokenOut, PoolUpdates{swapState.tick, swapState.liquidity, swapState.sqrtPrice}, swapState.globalSpreadRewardGrowth, nil + return SwapResult{ + AmountIn: amountIn, + AmountOut: amountOut, + SpreadRewards: swapState.globalSpreadRewardGrowth, + }, PoolUpdates{swapState.tick, swapState.liquidity, swapState.sqrtPrice}, nil } // computeInAmtGivenOut calculates tokens to be swapped in given the desired token out and spread factor deducted. It also returns @@ -470,15 +483,15 @@ func (k Keeper) computeInAmtGivenOut( spreadFactor sdk.Dec, priceLimit sdk.Dec, poolId uint64, -) (tokenIn, tokenOut sdk.Coin, poolUpdates PoolUpdates, totalSpreadFactors sdk.Dec, err error) { +) (swapResult SwapResult, poolUpdates PoolUpdates, err error) { p, spreadRewardAccumulator, uptimeAccums, err := k.swapSetup(ctx, poolId, tokenInDenom, desiredTokenOut.Denom) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } swapStrategy, sqrtPriceLimit, err := k.setupSwapStrategy(p, spreadFactor, tokenInDenom, priceLimit) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } // initialize swap state with the following parameters: @@ -498,7 +511,7 @@ func (k Keeper) computeInAmtGivenOut( nextInitializedTick, nextInitializedTickSqrtPrice, sqrtPriceTarget, err := iteratorToNextInitializedTickSqrtPriceTarget(nextInitTickIter, poolId, swapStrategy) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } // Utilizing the bucket's liquidity and knowing the sqrt price target, we calculate the how much tokenOut we get from the tokenIn @@ -511,7 +524,7 @@ func (k Keeper) computeInAmtGivenOut( ) if err := validateSwapProgressAndAmountConsumption(computedSqrtPrice, sqrtPriceStart, amountIn, amountOut); err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } swapState.updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal) @@ -530,19 +543,19 @@ func (k Keeper) computeInAmtGivenOut( swapState, err = k.swapCrossTickLogic(ctx, swapState, swapStrategy, nextInitializedTick, nextInitTickIter, p, spreadRewardAccumulator, uptimeAccums, tokenInDenom) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } } else if edgeCaseInequalityBasedOnSwapStrategy(swapStrategy.ZeroForOne(), nextInitializedTickSqrtPrice, computedSqrtPrice) { // If, based on the swap strategy, the computedSqrtPrice matches the edge case inequality, we return an error. // This is an edge case that occurs when swapping at/near tick boundaries that will be fixed in the next release. // For now, we return an error and ask the user to try again with a different swap amount. - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPrice} + return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPriceBigDec} } else if !sqrtPriceStart.Equal(computedSqrtPrice) { // Otherwise, if the computedSqrtPrice calculated from ComputeSwapWithinBucketInGivenOut(...) does not equal the sqrtPriceStart we started with at the // beginning of this iteration, we set the swapState tick to the corresponding tick of the computedSqrtPrice calculated from ComputeSwapWithinBucketInGivenOut(...) swapState.tick, err = math.CalculateSqrtPriceToTick(computedSqrtPrice) if err != nil { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, err + return SwapResult{}, PoolUpdates{}, err } } @@ -550,7 +563,7 @@ func (k Keeper) computeInAmtGivenOut( // See definition of swapNoProgressLimit for more details. if amountOut.IsZero() { if swapNoProgressIterationCount >= swapNoProgressLimit { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, types.SwapNoProgressError{PoolId: poolId, UserProvidedCoin: desiredTokenOut} + return SwapResult{}, PoolUpdates{}, types.SwapNoProgressError{PoolId: poolId, UserProvidedCoin: desiredTokenOut} } swapNoProgressIterationCount++ } @@ -558,7 +571,7 @@ func (k Keeper) computeInAmtGivenOut( // Note, this should be impossible to reach but we leave it as a defense-in-depth measure. if swapState.amountSpecifiedRemaining.IsNegative() { - return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, sdk.Dec{}, fmt.Errorf("over charged problem swap in given out by %s", swapState.amountSpecifiedRemaining) + return SwapResult{}, PoolUpdates{}, fmt.Errorf("over charged problem swap in given out by %s", swapState.amountSpecifiedRemaining) } // Add spread reward growth per share to the pool-global spread reward accumulator. @@ -566,18 +579,19 @@ func (k Keeper) computeInAmtGivenOut( // coin amounts require int values // Round amount in up to avoid under charging the user. - amt0 := swapState.amountCalculated.Ceil().TruncateInt() + amountIn := swapState.amountCalculated.Ceil().TruncateInt() // Round amount out down to avoid over charging the pool. - amt1 := desiredTokenOut.Amount.ToDec().Sub(swapState.amountSpecifiedRemaining).TruncateInt() - - ctx.Logger().Debug("final amount in", amt0) - ctx.Logger().Debug("final amount out", amt1) + amountOut := desiredTokenOut.Amount.ToDec().Sub(swapState.amountSpecifiedRemaining).TruncateInt() - tokenIn = sdk.NewCoin(tokenInDenom, amt0) - tokenOut = sdk.NewCoin(desiredTokenOut.Denom, amt1) + ctx.Logger().Debug("final amount in", amountIn) + ctx.Logger().Debug("final amount out", amountOut) - return tokenIn, tokenOut, PoolUpdates{swapState.tick, swapState.liquidity, swapState.sqrtPrice}, swapState.globalSpreadRewardGrowth, nil + return SwapResult{ + AmountIn: amountIn, + AmountOut: amountOut, + SpreadRewards: swapState.globalSpreadRewardGrowth, + }, PoolUpdates{swapState.tick, swapState.liquidity, swapState.sqrtPrice}, nil } func emitSwapDebugLogs(ctx sdk.Context, swapState SwapState, reachedPrice osmomath.BigDec, amountIn, amountOut, spreadCharge sdk.Dec) { diff --git a/x/concentrated-liquidity/swaps_test.go b/x/concentrated-liquidity/swaps_test.go index 4e82c5cb2cd..cba119a4969 100644 --- a/x/concentrated-liquidity/swaps_test.go +++ b/x/concentrated-liquidity/swaps_test.go @@ -2073,7 +2073,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { // perform compute cacheCtx, _ := s.Ctx.CacheContext() - tokenIn, tokenOut, poolUpdates, totalSpreadRewards, err := s.App.ConcentratedLiquidityKeeper.ComputeOutAmtGivenIn( + swapResult, poolUpdates, err := s.App.ConcentratedLiquidityKeeper.ComputeOutAmtGivenIn( cacheCtx, pool.GetId(), test.tokenIn, test.tokenOutDenom, @@ -2082,17 +2082,17 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { if test.expectErr { s.Require().Error(err) } else { - s.testSwapResult(test, pool, tokenIn, tokenOut, poolUpdates, err) + s.testSwapResult(test, pool, swapResult.AmountIn, swapResult.AmountOut, poolUpdates, err) - expectedSpreadFactors := tokenIn.Amount.ToDec().Mul(pool.GetSpreadFactor(s.Ctx)).TruncateInt() - s.Require().Equal(expectedSpreadFactors.String(), totalSpreadRewards.TruncateInt().String()) + expectedSpreadFactors := swapResult.AmountIn.ToDec().Mul(pool.GetSpreadFactor(s.Ctx)).TruncateInt() + s.Require().Equal(expectedSpreadFactors.String(), swapResult.SpreadRewards.TruncateInt().String()) // check that the pool has not been modified after performing calc s.assertPoolNotModified(poolBeforeCalc) } // perform swap - tokenIn, tokenOut, poolUpdates, err = s.App.ConcentratedLiquidityKeeper.SwapOutAmtGivenIn( + tokenIn, tokenOut, poolUpdates, err := s.App.ConcentratedLiquidityKeeper.SwapOutAmtGivenIn( s.Ctx, s.TestAccs[0], pool, test.tokenIn, test.tokenOutDenom, test.spreadFactor, test.priceLimit, @@ -2101,7 +2101,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapOutAmtGivenIn() { if test.expectErr { s.Require().Error(err) } else { - s.testSwapResult(test, pool, tokenIn, tokenOut, poolUpdates, err) + s.testSwapResult(test, pool, tokenIn.Amount, tokenOut.Amount, poolUpdates, err) s.assertSpreadRewardAccum(test, pool.GetId()) } }) @@ -2192,13 +2192,13 @@ func (s *KeeperTestSuite) TestSwapOutAmtGivenIn_TickUpdates() { } } -func (s *KeeperTestSuite) testSwapResult(test SwapTest, pool types.ConcentratedPoolExtension, tokenIn, tokenOut sdk.Coin, poolUpdates cl.PoolUpdates, err error) { +func (s *KeeperTestSuite) testSwapResult(test SwapTest, pool types.ConcentratedPoolExtension, amountIn, amountOut sdk.Int, poolUpdates cl.PoolUpdates, err error) { s.Require().NoError(err) // check that tokenIn, tokenOut, tick, and sqrtPrice from CalcOut are all what we expected s.Require().Equal(test.expectedSqrtPrice, poolUpdates.NewSqrtPrice, "resultant sqrt price not equal to expected sqrt price") - s.Require().Equal(test.expectedTokenOut.String(), tokenOut.String()) - s.Require().Equal(test.expectedTokenIn.String(), tokenIn.String()) + s.Require().Equal(test.expectedTokenOut.Amount.String(), amountOut.String()) + s.Require().Equal(test.expectedTokenIn.Amount.String(), amountIn.String()) s.Require().Equal(test.expectedTick, poolUpdates.NewCurrentTick) expectedLiquidity := s.getExpectedLiquidity(test, pool) @@ -2219,21 +2219,21 @@ func (s *KeeperTestSuite) TestComputeAndSwapInAmtGivenOut() { // perform compute cacheCtx, _ := s.Ctx.CacheContext() - tokenIn, tokenOut, poolUpdates, totalSpreadRewards, err := s.App.ConcentratedLiquidityKeeper.ComputeInAmtGivenOut( + swapResult, poolUpdates, err := s.App.ConcentratedLiquidityKeeper.ComputeInAmtGivenOut( cacheCtx, test.tokenOut, test.tokenInDenom, test.spreadFactor, test.priceLimit, pool.GetId()) if test.expectErr { s.Require().Error(err) } else { - s.testSwapResult(test, pool, tokenIn, tokenOut, poolUpdates, err) + s.testSwapResult(test, pool, swapResult.AmountIn, swapResult.AmountOut, poolUpdates, err) - expectedSpreadRewards := tokenIn.Amount.ToDec().Mul(pool.GetSpreadFactor(s.Ctx)).TruncateInt() - s.Require().Equal(expectedSpreadRewards.String(), totalSpreadRewards.TruncateInt().String()) + expectedSpreadRewards := swapResult.AmountIn.ToDec().Mul(pool.GetSpreadFactor(s.Ctx)).TruncateInt() + s.Require().Equal(expectedSpreadRewards.String(), swapResult.SpreadRewards.TruncateInt().String()) } // perform swap - tokenIn, tokenOut, poolUpdates, err = s.App.ConcentratedLiquidityKeeper.SwapInAmtGivenOut( + tokenIn, tokenOut, poolUpdates, err := s.App.ConcentratedLiquidityKeeper.SwapInAmtGivenOut( s.Ctx, s.TestAccs[0], pool, test.tokenOut, test.tokenInDenom, test.spreadFactor, test.priceLimit) @@ -2247,7 +2247,7 @@ func (s *KeeperTestSuite) TestComputeAndSwapInAmtGivenOut() { s.Require().NoError(err) // check that tokenIn, tokenOut, tick, and sqrtPrice from SwapOut are all what we expected - s.testSwapResult(test, pool, tokenIn, tokenOut, poolUpdates, err) + s.testSwapResult(test, pool, tokenIn.Amount, tokenOut.Amount, poolUpdates, err) // Check variables on pool were set correctly // - ensure the pool's currentTick and currentSqrtPrice was updated due to calling a mutative method @@ -2718,7 +2718,7 @@ func (s *KeeperTestSuite) TestComputeOutAmtGivenIn() { poolBeforeCalc := s.preparePoolAndDefaultPositions(test) // perform calc - _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.ComputeOutAmtGivenIn( + _, _, err := s.App.ConcentratedLiquidityKeeper.ComputeOutAmtGivenIn( s.Ctx, poolBeforeCalc.GetId(), test.tokenIn, test.tokenOutDenom, @@ -2804,7 +2804,7 @@ func (s *KeeperTestSuite) TestComputeInAmtGivenOut() { poolBeforeCalc := s.preparePoolAndDefaultPositions(test) // perform calc - _, _, _, _, err := s.App.ConcentratedLiquidityKeeper.ComputeInAmtGivenOut( + _, _, err := s.App.ConcentratedLiquidityKeeper.ComputeInAmtGivenOut( s.Ctx, test.tokenOut, test.tokenInDenom, test.spreadFactor, test.priceLimit, poolBeforeCalc.GetId()) diff --git a/x/gamm/simulation/sim_msgs.go b/x/gamm/simulation/sim_msgs.go index b97ee4109a4..c02ff440ac4 100644 --- a/x/gamm/simulation/sim_msgs.go +++ b/x/gamm/simulation/sim_msgs.go @@ -22,10 +22,11 @@ var PoolCreationFee = sdk.NewInt64Coin("stake", 10_000_000) // respective underlying token denoms, and attempts to execute a join pool transaction func RandomJoinPoolMsg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgJoinPool, error) { // get random pool - pool_id, pool, _, _, poolDenoms, _, err := getRandPool(k, sim, ctx) + pool, _, _, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } + poolDenoms := osmoutils.CoinsDenoms(pool.GetTotalPoolLiquidity(ctx)) // get address that has all denoms from the randomly selected pool sender, tokenIn, senderExists := sim.SelAddrWithDenoms(ctx, poolDenoms) @@ -47,7 +48,7 @@ func RandomJoinPoolMsg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) ( // TODO: Make MinShareOutAmt fuzz API: minShareOutAmt = sim.FuzzEqualInt(share_out_amount) return &types.MsgJoinPool{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: pool.GetId(), ShareOutAmount: minShareOutAmt, TokenInMaxs: tokenIn, }, nil @@ -57,10 +58,12 @@ func RandomJoinPoolMsg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) ( // respective unbonded gamm shares, and attempts to execute an exit pool transaction func RandomExitPoolMsg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgExitPool, error) { // get random pool - pool_id, pool, _, _, _, gammDenom, err := getRandPool(k, sim, ctx) + pool, _, _, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } + poolId := pool.GetId() + gammDenom := types.GetPoolShareDenom(poolId) // select an address that has gamm shares of the selected pool sender, gammShares, senderExists := sim.SelAddrWithDenom(ctx, gammDenom) @@ -76,7 +79,7 @@ func RandomExitPoolMsg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) ( return &types.MsgExitPool{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: poolId, ShareInAmount: gammShares.Amount, TokenOutMins: tokenOutMins, }, nil @@ -124,14 +127,14 @@ func RandomCreateUniV2Msg(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context // TODO: Improve this to swap through multiple pools func RandomSwapExactAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgSwapExactAmountIn, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, coinOut, _, _, err := getRandPool(k, sim, ctx) + pool, coinIn, coinOut, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } // set the swap route to use this pool route := []poolmanagertypes.SwapAmountInRoute{{ - PoolId: pool_id, + PoolId: pool.GetId(), TokenOutDenom: coinOut.Denom, }} @@ -173,14 +176,14 @@ func RandomSwapExactAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Cont // TODO: Improve this to swap through multiple pools func RandomSwapExactAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgSwapExactAmountOut, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, coinOut, _, _, err := getRandPool(k, sim, ctx) + pool, coinIn, coinOut, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } // set the swap route to use this pool route := []poolmanagertypes.SwapAmountOutRoute{{ - PoolId: pool_id, + PoolId: pool.GetId(), TokenInDenom: coinIn.Denom, }} @@ -225,7 +228,7 @@ func RandomSwapExactAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Con // amount of an asset for a minimum number of LP shares func RandomJoinSwapExternAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgJoinSwapExternAmountIn, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, _, _, _, err := getRandPool(k, sim, ctx) + pool, coinIn, _, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } @@ -247,7 +250,7 @@ func RandomJoinSwapExternAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk return &types.MsgJoinSwapExternAmountIn{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: pool.GetId(), TokenIn: newTokenIn[0], ShareOutMinAmount: minShareOutAmt, }, nil @@ -257,10 +260,11 @@ func RandomJoinSwapExternAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk // for an exact amount of LP shares func RandomJoinSwapShareAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgJoinSwapShareAmountOut, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, _, _, _, err := getRandPool(k, sim, ctx) + pool, coinIn, _, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } + poolId := pool.GetId() // find an address with the coinIn denom and randomly select a subset of the coin sender, tokenIn, senderExists := sim.SelAddrWithDenom(ctx, coinIn.Denom) @@ -280,7 +284,7 @@ func RandomJoinSwapShareAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk // use PoolAmountOutExtension to calculate correct tokenInMaxAmount extendedPool, ok := pool.(types.PoolAmountOutExtension) if !ok { - return nil, fmt.Errorf("pool with id %d does not support this kind of join", pool_id) + return nil, fmt.Errorf("pool with id %d does not support this kind of join", poolId) } tokenInAmount, err := extendedPool.CalcTokenInShareAmountOut(ctx, tokenIn.Denom, minShareOutAmt, pool.GetSpreadFactor(ctx)) if err != nil { @@ -294,7 +298,7 @@ func RandomJoinSwapShareAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk return &types.MsgJoinSwapShareAmountOut{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: poolId, TokenInDenom: tokenIn.Denom, ShareOutAmount: minShareOutAmt, TokenInMaxAmount: tokenInAmount, @@ -305,10 +309,12 @@ func RandomJoinSwapShareAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk // for an exact amount of one of the token pairs func RandomExitSwapExternAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgExitSwapExternAmountOut, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, coinOut, _, gammDenom, err := getRandPool(k, sim, ctx) + pool, coinIn, coinOut, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } + poolId := pool.GetId() + gammDenom := types.GetPoolShareDenom(poolId) // select an address that has gamm shares of the selected pool sender, gammShares, senderExists := sim.SelAddrWithDenom(ctx, gammDenom) @@ -337,7 +343,7 @@ func RandomExitSwapExternAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sd // since we are only doing half the swap out, we only use half the share in return &types.MsgExitSwapExternAmountOut{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: poolId, TokenOut: tokenOut, ShareInMaxAmount: gammShares.Amount.Quo(sdk.NewInt(2)), }, nil @@ -347,10 +353,12 @@ func RandomExitSwapExternAmountOut(k keeper.Keeper, sim *simtypes.SimCtx, ctx sd // for a minimum amount of one of the token pairs func RandomExitSwapShareAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (*types.MsgExitSwapShareAmountIn, error) { // get random pool, randomly select one of the pool denoms to be the coinIn, other is coinOut - pool_id, pool, coinIn, coinOut, _, gammDenom, err := getRandPool(k, sim, ctx) + pool, coinIn, coinOut, err := getRandPool(k, sim, ctx) if err != nil { return nil, err } + poolId := pool.GetId() + gammDenom := types.GetPoolShareDenom(poolId) // select an address that has gamm shares of the selected pool sender, gammShares, senderExists := sim.SelAddrWithDenom(ctx, gammDenom) @@ -379,7 +387,7 @@ func RandomExitSwapShareAmountIn(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk. // since we are only doing half the swap out, we only use half the share in return &types.MsgExitSwapShareAmountIn{ Sender: sender.Address.String(), - PoolId: pool_id, + PoolId: pool.GetId(), TokenOutDenom: tokenOut.Denom, ShareInAmount: gammShares.Amount.Quo(sdk.NewInt(2)), TokenOutMinAmount: tokenOut.Amount.Quo(sdk.NewInt(2)), @@ -435,23 +443,22 @@ func createPoolRestriction(sim *simtypes.SimCtx, ctx sdk.Context) simtypes.SimAc } } -func getRandPool(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (uint64, types.CFMMPoolI, sdk.Coin, sdk.Coin, []string, string, error) { +func getRandPool(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (types.CFMMPoolI, sdk.Coin, sdk.Coin, error) { // select a pseudo-random pool ID, max bound by the upcoming pool ID pools, err := k.GetPoolsAndPoke(ctx) if err != nil { - return 0, nil, sdk.NewCoin("denom", sdk.ZeroInt()), sdk.NewCoin("denom", sdk.ZeroInt()), []string{}, "", err + return nil, sdk.NewCoin("denom", sdk.ZeroInt()), sdk.NewCoin("denom", sdk.ZeroInt()), err } numPools := len(pools) if numPools == 0 { - return 0, nil, sdk.NewCoin("denom", sdk.ZeroInt()), sdk.NewCoin("denom", sdk.ZeroInt()), []string{}, "", fmt.Errorf("no pools exist") + return nil, sdk.NewCoin("denom", sdk.ZeroInt()), sdk.NewCoin("denom", sdk.ZeroInt()), fmt.Errorf("no pools exist") } rand := sim.GetRand() pool := pools[rand.Intn(numPools)] - poolId := pool.GetId() poolCoins := pool.GetTotalPoolLiquidity(ctx) // TODO: Improve this, don't just assume two asset pools @@ -461,7 +468,6 @@ func getRandPool(k keeper.Keeper, sim *simtypes.SimCtx, ctx sdk.Context) (uint64 coinIn := poolCoins[index] poolCoins = simtypes.RemoveIndex(poolCoins, index) coinOut := poolCoins[0] - poolDenoms := osmoutils.CoinsDenoms(pool.GetTotalPoolLiquidity(ctx)) - gammDenom := types.GetPoolShareDenom(poolId) - return poolId, pool, coinIn, coinOut, poolDenoms, gammDenom, err + + return pool, coinIn, coinOut, err } diff --git a/x/twap/client/cli/query.go b/x/twap/client/cli/query.go index 19e4d57b1b5..57f0d078345 100644 --- a/x/twap/client/cli/query.go +++ b/x/twap/client/cli/query.go @@ -16,6 +16,13 @@ import ( "github.com/osmosis-labs/osmosis/v19/x/twap/types" ) +type TwapQueryArgs struct { + PoolId uint64 + BaseDenom string + StartTime time.Time + EndTime time.Time +} + // GetQueryCmd returns the cli query commands for this module. func GetQueryCmd() *cobra.Command { cmd := osmocli.QueryIndexCmd(types.ModuleName) @@ -40,7 +47,7 @@ Example: Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { // boilerplate parse fields - poolId, baseDenom, startTime, endTime, err := twapQueryParseArgs(args) + twapArgs, err := twapQueryParseArgs(args) if err != nil { return err } @@ -48,18 +55,18 @@ Example: if err != nil { return err } - quoteDenom, err := getQuoteDenomFromLiquidity(cmd.Context(), clientCtx, poolId, baseDenom) + quoteDenom, err := getQuoteDenomFromLiquidity(cmd.Context(), clientCtx, twapArgs.PoolId, twapArgs.BaseDenom) if err != nil { return err } queryClient := queryproto.NewQueryClient(clientCtx) res, err := queryClient.ArithmeticTwap(cmd.Context(), &queryproto.ArithmeticTwapRequest{ - PoolId: poolId, - BaseAsset: baseDenom, + PoolId: twapArgs.PoolId, + BaseAsset: twapArgs.BaseDenom, QuoteAsset: quoteDenom, - StartTime: startTime, - EndTime: &endTime, + StartTime: twapArgs.StartTime, + EndTime: &twapArgs.EndTime, }) if err != nil { return err @@ -88,7 +95,7 @@ Example: Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { // boilerplate parse fields - poolId, baseDenom, startTime, endTime, err := twapQueryParseArgs(args) + twapArgs, err := twapQueryParseArgs(args) if err != nil { return err } @@ -96,7 +103,7 @@ Example: if err != nil { return err } - quoteDenom, err := getQuoteDenomFromLiquidity(cmd.Context(), clientCtx, poolId, baseDenom) + quoteDenom, err := getQuoteDenomFromLiquidity(cmd.Context(), clientCtx, twapArgs.PoolId, twapArgs.BaseDenom) if err != nil { return err } @@ -106,11 +113,11 @@ Example: } res, err := queryClient.GeometricTwap(cmd.Context(), &queryproto.GeometricTwapRequest{ - PoolId: poolId, - BaseAsset: baseDenom, + PoolId: twapArgs.PoolId, + BaseAsset: twapArgs.BaseDenom, QuoteAsset: quoteDenom, - StartTime: startTime, - EndTime: &endTime, + StartTime: twapArgs.StartTime, + EndTime: &twapArgs.EndTime, }) if err != nil { return err @@ -149,35 +156,40 @@ func getQuoteDenomFromLiquidity(ctx context.Context, clientCtx client.Context, p return quoteDenom, nil } -func twapQueryParseArgs(args []string) (poolId uint64, baseDenom string, startTime time.Time, endTime time.Time, err error) { +func twapQueryParseArgs(args []string) (TwapQueryArgs, error) { // boilerplate parse fields // - poolId, err = osmocli.ParseUint(args[0], "poolId") + poolId, err := osmocli.ParseUint(args[0], "poolId") if err != nil { - return + return TwapQueryArgs{}, err } // - baseDenom = strings.TrimSpace(args[1]) + baseDenom := strings.TrimSpace(args[1]) // - startTime, err = osmocli.ParseUnixTime(args[2], "start time") + startTime, err := osmocli.ParseUnixTime(args[2], "start time") if err != nil { - return + return TwapQueryArgs{}, err } // END TIME PARSE: ONEOF {, } // try parsing in unix time, if failed try parsing in duration - endTime, err = osmocli.ParseUnixTime(args[3], "end time") + endTime, err := osmocli.ParseUnixTime(args[3], "end time") if err != nil { // TODO if we don't use protoreflect: // make better error combiner, rather than just returning last error duration, err2 := time.ParseDuration(args[3]) if err2 != nil { err = err2 - return + return TwapQueryArgs{}, err } endTime = startTime.Add(duration) } - return poolId, baseDenom, startTime, endTime, nil + return TwapQueryArgs{ + PoolId: poolId, + BaseDenom: baseDenom, + StartTime: startTime, + EndTime: endTime, + }, nil } From ecc045ecb90e368440bdb95cfe5cd353911347da Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 13:50:41 +0200 Subject: [PATCH 04/13] attempt to fix linter in CI --- .github/workflows/lint.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bd5615a93a2..8d5159da943 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,21 +17,21 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 + - + uses: technote-space/get-diff-action@v6.1.2 + with: + PATTERNS: | + **/**.go + go.mod + go.sum + .github/** + Makefile - name: 🐿 Setup Golang uses: actions/setup-go@v4 with: go-version: ${{env.GO_VERSION}} - - - uses: technote-space/get-diff-action@v6.1.2 - if: env.GIT_DIFF - with: - PATTERNS: | - **/**.go - go.mod - go.sum - .github/** - Makefile + - name: Run golangci-lint if: env.GIT_DIFF From 075eb8f8f24c689eb4523ad6aa7fcf5824e4b9a4 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 14:03:55 +0200 Subject: [PATCH 05/13] remove depguard --- .golangci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 991c69e9ab1..cd6d5f6a718 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,7 +9,6 @@ linters: enable: - asciicheck - bidichk - - depguard - durationcheck - errcheck - errname From d26d9f0b9a68a047689c9161d72b4aa2c44fde57 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 14:14:02 +0200 Subject: [PATCH 06/13] godocs --- x/concentrated-liquidity/simulation/sim_msgs.go | 4 ++++ x/twap/client/cli/query.go | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/x/concentrated-liquidity/simulation/sim_msgs.go b/x/concentrated-liquidity/simulation/sim_msgs.go index 91d15706386..a8cb64792d8 100644 --- a/x/concentrated-liquidity/simulation/sim_msgs.go +++ b/x/concentrated-liquidity/simulation/sim_msgs.go @@ -17,6 +17,8 @@ import ( minttypes "github.com/osmosis-labs/osmosis/v19/x/mint/types" ) +// preparePoolConfig defines the parameters for creating a new pool +// returned from the respective randomizer helper. type preparePoolConfig struct { creator sdk.AccAddress coin0 sdk.Coin @@ -25,6 +27,8 @@ type preparePoolConfig struct { spreadFactor sdk.Dec } +// preparePositionConfig defines the parameters for creating a new position +// returned from the respective randomizer helper. type preparePositionConfig struct { owner sdk.AccAddress tokens sdk.Coins diff --git a/x/twap/client/cli/query.go b/x/twap/client/cli/query.go index 57f0d078345..c2d664d78eb 100644 --- a/x/twap/client/cli/query.go +++ b/x/twap/client/cli/query.go @@ -16,7 +16,9 @@ import ( "github.com/osmosis-labs/osmosis/v19/x/twap/types" ) -type TwapQueryArgs struct { +// twapQueryParseArgs represents the outcome +// of parsing the arguments for twap query command. +type twapQueryArgs struct { PoolId uint64 BaseDenom string StartTime time.Time @@ -156,12 +158,12 @@ func getQuoteDenomFromLiquidity(ctx context.Context, clientCtx client.Context, p return quoteDenom, nil } -func twapQueryParseArgs(args []string) (TwapQueryArgs, error) { +func twapQueryParseArgs(args []string) (twapQueryArgs, error) { // boilerplate parse fields // poolId, err := osmocli.ParseUint(args[0], "poolId") if err != nil { - return TwapQueryArgs{}, err + return twapQueryArgs{}, err } // @@ -170,7 +172,7 @@ func twapQueryParseArgs(args []string) (TwapQueryArgs, error) { // startTime, err := osmocli.ParseUnixTime(args[2], "start time") if err != nil { - return TwapQueryArgs{}, err + return twapQueryArgs{}, err } // END TIME PARSE: ONEOF {, } @@ -182,11 +184,11 @@ func twapQueryParseArgs(args []string) (TwapQueryArgs, error) { duration, err2 := time.ParseDuration(args[3]) if err2 != nil { err = err2 - return TwapQueryArgs{}, err + return twapQueryArgs{}, err } endTime = startTime.Add(duration) } - return TwapQueryArgs{ + return twapQueryArgs{ PoolId: poolId, BaseDenom: baseDenom, StartTime: startTime, From 7e00fc63645fd4a9c891149dad7483ace1e852df Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 14:24:23 +0200 Subject: [PATCH 07/13] move unused twap helper to test export --- x/twap/export_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/x/twap/export_test.go b/x/twap/export_test.go index d80a6a0d17a..c7071d43b5f 100644 --- a/x/twap/export_test.go +++ b/x/twap/export_test.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/osmosis-labs/osmosis/osmomath" + "github.com/osmosis-labs/osmosis/osmoutils" "github.com/osmosis-labs/osmosis/v19/x/twap/types" ) @@ -28,10 +29,6 @@ func (k Keeper) TrackChangedPool(ctx sdk.Context, poolId uint64) { k.trackChangedPool(ctx, poolId) } -func (k Keeper) GetAllHistoricalPoolIndexedTWAPs(ctx sdk.Context) ([]types.TwapRecord, error) { - return k.getAllHistoricalPoolIndexedTWAPs(ctx) -} - func (k Keeper) GetChangedPools(ctx sdk.Context) []uint64 { return k.getChangedPools(ctx) } @@ -111,3 +108,7 @@ func (k *Keeper) SetAmmInterface(poolManagerInterface types.PoolManagerInterface func (k *Keeper) AfterCreatePool(ctx sdk.Context, poolId uint64) error { return k.afterCreatePool(ctx, poolId) } + +func (k Keeper) GetAllHistoricalPoolIndexedTWAPs(ctx sdk.Context) ([]types.TwapRecord, error) { + return osmoutils.GatherValuesFromStorePrefix(ctx.KVStore(k.storeKey), []byte(types.HistoricalTWAPPoolIndexPrefix), types.ParseTwapFromBz) +} From 5836f98212720721cc7926874a9ee0619ed6cc42 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 14:41:46 +0200 Subject: [PATCH 08/13] bug --- x/concentrated-liquidity/swaps.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index 2516585a2d7..b60af4ce20f 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -222,7 +222,7 @@ func (k Keeper) swapOutAmtGivenIn( if err != nil { return sdk.Coin{}, sdk.Coin{}, PoolUpdates{}, err } - + tokenIn = sdk.NewCoin(tokenIn.Denom, swapResult.AmountIn) tokenOut := sdk.NewCoin(tokenOutDenom, swapResult.AmountOut) if !tokenOut.Amount.IsPositive() { From bd0ed589bc8d852786a893ea1da99c56e70abf19 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 18 Aug 2023 18:03:47 +0200 Subject: [PATCH 09/13] bring back getAllHistoricalPoolIndexedTWAPs and add nolint --- x/twap/export_test.go | 2 +- x/twap/store.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/twap/export_test.go b/x/twap/export_test.go index c7071d43b5f..f24df4fed22 100644 --- a/x/twap/export_test.go +++ b/x/twap/export_test.go @@ -110,5 +110,5 @@ func (k *Keeper) AfterCreatePool(ctx sdk.Context, poolId uint64) error { } func (k Keeper) GetAllHistoricalPoolIndexedTWAPs(ctx sdk.Context) ([]types.TwapRecord, error) { - return osmoutils.GatherValuesFromStorePrefix(ctx.KVStore(k.storeKey), []byte(types.HistoricalTWAPPoolIndexPrefix), types.ParseTwapFromBz) + return k.getAllHistoricalPoolIndexedTWAPs(ctx) } diff --git a/x/twap/store.go b/x/twap/store.go index 2ac0367eab8..42681fcd57c 100644 --- a/x/twap/store.go +++ b/x/twap/store.go @@ -157,7 +157,7 @@ func (k Keeper) GetAllHistoricalTimeIndexedTWAPs(ctx sdk.Context) ([]types.TwapR } // getAllHistoricalPoolIndexedTWAPs returns all historical TWAPs indexed by pool id. -// nolint:unused +// nolint: unused func (k Keeper) getAllHistoricalPoolIndexedTWAPs(ctx sdk.Context) ([]types.TwapRecord, error) { return osmoutils.GatherValuesFromStorePrefix(ctx.KVStore(k.storeKey), []byte(types.HistoricalTWAPPoolIndexPrefix), types.ParseTwapFromBz) } From 4a5f4e4fb972f372458b2a7e4f703506b39daca0 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 21 Aug 2023 11:32:00 +0200 Subject: [PATCH 10/13] Update .golangci.yml --- .golangci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.golangci.yml b/.golangci.yml index cd6d5f6a718..286694e9834 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -48,6 +48,7 @@ linters-settings: - name: function-result-limit severity: warning disabled: false + # limits the number of returns to 4 arguments: [4] issues: From c19f808ce8e6a580d0a00915e1997bc46d1cbb0d Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 28 Aug 2023 12:35:53 +0200 Subject: [PATCH 11/13] fix more issues --- x/concentrated-liquidity/math/precompute.go | 1 - x/incentives/keeper/distribute.go | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/x/concentrated-liquidity/math/precompute.go b/x/concentrated-liquidity/math/precompute.go index df3939ee3c4..e51298cb33c 100644 --- a/x/concentrated-liquidity/math/precompute.go +++ b/x/concentrated-liquidity/math/precompute.go @@ -9,7 +9,6 @@ import ( var ( sdkOneDec = sdk.OneDec() - sdkNineDec = sdk.NewDec(9) sdkTenDec = sdk.NewDec(10) powersOfTen []sdk.Dec negPowersOfTen []sdk.Dec diff --git a/x/incentives/keeper/distribute.go b/x/incentives/keeper/distribute.go index 4eb0bad4f01..6f34b09b9ef 100644 --- a/x/incentives/keeper/distribute.go +++ b/x/incentives/keeper/distribute.go @@ -284,7 +284,7 @@ func (k Keeper) AllocateAcrossGauges(ctx sdk.Context) error { // only allow distribution if the GroupGauge is Active if gauge.IsActiveGauge(currTime) { - coinsToDistributePerInternalGauge, coinsToDistributeThisEpoch, err := k.calcSplitPolicyCoins(ctx, groupGauge.SplittingPolicy, gauge, groupGauge) + coinsToDistributePerInternalGauge, coinsToDistributeThisEpoch, err := k.calcSplitPolicyCoins(groupGauge.SplittingPolicy, gauge, groupGauge) if err != nil { return err } @@ -298,7 +298,9 @@ func (k Keeper) AllocateAcrossGauges(ctx sdk.Context) error { // we distribute tokens from groupGauge to internal gauge therefore update groupGauge fields // updates filledEpoch and distributedCoins - k.updateGaugePostDistribute(ctx, *gauge, coinsToDistributeThisEpoch) + if err := k.updateGaugePostDistribute(ctx, *gauge, coinsToDistributeThisEpoch); err != nil { + return err + } } } @@ -307,7 +309,8 @@ func (k Keeper) AllocateAcrossGauges(ctx sdk.Context) error { // calcSplitPolicyCoins calculates tokens to split given a policy and groupGauge. // TODO: add volume split policy -func (k Keeper) calcSplitPolicyCoins(ctx sdk.Context, policy types.SplittingPolicy, groupGauge *types.Gauge, groupGaugeObj types.GroupGauge) (sdk.Coins, sdk.Coins, error) { +// nolint: unused +func (k Keeper) calcSplitPolicyCoins(policy types.SplittingPolicy, groupGauge *types.Gauge, groupGaugeObj types.GroupGauge) (sdk.Coins, sdk.Coins, error) { if policy == types.Evenly { remainCoins := groupGauge.Coins.Sub(groupGauge.DistributedCoins) From 3f1e1ad4fba26b6bf15e439b0cf753539445a40b Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 30 Aug 2023 15:50:08 -0400 Subject: [PATCH 12/13] conflict --- x/concentrated-liquidity/simulation/sim_msgs.go | 2 +- x/concentrated-liquidity/swaps.go | 4 ++-- x/twap/export_test.go | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/x/concentrated-liquidity/simulation/sim_msgs.go b/x/concentrated-liquidity/simulation/sim_msgs.go index a8cb64792d8..a88f4b9410b 100644 --- a/x/concentrated-liquidity/simulation/sim_msgs.go +++ b/x/concentrated-liquidity/simulation/sim_msgs.go @@ -51,7 +51,7 @@ func RandomMsgCreateConcentratedPool(k clkeeper.Keeper, sim *osmosimtypes.SimCtx // make sure the denoms are valid authorized quote denoms authorizedQuoteDenoms := k.GetAuthorizedQuoteDenoms(ctx) - authorizedQuoteDenoms = append(defaultParams.AuthorizedQuoteDenoms, coin1.Denom, coin0.Denom) + authorizedQuoteDenoms = append(defaultParams.AuthorizedQuoteDenoms, preparePoolInfo.coin1.Denom, preparePoolInfo.coin0.Denom) k.SetAuthorizedQuoteDenoms(ctx, authorizedQuoteDenoms) denomMetaData := banktypes.Metadata{ diff --git a/x/concentrated-liquidity/swaps.go b/x/concentrated-liquidity/swaps.go index b60af4ce20f..f91b21dcb26 100644 --- a/x/concentrated-liquidity/swaps.go +++ b/x/concentrated-liquidity/swaps.go @@ -426,7 +426,7 @@ func (k Keeper) computeOutAmtGivenIn( // If, based on the swap strategy, the computedSqrtPrice matches the edge case inequality, we return an error. // This is an edge case that occurs when swapping at/near tick boundaries that will be fixed in the next release. // For now, we return an error and ask the user to try again with a different swap amount. - return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPriceBigDec} + return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPrice} } else if !sqrtPriceStart.Equal(computedSqrtPrice) { // Otherwise if the sqrtPrice calculated from ComputeSwapWithinBucketOutGivenIn(...) does not equal the sqrtPriceStart we started with at the // beginning of this iteration, we set the swapState tick to the corresponding tick of the computedSqrtPrice calculated from ComputeSwapWithinBucketOutGivenIn(...) @@ -549,7 +549,7 @@ func (k Keeper) computeInAmtGivenOut( // If, based on the swap strategy, the computedSqrtPrice matches the edge case inequality, we return an error. // This is an edge case that occurs when swapping at/near tick boundaries that will be fixed in the next release. // For now, we return an error and ask the user to try again with a different swap amount. - return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPriceBigDec} + return SwapResult{}, PoolUpdates{}, types.ComputedSqrtPriceInequalityError{IsZeroForOne: swapStrategy.ZeroForOne(), ComputedSqrtPrice: computedSqrtPrice, NextInitializedTickSqrtPrice: nextInitializedTickSqrtPrice} } else if !sqrtPriceStart.Equal(computedSqrtPrice) { // Otherwise, if the computedSqrtPrice calculated from ComputeSwapWithinBucketInGivenOut(...) does not equal the sqrtPriceStart we started with at the // beginning of this iteration, we set the swapState tick to the corresponding tick of the computedSqrtPrice calculated from ComputeSwapWithinBucketInGivenOut(...) diff --git a/x/twap/export_test.go b/x/twap/export_test.go index f24df4fed22..bd2a05f86e5 100644 --- a/x/twap/export_test.go +++ b/x/twap/export_test.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/osmosis-labs/osmosis/osmomath" - "github.com/osmosis-labs/osmosis/osmoutils" "github.com/osmosis-labs/osmosis/v19/x/twap/types" ) From 6759029e4c6205fd1b1c36f1cc8779dcee647588 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 30 Aug 2023 16:02:10 -0400 Subject: [PATCH 13/13] new lints --- x/concentrated-liquidity/simulation/sim_msgs.go | 3 +-- x/superfluid/keeper/epoch.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x/concentrated-liquidity/simulation/sim_msgs.go b/x/concentrated-liquidity/simulation/sim_msgs.go index a88f4b9410b..533c0c82ac5 100644 --- a/x/concentrated-liquidity/simulation/sim_msgs.go +++ b/x/concentrated-liquidity/simulation/sim_msgs.go @@ -50,8 +50,7 @@ func RandomMsgCreateConcentratedPool(k clkeeper.Keeper, sim *osmosimtypes.SimCtx k.SetParams(ctx, defaultParams) // make sure the denoms are valid authorized quote denoms - authorizedQuoteDenoms := k.GetAuthorizedQuoteDenoms(ctx) - authorizedQuoteDenoms = append(defaultParams.AuthorizedQuoteDenoms, preparePoolInfo.coin1.Denom, preparePoolInfo.coin0.Denom) + authorizedQuoteDenoms := append(k.GetAuthorizedQuoteDenoms(ctx), preparePoolInfo.coin1.Denom, preparePoolInfo.coin0.Denom) k.SetAuthorizedQuoteDenoms(ctx, authorizedQuoteDenoms) denomMetaData := banktypes.Metadata{ diff --git a/x/superfluid/keeper/epoch.go b/x/superfluid/keeper/epoch.go index f0ce7186e57..73864f7bf61 100644 --- a/x/superfluid/keeper/epoch.go +++ b/x/superfluid/keeper/epoch.go @@ -139,7 +139,7 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup k.SetOsmoEquivalentMultiplier(ctx, newEpochNumber, asset.Denom, multiplier) } else if asset.AssetType == types.SuperfluidAssetTypeConcentratedShare { // https://github.com/osmosis-labs/osmosis/issues/6229 - osmoutils.ApplyFuncIfNoError(ctx, func(cacheCtx sdk.Context) error { + _ = osmoutils.ApplyFuncIfNoError(ctx, func(cacheCtx sdk.Context) error { return k.updateConcentratedOsmoEquivalentMultiplier(cacheCtx, asset, newEpochNumber) }) } else if asset.AssetType == types.SuperfluidAssetTypeNative {