diff --git a/proto/stride/stakeibc/trade_route.proto b/proto/stride/stakeibc/trade_route.proto index d556723155..1ca3226b90 100644 --- a/proto/stride/stakeibc/trade_route.proto +++ b/proto/stride/stakeibc/trade_route.proto @@ -64,6 +64,7 @@ message TradeRoute { ]; // min and max set boundaries of reward denom on trade chain we will swap + // min also decides when reward token transfers are worth it (transfer fees) string min_swap_amount = 13 [ (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false diff --git a/x/stakeibc/keeper/reward_converter.go b/x/stakeibc/keeper/reward_converter.go index 57b6a90e94..f4b7f9ac1e 100644 --- a/x/stakeibc/keeper/reward_converter.go +++ b/x/stakeibc/keeper/reward_converter.go @@ -5,6 +5,7 @@ import ( "time" errorsmod "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" bankTypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -41,7 +42,14 @@ import ( // This will be two hops to unwind the ibc denom through the rewardZone using pfm in the transfer memo if possible // // msgs with packet forwarding memos can unwind through the reward zone and chain two transfer hops without callbacks -func (k Keeper) TransferRewardTokensHostToTrade(ctx sdk.Context, amount sdk.Int, route types.TradeRoute) error { +func (k Keeper) TransferRewardTokensHostToTrade(ctx sdk.Context, amount sdkmath.Int, route types.TradeRoute) error { + // If the min swap amount was not set it would be ZeroInt, if positive we need to compare to the amount given + // then if the min swap amount is greater than the current amount, do nothing this epoch to avoid small transfers + // Particularly important for the PFM hop if the reward chain has frictional transfer fees (like noble chain) + if route.MinSwapAmount.IsPositive() && route.MinSwapAmount.GT(amount) { + return nil + } + // Timeout for ica tx and the transfer msgs is at end of epoch strideEpochTracker, found := k.GetEpochTracker(ctx, epochstypes.STRIDE_EPOCH) if !found { @@ -90,7 +98,7 @@ func (k Keeper) TransferRewardTokensHostToTrade(ctx sdk.Context, amount sdk.Int, } // ICA tx to kick off transfering the converted tokens back from tradeZone to the hostZone withdrawal ICA -func (k Keeper) TransferConvertedTokensTradeToHost(ctx sdk.Context, amount sdk.Int, route types.TradeRoute) error { +func (k Keeper) TransferConvertedTokensTradeToHost(ctx sdk.Context, amount sdkmath.Int, route types.TradeRoute) error { // Timeout for ica tx and the transfer msgs is at end of epoch strideEpochTracker, found := k.GetEpochTracker(ctx, epochstypes.STRIDE_EPOCH) if !found { @@ -133,7 +141,7 @@ func (k Keeper) TransferConvertedTokensTradeToHost(ctx sdk.Context, amount sdk.I // Trade reward tokens in the Trade ICA for the target output token type using ICA remote tx on trade zone // The amount represents the total amount of the reward token in the trade ICA found by the calling ICQ // Depending on min and max swap amounts set in the route, it is possible not the full amount given will swap -func (k Keeper) TradeRewardTokens(ctx sdk.Context, rewardAmount sdk.Int, route types.TradeRoute) error { +func (k Keeper) TradeRewardTokens(ctx sdk.Context, rewardAmount sdkmath.Int, route types.TradeRoute) error { // If the min swap amount was not set it would be ZeroInt, if positive we need to compare to the amount given // then if the min swap amount is greater than the current amount, do nothing this epoch to avoid small swaps if route.MinSwapAmount.IsPositive() && route.MinSwapAmount.GT(rewardAmount) { diff --git a/x/stakeibc/keeper/trade_route_test.go b/x/stakeibc/keeper/trade_route_test.go index 43212ef5aa..a6d4d49671 100644 --- a/x/stakeibc/keeper/trade_route_test.go +++ b/x/stakeibc/keeper/trade_route_test.go @@ -55,7 +55,7 @@ func (s *KeeperTestSuite) CreateTradeRoutes() (routes []types.TradeRoute) { TradeToHostHop: tradeHostHop, PoolId: uint64(i * 100), - HostTokenPrice: sdk.OneDec(), + SwapPrice: sdk.OneDec(), MinSwapAmount: sdk.ZeroInt(), MaxSwapAmount: sdk.NewInt(1_000_000_000), diff --git a/x/stakeibc/types/trade_route.pb.go b/x/stakeibc/types/trade_route.pb.go index 4959d53182..bd8a5fe177 100644 --- a/x/stakeibc/types/trade_route.pb.go +++ b/x/stakeibc/types/trade_route.pb.go @@ -125,6 +125,7 @@ type TradeRoute struct { // deviation from the current value MaxAllowedSwapLossRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,12,opt,name=max_allowed_swap_loss_rate,json=maxAllowedSwapLossRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_allowed_swap_loss_rate"` // min and max set boundaries of reward denom on trade chain we will swap + // min also decides when reward token transfers are worth it (transfer fees) MinSwapAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,13,opt,name=min_swap_amount,json=minSwapAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"min_swap_amount"` MaxSwapAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,14,opt,name=max_swap_amount,json=maxSwapAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"max_swap_amount"` }