From 59a32947e1d5bd2c3a773b56002f494582118c11 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Tue, 21 Feb 2023 21:59:36 -0500 Subject: [PATCH 01/17] migrate stXXX/XXX constant product pool -> stableswap pool --- app/upgrades/v15/constants.go | 5 ++ app/upgrades/v15/export_test.go | 5 ++ app/upgrades/v15/upgrade_test.go | 82 +++++++++++++++++++++++++++++++- app/upgrades/v15/upgrades.go | 51 +++++++++++++++++++- x/gamm/keeper/pool.go | 5 ++ 5 files changed, 145 insertions(+), 3 deletions(-) diff --git a/app/upgrades/v15/constants.go b/app/upgrades/v15/constants.go index 4c180a09714..4380dfb74db 100644 --- a/app/upgrades/v15/constants.go +++ b/app/upgrades/v15/constants.go @@ -15,6 +15,11 @@ import ( // UpgradeName defines the on-chain upgrade name for the Osmosis v15 upgrade. const UpgradeName = "v15" +// pool ids to migrate +const stOSMO_OSMOPoolId = 833 +const stJUNO_JUNOPoolId = 817 +const stSTARS_STARSPoolId = 810 + var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, CreateUpgradeHandler: CreateUpgradeHandler, diff --git a/app/upgrades/v15/export_test.go b/app/upgrades/v15/export_test.go index e73d42fff27..cd311fc3cbe 100644 --- a/app/upgrades/v15/export_test.go +++ b/app/upgrades/v15/export_test.go @@ -7,6 +7,7 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" gammkeeper "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + "github.com/osmosis-labs/osmosis/v14/x/poolmanager" poolmanagerkeeper "github.com/osmosis-labs/osmosis/v14/x/poolmanager" ) @@ -21,3 +22,7 @@ func RegisterOsmoIonMetadata(ctx sdk.Context, bankKeeper bankkeeper.Keeper) { func SetICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { setICQParams(ctx, icqKeeper) } + +func MigrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, poolId uint64) { + migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolId) +} diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index 6df58662fc1..30ed1acd1df 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -4,18 +4,29 @@ import ( "reflect" "testing" - gamm "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" - + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" "github.com/osmosis-labs/osmosis/v14/app/apptesting" v15 "github.com/osmosis-labs/osmosis/v14/app/upgrades/v15" + gamm "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + balancer "github.com/osmosis-labs/osmosis/v14/x/gamm/pool-models/balancer" + balancertypes "github.com/osmosis-labs/osmosis/v14/x/gamm/pool-models/balancer" + "github.com/osmosis-labs/osmosis/v14/x/gamm/types" + poolmanagertypes "github.com/osmosis-labs/osmosis/v14/x/poolmanager/types" ) type UpgradeTestSuite struct { apptesting.KeeperTestHelper } +var DefaultAcctFunds sdk.Coins = sdk.NewCoins( + sdk.NewCoin("uosmo", sdk.NewInt(10000000000)), + sdk.NewCoin("foo", sdk.NewInt(10000000)), + sdk.NewCoin("bar", sdk.NewInt(10000000)), + sdk.NewCoin("baz", sdk.NewInt(10000000)), +) + func (suite *UpgradeTestSuite) SetupTest() { suite.Setup() } @@ -67,6 +78,73 @@ func (suite *UpgradeTestSuite) TestMigrateNextPoolIdAndCreatePool() { suite.Require().Equal(gammPoolCreationFee, poolmanagerPoolCreationFee) } + +func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { + suite.SetupTest() // reset + + ctx := suite.Ctx + gammKeeper := suite.App.GAMMKeeper + poolmanagerKeeper := suite.App.PoolManagerKeeper + // bankKeeper := suite.App.BankKeeper + testAccount := suite.TestAccs[0] + + // Mint some assets to the accounts. + suite.FundAcc(testAccount, DefaultAcctFunds) + + // Create the balancer pool + swapFee, err := sdk.NewDecFromStr("0.003") + exitFee, err := sdk.NewDecFromStr("0.025") + poolID, err := suite.App.PoolManagerKeeper.CreatePool( + suite.Ctx, + balancer.NewMsgCreateBalancerPool(suite.TestAccs[0], + balancer.PoolParams{ + SwapFee: swapFee, + ExitFee: exitFee, + }, + []balancertypes.PoolAsset{ + { + Weight: sdk.NewInt(100), + Token: sdk.NewCoin("foo", sdk.NewInt(5000000)), + }, + { + Weight: sdk.NewInt(200), + Token: sdk.NewCoin("bar", sdk.NewInt(5000000)), + }, + }, + ""), + ) + _ = poolID + suite.Require().NoError(err) + + balancerPool, err := gammKeeper.GetPool(suite.Ctx, poolID) + suite.Require().NoError(err) + balancerShares := balancerPool.GetTotalShares() + + // join pool + sharesRequested := types.OneShare.MulRaw(1) + tokenInMaxs := sdk.Coins{} + _, _, err = gammKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, sharesRequested, tokenInMaxs) + suite.Require().Equal(sharesRequested.String(), bankKeeper.GetBalance(suite.Ctx, testAccount, "gamm/pool/1").Amount.String()) + liquidity := gammKeeper.GetTotalLiquidity(suite.Ctx) + suite.Require().Equal("15000bar,15000foo", liquidity.String()) + + // test migrating the balancer pool to a stable pool + v15.MigrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolID) + + // check that the pool is now a stable pool + stablepool, err := gammKeeper.GetPool(ctx, poolID) + suite.Require().NoError(err) + suite.Require().Equal(stablepool.GetType(), poolmanagertypes.Stableswap) + + // check that a user can withdraw from the pool + + // check that a user can swap in the pool + + // check that the number of stableswap LP shares is the same as the number of balancer LP shares + suite.Require().Equal(balancerShares.String(), stablepool.GetTotalShares().String()) + +} + func (suite *UpgradeTestSuite) TestRegisterOsmoIonMetadata() { suite.SetupTest() // reset diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index e6a705f2649..6c16e4a22b3 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -4,11 +4,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v14/wasmbinding" icqkeeper "github.com/strangelove-ventures/async-icq/v4/keeper" icqtypes "github.com/strangelove-ventures/async-icq/v4/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" + "github.com/osmosis-labs/osmosis/v14/wasmbinding" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" @@ -17,6 +18,8 @@ import ( appParams "github.com/osmosis-labs/osmosis/v14/app/params" "github.com/osmosis-labs/osmosis/v14/app/upgrades" gammkeeper "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" + "github.com/osmosis-labs/osmosis/v14/x/gamm/pool-models/stableswap" + gammtypes "github.com/osmosis-labs/osmosis/v14/x/gamm/types" "github.com/osmosis-labs/osmosis/v14/x/poolmanager" poolmanagertypes "github.com/osmosis-labs/osmosis/v14/x/poolmanager/types" ) @@ -47,6 +50,10 @@ func CreateUpgradeHandler( // They are added in this upgrade. registerOsmoIonMetadata(ctx, keepers.BankKeeper) + // Stride stXXX/XXX pools are being migrated from the standard balancer curve to the + // solidly stable curve. + migrateBalancerPoolsToSolidlyStable(ctx, keepers.GAMMKeeper, keepers.PoolManagerKeeper) + return mm.RunMigrations(ctx, configurator, fromVM) } } @@ -59,6 +66,48 @@ func setICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { icqKeeper.SetParams(ctx, icqparams) } +func migrateBalancerPoolsToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper) { + // migrate stOSMO_OSMOPoolId, stJUNO_JUNOPoolId, stSTARS_STARSPoolId + pools := []uint64{stOSMO_OSMOPoolId, stJUNO_JUNOPoolId, stSTARS_STARSPoolId} + for _, poolId := range pools { + migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolId) + } +} + +func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, poolId uint64) { + // fetch the pool with the given poolId + balancerPool, err := gammKeeper.GetPool(ctx, poolId) + if err != nil { + panic(err) + } + + // initialize the stableswap pool + stableswapPool, err := stableswap.NewStableswapPool( + poolId, + stableswap.PoolParams{SwapFee: balancerPool.GetSwapFee(ctx), ExitFee: balancerPool.GetExitFee(ctx)}, + balancerPool.GetTotalPoolLiquidity(ctx), + []uint64{1, 1}, + "osmo1k8c2m5cn322akk5wy8lpt87dd2f4yh9afcd7af", // Stride Foundation 2/3 multisig + "", + ) + if err != nil { + panic(err) + } + + // ensure the number of stableswap LP shares is the same as the number of balancer LP shares + totalShares := sdk.NewCoin( + gammtypes.GetPoolShareDenom(poolId), + balancerPool.GetTotalShares(), + ) + stableswapPool.TotalShares = totalShares + + // overwrite the balancer pool with the new stableswap pool + err = gammKeeper.OverwritePool(ctx, &stableswapPool) + if err != nil { + panic(err) + } +} + func migrateNextPoolId(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper) { // N.B: pool id in gamm is to be deprecated in the future // Instead,it is moved to poolmanager. diff --git a/x/gamm/keeper/pool.go b/x/gamm/keeper/pool.go index 08791b45770..0770861cade 100644 --- a/x/gamm/keeper/pool.go +++ b/x/gamm/keeper/pool.go @@ -105,6 +105,11 @@ func (k Keeper) setPool(ctx sdk.Context, pool poolmanagertypes.PoolI) error { return nil } +// Is this the preferred way to call setPool from the upgrade handler? +func (k Keeper) OverwritePool(ctx sdk.Context, pool poolmanagertypes.PoolI) error { + return k.setPool(ctx, pool) +} + func (k Keeper) DeletePool(ctx sdk.Context, poolId uint64) error { store := ctx.KVStore(k.storeKey) poolKey := types.GetKeyPrefixPools(poolId) From 27ebcd8f08f2fb19aa5182f348ed21346f837f5d Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 12:24:18 -0500 Subject: [PATCH 02/17] update upgrade unittest --- app/upgrades/v15/upgrade_test.go | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index 30ed1acd1df..f5dbab1efff 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -12,7 +12,6 @@ import ( gamm "github.com/osmosis-labs/osmosis/v14/x/gamm/keeper" balancer "github.com/osmosis-labs/osmosis/v14/x/gamm/pool-models/balancer" balancertypes "github.com/osmosis-labs/osmosis/v14/x/gamm/pool-models/balancer" - "github.com/osmosis-labs/osmosis/v14/x/gamm/types" poolmanagertypes "github.com/osmosis-labs/osmosis/v14/x/poolmanager/types" ) @@ -116,18 +115,11 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { _ = poolID suite.Require().NoError(err) + // create the pool balancerPool, err := gammKeeper.GetPool(suite.Ctx, poolID) suite.Require().NoError(err) balancerShares := balancerPool.GetTotalShares() - // join pool - sharesRequested := types.OneShare.MulRaw(1) - tokenInMaxs := sdk.Coins{} - _, _, err = gammKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, sharesRequested, tokenInMaxs) - suite.Require().Equal(sharesRequested.String(), bankKeeper.GetBalance(suite.Ctx, testAccount, "gamm/pool/1").Amount.String()) - liquidity := gammKeeper.GetTotalLiquidity(suite.Ctx) - suite.Require().Equal("15000bar,15000foo", liquidity.String()) - // test migrating the balancer pool to a stable pool v15.MigrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolID) @@ -136,10 +128,6 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.Require().NoError(err) suite.Require().Equal(stablepool.GetType(), poolmanagertypes.Stableswap) - // check that a user can withdraw from the pool - - // check that a user can swap in the pool - // check that the number of stableswap LP shares is the same as the number of balancer LP shares suite.Require().Equal(balancerShares.String(), stablepool.GetTotalShares().String()) From 932c73bf498fa56256d88ba0f7d6ac8ffd12451b Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 12:37:22 -0500 Subject: [PATCH 03/17] send LP tokens to lpWallet --- tests/e2e/configurer/upgrade.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index bfe270e5c1f..fbdede51fee 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -108,6 +108,7 @@ func (uc *UpgradeConfigurer) ConfigureChain(chainConfig *chain.Config) error { func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { const lockupWallet = "lockup-wallet" const lockupWalletSuperfluid = "lockup-wallet-superfluid" + const lpWallet = "lp-wallet" chainA := uc.chainConfigs[0] chainANode, err := chainA.GetDefaultNode() @@ -140,6 +141,20 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { // test lock and add to existing lock for both regular and superfluid lockups (only chainA) chainA.LockAndAddToExistingLock(sdk.NewInt(1000000000000000000), poolShareDenom, lockupWalletAddrA, lockupWalletSuperfluidAddrA) + // LP to pools 833, 817, 810 + // ASSUMPTION: the above pools were intialized in osmosis/tests/e2e/initialization/config.go + // initialize lp wallets + lpWalletAddr := chainANode.CreateWallet(lpWallet) + // send lp tokens to lp wallet for pool 833 + poolDenom833 := fmt.Sprintf("gamm/pool/%d", 833) + chainANode.BankSend("10000000000000000000"+poolDenom833, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) + // send lp tokens to lp wallet for pool 817 + poolDenom817 := fmt.Sprintf("gamm/pool/%d", 817) + chainANode.BankSend("10000000000000000000"+poolDenom817, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) + // send lp tokens to lp wallet for pool 810 + poolDenom810 := fmt.Sprintf("gamm/pool/%d", 810) + chainANode.BankSend("10000000000000000000"+poolDenom810, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) + return nil } From fd7842906eb872663415a2c7b8b318da703f9bea Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 14:13:40 -0500 Subject: [PATCH 04/17] update tests --- tests/e2e/configurer/chain/commands.go | 17 ++++++++++++ tests/e2e/configurer/upgrade.go | 24 ++++++++++------- tests/e2e/e2e_test.go | 36 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index b100a728e54..cc20a0ada26 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -166,6 +166,23 @@ func (n *NodeConfig) SwapExactAmountIn(tokenInCoin, tokenOutMinAmountInt string, n.LogActionF("successfully swapped") } +// osmosisd tx gamm join-pool max-amounts-in pool-id share-amount-out --from
+func (n *NodeConfig) JoinPool(maxAmountsIn string, poolId string, shareAmountOut string, from string) { + n.LogActionF("joining pool %s with maxAmountsIn %s to get shareAmountOut (%s) from (%s)", poolId, maxAmountsIn, shareAmountOut, from) + cmd := []string{"osmosisd", "tx", "gamm", "swap-exact-amount-in", maxAmountsIn, poolId, shareAmountOut, fmt.Sprintf("--from=%s", from)} + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) + require.NoError(n.t, err) + n.LogActionF("successfully joined pool") +} + +func (n *NodeConfig) ExitPool(from, minAmountsOut string, poolId string, shareAmountIn string) { + n.LogActionF("exiting gamm pool") + cmd := []string{"osmosisd", "tx", "gamm", "exit-pool", minAmountsOut, poolId, shareAmountIn, fmt.Sprintf("--from=%s", from)} + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) + require.NoError(n.t, err) + n.LogActionF("successfully exited pool %s, minAmountsOut %s, shareAmountIn %s", poolId, minAmountsOut, shareAmountIn) +} + func (n *NodeConfig) SubmitUpgradeProposal(upgradeVersion string, upgradeHeight int64, initialDeposit sdk.Coin) { n.LogActionF("submitting upgrade proposal %s for height %d", upgradeVersion, upgradeHeight) cmd := []string{"osmosisd", "tx", "gov", "submit-proposal", "software-upgrade", upgradeVersion, fmt.Sprintf("--title=\"%s upgrade\"", upgradeVersion), "--description=\"upgrade proposal submission\"", fmt.Sprintf("--upgrade-height=%d", upgradeHeight), "--upgrade-info=\"\"", "--from=val", fmt.Sprintf("--deposit=%s", initialDeposit)} diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index fbdede51fee..cb702a99254 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "strconv" "testing" "time" @@ -142,18 +143,21 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { chainA.LockAndAddToExistingLock(sdk.NewInt(1000000000000000000), poolShareDenom, lockupWalletAddrA, lockupWalletSuperfluidAddrA) // LP to pools 833, 817, 810 - // ASSUMPTION: the above pools were intialized in osmosis/tests/e2e/initialization/config.go // initialize lp wallets lpWalletAddr := chainANode.CreateWallet(lpWallet) - // send lp tokens to lp wallet for pool 833 - poolDenom833 := fmt.Sprintf("gamm/pool/%d", 833) - chainANode.BankSend("10000000000000000000"+poolDenom833, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) - // send lp tokens to lp wallet for pool 817 - poolDenom817 := fmt.Sprintf("gamm/pool/%d", 817) - chainANode.BankSend("10000000000000000000"+poolDenom817, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) - // send lp tokens to lp wallet for pool 810 - poolDenom810 := fmt.Sprintf("gamm/pool/%d", 810) - chainANode.BankSend("10000000000000000000"+poolDenom810, chainA.NodeConfigs[0].PublicAddress, lpWalletAddr) + // JoinPool 833 from lpWallet + // TODO: updaet the amounts based on the pool initialization + maxAmountsIn833 := strconv.Itoa(1000000000000000000) + shareAmountOut833 := strconv.Itoa(1000000000000000000) + chainANode.JoinPool(maxAmountsIn833, strconv.Itoa(833), shareAmountOut833, lpWalletAddr) + // JoinPool 817 from lpWallet + maxAmountsIn817 := strconv.Itoa(1000000000000000000) + shareAmountOut817 := strconv.Itoa(1000000000000000000) + chainANode.JoinPool(maxAmountsIn817, strconv.Itoa(817), shareAmountOut817, lpWalletAddr) + // JoinPool 810 from lpWallet + maxAmountsIn810 := strconv.Itoa(1000000000000000000) + shareAmountOut810 := strconv.Itoa(1000000000000000000) + chainANode.JoinPool(maxAmountsIn810, strconv.Itoa(810), shareAmountOut810, lpWalletAddr) return nil } diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index c4f7a199bc9..a60f2eb6c4b 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -354,6 +354,42 @@ func (s *IntegrationTestSuite) TestGeometricTwapMigration() { node.SwapExactAmountIn(uosmoIn, minAmountOut, fmt.Sprintf("%d", config.PreUpgradePoolId), otherDenom, swapWalletAddr) } +// TestMigrateBalancerToStable tests that balancer to stable swap +// pool migrations run successfully. It does so by attempting to +// execute swaps and exit the pool for an account that is LPing +// the pool post-upgrade. +func (s *IntegrationTestSuite) TestMigrateBalancerToStable() { + if s.skipUpgrade { + s.T().Skip("Skipping upgrade tests") + } + + const ( + // This pool gets initialized pre-upgrade and migrated in the upgrade. + // TODO: Update these amounts to reflect the genesis initialization + swapAmountIn = "1000000uosmo" + swapMinAmountOut = "1" + otherDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" + lpWallet = "lp-wallet" + exitMinAmountOut = "1" + exitShareAmountIn = "1" + ) + + chainA := s.configurer.GetChainConfig(0) + node, err := chainA.GetDefaultNode() + s.Require().NoError(err) + + // pools migrated to stable swap + pools := []uint{833, 817, 810} + lpWalletAddr := node.CreateWallet(lpWallet) + + for _, poolID := range pools { + // execute a swap on the pool + node.SwapExactAmountIn(swapAmountIn, swapMinAmountOut, fmt.Sprintf("%d", poolID), otherDenom, lpWalletAddr) + // exit the pool + node.ExitPool(lpWalletAddr, exitMinAmountOut, fmt.Sprintf("%d", poolID), exitShareAmountIn) + } +} + // TestIBCTokenTransfer tests that IBC token transfers work as expected. // Additionally, it attempst to create a pool with IBC denoms. func (s *IntegrationTestSuite) TestIBCTokenTransferAndCreatePool() { From 09dd27f3f5a848ccfb3bc5b12415876b5affa1f0 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 16:55:20 -0500 Subject: [PATCH 05/17] add join, exit unittest --- app/upgrades/v15/upgrade_test.go | 19 ++++++++++++++++--- app/upgrades/v15/upgrades.go | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index f5dbab1efff..8cea2ab482e 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -112,13 +112,19 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { }, ""), ) - _ = poolID suite.Require().NoError(err) - // create the pool + // Join the pool + shareOutAmount := sdk.NewInt(10000000) + tokenInMaxs := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(5000000)), sdk.NewCoin("bar", sdk.NewInt(5000000))) + _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) + suite.Require().NoError(err) + + // shares before migration balancerPool, err := gammKeeper.GetPool(suite.Ctx, poolID) suite.Require().NoError(err) balancerShares := balancerPool.GetTotalShares() + balancerLiquidity := balancerPool.GetTotalPoolLiquidity(ctx).String() // test migrating the balancer pool to a stable pool v15.MigrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolID) @@ -130,7 +136,14 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { // check that the number of stableswap LP shares is the same as the number of balancer LP shares suite.Require().Equal(balancerShares.String(), stablepool.GetTotalShares().String()) - + // check that the pool liquidity is the same + suite.Require().Equal(balancerLiquidity, stablepool.GetTotalPoolLiquidity(ctx).String()) + // TODO: check bank balances + + // Exit the pool + shareInAmount := sdk.NewInt(200000000) + tokenOutMins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000)), sdk.NewCoin("bar", sdk.NewInt(10000000))) + _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, shareInAmount, tokenOutMins) } func (suite *UpgradeTestSuite) TestRegisterOsmoIonMetadata() { diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 6c16e4a22b3..8d6b433fb84 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -101,6 +101,8 @@ func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper. ) stableswapPool.TotalShares = totalShares + // TODO: check balances + // balancesBefore := // overwrite the balancer pool with the new stableswap pool err = gammKeeper.OverwritePool(ctx, &stableswapPool) if err != nil { From f1332e43671a27b2e9ecaea81ae73ed64d2dc313 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 17:06:50 -0500 Subject: [PATCH 06/17] add checks per comments --- app/upgrades/v15/export_test.go | 4 ++-- app/upgrades/v15/upgrade_test.go | 13 ++++++++----- app/upgrades/v15/upgrades.go | 15 +++++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/upgrades/v15/export_test.go b/app/upgrades/v15/export_test.go index cd311fc3cbe..71be4c6b585 100644 --- a/app/upgrades/v15/export_test.go +++ b/app/upgrades/v15/export_test.go @@ -23,6 +23,6 @@ func SetICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { setICQParams(ctx, icqKeeper) } -func MigrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, poolId uint64) { - migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolId) +func MigrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, bankKeeper bankkeeper.Keeper, poolId uint64) { + migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, bankKeeper, poolId) } diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index 8cea2ab482e..e4ce7871868 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -114,7 +114,7 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { ) suite.Require().NoError(err) - // Join the pool + // join the pool shareOutAmount := sdk.NewInt(10000000) tokenInMaxs := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(5000000)), sdk.NewCoin("bar", sdk.NewInt(5000000))) _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) @@ -125,22 +125,25 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.Require().NoError(err) balancerShares := balancerPool.GetTotalShares() balancerLiquidity := balancerPool.GetTotalPoolLiquidity(ctx).String() + // check balancer pool liquidity using the bank module + balancerBalances := suite.App.BankKeeper.GetAllBalances(ctx, balancerPool.GetAddress()) // test migrating the balancer pool to a stable pool - v15.MigrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolID) + v15.MigrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, suite.App.BankKeeper, poolID) // check that the pool is now a stable pool stablepool, err := gammKeeper.GetPool(ctx, poolID) suite.Require().NoError(err) suite.Require().Equal(stablepool.GetType(), poolmanagertypes.Stableswap) - // check that the number of stableswap LP shares is the same as the number of balancer LP shares suite.Require().Equal(balancerShares.String(), stablepool.GetTotalShares().String()) // check that the pool liquidity is the same suite.Require().Equal(balancerLiquidity, stablepool.GetTotalPoolLiquidity(ctx).String()) - // TODO: check bank balances + // check pool liquidity using the bank module + stableBalances := suite.App.BankKeeper.GetAllBalances(ctx, stablepool.GetAddress()) + suite.Require().Equal(balancerBalances, stableBalances) - // Exit the pool + // exit the pool shareInAmount := sdk.NewInt(200000000) tokenOutMins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000)), sdk.NewCoin("bar", sdk.NewInt(10000000))) _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, shareInAmount, tokenOutMins) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 8d6b433fb84..7c2f7676a02 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -52,7 +52,7 @@ func CreateUpgradeHandler( // Stride stXXX/XXX pools are being migrated from the standard balancer curve to the // solidly stable curve. - migrateBalancerPoolsToSolidlyStable(ctx, keepers.GAMMKeeper, keepers.PoolManagerKeeper) + migrateBalancerPoolsToSolidlyStable(ctx, keepers.GAMMKeeper, keepers.PoolManagerKeeper, keepers.BankKeeper) return mm.RunMigrations(ctx, configurator, fromVM) } @@ -66,15 +66,15 @@ func setICQParams(ctx sdk.Context, icqKeeper *icqkeeper.Keeper) { icqKeeper.SetParams(ctx, icqparams) } -func migrateBalancerPoolsToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper) { +func migrateBalancerPoolsToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, bankKeeper bankkeeper.Keeper) { // migrate stOSMO_OSMOPoolId, stJUNO_JUNOPoolId, stSTARS_STARSPoolId pools := []uint64{stOSMO_OSMOPoolId, stJUNO_JUNOPoolId, stSTARS_STARSPoolId} for _, poolId := range pools { - migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, poolId) + migrateBalancerPoolToSolidlyStable(ctx, gammKeeper, poolmanagerKeeper, bankKeeper, poolId) } } -func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, poolId uint64) { +func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper, bankKeeper bankkeeper.Keeper, poolId uint64) { // fetch the pool with the given poolId balancerPool, err := gammKeeper.GetPool(ctx, poolId) if err != nil { @@ -101,13 +101,16 @@ func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper. ) stableswapPool.TotalShares = totalShares - // TODO: check balances - // balancesBefore := + balancesBefore := bankKeeper.GetAllBalances(ctx, balancerPool.GetAddress()) // overwrite the balancer pool with the new stableswap pool err = gammKeeper.OverwritePool(ctx, &stableswapPool) if err != nil { panic(err) } + balancesAfter := bankKeeper.GetAllBalances(ctx, stableswapPool.GetAddress()) + if !balancesBefore.IsEqual(balancesAfter) { + panic("balances before and after migration are not equal") + } } func migrateNextPoolId(ctx sdk.Context, gammKeeper *gammkeeper.Keeper, poolmanagerKeeper *poolmanager.Keeper) { From 1903f0867939bf34d1b4cb3cf201ec7f96ff0d08 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Wed, 22 Feb 2023 17:08:35 -0500 Subject: [PATCH 07/17] one more comment --- app/upgrades/v15/upgrade_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index e4ce7871868..16320639c4e 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -147,6 +147,11 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { shareInAmount := sdk.NewInt(200000000) tokenOutMins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000)), sdk.NewCoin("bar", sdk.NewInt(10000000))) _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, shareInAmount, tokenOutMins) + + // join again + _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) + suite.Require().NoError(err) + } func (suite *UpgradeTestSuite) TestRegisterOsmoIonMetadata() { From 5ef34d20a83baf5de8b1418ba86c5c63848422ca Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 00:20:14 +0000 Subject: [PATCH 08/17] lp pre-upgrade --- tests/e2e/configurer/chain/commands.go | 7 +++--- tests/e2e/configurer/upgrade.go | 32 ++++++++++++++------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index cc20a0ada26..20792bb94c8 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -166,10 +166,9 @@ func (n *NodeConfig) SwapExactAmountIn(tokenInCoin, tokenOutMinAmountInt string, n.LogActionF("successfully swapped") } -// osmosisd tx gamm join-pool max-amounts-in pool-id share-amount-out --from
-func (n *NodeConfig) JoinPool(maxAmountsIn string, poolId string, shareAmountOut string, from string) { - n.LogActionF("joining pool %s with maxAmountsIn %s to get shareAmountOut (%s) from (%s)", poolId, maxAmountsIn, shareAmountOut, from) - cmd := []string{"osmosisd", "tx", "gamm", "swap-exact-amount-in", maxAmountsIn, poolId, shareAmountOut, fmt.Sprintf("--from=%s", from)} +func (n *NodeConfig) JoinPoolExactAmountIn(tokenIn string, poolId uint64, shareOutMinAmount string, from string) { + n.LogActionF("join-swap-extern-amount-in (%s) (%s) from (%s), pool id (%d)", tokenIn, shareOutMinAmount, from, poolId) + cmd := []string{"osmosisd", "tx", "gamm", "join-swap-extern-amount-in", tokenIn, shareOutMinAmount, fmt.Sprintf("--pool-id=%d", poolId), fmt.Sprintf("--from=%s", from)} _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) n.LogActionF("successfully joined pool") diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index cb702a99254..ee53dc127b9 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "os" - "strconv" "testing" "time" @@ -144,20 +143,23 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { // LP to pools 833, 817, 810 // initialize lp wallets - lpWalletAddr := chainANode.CreateWallet(lpWallet) - // JoinPool 833 from lpWallet - // TODO: updaet the amounts based on the pool initialization - maxAmountsIn833 := strconv.Itoa(1000000000000000000) - shareAmountOut833 := strconv.Itoa(1000000000000000000) - chainANode.JoinPool(maxAmountsIn833, strconv.Itoa(833), shareAmountOut833, lpWalletAddr) - // JoinPool 817 from lpWallet - maxAmountsIn817 := strconv.Itoa(1000000000000000000) - shareAmountOut817 := strconv.Itoa(1000000000000000000) - chainANode.JoinPool(maxAmountsIn817, strconv.Itoa(817), shareAmountOut817, lpWalletAddr) - // JoinPool 810 from lpWallet - maxAmountsIn810 := strconv.Itoa(1000000000000000000) - shareAmountOut810 := strconv.Itoa(1000000000000000000) - chainANode.JoinPool(maxAmountsIn810, strconv.Itoa(810), shareAmountOut810, lpWalletAddr) + amountOfEachTokenToLP := initialization.DefaultStrideDenomBalance / 1_000_000 + shareOutMin := "1" + + lpWalletAddr := chainANode.CreateWalletAndFund(lpWallet, []string{ + fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StOsmoDenom), + fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StJunoDenom), + fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StStarsDenom), + }) + + tokenInStOsmo := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StOsmoDenom) + chainANode.JoinPoolExactAmountIn(tokenInStOsmo, initialization.StOSMO_OSMOPoolId, shareOutMin, lpWalletAddr) + + tokenInStJuno := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StJunoDenom) + chainANode.JoinPoolExactAmountIn(tokenInStJuno, initialization.StJUNO_JUNOPoolId, shareOutMin, lpWalletAddr) + + tokenInStStars := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StStarsDenom) + chainANode.JoinPoolExactAmountIn(tokenInStStars, initialization.StSTARS_STARSPoolId, shareOutMin, lpWalletAddr) return nil } From 11154e36a39051935756f5940fc292bc007abd43 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 00:40:39 +0000 Subject: [PATCH 09/17] clean up and TODOs --- tests/e2e/configurer/config/constants.go | 2 ++ tests/e2e/configurer/upgrade.go | 3 +-- tests/e2e/e2e_test.go | 34 ++++++++++++++++-------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/tests/e2e/configurer/config/constants.go b/tests/e2e/configurer/config/constants.go index cefee9aa4a3..b37e1c2be7e 100644 --- a/tests/e2e/configurer/config/constants.go +++ b/tests/e2e/configurer/config/constants.go @@ -35,4 +35,6 @@ var ( // creation in case more pools are added to genesis // in the future PreUpgradePoolId uint64 = 2 + + StrideMigrateWallet = "stride-migration" ) diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index ee53dc127b9..03c77c62924 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -108,7 +108,6 @@ func (uc *UpgradeConfigurer) ConfigureChain(chainConfig *chain.Config) error { func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { const lockupWallet = "lockup-wallet" const lockupWalletSuperfluid = "lockup-wallet-superfluid" - const lpWallet = "lp-wallet" chainA := uc.chainConfigs[0] chainANode, err := chainA.GetDefaultNode() @@ -146,7 +145,7 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { amountOfEachTokenToLP := initialization.DefaultStrideDenomBalance / 1_000_000 shareOutMin := "1" - lpWalletAddr := chainANode.CreateWalletAndFund(lpWallet, []string{ + lpWalletAddr := chainANode.CreateWalletAndFund(config.StrideMigrateWallet, []string{ fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StOsmoDenom), fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StJunoDenom), fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StStarsDenom), diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index a5cfe8171e4..1aac1735116 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -366,11 +366,11 @@ func (s *IntegrationTestSuite) TestMigrateBalancerToStable() { const ( // This pool gets initialized pre-upgrade and migrated in the upgrade. // TODO: Update these amounts to reflect the genesis initialization - swapAmountIn = "1000000uosmo" - swapMinAmountOut = "1" - otherDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" - lpWallet = "lp-wallet" - exitMinAmountOut = "1" + swapAmountIn = "1000000uosmo" + swapMinAmountOut = "1" + otherDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" + lpWallet = "lp-wallet" + exitMinAmountOut = "1" exitShareAmountIn = "1" ) @@ -378,7 +378,7 @@ func (s *IntegrationTestSuite) TestMigrateBalancerToStable() { node, err := chainA.GetDefaultNode() s.Require().NoError(err) - // pools migrated to stable swap + // pools migrated to stable swap pools := []uint{833, 817, 810} lpWalletAddr := node.CreateWallet(lpWallet) @@ -1160,22 +1160,34 @@ func (s *IntegrationTestSuite) TestStridePoolMigration() { const ( // Configurations for tests/e2e/scripts/pool1A.json // This pool gets initialized pre-upgrade. - minAmountOut = "1" - migrationWallet = "stride-migration" + minAmountOut = "1" ) chainA := s.configurer.GetChainConfig(0) node, err := chainA.GetDefaultNode() s.Require().NoError(err) + // If upgrade tests are run, the wallet is created in the upgrade configurer to create + // LP positions pre-upgrade. + if s.skipUpgrade { + node.CreateWallet(config.StrideMigrateWallet) + } + fundTokens := []string{fmt.Sprintf("1000000%s", initialization.StOsmoDenom), fmt.Sprintf("1000000%s", initialization.StJunoDenom), fmt.Sprintf("1000000%s", initialization.StStarsDenom)} + for _, token := range fundTokens { + node.BankSend(token, initialization.ValidatorWalletName, config.StrideMigrateWallet) + } + otherDenoms := []string{initialization.OsmoDenom, initialization.JunoDenom, initialization.StarsDenom} - swapWalletAddr := node.CreateWalletAndFund(migrationWallet, fundTokens) migrationPools := []uint64{initialization.StOSMO_OSMOPoolId, initialization.StJUNO_JUNOPoolId, initialization.StSTARS_STARSPoolId} for i, poolId := range migrationPools { - // Swap to make sure that - node.SwapExactAmountIn(fundTokens[i], minAmountOut, fmt.Sprintf("%d", poolId), otherDenoms[i], swapWalletAddr) + // TODO: add query and assert to make sure that pool type is stableswap + + // Swap to make sure that migrations did not break anything critical. + node.SwapExactAmountIn(fundTokens[i], minAmountOut, fmt.Sprintf("%d", poolId), otherDenoms[i], config.StrideMigrateWallet) + + // TODO: Exit one share } } From ed2d315521a76ab524988490ff9413fe764c7d25 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 18:40:16 +0000 Subject: [PATCH 10/17] fix e2e --- tests/e2e/configurer/upgrade.go | 8 ++++---- tests/e2e/e2e_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/e2e/configurer/upgrade.go b/tests/e2e/configurer/upgrade.go index 1356bb223a3..d6f223c39c3 100644 --- a/tests/e2e/configurer/upgrade.go +++ b/tests/e2e/configurer/upgrade.go @@ -156,20 +156,20 @@ func (uc *UpgradeConfigurer) CreatePreUpgradeState() error { amountOfEachTokenToLP := initialization.DefaultStrideDenomBalance / 1_000_000 shareOutMin := "1" - lpWalletAddr := chainANode.CreateWalletAndFund(config.StrideMigrateWallet, []string{ + config.StrideMigrateWallet = chainANode.CreateWalletAndFund(config.StrideMigrateWallet, []string{ fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StOsmoDenom), fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StJunoDenom), fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StStarsDenom), }) tokenInStOsmo := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StOsmoDenom) - chainANode.JoinPoolExactAmountIn(tokenInStOsmo, initialization.StOSMO_OSMOPoolId, shareOutMin, lpWalletAddr) + chainANode.JoinPoolExactAmountIn(tokenInStOsmo, initialization.StOSMO_OSMOPoolId, shareOutMin, config.StrideMigrateWallet) tokenInStJuno := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StJunoDenom) - chainANode.JoinPoolExactAmountIn(tokenInStJuno, initialization.StJUNO_JUNOPoolId, shareOutMin, lpWalletAddr) + chainANode.JoinPoolExactAmountIn(tokenInStJuno, initialization.StJUNO_JUNOPoolId, shareOutMin, config.StrideMigrateWallet) tokenInStStars := fmt.Sprintf("%d%s", amountOfEachTokenToLP, initialization.StStarsDenom) - chainANode.JoinPoolExactAmountIn(tokenInStStars, initialization.StSTARS_STARSPoolId, shareOutMin, lpWalletAddr) + chainANode.JoinPoolExactAmountIn(tokenInStStars, initialization.StSTARS_STARSPoolId, shareOutMin, config.StrideMigrateWallet) return nil } diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 0906d322a30..6e2fd7c73da 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1144,7 +1144,7 @@ func (s *IntegrationTestSuite) TestStridePoolMigration() { // If upgrade tests are run, the wallet is created in the upgrade configurer to create // LP positions pre-upgrade. if s.skipUpgrade { - node.CreateWallet(config.StrideMigrateWallet) + config.StrideMigrateWallet = node.CreateWallet(config.StrideMigrateWallet) } fundTokens := []string{fmt.Sprintf("1000000%s", initialization.StOsmoDenom), fmt.Sprintf("1000000%s", initialization.StJunoDenom), fmt.Sprintf("1000000%s", initialization.StStarsDenom)} From 98627d34b05e0ab34068786da3ce3ceb46c6a3bb Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Thu, 23 Feb 2023 14:14:56 -0500 Subject: [PATCH 11/17] add query --- tests/e2e/configurer/chain/queries.go | 12 ++++++++++++ tests/e2e/e2e_test.go | 11 ++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tests/e2e/configurer/chain/queries.go b/tests/e2e/configurer/chain/queries.go index 1483019f17c..434097ec92f 100644 --- a/tests/e2e/configurer/chain/queries.go +++ b/tests/e2e/configurer/chain/queries.go @@ -255,6 +255,18 @@ func (n *NodeConfig) QueryNumPools() uint64 { return numPools.NumPools } +func (n *NodeConfig) QueryPoolType(poolId string) string { + path := fmt.Sprintf("/osmosis/gamm/v1beta1/pool_type/%s", poolId) + bz, err := n.QueryGRPCGateway(path) + require.NoError(n.t, err) + + var poolTypeResponse gammtypes.QueryPoolTypeResponse + err = util.Cdc.UnmarshalJSON(bz, &poolTypeResponse) + require.NoError(n.t, err) + + return poolTypeResponse.PoolType +} + func (n *NodeConfig) QueryConcentratedPositions(address string) []cltypes.FullPositionByOwnerResult { path := fmt.Sprintf("/osmosis/concentratedliquidity/v1beta1/positions/%s", address) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 0906d322a30..d5983e0aba7 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -10,9 +10,10 @@ import ( "time" transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - "github.com/iancoleman/orderedmap" + poolmanagertypes "github.com/osmosis-labs/osmosis/v14/x/poolmanager/types" + "github.com/osmosis-labs/osmosis/v14/tests/e2e/configurer/chain" "github.com/osmosis-labs/osmosis/v14/tests/e2e/util" @@ -1157,11 +1158,15 @@ func (s *IntegrationTestSuite) TestStridePoolMigration() { migrationPools := []uint64{initialization.StOSMO_OSMOPoolId, initialization.StJUNO_JUNOPoolId, initialization.StSTARS_STARSPoolId} for i, poolId := range migrationPools { - // TODO: add query and assert to make sure that pool type is stableswap + // Query and assert to make sure that pool type is stableswap + poolType := node.QueryPoolType(fmt.Sprintf("%d", poolId)) + stableswapType := poolmanagertypes.Stableswap.String() + s.Require().Equal(poolType, stableswapType, "Pool type should be stableswap after upgrade") // Swap to make sure that migrations did not break anything critical. node.SwapExactAmountIn(fundTokens[i], minAmountOut, fmt.Sprintf("%d", poolId), otherDenoms[i], config.StrideMigrateWallet) - // TODO: Exit one share + // Exit one share + node.ExitPool(config.StrideMigrateWallet, fundTokens[i], fmt.Sprintf("%d", poolId), minAmountOut) } } From 56e599d167f5dc17dabbf0184d3eac7566cda360 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Thu, 23 Feb 2023 14:24:06 -0500 Subject: [PATCH 12/17] rm TestMigrateBalancerToStable, update ExitPool in upgrade_test.go --- app/upgrades/v15/upgrade_test.go | 6 ++---- app/upgrades/v15/upgrades.go | 2 +- x/gamm/keeper/pool.go | 5 +++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index d2a09de60dd..2ea88d42eb6 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -126,7 +126,7 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { // join the pool shareOutAmount := sdk.NewInt(10000000) tokenInMaxs := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(5000000)), sdk.NewCoin("bar", sdk.NewInt(5000000))) - _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) + tokenIn, sharesOut, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) suite.Require().NoError(err) // shares before migration @@ -153,9 +153,7 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.Require().Equal(balancerBalances, stableBalances) // exit the pool - shareInAmount := sdk.NewInt(200000000) - tokenOutMins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000)), sdk.NewCoin("bar", sdk.NewInt(10000000))) - _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, shareInAmount, tokenOutMins) + _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, sharesOut, tokenIn) // join again _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) diff --git a/app/upgrades/v15/upgrades.go b/app/upgrades/v15/upgrades.go index 9fc27e715d3..c9ca461b2f6 100644 --- a/app/upgrades/v15/upgrades.go +++ b/app/upgrades/v15/upgrades.go @@ -116,7 +116,7 @@ func migrateBalancerPoolToSolidlyStable(ctx sdk.Context, gammKeeper *gammkeeper. balancesBefore := bankKeeper.GetAllBalances(ctx, balancerPool.GetAddress()) // overwrite the balancer pool with the new stableswap pool - err = gammKeeper.OverwritePool(ctx, &stableswapPool) + err = gammKeeper.OverwritePoolV15MigrationUnsafe(ctx, &stableswapPool) if err != nil { panic(err) } diff --git a/x/gamm/keeper/pool.go b/x/gamm/keeper/pool.go index 0770861cade..341d33973de 100644 --- a/x/gamm/keeper/pool.go +++ b/x/gamm/keeper/pool.go @@ -105,8 +105,9 @@ func (k Keeper) setPool(ctx sdk.Context, pool poolmanagertypes.PoolI) error { return nil } -// Is this the preferred way to call setPool from the upgrade handler? -func (k Keeper) OverwritePool(ctx sdk.Context, pool poolmanagertypes.PoolI) error { +// OverwritePoolV15MigrationUnsafe is a temporary method for calling from the v15 upgrade handler +// for balancer to stableswap pool migration. Do not use for other purposes. +func (k Keeper) OverwritePoolV15MigrationUnsafe(ctx sdk.Context, pool poolmanagertypes.PoolI) error { return k.setPool(ctx, pool) } From 92640d54b7f21cbef979dc2a86fe8b029b3b5c59 Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Thu, 23 Feb 2023 14:24:22 -0500 Subject: [PATCH 13/17] rm TestMigrateBalancerToStable --- tests/e2e/e2e_test.go | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 6494e1171db..ab4d2715f1a 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -354,42 +354,6 @@ func (s *IntegrationTestSuite) TestGeometricTwapMigration() { node.SwapExactAmountIn(uosmoIn, minAmountOut, fmt.Sprintf("%d", config.PreUpgradePoolId), otherDenom, swapWalletAddr) } -// TestMigrateBalancerToStable tests that balancer to stable swap -// pool migrations run successfully. It does so by attempting to -// execute swaps and exit the pool for an account that is LPing -// the pool post-upgrade. -func (s *IntegrationTestSuite) TestMigrateBalancerToStable() { - if s.skipUpgrade { - s.T().Skip("Skipping upgrade tests") - } - - const ( - // This pool gets initialized pre-upgrade and migrated in the upgrade. - // TODO: Update these amounts to reflect the genesis initialization - swapAmountIn = "1000000uosmo" - swapMinAmountOut = "1" - otherDenom = "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518" - lpWallet = "lp-wallet" - exitMinAmountOut = "1" - exitShareAmountIn = "1" - ) - - chainA := s.configurer.GetChainConfig(0) - node, err := chainA.GetDefaultNode() - s.Require().NoError(err) - - // pools migrated to stable swap - pools := []uint{833, 817, 810} - lpWalletAddr := node.CreateWallet(lpWallet) - - for _, poolID := range pools { - // execute a swap on the pool - node.SwapExactAmountIn(swapAmountIn, swapMinAmountOut, fmt.Sprintf("%d", poolID), otherDenom, lpWalletAddr) - // exit the pool - node.ExitPool(lpWalletAddr, exitMinAmountOut, fmt.Sprintf("%d", poolID), exitShareAmountIn) - } -} - // TestIBCTokenTransfer tests that IBC token transfers work as expected. // Additionally, it attempst to create a pool with IBC denoms. func (s *IntegrationTestSuite) TestIBCTokenTransferAndCreatePool() { From e9ed4dbc050954b25ac8bfbcf7361b8baf739bec Mon Sep 17 00:00:00 2001 From: Aidan Salzmann Date: Thu, 23 Feb 2023 14:30:27 -0500 Subject: [PATCH 14/17] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b959f4dff..5cdf4fa3433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Misc Improvements * [#4131](https://github.com/osmosis-labs/osmosis/pull/4141) Add GatherValuesFromStorePrefixWithKeyParser function to osmoutils. * [#4388](https://github.com/osmosis-labs/osmosis/pull/4388) Increase the max allowed contract size for non-proposal contracts to 3MB + * [#4384](https://github.com/osmosis-labs/osmosis/pull/4384) migrate stXXX/XXX constant product pools 833, 817, 810 to stable swap ### API breaks From d03f9e06f90d3e0332fc1352c664190df0a87acd Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 20:12:02 +0000 Subject: [PATCH 15/17] fix e2e --- tests/e2e/configurer/chain/commands.go | 4 ++-- tests/e2e/e2e_test.go | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index e7b222118d9..889c65764f1 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -204,9 +204,9 @@ func (n *NodeConfig) JoinPoolExactAmountIn(tokenIn string, poolId uint64, shareO n.LogActionF("successfully joined pool") } -func (n *NodeConfig) ExitPool(from, minAmountsOut string, poolId string, shareAmountIn string) { +func (n *NodeConfig) ExitPool(from, minAmountsOut string, poolId uint64, shareAmountIn string) { n.LogActionF("exiting gamm pool") - cmd := []string{"osmosisd", "tx", "gamm", "exit-pool", minAmountsOut, poolId, shareAmountIn, fmt.Sprintf("--from=%s", from)} + cmd := []string{"osmosisd", "tx", "gamm", "exit-pool", fmt.Sprintf("--min-amounts-out=%s", minAmountsOut), fmt.Sprintf("--share-amount-in=%s", shareAmountIn), fmt.Sprintf("--pool-id=%d", poolId), fmt.Sprintf("--from=%s", from)} _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) n.LogActionF("successfully exited pool %s, minAmountsOut %s, shareAmountIn %s", poolId, minAmountsOut, shareAmountIn) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index ab4d2715f1a..9ff1034e302 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1096,22 +1096,21 @@ func (s *IntegrationTestSuite) TestGeometricTWAP() { // This test is to be re-enabled for upgrade once the upgrade handler logic is added and // the balancer pool genesis is backported to v14. func (s *IntegrationTestSuite) TestStridePoolMigration() { + if s.skipUpgrade { + s.T().Log("Skipping migration test when upgrade is disable. This test depends on running v15 upgrade handler.") + } + const ( // Configurations for tests/e2e/scripts/pool1A.json // This pool gets initialized pre-upgrade. - minAmountOut = "1" + minAmountOut = "1" + shareAmountIn = "1" ) chainA := s.configurer.GetChainConfig(0) node, err := chainA.GetDefaultNode() s.Require().NoError(err) - // If upgrade tests are run, the wallet is created in the upgrade configurer to create - // LP positions pre-upgrade. - if s.skipUpgrade { - config.StrideMigrateWallet = node.CreateWallet(config.StrideMigrateWallet) - } - fundTokens := []string{fmt.Sprintf("1000000%s", initialization.StOsmoDenom), fmt.Sprintf("1000000%s", initialization.StJunoDenom), fmt.Sprintf("1000000%s", initialization.StStarsDenom)} for _, token := range fundTokens { node.BankSend(token, initialization.ValidatorWalletName, config.StrideMigrateWallet) @@ -1131,6 +1130,6 @@ func (s *IntegrationTestSuite) TestStridePoolMigration() { node.SwapExactAmountIn(fundTokens[i], minAmountOut, fmt.Sprintf("%d", poolId), otherDenoms[i], config.StrideMigrateWallet) // Exit one share - node.ExitPool(config.StrideMigrateWallet, fundTokens[i], fmt.Sprintf("%d", poolId), minAmountOut) + node.ExitPool(config.StrideMigrateWallet, "", poolId, shareAmountIn) } } From 04b072f85ebbfb4c224260734afc0ae1e01b63c6 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 20:31:58 +0000 Subject: [PATCH 16/17] more assertions for TestMigrateBalancerToStablePools --- app/upgrades/v15/upgrade_test.go | 51 ++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/app/upgrades/v15/upgrade_test.go b/app/upgrades/v15/upgrade_test.go index 2ea88d42eb6..836140ef8f0 100644 --- a/app/upgrades/v15/upgrade_test.go +++ b/app/upgrades/v15/upgrade_test.go @@ -12,6 +12,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/osmosis-labs/osmosis/osmoutils/osmoassert" ibcratelimittypes "github.com/osmosis-labs/osmosis/v14/x/ibc-rate-limit/types" "github.com/stretchr/testify/suite" @@ -86,7 +87,6 @@ func (suite *UpgradeTestSuite) TestMigrateNextPoolIdAndCreatePool() { suite.Require().Equal(gammPoolCreationFee, poolmanagerPoolCreationFee) } - func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.SetupTest() // reset @@ -100,31 +100,31 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.FundAcc(testAccount, DefaultAcctFunds) // Create the balancer pool - swapFee, err := sdk.NewDecFromStr("0.003") - exitFee, err := sdk.NewDecFromStr("0.025") + swapFee := sdk.MustNewDecFromStr("0.003") + exitFee := sdk.MustNewDecFromStr("0.025") poolID, err := suite.App.PoolManagerKeeper.CreatePool( suite.Ctx, balancer.NewMsgCreateBalancerPool(suite.TestAccs[0], - balancer.PoolParams{ - SwapFee: swapFee, - ExitFee: exitFee, - }, - []balancertypes.PoolAsset{ - { - Weight: sdk.NewInt(100), - Token: sdk.NewCoin("foo", sdk.NewInt(5000000)), + balancer.PoolParams{ + SwapFee: swapFee, + ExitFee: exitFee, }, - { - Weight: sdk.NewInt(200), - Token: sdk.NewCoin("bar", sdk.NewInt(5000000)), + []balancertypes.PoolAsset{ + { + Weight: sdk.NewInt(100), + Token: sdk.NewCoin("foo", sdk.NewInt(5000000)), + }, + { + Weight: sdk.NewInt(200), + Token: sdk.NewCoin("bar", sdk.NewInt(5000000)), + }, }, - }, - ""), + ""), ) suite.Require().NoError(err) // join the pool - shareOutAmount := sdk.NewInt(10000000) + shareOutAmount := sdk.NewInt(1_000_000_000_000_000) tokenInMaxs := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(5000000)), sdk.NewCoin("bar", sdk.NewInt(5000000))) tokenIn, sharesOut, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) suite.Require().NoError(err) @@ -153,12 +153,16 @@ func (suite *UpgradeTestSuite) TestMigrateBalancerToStablePools() { suite.Require().Equal(balancerBalances, stableBalances) // exit the pool - _, err = suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, sharesOut, tokenIn) + exitCoins, err := suite.App.GAMMKeeper.ExitPool(suite.Ctx, testAccount, poolID, sharesOut, sdk.NewCoins()) + suite.Require().NoError(err) + + suite.validateCons(exitCoins, tokenIn) // join again - _, _, err = suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) + tokenInStable, _, err := suite.App.GAMMKeeper.JoinPoolNoSwap(suite.Ctx, testAccount, poolID, shareOutAmount, tokenInMaxs) suite.Require().NoError(err) + suite.validateCons(tokenInStable, tokenIn) } func (suite *UpgradeTestSuite) TestRegisterOsmoIonMetadata() { @@ -243,3 +247,12 @@ func (suite *UpgradeTestSuite) TestSetRateLimits() { suite.Require().Greaterf(len(state), 0, "state should not be empty") } + +func (suite *UpgradeTestSuite) validateCons(coinsA, coinsB sdk.Coins) { + suite.Require().Equal(len(coinsA), len(coinsB)) + for _, coinA := range coinsA { + coinBAmount := coinsB.AmountOf(coinA.Denom) + // minor tolerance due to fees and rounding + osmoassert.DecApproxEq(suite.T(), coinBAmount.ToDec(), coinA.Amount.ToDec(), sdk.NewDec(2)) + } +} From fe738f324e4f046bf0b9dba4c40e1eb6cb77e08a Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Feb 2023 20:33:20 +0000 Subject: [PATCH 17/17] lint --- tests/e2e/configurer/chain/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index 889c65764f1..187a453441c 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -209,7 +209,7 @@ func (n *NodeConfig) ExitPool(from, minAmountsOut string, poolId uint64, shareAm cmd := []string{"osmosisd", "tx", "gamm", "exit-pool", fmt.Sprintf("--min-amounts-out=%s", minAmountsOut), fmt.Sprintf("--share-amount-in=%s", shareAmountIn), fmt.Sprintf("--pool-id=%d", poolId), fmt.Sprintf("--from=%s", from)} _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) - n.LogActionF("successfully exited pool %s, minAmountsOut %s, shareAmountIn %s", poolId, minAmountsOut, shareAmountIn) + n.LogActionF("successfully exited pool %d, minAmountsOut %s, shareAmountIn %s", poolId, minAmountsOut, shareAmountIn) } func (n *NodeConfig) SubmitUpgradeProposal(upgradeVersion string, upgradeHeight int64, initialDeposit sdk.Coin) {