From f353b3cc4f00ea7f349ce4dd8b1e3ce5499e9a8a Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 5 Dec 2023 15:44:18 -0600 Subject: [PATCH 1/5] added success case for create trade route --- app/apptesting/test_helpers.go | 28 +++- x/stakeibc/keeper/keeper_test.go | 7 +- .../msg_server_create_trade_route_test.go | 127 ++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 x/stakeibc/keeper/msg_server_create_trade_route_test.go diff --git a/app/apptesting/test_helpers.go b/app/apptesting/test_helpers.go index 7153505ab..65b92d7ba 100644 --- a/app/apptesting/test_helpers.go +++ b/app/apptesting/test_helpers.go @@ -446,18 +446,44 @@ func (s *AppTestHelper) MockClientLatestHeight(height uint64) { // Helper function to mock out a client and connection to test // mapping from connection ID back to chain ID +// This also mocks out the consensus state to enable testing registering interchain accounts func (s *AppTestHelper) MockClientAndConnection(chainId, clientId, connectionId string) { + clientHeight := clienttypes.Height{ + RevisionHeight: uint64(s.Ctx.BlockHeight()), + } clientState := tendermint.ClientState{ - ChainId: chainId, + ChainId: chainId, + LatestHeight: clientHeight, + TrustingPeriod: time.Minute * 10, } s.App.IBCKeeper.ClientKeeper.SetClientState(s.Ctx, clientId, &clientState) + consensusState := tendermint.ConsensusState{ + Timestamp: s.Ctx.BlockTime(), + } + s.App.IBCKeeper.ClientKeeper.SetClientConsensusState(s.Ctx, clientId, clientHeight, &consensusState) + connection := connectiontypes.ConnectionEnd{ ClientId: clientId, + Versions: []*connectiontypes.Version{connectiontypes.DefaultIBCVersion}, } s.App.IBCKeeper.ConnectionKeeper.SetConnection(s.Ctx, connectionId, connection) } +// Helper function to mock out an ICA address +func (s *AppTestHelper) MockICAChannel(connectionId, channelId, owner, address string) { + // Create an open channel with the ICA port + portId, _ := icatypes.NewControllerPortID(owner) + channel := channeltypes.Channel{ + State: channeltypes.OPEN, + } + s.App.IBCKeeper.ChannelKeeper.SetChannel(s.Ctx, portId, channelId, channel) + + // Then set the address and make the channel active + s.App.ICAControllerKeeper.SetInterchainAccountAddress(s.Ctx, connectionId, portId, address) + s.App.ICAControllerKeeper.SetActiveChannelID(s.Ctx, connectionId, portId, channelId) +} + func (s *AppTestHelper) ConfirmUpgradeSucceededs(upgradeName string, upgradeHeight int64) { s.Ctx = s.Ctx.WithBlockHeight(upgradeHeight - 1) plan := upgradetypes.Plan{Name: upgradeName, Height: upgradeHeight} diff --git a/x/stakeibc/keeper/keeper_test.go b/x/stakeibc/keeper/keeper_test.go index 94976b8b1..ff427b7e5 100644 --- a/x/stakeibc/keeper/keeper_test.go +++ b/x/stakeibc/keeper/keeper_test.go @@ -7,13 +7,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/Stride-Labs/stride/v16/app/apptesting" epochtypes "github.com/Stride-Labs/stride/v16/x/epochs/types" "github.com/Stride-Labs/stride/v16/x/stakeibc/keeper" "github.com/Stride-Labs/stride/v16/x/stakeibc/types" ) -const ( +var ( Atom = "uatom" StAtom = "stuatom" IbcAtom = "ibc/uatom" @@ -37,6 +40,8 @@ const ( DepositAddress = "deposit" CommunityPoolStakeHoldingAddress = "staking-holding" CommunityPoolRedeemHoldingAddress = "redeem-holding" + + Authority = authtypes.NewModuleAddress(govtypes.ModuleName).String() ) type KeeperTestSuite struct { diff --git a/x/stakeibc/keeper/msg_server_create_trade_route_test.go b/x/stakeibc/keeper/msg_server_create_trade_route_test.go new file mode 100644 index 000000000..e206fd68c --- /dev/null +++ b/x/stakeibc/keeper/msg_server_create_trade_route_test.go @@ -0,0 +1,127 @@ +package keeper_test + +import ( + sdkmath "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Stride-Labs/stride/v16/x/stakeibc/types" +) + +func (s *KeeperTestSuite) TestMsgCreateTradeRoute() { + rewardChainId := "reward-0" + tradeChainId := "trade-0" + + hostConnectionId := "connection-0" + rewardConnectionId := "connection-1" + tradeConnectionId := "connection-2" + + hostToRewardChannelId := "channel-100" + rewardToTradeChannelId := "channel-200" + tradeToHostChannelId := "channel-300" + + rewardDenomOnHost := "ibc/reward-on-host" + rewardDenomOnReward := RewardDenom + rewardDenomOnTrade := "ibc/reward-on-trade" + hostDenomOnTrade := "ibc/host-on-trade" + hostDenomOnHost := HostDenom + + withdrawalAddress := "withdrawal-address" + unwindAddress := "unwind-address" + + poolId := uint64(100) + maxAllowedSwapLossRate := "0.05" + minSwapAmount := sdkmath.NewInt(100) + maxSwapAmount := sdkmath.NewInt(1_000) + + // Mock out connections for the reward an trade chain so that an ICA registration can be submitted + s.MockClientAndConnection(rewardChainId, "07-tendermint-0", rewardConnectionId) + s.MockClientAndConnection(tradeChainId, "07-tendermint-1", tradeConnectionId) + + // Register an exisiting ICA account for the unwind ICA to test that + // existing accounts are re-used + // TODO [DYDX]: Replace with trade route owner + owner := types.FormatICAAccountOwner(rewardChainId, types.ICAAccountType_CONVERTER_UNWIND) + s.MockICAChannel(rewardConnectionId, "channel-0", owner, unwindAddress) + + // Create a host zone with an exisiting withdrawal address + hostZone := types.HostZone{ + ChainId: HostChainId, + ConnectionId: hostConnectionId, + WithdrawalIcaAddress: withdrawalAddress, + } + s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) + + // Define a valid message given the parameters above + msg := types.MsgCreateTradeRoute{ + Authority: Authority, + HostChainId: HostChainId, + + StrideToRewardConnectionId: rewardConnectionId, + StrideToTradeConnectionId: tradeConnectionId, + + HostToRewardTransferChannelId: hostToRewardChannelId, + RewardToTradeTransferChannelId: rewardToTradeChannelId, + TradeToHostTransferChannelId: tradeToHostChannelId, + + RewardDenomOnHost: rewardDenomOnHost, + RewardDenomOnReward: rewardDenomOnReward, + RewardDenomOnTrade: rewardDenomOnTrade, + HostDenomOnTrade: hostDenomOnTrade, + HostDenomOnHost: hostDenomOnHost, + + PoolId: poolId, + MaxAllowedSwapLossRate: maxAllowedSwapLossRate, + MinSwapAmount: minSwapAmount, + MaxSwapAmount: maxSwapAmount, + } + + // Build out the expected trade route given the above + expectedTradeRoute := types.TradeRoute{ + RewardDenomOnHostZone: rewardDenomOnHost, + RewardDenomOnRewardZone: rewardDenomOnReward, + RewardDenomOnTradeZone: rewardDenomOnTrade, + HostDenomOnTradeZone: hostDenomOnTrade, + HostDenomOnHostZone: hostDenomOnHost, + + HostAccount: types.ICAAccount{ + ChainId: HostChainId, + Type: types.ICAAccountType_WITHDRAWAL, + ConnectionId: hostConnectionId, + Address: withdrawalAddress, + }, + RewardAccount: types.ICAAccount{ + ChainId: rewardChainId, + Type: types.ICAAccountType_CONVERTER_UNWIND, + ConnectionId: rewardConnectionId, + Address: unwindAddress, + }, + TradeAccount: types.ICAAccount{ + ChainId: tradeChainId, + Type: types.ICAAccountType_CONVERTER_TRADE, + ConnectionId: tradeConnectionId, + }, + + HostToRewardChannelId: hostToRewardChannelId, + RewardToTradeChannelId: rewardToTradeChannelId, + TradeToHostChannelId: tradeToHostChannelId, + + TradeConfig: types.TradeConfig{ + PoolId: poolId, + SwapPrice: sdk.ZeroDec(), + PriceUpdateTimestamp: 0, + + MaxAllowedSwapLossRate: sdk.MustNewDecFromStr(maxAllowedSwapLossRate), + MinSwapAmount: minSwapAmount, + MaxSwapAmount: maxSwapAmount, + }, + } + + // Create the trade route and confirm the created route matches expectations + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().NoError(err, "no error expected when creating trade route") + + actualTradeRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + s.Require().True(found, "trade route should have been created") + s.Require().Equal(expectedTradeRoute, actualTradeRoute, "trade route") +} From 8705302601ab6e13fc31b698397dd67a1e4373bb Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 5 Dec 2023 16:34:09 -0600 Subject: [PATCH 2/5] added failures cases for create trade route --- .../keeper/msg_server_create_trade_route.go | 2 +- .../msg_server_create_trade_route_test.go | 103 +++++++++++++++++- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/x/stakeibc/keeper/msg_server_create_trade_route.go b/x/stakeibc/keeper/msg_server_create_trade_route.go index 73654d7f0..c1a9c24d1 100644 --- a/x/stakeibc/keeper/msg_server_create_trade_route.go +++ b/x/stakeibc/keeper/msg_server_create_trade_route.go @@ -66,7 +66,7 @@ func (ms msgServer) CreateTradeRoute(goCtx context.Context, msg *types.MsgCreate _, found := ms.Keeper.GetTradeRoute(ctx, msg.RewardDenomOnReward, msg.HostDenomOnHost) if found { return nil, errorsmod.Wrapf(types.ErrTradeRouteAlreadyExists, - "startDenom: %s, endDenom: %s", msg.RewardDenomOnReward, msg.HostDenomOnHost) + "trade route already exists for rewardDenom %s, hostDenom %s", msg.RewardDenomOnReward, msg.HostDenomOnHost) } // Confirm the host chain exists and the withdrawal address has been initialized diff --git a/x/stakeibc/keeper/msg_server_create_trade_route_test.go b/x/stakeibc/keeper/msg_server_create_trade_route_test.go index e206fd68c..895aa0eef 100644 --- a/x/stakeibc/keeper/msg_server_create_trade_route_test.go +++ b/x/stakeibc/keeper/msg_server_create_trade_route_test.go @@ -4,11 +4,12 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" "github.com/Stride-Labs/stride/v16/x/stakeibc/types" ) -func (s *KeeperTestSuite) TestMsgCreateTradeRoute() { +func (s *KeeperTestSuite) SetupTestCreateTradeRoute() (msg types.MsgCreateTradeRoute, expectedTradeRoute types.TradeRoute) { rewardChainId := "reward-0" tradeChainId := "trade-0" @@ -53,7 +54,7 @@ func (s *KeeperTestSuite) TestMsgCreateTradeRoute() { s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone) // Define a valid message given the parameters above - msg := types.MsgCreateTradeRoute{ + msg = types.MsgCreateTradeRoute{ Authority: Authority, HostChainId: HostChainId, @@ -77,7 +78,7 @@ func (s *KeeperTestSuite) TestMsgCreateTradeRoute() { } // Build out the expected trade route given the above - expectedTradeRoute := types.TradeRoute{ + expectedTradeRoute = types.TradeRoute{ RewardDenomOnHostZone: rewardDenomOnHost, RewardDenomOnRewardZone: rewardDenomOnReward, RewardDenomOnTradeZone: rewardDenomOnTrade, @@ -117,11 +118,101 @@ func (s *KeeperTestSuite) TestMsgCreateTradeRoute() { }, } - // Create the trade route and confirm the created route matches expectations + return msg, expectedTradeRoute +} + +// Helper function to create a trade route and check the created route matched expectations +func (s *KeeperTestSuite) submitCreateTradeRouteAndValidate(msg types.MsgCreateTradeRoute, expectedRoute types.TradeRoute) { _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) s.Require().NoError(err, "no error expected when creating trade route") - actualTradeRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + actualRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) s.Require().True(found, "trade route should have been created") - s.Require().Equal(expectedTradeRoute, actualTradeRoute, "trade route") + s.Require().Equal(expectedRoute, actualRoute, "trade route") +} + +// Tests a successful trade route creation +func (s *KeeperTestSuite) TestCreateTradeRoute_Success() { + msg, expectedTradeRoute := s.SetupTestCreateTradeRoute() + s.submitCreateTradeRouteAndValidate(msg, expectedTradeRoute) +} + +// Tests creating a trade route that uses the default pool config values +func (s *KeeperTestSuite) TestCreateTradeRoute_Success_DefaultPoolConfig() { + msg, expectedTradeRoute := s.SetupTestCreateTradeRoute() + + // Update the message and remove some trade config parameters + msg.MaxSwapAmount = sdk.ZeroInt() + msg.MaxAllowedSwapLossRate = "" + + // Update the expected message to have the default values + msg, expectedTradeRoute = s.SetupTestCreateTradeRoute() + s.submitCreateTradeRouteAndValidate(msg, expectedTradeRoute) +} + +// Tests creating a duplicate trade route +func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_DuplicateTradeRoute() { + msg, _ := s.SetupTestCreateTradeRoute() + + // Store down a trade route so the tx hits a duplicate trade route error + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, types.TradeRoute{ + RewardDenomOnRewardZone: RewardDenom, + HostDenomOnHostZone: HostDenom, + }) + + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "Trade route already exists") +} + +// Tests creating a trade route when the host zone or withdrawal address does not exist +func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_HostZoneNotRegistered() { + msg, _ := s.SetupTestCreateTradeRoute() + + // Remove the host zone withdrawal address and confirm it fails + invalidHostZone := s.MustGetHostZone(HostChainId) + invalidHostZone.WithdrawalIcaAddress = "" + s.App.StakeibcKeeper.SetHostZone(s.Ctx, invalidHostZone) + + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "withdrawal account not initialized on host zone") + + // Remove the host zone completely and check that that also fails + s.App.StakeibcKeeper.RemoveHostZone(s.Ctx, HostChainId) + + _, err = s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "host zone not found") +} + +// Tests creating a trade route where the ICA channels cannot be created +// because the ICA connections do not exist +func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_ConnectionNotFound() { + // Test with non-existent reward connection + msg, _ := s.SetupTestCreateTradeRoute() + msg.StrideToRewardConnectionId = "connection-X" + + // Remove the host zone completely and check that that also fails + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "unable to register the unwind ICA account: connection connection-X not found") + + // Setup again, but this time use a non-existent trade connection + msg, _ = s.SetupTestCreateTradeRoute() + msg.StrideToTradeConnectionId = "connection-Y" + + _, err = s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "unable to register the trade ICA account: connection connection-Y not found") +} + +// Tests creating a trade route where the ICA registration step fails +func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_UnableToRegisterICA() { + msg, expectedRoute := s.SetupTestCreateTradeRoute() + + // Disable ICA middleware for the trade channel so the ICA fails + // TODO [DYDX]: Replace with new formatter + tradeAccount := expectedRoute.TradeAccount + tradeOwner := types.FormatICAAccountOwner(tradeAccount.ChainId, types.ICAAccountType_CONVERTER_TRADE) + tradePortId, _ := icatypes.NewControllerPortID(tradeOwner) + s.App.ICAControllerKeeper.SetMiddlewareDisabled(s.Ctx, tradePortId, tradeAccount.ConnectionId) + + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "unable to register the trade ICA account") } From 66a6702dfc953ba565ed5f8a707c0e3ffae355eb Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 5 Dec 2023 17:24:22 -0600 Subject: [PATCH 3/5] added unit tests for update trade route --- .../msg_server_create_trade_route_test.go | 10 +++ .../msg_server_update_trade_route_test.go | 86 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 x/stakeibc/keeper/msg_server_update_trade_route_test.go diff --git a/x/stakeibc/keeper/msg_server_create_trade_route_test.go b/x/stakeibc/keeper/msg_server_create_trade_route_test.go index 895aa0eef..2111932f0 100644 --- a/x/stakeibc/keeper/msg_server_create_trade_route_test.go +++ b/x/stakeibc/keeper/msg_server_create_trade_route_test.go @@ -150,6 +150,16 @@ func (s *KeeperTestSuite) TestCreateTradeRoute_Success_DefaultPoolConfig() { s.submitCreateTradeRouteAndValidate(msg, expectedTradeRoute) } +// Tests trying to create a route from an invalid authority +func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_Authority() { + msg, _ := s.SetupTestCreateTradeRoute() + + msg.Authority = "not-gov-address" + + _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "invalid authority") +} + // Tests creating a duplicate trade route func (s *KeeperTestSuite) TestCreateTradeRoute_Failure_DuplicateTradeRoute() { msg, _ := s.SetupTestCreateTradeRoute() diff --git a/x/stakeibc/keeper/msg_server_update_trade_route_test.go b/x/stakeibc/keeper/msg_server_update_trade_route_test.go new file mode 100644 index 000000000..54ca88b2b --- /dev/null +++ b/x/stakeibc/keeper/msg_server_update_trade_route_test.go @@ -0,0 +1,86 @@ +package keeper_test + +import ( + sdkmath "cosmossdk.io/math" + + "github.com/Stride-Labs/stride/v16/x/stakeibc/keeper" + "github.com/Stride-Labs/stride/v16/x/stakeibc/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Helper function to update a trade route and check the updated route matched expectations +func (s *KeeperTestSuite) submitUpdateTradeRouteAndValidate(msg types.MsgUpdateTradeRoute, expectedRoute types.TradeRoute) { + _, err := s.GetMsgServer().UpdateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().NoError(err, "no error expected when updating trade route") + + actualRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + s.Require().True(found, "trade route should have been created") + s.Require().Equal(expectedRoute, actualRoute, "trade route") +} + +func (s *KeeperTestSuite) TestUpdateTradeRoute() { + poolId := uint64(100) + maxAllowedSwapLossRate := "0.05" + minSwapAmount := sdkmath.NewInt(100) + maxSwapAmount := sdkmath.NewInt(1_000) + + // Create a trade route with no parameters + initialRoute := types.TradeRoute{ + RewardDenomOnRewardZone: RewardDenom, + HostDenomOnHostZone: HostDenom, + } + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, initialRoute) + + // Define a valid message given the parameters above + msg := types.MsgUpdateTradeRoute{ + Authority: Authority, + + RewardDenom: RewardDenom, + HostDenom: HostDenom, + + PoolId: poolId, + MaxAllowedSwapLossRate: maxAllowedSwapLossRate, + MinSwapAmount: minSwapAmount, + MaxSwapAmount: maxSwapAmount, + } + + // Build out the expected trade route given the above + expectedRoute := initialRoute + expectedRoute.TradeConfig = types.TradeConfig{ + PoolId: poolId, + SwapPrice: sdk.ZeroDec(), + PriceUpdateTimestamp: 0, + + MaxAllowedSwapLossRate: sdk.MustNewDecFromStr(maxAllowedSwapLossRate), + MinSwapAmount: minSwapAmount, + MaxSwapAmount: maxSwapAmount, + } + + // Update the route and confirm the changes persisted + s.submitUpdateTradeRouteAndValidate(msg, expectedRoute) + + // Update it again, this time using default args + defaultMsg := msg + defaultMsg.MaxAllowedSwapLossRate = "" + defaultMsg.MaxSwapAmount = sdkmath.ZeroInt() + + expectedRoute.TradeConfig.MaxAllowedSwapLossRate = sdk.MustNewDecFromStr(keeper.DefaultMaxAllowedSwapLossRate) + expectedRoute.TradeConfig.MaxSwapAmount = keeper.DefaultMaxSwapAmount + + s.submitUpdateTradeRouteAndValidate(defaultMsg, expectedRoute) + + // Test that an error is thrown if the correct authority is not specified + invalidMsg := msg + invalidMsg.Authority = "not-gov-address" + + _, err := s.GetMsgServer().UpdateTradeRoute(sdk.WrapSDKContext(s.Ctx), &invalidMsg) + s.Require().ErrorContains(err, "invalid authority") + + // Test that an error is thrown if the route doesn't exist + invalidMsg = msg + invalidMsg.RewardDenom = "invalid-reward-denom" + + _, err = s.GetMsgServer().UpdateTradeRoute(sdk.WrapSDKContext(s.Ctx), &invalidMsg) + s.Require().ErrorContains(err, "trade route not found") +} From 243c9afc4c443dd4c51a7aea1a0e615fe9a4993d Mon Sep 17 00:00:00 2001 From: sampocs Date: Tue, 5 Dec 2023 17:30:33 -0600 Subject: [PATCH 4/5] added unit tests for delete trade route --- .../msg_server_create_trade_route_test.go | 15 ++++--- .../msg_server_delete_trade_route_test.go | 44 +++++++++++++++++++ .../msg_server_update_trade_route_test.go | 2 +- 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 x/stakeibc/keeper/msg_server_delete_trade_route_test.go diff --git a/x/stakeibc/keeper/msg_server_create_trade_route_test.go b/x/stakeibc/keeper/msg_server_create_trade_route_test.go index 2111932f0..8b1b7b89d 100644 --- a/x/stakeibc/keeper/msg_server_create_trade_route_test.go +++ b/x/stakeibc/keeper/msg_server_create_trade_route_test.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/Stride-Labs/stride/v16/x/stakeibc/keeper" "github.com/Stride-Labs/stride/v16/x/stakeibc/types" ) @@ -133,21 +134,23 @@ func (s *KeeperTestSuite) submitCreateTradeRouteAndValidate(msg types.MsgCreateT // Tests a successful trade route creation func (s *KeeperTestSuite) TestCreateTradeRoute_Success() { - msg, expectedTradeRoute := s.SetupTestCreateTradeRoute() - s.submitCreateTradeRouteAndValidate(msg, expectedTradeRoute) + msg, expectedRoute := s.SetupTestCreateTradeRoute() + s.submitCreateTradeRouteAndValidate(msg, expectedRoute) } // Tests creating a trade route that uses the default pool config values func (s *KeeperTestSuite) TestCreateTradeRoute_Success_DefaultPoolConfig() { - msg, expectedTradeRoute := s.SetupTestCreateTradeRoute() + msg, expectedRoute := s.SetupTestCreateTradeRoute() // Update the message and remove some trade config parameters + // so that the defaults are used msg.MaxSwapAmount = sdk.ZeroInt() msg.MaxAllowedSwapLossRate = "" - // Update the expected message to have the default values - msg, expectedTradeRoute = s.SetupTestCreateTradeRoute() - s.submitCreateTradeRouteAndValidate(msg, expectedTradeRoute) + expectedRoute.TradeConfig.MaxAllowedSwapLossRate = sdk.MustNewDecFromStr(keeper.DefaultMaxAllowedSwapLossRate) + expectedRoute.TradeConfig.MaxSwapAmount = keeper.DefaultMaxSwapAmount + + s.submitCreateTradeRouteAndValidate(msg, expectedRoute) } // Tests trying to create a route from an invalid authority diff --git a/x/stakeibc/keeper/msg_server_delete_trade_route_test.go b/x/stakeibc/keeper/msg_server_delete_trade_route_test.go new file mode 100644 index 000000000..7b7c5cecc --- /dev/null +++ b/x/stakeibc/keeper/msg_server_delete_trade_route_test.go @@ -0,0 +1,44 @@ +package keeper_test + +import ( + "github.com/Stride-Labs/stride/v16/x/stakeibc/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *KeeperTestSuite) TestDeleteTradeRoute() { + initialRoute := types.TradeRoute{ + RewardDenomOnRewardZone: RewardDenom, + HostDenomOnHostZone: HostDenom, + } + s.App.StakeibcKeeper.SetTradeRoute(s.Ctx, initialRoute) + + msg := types.MsgDeleteTradeRoute{ + Authority: Authority, + RewardDenom: RewardDenom, + HostDenom: HostDenom, + } + + // Confirm the route is present before attepmting to delete was deleted + _, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + s.Require().True(found, "trade route should have been found before delete message") + + // Delete the trade route + _, err := s.GetMsgServer().DeleteTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().NoError(err, "no error expected when deleting trade route") + + // Confirm it was deleted + _, found = s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + s.Require().False(found, "trade route should have been deleted") + + // Attempt to delete it again, it should fail since it doesn't exist + _, err = s.GetMsgServer().DeleteTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) + s.Require().ErrorContains(err, "trade route not found") + + // Attempt to delete with the wrong authority - it should fail + invalidMsg := msg + invalidMsg.Authority = "not-gov-address" + + _, err = s.GetMsgServer().DeleteTradeRoute(sdk.WrapSDKContext(s.Ctx), &invalidMsg) + s.Require().ErrorContains(err, "invalid authority") +} diff --git a/x/stakeibc/keeper/msg_server_update_trade_route_test.go b/x/stakeibc/keeper/msg_server_update_trade_route_test.go index 54ca88b2b..75c666023 100644 --- a/x/stakeibc/keeper/msg_server_update_trade_route_test.go +++ b/x/stakeibc/keeper/msg_server_update_trade_route_test.go @@ -15,7 +15,7 @@ func (s *KeeperTestSuite) submitUpdateTradeRouteAndValidate(msg types.MsgUpdateT s.Require().NoError(err, "no error expected when updating trade route") actualRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) - s.Require().True(found, "trade route should have been created") + s.Require().True(found, "trade route should have been updated") s.Require().Equal(expectedRoute, actualRoute, "trade route") } From eb6db08359da074582b01ccccf7bb9e60b2a08de Mon Sep 17 00:00:00 2001 From: sampocs Date: Fri, 8 Dec 2023 09:08:47 -0600 Subject: [PATCH 5/5] addressed ethan pr comment --- x/stakeibc/keeper/msg_server_create_trade_route_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stakeibc/keeper/msg_server_create_trade_route_test.go b/x/stakeibc/keeper/msg_server_create_trade_route_test.go index 8b1b7b89d..694777aac 100644 --- a/x/stakeibc/keeper/msg_server_create_trade_route_test.go +++ b/x/stakeibc/keeper/msg_server_create_trade_route_test.go @@ -127,7 +127,7 @@ func (s *KeeperTestSuite) submitCreateTradeRouteAndValidate(msg types.MsgCreateT _, err := s.GetMsgServer().CreateTradeRoute(sdk.WrapSDKContext(s.Ctx), &msg) s.Require().NoError(err, "no error expected when creating trade route") - actualRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, RewardDenom, HostDenom) + actualRoute, found := s.App.StakeibcKeeper.GetTradeRoute(s.Ctx, msg.RewardDenomOnReward, msg.HostDenomOnHost) s.Require().True(found, "trade route should have been created") s.Require().Equal(expectedRoute, actualRoute, "trade route") }