diff --git a/CHANGELOG.md b/CHANGELOG.md index 47127509a7e..a96073a8bb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#7181](https://github.com/osmosis-labs/osmosis/pull/7181) Improve errors for out of gas * [#7376](https://github.com/osmosis-labs/osmosis/pull/7376) Add uptime validation logic for `NoLock` (CL) gauges and switch CL gauge to pool ID links to be duration-based +* [#7357](https://github.com/osmosis-labs/osmosis/pull/7357) Fix: Ensure rate limits are not applied to packets that aren't ics20s ### Bug Fixes diff --git a/x/ibc-rate-limit/ibc_middleware_test.go b/x/ibc-rate-limit/ibc_middleware_test.go index c8e0eaa9c15..bc9933bb8e0 100644 --- a/x/ibc-rate-limit/ibc_middleware_test.go +++ b/x/ibc-rate-limit/ibc_middleware_test.go @@ -2,6 +2,7 @@ package ibc_rate_limit_test import ( "fmt" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "strconv" "strings" "testing" @@ -542,3 +543,23 @@ func (suite *MiddlewareTestSuite) TestUnsetRateLimitingContract() { // N.B.: this panics if validation fails. paramSpace.SetParamSet(suite.chainA.GetContext(), ¶ms) } + +// Test rate limits are reverted if a "send" fails +func (suite *MiddlewareTestSuite) TestNonICS20() { + suite.initializeEscrow() + // Setup contract + suite.chainA.StoreContractCode(&suite.Suite, "./bytecode/rate_limiter.wasm") + quotas := suite.BuildChannelQuota("weekly", "channel-0", sdk.DefaultBondDenom, 604800, 1, 1) + addr := suite.chainA.InstantiateRLContract(&suite.Suite, quotas) + suite.chainA.RegisterRateLimitingContract(addr) + + osmosisApp := suite.chainA.GetOsmosisApp() + + data := []byte("{}") + _, err := osmosisApp.RateLimitingICS4Wrapper.SendPacket(suite.chainA.GetContext(), capabilitytypes.NewCapability(1), "wasm.osmo1873ls0d60tg7hk00976teq9ywhzv45u3hk2urw8t3eau9eusa4eqtun9xn", "channel-0", clienttypes.NewHeight(0, 0), 1, data) + + suite.Require().Error(err) + // This will error out, but not because of rate limiting + suite.Require().NotContains(err.Error(), "rate limit") + suite.Require().Contains(err.Error(), "channel not found") +} diff --git a/x/ibc-rate-limit/ics4_wrapper.go b/x/ibc-rate-limit/ics4_wrapper.go index 3e29b3d71fc..c52f390c2e4 100644 --- a/x/ibc-rate-limit/ics4_wrapper.go +++ b/x/ibc-rate-limit/ics4_wrapper.go @@ -1,19 +1,21 @@ package ibc_rate_limit import ( + "encoding/json" + errorsmod "cosmossdk.io/errors" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" sdk "github.com/cosmos/cosmos-sdk/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" - "github.com/osmosis-labs/osmosis/v22/x/ibc-rate-limit/types" ) @@ -57,6 +59,13 @@ func NewICS4Middleware( // If the contract param is not configured, or the contract doesn't have a configuration for the (channel+denom) being // used, transfers are not prevented and handled by the wrapped IBC app func (i *ICS4Wrapper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, sourcePort, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) { + var packetdata transfertypes.FungibleTokenPacketData + if err := json.Unmarshal(data, &packetdata); err != nil { + return i.channel.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + } + if packetdata.Denom == "" || packetdata.Amount == "" { + return i.channel.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + } contract := i.GetContractAddress(ctx) if contract == "" { // The contract has not been configured. Continue as usual