From b6d342ac7a2e23354c6bcf27935293a51753fc88 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 12 Apr 2022 11:30:33 -0400 Subject: [PATCH] refactor: add PokeTokenWeights to Pool interface (#1232) * updates * updates * updates * updates * updates * updates * updates * updates --- app/apptesting/test_suite.go | 13 ++-- app/upgrades/v5/whitelist_feetokens.go | 2 +- app/wasm/queries.go | 4 +- x/gamm/genesis.go | 3 +- x/gamm/genesis_test.go | 13 ++-- x/gamm/keeper/grpc_query.go | 14 ++-- x/gamm/keeper/invariants.go | 2 +- x/gamm/keeper/multihop_test.go | 11 ++-- x/gamm/keeper/pool.go | 15 +++-- x/gamm/keeper/pool_service.go | 7 +- x/gamm/keeper/pool_service_test.go | 6 +- x/gamm/pool-models/balancer/amm_test.go | 3 +- x/gamm/pool-models/balancer/balancer_pool.go | 64 +++++++++++-------- .../balancer/balancer_pool_test.go | 10 +-- x/gamm/pool-models/stableswap/pool.go | 7 +- x/gamm/types/pool.go | 7 ++ x/pool-incentives/keeper/grpc_query_test.go | 6 +- x/pool-incentives/keeper/keeper_test.go | 2 +- x/superfluid/keeper/epoch.go | 6 +- x/superfluid/keeper/hooks_test.go | 2 +- x/superfluid/simulation/proposals.go | 6 +- x/superfluid/types/expected_keepers.go | 5 +- 22 files changed, 117 insertions(+), 91 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 1996505c13a..94eaaf924ee 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -6,24 +6,21 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/simapp" - - abci "github.com/tendermint/tendermint/abci/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - sdk "github.com/cosmos/cosmos-sdk/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/ed25519" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/osmosis-labs/osmosis/v7/app" "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" lockupkeeper "github.com/osmosis-labs/osmosis/v7/x/lockup/keeper" lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" - - "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto/ed25519" ) type KeeperTestHelper struct { @@ -179,7 +176,7 @@ func (keeperTestHelper *KeeperTestHelper) SetupGammPoolsWithBondDenomMultiplier( poolId, err := keeperTestHelper.App.GAMMKeeper.CreatePool(keeperTestHelper.Ctx, msg) keeperTestHelper.Require().NoError(err) - pool, err := keeperTestHelper.App.GAMMKeeper.GetPool(keeperTestHelper.Ctx, poolId) + pool, err := keeperTestHelper.App.GAMMKeeper.GetPoolAndPoke(keeperTestHelper.Ctx, poolId) keeperTestHelper.Require().NoError(err) pools = append(pools, pool) diff --git a/app/upgrades/v5/whitelist_feetokens.go b/app/upgrades/v5/whitelist_feetokens.go index 7149837e83c..2345ea81559 100644 --- a/app/upgrades/v5/whitelist_feetokens.go +++ b/app/upgrades/v5/whitelist_feetokens.go @@ -58,7 +58,7 @@ func InitialWhitelistedFeetokens(ctx sdk.Context, gamm *gammkeeper.Keeper) []typ panic(err) } - pool, poolExistsErr := gamm.GetPool(ctx, poolId) + pool, poolExistsErr := gamm.GetPoolAndPoke(ctx, poolId) _ = pool if poolExistsErr != nil { continue diff --git a/app/wasm/queries.go b/app/wasm/queries.go index 4d15cb4de95..8aa971bda31 100644 --- a/app/wasm/queries.go +++ b/app/wasm/queries.go @@ -24,7 +24,7 @@ func NewQueryPlugin( } func (qp QueryPlugin) GetPoolState(ctx sdk.Context, poolID uint64) (*wasmbindings.PoolAssets, error) { - poolData, err := qp.gammKeeper.GetPool(ctx, poolID) + poolData, err := qp.gammKeeper.GetPoolAndPoke(ctx, poolID) if err != nil { return nil, sdkerrors.Wrap(err, "gamm get pool") } @@ -50,7 +50,7 @@ func (qp QueryPlugin) GetSpotPrice(ctx sdk.Context, spotPrice *wasmbindings.Spot return nil, sdkerrors.Wrap(err, "gamm get spot price") } if withSwapFee { - poolData, err := qp.gammKeeper.GetPool(ctx, poolId) + poolData, err := qp.gammKeeper.GetPoolAndPoke(ctx, poolId) if err != nil { return nil, sdkerrors.Wrap(err, "gamm get pool") } diff --git a/x/gamm/genesis.go b/x/gamm/genesis.go index 3929bf9fcce..a0155e989e1 100644 --- a/x/gamm/genesis.go +++ b/x/gamm/genesis.go @@ -3,6 +3,7 @@ package gamm import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v7/x/gamm/keeper" "github.com/osmosis-labs/osmosis/v7/x/gamm/types" ) @@ -36,7 +37,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState, // ExportGenesis returns the capability module's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - pools, err := k.GetPools(ctx) + pools, err := k.GetPoolsAndPoke(ctx) if err != nil { panic(err) } diff --git a/x/gamm/genesis_test.go b/x/gamm/genesis_test.go index f6518a8edc7..1240407b0b1 100644 --- a/x/gamm/genesis_test.go +++ b/x/gamm/genesis_test.go @@ -6,14 +6,15 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - osmoapp "github.com/osmosis-labs/osmosis/v7/app" - "github.com/osmosis-labs/osmosis/v7/x/gamm" - "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" - "github.com/osmosis-labs/osmosis/v7/x/gamm/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + osmoapp "github.com/osmosis-labs/osmosis/v7/app" + "github.com/osmosis-labs/osmosis/v7/x/gamm" + "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" + "github.com/osmosis-labs/osmosis/v7/x/gamm/types" ) func TestGammInitGenesis(t *testing.T) { @@ -47,7 +48,7 @@ func TestGammInitGenesis(t *testing.T) { }, app.AppCodec()) require.Equal(t, app.GAMMKeeper.GetNextPoolNumberAndIncrement(ctx), uint64(2)) - poolStored, err := app.GAMMKeeper.GetPool(ctx, 1) + poolStored, err := app.GAMMKeeper.GetPoolAndPoke(ctx, 1) require.NoError(t, err) require.Equal(t, balancerPool.GetId(), poolStored.GetId()) require.Equal(t, balancerPool.GetAddress(), poolStored.GetAddress()) @@ -58,7 +59,7 @@ func TestGammInitGenesis(t *testing.T) { // require.Equal(t, balancerPool.GetAllPoolAssets(), poolStored.GetAllPoolAssets()) require.Equal(t, balancerPool.String(), poolStored.String()) - _, err = app.GAMMKeeper.GetPool(ctx, 2) + _, err = app.GAMMKeeper.GetPoolAndPoke(ctx, 2) require.Error(t, err) liquidity := app.GAMMKeeper.GetTotalLiquidity(ctx) diff --git a/x/gamm/keeper/grpc_query.go b/x/gamm/keeper/grpc_query.go index 2436d7af06f..8b1f24d77a6 100644 --- a/x/gamm/keeper/grpc_query.go +++ b/x/gamm/keeper/grpc_query.go @@ -53,7 +53,7 @@ func (q Querier) Pool( sdkCtx := sdk.UnwrapSDKContext(ctx) - pool, err := q.Keeper.GetPool(sdkCtx, req.PoolId) + pool, err := q.Keeper.GetPoolAndPoke(sdkCtx, req.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -85,8 +85,8 @@ func (q Querier) Pools( return err } - // Use GetPool function because it runs PokeWeights - poolI, err = q.Keeper.GetPool(sdkCtx, poolI.GetId()) + // Use GetPoolAndPoke function because it runs PokeWeights + poolI, err = q.Keeper.GetPoolAndPoke(sdkCtx, poolI.GetId()) if err != nil { return err } @@ -130,7 +130,7 @@ func (q Querier) PoolParams(ctx context.Context, req *types.QueryPoolParamsReque sdkCtx := sdk.UnwrapSDKContext(ctx) - pool, err := q.Keeper.GetPool(sdkCtx, req.PoolId) + pool, err := q.Keeper.GetPoolAndPoke(sdkCtx, req.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -159,7 +159,7 @@ func (q Querier) TotalPoolLiquidity(ctx context.Context, req *types.QueryTotalPo sdkCtx := sdk.UnwrapSDKContext(ctx) - pool, err := q.Keeper.GetPool(sdkCtx, req.PoolId) + pool, err := q.Keeper.GetPoolAndPoke(sdkCtx, req.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -176,7 +176,7 @@ func (q Querier) TotalShares(ctx context.Context, req *types.QueryTotalSharesReq sdkCtx := sdk.UnwrapSDKContext(ctx) - pool, err := q.Keeper.GetPool(sdkCtx, req.PoolId) + pool, err := q.Keeper.GetPoolAndPoke(sdkCtx, req.PoolId) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -203,7 +203,7 @@ func (q Querier) SpotPrice(ctx context.Context, req *types.QuerySpotPriceRequest sdkCtx := sdk.UnwrapSDKContext(ctx) - pool, err := q.Keeper.GetPool(sdkCtx, req.PoolId) + pool, err := q.Keeper.GetPoolAndPoke(sdkCtx, req.PoolId) if err != nil { return nil, status.Errorf(codes.Internal, "failed to get pool by ID: %s", err) } diff --git a/x/gamm/keeper/invariants.go b/x/gamm/keeper/invariants.go index abe051ab12b..95f970d3f59 100644 --- a/x/gamm/keeper/invariants.go +++ b/x/gamm/keeper/invariants.go @@ -29,7 +29,7 @@ func AllInvariants(keeper Keeper, bk types.BankKeeper) sdk.Invariant { // pool assets func PoolAccountInvariant(keeper Keeper, bk types.BankKeeper) sdk.Invariant { return func(ctx sdk.Context) (string, bool) { - pools, err := keeper.GetPools(ctx) + pools, err := keeper.GetPoolsAndPoke(ctx) if err != nil { return sdk.FormatInvariant(types.ModuleName, poolBalanceInvariantName, "\tgamm pool retrieval failed"), true diff --git a/x/gamm/keeper/multihop_test.go b/x/gamm/keeper/multihop_test.go index f704f4453a5..b7ef8565f25 100644 --- a/x/gamm/keeper/multihop_test.go +++ b/x/gamm/keeper/multihop_test.go @@ -59,7 +59,7 @@ func (suite *KeeperTestSuite) TestBalancerPoolSimpleMultihopSwapExactAmountIn() if i != 0 { tokenInDenom = test.param.routes[i-1].TokenOutDenom } - pool, err := keeper.GetPool(suite.ctx, route.PoolId) + pool, err := keeper.GetPoolAndPoke(suite.ctx, route.PoolId) suite.NoError(err, "test: %v", test.name) sp, err := pool.SpotPrice(suite.ctx, tokenInDenom, route.TokenOutDenom) @@ -80,7 +80,8 @@ func (suite *KeeperTestSuite) TestBalancerPoolSimpleMultihopSwapExactAmountIn() if i != 0 { tokenInDenom = test.param.routes[i-1].TokenOutDenom } - pool, err := keeper.GetPool(suite.ctx, route.PoolId) + + pool, err := keeper.GetPoolAndPoke(suite.ctx, route.PoolId) suite.NoError(err, "test: %v", test.name) sp, err := pool.SpotPrice(suite.ctx, tokenInDenom, route.TokenOutDenom) @@ -151,7 +152,8 @@ func (suite *KeeperTestSuite) TestBalancerPoolSimpleMultihopSwapExactAmountOut() if i != len(test.param.routes)-1 { tokenOutDenom = test.param.routes[i+1].TokenInDenom } - pool, err := keeper.GetPool(suite.ctx, route.PoolId) + + pool, err := keeper.GetPoolAndPoke(suite.ctx, route.PoolId) suite.NoError(err, "test: %v", test.name) sp, err := pool.SpotPrice(suite.ctx, route.TokenInDenom, tokenOutDenom) @@ -172,7 +174,8 @@ func (suite *KeeperTestSuite) TestBalancerPoolSimpleMultihopSwapExactAmountOut() if i != len(test.param.routes)-1 { tokenOutDenom = test.param.routes[i+1].TokenInDenom } - pool, err := keeper.GetPool(suite.ctx, route.PoolId) + + pool, err := keeper.GetPoolAndPoke(suite.ctx, route.PoolId) suite.NoError(err, "test: %v", test.name) sp, err := pool.SpotPrice(suite.ctx, route.TokenInDenom, tokenOutDenom) diff --git a/x/gamm/keeper/pool.go b/x/gamm/keeper/pool.go index 0fb02c9d08d..655c6e5d8fb 100644 --- a/x/gamm/keeper/pool.go +++ b/x/gamm/keeper/pool.go @@ -20,7 +20,9 @@ func (k Keeper) UnmarshalPool(bz []byte) (types.PoolI, error) { return acc, k.cdc.UnmarshalInterface(bz, &acc) } -func (k Keeper) GetPool(ctx sdk.Context, poolId uint64) (types.PoolI, error) { +// GetPoolAndPoke returns a PoolI based on it's identifier if one exists. Prior +// to returning the pool, the weights of the pool are updated via PokePool. +func (k Keeper) GetPoolAndPoke(ctx sdk.Context, poolId uint64) (types.PoolI, error) { store := ctx.KVStore(k.storeKey) poolKey := types.GetKeyPrefixPools(poolId) if !store.Has(poolKey) { @@ -34,14 +36,14 @@ func (k Keeper) GetPool(ctx sdk.Context, poolId uint64) (types.PoolI, error) { return nil, err } - // pool.PokeTokenWeights(ctx.BlockTime()) + pool.PokePool(ctx.BlockTime()) return pool, nil } // Get pool, and check if the pool is active / allowed to be swapped against func (k Keeper) getPoolForSwap(ctx sdk.Context, poolId uint64) (types.PoolI, error) { - pool, err := k.GetPool(ctx, poolId) + pool, err := k.GetPoolAndPoke(ctx, poolId) if err != nil { return &balancer.Pool{}, err } @@ -57,7 +59,7 @@ func (k Keeper) iterator(ctx sdk.Context, prefix []byte) sdk.Iterator { return sdk.KVStorePrefixIterator(store, prefix) } -func (k Keeper) GetPools(ctx sdk.Context) (res []types.PoolI, err error) { +func (k Keeper) GetPoolsAndPoke(ctx sdk.Context) (res []types.PoolI, err error) { iter := k.iterator(ctx, types.KeyPrefixPools) defer iter.Close() @@ -69,12 +71,11 @@ func (k Keeper) GetPools(ctx sdk.Context) (res []types.PoolI, err error) { return nil, err } - // pool.PokeTokenWeights(ctx.BlockTime()) - + pool.PokePool(ctx.BlockTime()) res = append(res, pool) } - return + return res, nil } func (k Keeper) SetPool(ctx sdk.Context, pool types.PoolI) error { diff --git a/x/gamm/keeper/pool_service.go b/x/gamm/keeper/pool_service.go index 9257b3887fa..54034a03b1d 100644 --- a/x/gamm/keeper/pool_service.go +++ b/x/gamm/keeper/pool_service.go @@ -21,10 +21,11 @@ func (k Keeper) CalculateSpotPrice( baseAssetDenom string, quoteAssetDenom string, ) (sdk.Dec, error) { - pool, err := k.GetPool(ctx, poolID) + pool, err := k.GetPoolAndPoke(ctx, poolID) if err != nil { return sdk.Dec{}, err } + return pool.SpotPrice(ctx, baseAssetDenom, quoteAssetDenom) } @@ -182,7 +183,7 @@ func (k Keeper) JoinPoolNoSwap( shareOutAmount sdk.Int, tokenInMaxs sdk.Coins, ) (err error) { - pool, err := k.GetPool(ctx, poolId) + pool, err := k.GetPoolAndPoke(ctx, poolId) if err != nil { return err } @@ -330,7 +331,7 @@ func (k Keeper) ExitPool( shareInAmount sdk.Int, tokenOutMins sdk.Coins, ) (exitCoins sdk.Coins, err error) { - pool, err := k.GetPool(ctx, poolId) + pool, err := k.GetPoolAndPoke(ctx, poolId) if err != nil { return sdk.Coins{}, err } diff --git a/x/gamm/keeper/pool_service_test.go b/x/gamm/keeper/pool_service_test.go index e36768fdebb..e9dbdf7a446 100644 --- a/x/gamm/keeper/pool_service_test.go +++ b/x/gamm/keeper/pool_service_test.go @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestCreateBalancerPool() { poolId, err := keeper.CreatePool(suite.ctx, msg) suite.Require().NoError(err) - pool, err := keeper.GetPool(suite.ctx, poolId) + pool, err := keeper.GetPoolAndPoke(suite.ctx, poolId) suite.Require().NoError(err) suite.Require().Equal(types.InitPoolSharesSupply.String(), pool.GetTotalShares().String(), fmt.Sprintf("share token should be minted as %s initially", types.InitPoolSharesSupply.String()), @@ -220,7 +220,7 @@ func (suite *KeeperTestSuite) TestCreateBalancerPool() { }, defaultPoolAssets, defaultFutureGovernor) _, err := keeper.CreatePool(suite.ctx, msg) suite.Require().NoError(err) - pools, err := keeper.GetPools(suite.ctx) + pools, err := keeper.GetPoolsAndPoke(suite.ctx) suite.Require().Len(pools, 1) suite.Require().NoError(err) }, @@ -236,7 +236,7 @@ func (suite *KeeperTestSuite) TestCreateBalancerPool() { }, defaultPoolAssets, defaultFutureGovernor) _, err := keeper.CreatePool(suite.ctx, msg) suite.Require().NoError(err) - pools, err := keeper.GetPools(suite.ctx) + pools, err := keeper.GetPoolsAndPoke(suite.ctx) suite.Require().Len(pools, 1) suite.Require().NoError(err) }, diff --git a/x/gamm/pool-models/balancer/amm_test.go b/x/gamm/pool-models/balancer/amm_test.go index 03768c74707..b8df955f09f 100644 --- a/x/gamm/pool-models/balancer/amm_test.go +++ b/x/gamm/pool-models/balancer/amm_test.go @@ -2,6 +2,7 @@ package balancer_test import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" ) @@ -56,7 +57,7 @@ func (suite *KeeperTestSuite) TestBalancerSpotPrice() { tc.quoteDenomPoolInput, ) - pool, err := suite.App.GAMMKeeper.GetPool(suite.Ctx, poolId) + pool, err := suite.App.GAMMKeeper.GetPoolAndPoke(suite.Ctx, poolId) suite.Require().NoError(err, "test: %s", tc.name) balancerPool, isPool := pool.(*balancer.Pool) suite.Require().True(isPool, "test: %s", tc.name) diff --git a/x/gamm/pool-models/balancer/balancer_pool.go b/x/gamm/pool-models/balancer/balancer_pool.go index 6d916c044a4..0efdfa8550b 100644 --- a/x/gamm/pool-models/balancer/balancer_pool.go +++ b/x/gamm/pool-models/balancer/balancer_pool.go @@ -377,55 +377,63 @@ func (pa *Pool) updateAllWeights(newWeights []PoolAsset) { pa.TotalWeight = totalWeight } -// PokeTokenWeights checks to see if the pool's token weights need to be updated, -// and if so, does so. -func (pa *Pool) PokeTokenWeights(blockTime time.Time) { - // Pool weights aren't changing, do nothing. - poolWeightsChanging := (pa.PoolParams.SmoothWeightChangeParams != nil) +// PokePool checks to see if the pool's token weights need to be updated, and +// if so, does so. +func (pa *Pool) PokePool(blockTime time.Time) { + // check if pool weights didn't change + poolWeightsChanging := pa.PoolParams.SmoothWeightChangeParams != nil if !poolWeightsChanging { return } - // Pool weights are changing. - // TODO: Add intra-block cache check that we haven't already poked - // the block yet. + params := *pa.PoolParams.SmoothWeightChangeParams - // the weights w(t) for the pool at time `t` is the following: - // t <= start_time: w(t) = initial_pool_weights - // start_time < t <= start_time + duration: + // The weights w(t) for the pool at time `t` is defined in one of three + // possible ways: + // + // 1. t <= start_time: w(t) = initial_pool_weights + // + // 2. start_time < t <= start_time + duration: // w(t) = initial_pool_weights + (t - start_time) * // (target_pool_weights - initial_pool_weights) / (duration) - // t > start_time + duration: w(t) = target_pool_weights - - // t <= StartTime - if blockTime.Before(params.StartTime) || params.StartTime.Equal(blockTime) { - // Do nothing + // + // 3. t > start_time + duration: w(t) = target_pool_weights + switch { + case blockTime.Before(params.StartTime) || params.StartTime.Equal(blockTime): + // case 1: t <= start_time return - } else if blockTime.After(params.StartTime.Add(params.Duration)) { - // t > start_time + duration + + case blockTime.After(params.StartTime.Add(params.Duration)): + // case 2: start_time < t <= start_time + duration: + // Update weights to be the target weights. - // TODO: When we add support for adding new assets via this method, - // Ensure the new asset has some token sent with it. + // + // TODO: When we add support for adding new assets via this method, ensure + // the new asset has some token sent with it. pa.updateAllWeights(params.TargetPoolWeights) - // We've finished updating weights, so delete this parameter + + // we've finished updating the weights, so reset the following fields pa.PoolParams.SmoothWeightChangeParams = nil return - } else { - // w(t) = initial_pool_weights + (t - start_time) * - // (target_pool_weights - initial_pool_weights) / (duration) - // We first compute percent duration elapsed = (t - start_time) / duration, via Unix time. + + default: + // case 3: t > start_time + duration: w(t) = target_pool_weights + shiftedBlockTime := blockTime.Sub(params.StartTime).Milliseconds() percentDurationElapsed := sdk.NewDec(shiftedBlockTime).QuoInt64(params.Duration.Milliseconds()) - // If the duration elapsed is equal to the total time, - // or a rounding error makes it seem like it is, just set to target weight + + // If the duration elapsed is equal to the total time, or a rounding error + // makes it seem like it is, just set to target weight. if percentDurationElapsed.GTE(sdk.OneDec()) { pa.updateAllWeights(params.TargetPoolWeights) return } + + // below will be auto-truncated according to internal weight precision routine totalWeightsDiff := subPoolAssetWeights(params.TargetPoolWeights, params.InitialPoolWeights) - // Below will be auto-truncated according to internal weight precision routine. scaledDiff := poolAssetsMulDec(totalWeightsDiff, percentDurationElapsed) updatedWeights := addPoolAssetWeights(params.InitialPoolWeights, scaledDiff) + pa.updateAllWeights(updatedWeights) } } diff --git a/x/gamm/pool-models/balancer/balancer_pool_test.go b/x/gamm/pool-models/balancer/balancer_pool_test.go index 29050c5e868..85e6040ef6a 100644 --- a/x/gamm/pool-models/balancer/balancer_pool_test.go +++ b/x/gamm/pool-models/balancer/balancer_pool_test.go @@ -359,7 +359,7 @@ func TestBalancerPoolPokeTokenWeights(t *testing.T) { defaultStartTime := time.Unix(1618703511, 0) defaultStartTimeUnix := defaultStartTime.Unix() defaultDuration := 100 * time.Second - floatGuaranteedPrecison := float64(GuaranteedWeightPrecision) + floatGuaranteedPrecision := float64(GuaranteedWeightPrecision) // testCases don't need to be ordered by time. but the blockTime should be // less than the end time of the SmoothWeightChange. Testing past the end time @@ -421,7 +421,7 @@ func TestBalancerPoolPokeTokenWeights(t *testing.T) { expectedWeights: []sdk.Int{ sdk.NewInt(1 * GuaranteedWeightPrecision), // Quarter way between 1 & 2 = 1.25 - sdk.NewInt(int64(1.25 * floatGuaranteedPrecison)), + sdk.NewInt(int64(1.25 * floatGuaranteedPrecision)), }, }, }, @@ -469,9 +469,9 @@ func TestBalancerPoolPokeTokenWeights(t *testing.T) { blockTime: time.Unix(defaultStartTimeUnix+25, 0), expectedWeights: []sdk.Int{ // Quarter way between 2 & 4 = 2.5 - sdk.NewInt(int64(2.5 * floatGuaranteedPrecison)), + sdk.NewInt(int64(2.5 * floatGuaranteedPrecision)), // Quarter way between 2 & 1 = 1.75 - sdk.NewInt(int64(1.75 * floatGuaranteedPrecison)), + sdk.NewInt(int64(1.75 * floatGuaranteedPrecision)), }, }, }, @@ -546,7 +546,7 @@ func TestBalancerPoolPokeTokenWeights(t *testing.T) { testCases := addDefaultCases(paramsCopy, tc.cases) for caseNum, testCase := range testCases { - pacc.PokeTokenWeights(testCase.blockTime) + pacc.PokePool(testCase.blockTime) totalWeight := sdk.ZeroInt() diff --git a/x/gamm/pool-models/stableswap/pool.go b/x/gamm/pool-models/stableswap/pool.go index 8f941d15a50..1811d6a8d88 100644 --- a/x/gamm/pool-models/stableswap/pool.go +++ b/x/gamm/pool-models/stableswap/pool.go @@ -2,7 +2,8 @@ package stableswap import ( "encoding/json" - fmt "fmt" + "fmt" + "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -84,3 +85,7 @@ func (pa *Pool) ExitPool(ctx sdk.Context, numShares sdk.Int, exitFee sdk.Dec) (e func (pa Pool) CalcExitPoolShares(ctx sdk.Context, numShares sdk.Int, exitFee sdk.Dec) (exitedCoins sdk.Coins, err error) { return sdk.Coins{}, types.ErrNotImplemented } + +func (pa *Pool) PokePool(blockTime time.Time) { + panic("not implemented yet") +} diff --git a/x/gamm/types/pool.go b/x/gamm/types/pool.go index 194a858fdb3..be697f681e2 100644 --- a/x/gamm/types/pool.go +++ b/x/gamm/types/pool.go @@ -1,8 +1,11 @@ package types import ( + "time" + sdk "github.com/cosmos/cosmos-sdk/types" proto "github.com/gogo/protobuf/proto" + "github.com/osmosis-labs/osmosis/v7/v043_temp/address" ) @@ -65,6 +68,10 @@ type PoolI interface { // CalcExitPoolShares returns how many coins ExitPool would return on these arguments. // This does not mutate the pool, or state. CalcExitPoolShares(ctx sdk.Context, numShares sdk.Int, exitFee sdk.Dec) (exitedCoins sdk.Coins, err error) + + // PokePool determines if a pool's weights need to be updated and updates + // them if so. + PokePool(blockTime time.Time) } func NewPoolAddress(poolId uint64) sdk.AccAddress { diff --git a/x/pool-incentives/keeper/grpc_query_test.go b/x/pool-incentives/keeper/grpc_query_test.go index 2640a413144..45b8a7b7222 100644 --- a/x/pool-incentives/keeper/grpc_query_test.go +++ b/x/pool-incentives/keeper/grpc_query_test.go @@ -4,10 +4,10 @@ import ( "context" "time" + sdk "github.com/cosmos/cosmos-sdk/types" + gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" - - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/types" ) @@ -30,7 +30,7 @@ func (suite *KeeperTestSuite) TestGaugeIds() { suite.Equal(3, len(lockableDurations)) poolId := suite.prepareBalancerPool() - pool, err := suite.app.GAMMKeeper.GetPool(suite.ctx, poolId) + pool, err := suite.app.GAMMKeeper.GetPoolAndPoke(suite.ctx, poolId) suite.NoError(err) res, err := queryClient.GaugeIds(context.Background(), &types.QueryGaugeIdsRequest{ diff --git a/x/pool-incentives/keeper/keeper_test.go b/x/pool-incentives/keeper/keeper_test.go index 374ca0766ad..cbebccf46fb 100644 --- a/x/pool-incentives/keeper/keeper_test.go +++ b/x/pool-incentives/keeper/keeper_test.go @@ -111,7 +111,7 @@ func (suite *KeeperTestSuite) TestCreateBalancerPoolGauges() { for i := 0; i < 3; i++ { poolId := suite.prepareBalancerPool() - pool, err := suite.app.GAMMKeeper.GetPool(suite.ctx, poolId) + pool, err := suite.app.GAMMKeeper.GetPoolAndPoke(suite.ctx, poolId) suite.NoError(err) poolLpDenom := gammtypes.GetPoolShareDenom(pool.GetId()) diff --git a/x/superfluid/keeper/epoch.go b/x/superfluid/keeper/epoch.go index 78d03f98dd6..77a63e06e1b 100644 --- a/x/superfluid/keeper/epoch.go +++ b/x/superfluid/keeper/epoch.go @@ -4,12 +4,12 @@ import ( "errors" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v7/osmoutils" gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" - "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" - incentivestypes "github.com/osmosis-labs/osmosis/v7/x/incentives/types" lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" + "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" ) func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ int64) { @@ -99,7 +99,7 @@ func (k Keeper) UpdateOsmoEquivalentMultipliers(ctx sdk.Context, asset types.Sup if asset.AssetType == types.SuperfluidAssetTypeLPShare { // LP_token_Osmo_equivalent = OSMO_amount_on_pool / LP_token_supply poolId := gammtypes.MustGetPoolIdFromShareDenom(asset.Denom) - pool, err := k.gk.GetPool(ctx, poolId) + pool, err := k.gk.GetPoolAndPoke(ctx, poolId) if err != nil { // Pool has been unexpectedly deleted k.Logger(ctx).Error(err.Error()) diff --git a/x/superfluid/keeper/hooks_test.go b/x/superfluid/keeper/hooks_test.go index e946a95d2a1..859b2a96b5a 100644 --- a/x/superfluid/keeper/hooks_test.go +++ b/x/superfluid/keeper/hooks_test.go @@ -54,7 +54,7 @@ func (suite *KeeperTestSuite) TestSuperfluidAfterEpochEnd() { suite.checkIntermediaryAccountDelegations(intermediaryAccs) // run swap and set spot price - pool, err := suite.App.GAMMKeeper.GetPool(suite.Ctx, poolIds[0]) + pool, err := suite.App.GAMMKeeper.GetPoolAndPoke(suite.Ctx, poolIds[0]) suite.Require().NoError(err) coins := pool.GetTotalPoolLiquidity(suite.Ctx) suite.SwapAndSetSpotPrice(poolIds[0], coins[1], coins[0]) diff --git a/x/superfluid/simulation/proposals.go b/x/superfluid/simulation/proposals.go index 71fabae56aa..eecb67e3cc3 100644 --- a/x/superfluid/simulation/proposals.go +++ b/x/superfluid/simulation/proposals.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" - "github.com/cosmos/cosmos-sdk/x/simulation" + + gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" "github.com/osmosis-labs/osmosis/v7/x/superfluid/keeper" "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" ) @@ -31,7 +31,7 @@ func ProposalContents(k keeper.Keeper, gk types.GammKeeper) []simtypes.WeightedP // SimulateSetSuperfluidAssetsProposal generates random superfluid asset set proposal content. func SimulateSetSuperfluidAssetsProposal(k keeper.Keeper, gk types.GammKeeper) simtypes.ContentSimulatorFn { return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { - pools, err := gk.GetPools(ctx) + pools, err := gk.GetPoolsAndPoke(ctx) if err != nil { return nil } diff --git a/x/superfluid/types/expected_keepers.go b/x/superfluid/types/expected_keepers.go index 1705a34511f..82cb0785cda 100644 --- a/x/superfluid/types/expected_keepers.go +++ b/x/superfluid/types/expected_keepers.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + epochstypes "github.com/osmosis-labs/osmosis/v7/x/epochs/types" gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" incentivestypes "github.com/osmosis-labs/osmosis/v7/x/incentives/types" @@ -39,8 +40,8 @@ type LockupMsgServer interface { // GammKeeper defines the expected interface needed for superfluid module. type GammKeeper interface { CalculateSpotPrice(ctx sdk.Context, poolId uint64, tokenInDenom, tokenOutDenom string) (sdk.Dec, error) - GetPool(ctx sdk.Context, poolId uint64) (gammtypes.PoolI, error) - GetPools(ctx sdk.Context) (res []gammtypes.PoolI, err error) + GetPoolAndPoke(ctx sdk.Context, poolId uint64) (gammtypes.PoolI, error) + GetPoolsAndPoke(ctx sdk.Context) (res []gammtypes.PoolI, err error) } type BankKeeper interface {