From bb5c1c99b4810c07364d34b6e04fa5741fccc5d7 Mon Sep 17 00:00:00 2001
From: Nicolas Lara <nicolaslara@gmail.com>
Date: Mon, 31 Oct 2022 05:40:38 +0100
Subject: [PATCH] Rate limit - Cleaner tests (#3183)

* improved testing framework

* can test both send and recv for success and failure

* cleanner testing framework

* added contract instantiation

* working wasm integration

* added params for contract config

* extracted param registration

* active rate limiting

* calculating channel value

* cleaner tests

* fix issue with epochs

* fixed tests

* testing rate limit reset

* linting

* added receive middleware

* added test for non-configured channel

* make format

* Revert "make format"

This reverts commit 9ffdc37c3d473e3c640e8fd85872f3a2f178c857.

* only applying format to ibc-rate-limit

* applying fmt to app.go

* added gov_module and changed no-quota default to "allow all"

* added asymetric quotas

* moved getters to modules.go

* initial work to support multiple quotas

* added multiple quotas

* small fixes

* reordered imports

* added management messages

* reorganized management messages and experimenting with e2e testing

* commenting out test configuration test for now

* added query

* added flow unit test

* cleanup

* added AddChannel tests

* format

* test values are properly stored

* testing remove channel

* some more rate limiting tests

* moved tests about test setup to the right place

* fixed params

* merged main

* running gofumpt

* added ibc-rate-limiting contract

* added ibc-rate-limit middleware

* added chain integration and tests

* reverted change to match merged branch in main (#2341 instead of #2274)

* added cosmwasm workflow

* added a migrate message

* added some doc comments to the state

* added doc comments

* fixed dependency after merging https://github.com/osmosis-labs/cosmos-sdk/pull/312

* added migration msg

* added workflow

* experimenting with better workflow

* added missing $

* using env

* Update x/ibc-rate-limit/contracts/rate-limiter/src/msg.rs

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>

* using stable for clippy

* removed gitkeep

* using the minimal profile for clippy

* experimenting with cache

* removed target from lints

* cleaner matrix?

* COmments & questions

* debugging

* more debugging

* debug faster

* quick cache debug

* typo

* quick workflow check

* working tests with optimization

* testing artifacts

* split the wasm target into its own step

* artifacts without slash

* full working tests

* clippy fixes

* workflow without test data checks and clippy fixes

* renamed CHANNEL_FLOWS

* renaming and code clenaup

* more renames

* renames and code fixes

* reordered imports

* cargo fmt

* added danom tracking

* cleanup

* refactoring

* changes to the expiration logic so that balances are calculated based on the direction (as suggested by @ValarDragon)

* slightly slower but considerably cleanner

* cleanup attributes and removed redundancy when not testing

* update to edition 2021

* added comments explaining the tests

* removed .beaker

* unified gitignore

* removed second gitignore

* better doc comments

* spelling

* spelling

* added channel value cache

* updated the middlware to use the new contract interface

* update middleware to match new contract interface

* added missing updates

* updated dependencies

* added missing helpers

* go.mod changes shouldn't be in this branch

* Revert "go.mod changes shouldn't be in this branch"

This reverts commit f8b972a5ea2f2c2b8007fa31c3db5d4450d8ab56.

* moved send and receive to sudo

* reorganizing

* calling the contract via sudo

* lint

* removed gitkeep

* using sudo instead of execute

* cleaned up and updated contract and integration

* updated x86 test wasm file

* fixed bad print

* storing and instantiating the contract

* setting up E2E tests for ibc rate limits

* fixed proposal. Now just have to get the math right and cleanup

* Using the supply for the channel value

* experimenting with e2e tests

* passing the contract keeper instead of instantiating it each time

* changes from code review

* added contract from main and changes to the middleware from code review

* using the correct bank supply method

* debugging issues with e2e tests. Everything works after one interaction from the cli, but not before

* updated dependency to match latest sdk form (now that the changes to this repo have been applied)

* working E2E test for rate limiting

* added e2e tests and changes from code review

* removed debug logs

* remove debug logs

* updated test to also use GetSupplyWithOffset

* using correct GetSupplyWithOffset method

* using correct GetSupplyWithOffset method

* lint

* removed e2e from this branch as it's not doing anything without the integration

* lint

* tests fail on CI because of "inactive" proposal. Is the deposit the issue?

* remove rate limiting after the test so it doesn't interfeer with the other tests

* using standard proposals instead of expedited

* added packet reverts on unsuccessful acks and timeouts

* lint

* ran gofumpt

* lint

* added undo to the contract

* integrating undo

* updated contract with x86 wasm file

* added undo for sent packages when they are rejected bia timeout or a bad ack

* added a readme

* markdown lint

* added readme

* abstracted params

* better params and param tests

* using a helper function instead of returning from the test

* updated contract to allow for undo

* added undo, readme, and cleanup based on reviews

* updated wasm file with x86 version

* using string params in e2e tests

* updated to v12

* removed unnecessary keeper

* only exposing what's needed

* refactoring

* updated types

* added shell history to gitignore

* adding only one wasm file to the codebase

* remove test for same wasm files. No longer needed.

* refactor based on code review

* removed integration tests as they won't pass without integration

* added params unit test

* reorganized tests

* reorganizing tests

* refactoring

* added address length limit

* added tests and fixed lack of return

* remove tests from bad merge

* remove from bad merge again

* comment

* test helpers for cosmwasm contracts

* added helpers for ibctesting

* comments

* removed unnecessary txConfig

* fixed typos

* clearer comment

* using second helper function for ExportGenesis

* added new wasm file

* updated the contract to cosmwasm 1.1 and Uint256 for amounts

* Fixed send with ibc assets. Better tests and error messages

* updated contract with x86 version

* gofumpt

* fixed clippy errors

* using the escrowed value as the channel value for native tokens

* gofumpt

* update fail string

* initial experiments with moving the calculations into the contract

* initial experiments with using the packet inside the contract

* improved tests. Experiments with packet in the contract.

* original contract

* cleaner tests

* more test cleanup

* cleaner tests

* cleanup

* align values from the tests and the contract

* fixed amounts for receive and cleanup code

* removed redundant wrapping logic

* adaped failed send test to the new testing abstractions

* only manipulate time on chain A

* remove commented out block

* changed lints to stable so they change less often

* gofumpt

* update channel value tests

* added x86 version of the contract for ci

* remove lint type that doesn't exist on stable

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
Co-authored-by: Dev Ojha <dojha@berkeley.edu>
---
 .github/workflows/contracts.yml               |  12 +-
 .gitignore                                    |   4 +
 app/apptesting/events.go                      |   6 +
 app/keepers/keepers.go                        |  32 +-
 tests/e2e/configurer/chain/commands.go        |   2 +-
 tests/e2e/e2e_test.go                         | 123 +++++
 .../rate-limiter/src/contract_tests.rs        |  18 +-
 .../contracts/rate-limiter/src/error.rs       |   8 +-
 .../rate-limiter/src/integration_tests.rs     |  22 +-
 .../contracts/rate-limiter/src/packet.rs      |  64 +++
 .../contracts/rate-limiter/src/state.rs       |  59 ++-
 x/ibc-rate-limit/ibc_middleware_test.go       | 462 ++++++++++++++++++
 x/ibc-rate-limit/ibc_module.go                |  24 +-
 x/ibc-rate-limit/ics4_wrapper.go              |  15 +-
 x/ibc-rate-limit/rate_limit.go                |  44 +-
 x/ibc-rate-limit/testdata/rate_limiter.wasm   | Bin 199435 -> 203516 bytes
 x/ibc-rate-limit/testutil/chain.go            |  96 ++++
 x/ibc-rate-limit/testutil/wasm.go             |  70 +++
 x/ibc-rate-limit/types/errors.go              |   3 +-
 19 files changed, 1012 insertions(+), 52 deletions(-)
 create mode 100644 x/ibc-rate-limit/contracts/rate-limiter/src/packet.rs
 create mode 100644 x/ibc-rate-limit/ibc_middleware_test.go
 create mode 100644 x/ibc-rate-limit/testutil/chain.go
 create mode 100644 x/ibc-rate-limit/testutil/wasm.go

diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml
index f5f5301c3..50dc9addb 100644
--- a/.github/workflows/contracts.yml
+++ b/.github/workflows/contracts.yml
@@ -82,11 +82,11 @@ jobs:
           path: ${{ matrix.contract.workdir }}${{ matrix.contract.build }}
           retention-days: 1
 
-#      - name: Check Test Data
-#        working-directory: ${{ matrix.contract.workdir }}
-#        if: ${{ matrix.contract.output != null }}
-#        run: >
-#          diff ${{ matrix.contract.output }} ${{ matrix.contract.build }}
+      - name: Check Test Data
+        working-directory: ${{ matrix.contract.workdir }}
+        if: ${{ matrix.contract.output != null }}
+        run: >
+          diff ${{ matrix.contract.output }} ${{ matrix.contract.build }}
   
 
   lints:
@@ -107,7 +107,7 @@ jobs:
         uses: actions-rs/toolchain@v1
         with:
           profile: minimal
-          toolchain: nightly
+          toolchain: stable
           override: true
           components: rustfmt, clippy
 
diff --git a/.gitignore b/.gitignore
index 713ac5a10..ff99e2886 100644
--- a/.gitignore
+++ b/.gitignore
@@ -230,3 +230,7 @@ Cargo.lock
 .beaker
 blocks.db
 **/blocks.db*
+
+# Ignore e2e test artifacts (which clould leak information if commited)
+.ash_history
+.bash_history
\ No newline at end of file
diff --git a/app/apptesting/events.go b/app/apptesting/events.go
index 7d0a4d4df..cdfae5028 100644
--- a/app/apptesting/events.go
+++ b/app/apptesting/events.go
@@ -21,11 +21,17 @@ func (s *KeeperTestHelper) AssertEventEmitted(ctx sdk.Context, eventTypeExpected
 
 func (s *KeeperTestHelper) FindEvent(events []sdk.Event, name string) sdk.Event {
 	index := slices.IndexFunc(events, func(e sdk.Event) bool { return e.Type == name })
+	if index == -1 {
+		return sdk.Event{}
+	}
 	return events[index]
 }
 
 func (s *KeeperTestHelper) ExtractAttributes(event sdk.Event) map[string]string {
 	attrs := make(map[string]string)
+	if event.Attributes == nil {
+		return attrs
+	}
 	for _, a := range event.Attributes {
 		attrs[string(a.Key)] = string(a.Value)
 	}
diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go
index 7804dc340..83c53e3f2 100644
--- a/app/keepers/keepers.go
+++ b/app/keepers/keepers.go
@@ -2,6 +2,7 @@ package keepers
 
 import (
 	"github.com/CosmWasm/wasmd/x/wasm"
+	wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
 	"github.com/cosmos/cosmos-sdk/baseapp"
 	"github.com/cosmos/cosmos-sdk/codec"
 	sdk "github.com/cosmos/cosmos-sdk/types"
@@ -32,6 +33,8 @@ import (
 	"github.com/cosmos/cosmos-sdk/x/upgrade"
 	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
 	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+	ibcratelimit "github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit"
+	ibcratelimittypes "github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/types"
 
 	icahost "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host"
 	icahostkeeper "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/keeper"
@@ -110,10 +113,13 @@ type AppKeepers struct {
 	SuperfluidKeeper     *superfluidkeeper.Keeper
 	GovKeeper            *govkeeper.Keeper
 	WasmKeeper           *wasm.Keeper
+	ContractKeeper       *wasmkeeper.PermissionedKeeper
 	TokenFactoryKeeper   *tokenfactorykeeper.Keeper
+
 	// IBC modules
 	// transfer module
-	TransferModule transfer.AppModule
+	TransferModule          transfer.AppModule
+	RateLimitingICS4Wrapper *ibcratelimit.ICS4Wrapper
 
 	// keys to access the substores
 	keys    map[string]*sdk.KVStoreKey
@@ -195,12 +201,24 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
 		appKeepers.ScopedIBCKeeper,
 	)
 
+	// ChannelKeeper wrapper for rate limiting SendPacket(). The wasmKeeper needs to be added after it's created
+	rateLimitingParams := appKeepers.GetSubspace(ibcratelimittypes.ModuleName)
+	rateLimitingParams = rateLimitingParams.WithKeyTable(ibcratelimittypes.ParamKeyTable())
+	rateLimitingICS4Wrapper := ibcratelimit.NewICS4Middleware(
+		appKeepers.IBCKeeper.ChannelKeeper,
+		appKeepers.AccountKeeper,
+		nil,
+		appKeepers.BankKeeper,
+		rateLimitingParams,
+	)
+	appKeepers.RateLimitingICS4Wrapper = &rateLimitingICS4Wrapper
+
 	// Create Transfer Keepers
 	transferKeeper := ibctransferkeeper.NewKeeper(
 		appCodec,
 		appKeepers.keys[ibctransfertypes.StoreKey],
 		appKeepers.GetSubspace(ibctransfertypes.ModuleName),
-		appKeepers.IBCKeeper.ChannelKeeper,
+		appKeepers.RateLimitingICS4Wrapper, // The ICS4Wrapper is replaced by the rateLimitingICS4Wrapper instead of the channel
 		appKeepers.IBCKeeper.ChannelKeeper,
 		&appKeepers.IBCKeeper.PortKeeper,
 		appKeepers.AccountKeeper,
@@ -211,6 +229,9 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
 	appKeepers.TransferModule = transfer.NewAppModule(*appKeepers.TransferKeeper)
 	transferIBCModule := transfer.NewIBCModule(*appKeepers.TransferKeeper)
 
+	// RateLimiting IBC Middleware
+	rateLimitingTransferModule := ibcratelimit.NewIBCModule(transferIBCModule, appKeepers.RateLimitingICS4Wrapper)
+
 	icaHostKeeper := icahostkeeper.NewKeeper(
 		appCodec, appKeepers.keys[icahosttypes.StoreKey],
 		appKeepers.GetSubspace(icahosttypes.SubModuleName),
@@ -226,7 +247,8 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
 	// Create static IBC router, add transfer route, then set and seal it
 	ibcRouter := porttypes.NewRouter()
 	ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule).
-		AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
+		// The transferIBC module is replaced by rateLimitingTransferModule
+		AddRoute(ibctransfertypes.ModuleName, &rateLimitingTransferModule)
 	// Note: the sealing is done after creating wasmd and wiring that up
 
 	// create evidence keeper with router
@@ -343,6 +365,9 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
 		wasmOpts...,
 	)
 	appKeepers.WasmKeeper = &wasmKeeper
+	// Update the ICS4Wrapper with the proper contractKeeper
+	appKeepers.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(appKeepers.WasmKeeper)
+	appKeepers.RateLimitingICS4Wrapper.ContractKeeper = appKeepers.ContractKeeper
 
 	// wire up x/wasm to IBC
 	ibcRouter.AddRoute(wasm.ModuleName, wasm.NewIBCHandler(appKeepers.WasmKeeper, appKeepers.IBCKeeper.ChannelKeeper))
@@ -437,6 +462,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
 	paramsKeeper.Subspace(wasm.ModuleName)
 	paramsKeeper.Subspace(tokenfactorytypes.ModuleName)
 	paramsKeeper.Subspace(twaptypes.ModuleName)
+	paramsKeeper.Subspace(ibcratelimittypes.ModuleName)
 
 	return paramsKeeper
 }
diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go
index ee070b4b7..335d4924e 100644
--- a/tests/e2e/configurer/chain/commands.go
+++ b/tests/e2e/configurer/chain/commands.go
@@ -105,7 +105,7 @@ func (n *NodeConfig) FailIBCTransfer(from, recipient, amount string) {
 
 	cmd := []string{"osmosisd", "tx", "ibc-transfer", "transfer", "transfer", "channel-0", recipient, amount, fmt.Sprintf("--from=%s", from)}
 
-	_, _, err := n.containerManager.ExecTxCmdWithSuccessString(n.t, n.chainId, n.Name, cmd, "rate limit exceeded")
+	_, _, err := n.containerManager.ExecTxCmdWithSuccessString(n.t, n.chainId, n.Name, cmd, "Rate Limit exceeded")
 	require.NoError(n.t, err)
 
 	n.LogActionF("Failed to send IBC transfer (as expected)")
diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go
index 5c9b97e0a..ec98a2908 100644
--- a/tests/e2e/e2e_test.go
+++ b/tests/e2e/e2e_test.go
@@ -1,12 +1,17 @@
 package e2e
 
 import (
+	"encoding/json"
 	"fmt"
+	"io"
 	"os"
 	"path/filepath"
 	"strconv"
 	"time"
 
+	paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils"
+	ibcratelimittypes "github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/types"
+
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	coretypes "github.com/tendermint/tendermint/rpc/core/types"
 
@@ -107,6 +112,124 @@ func (s *IntegrationTestSuite) TestSuperfluidVoting() {
 	)
 }
 
+// Copy a file from A to B with io.Copy
+func copyFile(a, b string) error {
+	source, err := os.Open(a)
+	if err != nil {
+		return err
+	}
+	defer source.Close()
+	destination, err := os.Create(b)
+	if err != nil {
+		return err
+	}
+	defer destination.Close()
+	_, err = io.Copy(destination, source)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *IntegrationTestSuite) TestIBCTokenTransferRateLimiting() {
+	if s.skipIBC {
+		s.T().Skip("Skipping IBC tests")
+	}
+	chainA := s.configurer.GetChainConfig(0)
+	chainB := s.configurer.GetChainConfig(1)
+
+	node, err := chainA.GetDefaultNode()
+	s.NoError(err)
+
+	supply, err := node.QueryTotalSupply()
+	s.NoError(err)
+	osmoSupply := supply.AmountOf("uosmo")
+
+	// balance, err := node.QueryBalances(chainA.NodeConfigs[1].PublicAddress)
+	// s.NoError(err)
+
+	f, err := osmoSupply.ToDec().Float64()
+	s.NoError(err)
+
+	over := f * 0.02
+
+	// Sending >1%
+	chainA.SendIBC(chainB, chainB.NodeConfigs[0].PublicAddress, sdk.NewInt64Coin(initialization.OsmoDenom, int64(over)))
+
+	// copy the contract from x/rate-limit/testdata/
+	wd, err := os.Getwd()
+	s.NoError(err)
+	// co up two levels
+	projectDir := filepath.Dir(filepath.Dir(wd))
+	fmt.Println(wd, projectDir)
+	err = copyFile(projectDir+"/x/ibc-rate-limit/testdata/rate_limiter.wasm", wd+"/scripts/rate_limiter.wasm")
+	s.NoError(err)
+	node.StoreWasmCode("rate_limiter.wasm", initialization.ValidatorWalletName)
+	chainA.LatestCodeId += 1
+	node.InstantiateWasmContract(
+		strconv.Itoa(chainA.LatestCodeId),
+		fmt.Sprintf(`{"gov_module": "%s", "ibc_module": "%s", "paths": [{"channel_id": "channel-0", "denom": "%s", "quotas": [{"name":"testQuota", "duration": 86400, "send_recv": [1, 1]}] } ] }`, node.PublicAddress, node.PublicAddress, initialization.OsmoToken.Denom),
+		initialization.ValidatorWalletName)
+
+	// Using code_id 1 because this is the only contract right now. This may need to change if more contracts are added
+	contracts, err := node.QueryContractsFromId(chainA.LatestCodeId)
+	s.NoError(err)
+	s.Require().Len(contracts, 1, "Wrong number of contracts for the rate limiter")
+
+	proposal := paramsutils.ParamChangeProposalJSON{
+		Title:       "Param Change",
+		Description: "Changing the rate limit contract param",
+		Changes: paramsutils.ParamChangesJSON{
+			paramsutils.ParamChangeJSON{
+				Subspace: ibcratelimittypes.ModuleName,
+				Key:      "contract",
+				Value:    []byte(fmt.Sprintf(`"%s"`, contracts[0])),
+			},
+		},
+		Deposit: "625000000uosmo",
+	}
+	proposalJson, err := json.Marshal(proposal)
+	s.NoError(err)
+
+	node.SubmitParamChangeProposal(string(proposalJson), initialization.ValidatorWalletName)
+	chainA.LatestProposalNumber += 1
+
+	for _, n := range chainA.NodeConfigs {
+		n.VoteYesProposal(initialization.ValidatorWalletName, chainA.LatestProposalNumber)
+	}
+
+	// The value is returned as a string, so we have to unmarshal twice
+	type Params struct {
+		Key      string `json:"key"`
+		Subspace string `json:"subspace"`
+		Value    string `json:"value"`
+	}
+
+	s.Eventually(
+		func() bool {
+			var params Params
+			node.QueryParams(ibcratelimittypes.ModuleName, "contract", &params)
+			var val string
+			err := json.Unmarshal([]byte(params.Value), &val)
+			if err != nil {
+				return false
+			}
+			return val != ""
+		},
+		1*time.Minute,
+		10*time.Millisecond,
+		"Osmosis node failed to retrieve params",
+	)
+
+	// Sending <1%. Should work
+	chainA.SendIBC(chainB, chainB.NodeConfigs[0].PublicAddress, sdk.NewInt64Coin(initialization.OsmoDenom, 1))
+	// Sending >1%. Should fail
+	node.FailIBCTransfer(initialization.ValidatorWalletName, chainB.NodeConfigs[0].PublicAddress, fmt.Sprintf("%duosmo", int(over)))
+
+	// Removing the rate limit so it doesn't affect other tests
+	node.WasmExecute(contracts[0], `{"remove_path": {"channel_id": "channel-0", "denom": "uosmo"}}`, initialization.ValidatorWalletName)
+}
+
 // TestAddToExistingLockPostUpgrade ensures addToExistingLock works for locks created preupgrade.
 func (s *IntegrationTestSuite) TestAddToExistingLockPostUpgrade() {
 	if s.skipUpgrade {
diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs
index 16bc08802..fa5b99e49 100644
--- a/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs
+++ b/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs
@@ -52,7 +52,7 @@ fn consume_allowance() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let res = sudo(deps.as_mut(), mock_env(), msg).unwrap();
@@ -64,7 +64,7 @@ fn consume_allowance() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let err = sudo(deps.as_mut(), mock_env(), msg).unwrap_err();
@@ -91,7 +91,7 @@ fn symetric_flows_dont_consume_allowance() {
     let send_msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let recv_msg = SudoMsg::RecvPacket {
@@ -154,7 +154,7 @@ fn asymetric_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_060_u32.into(),
         funds: 60_u32.into(),
     };
     let res = sudo(deps.as_mut(), mock_env(), msg).unwrap();
@@ -166,7 +166,7 @@ fn asymetric_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_060_u32.into(),
         funds: 60_u32.into(),
     };
 
@@ -195,7 +195,7 @@ fn asymetric_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_060_u32.into(),
         funds: 60_u32.into(),
     };
     let err = sudo(deps.as_mut(), mock_env(), msg.clone()).unwrap_err();
@@ -205,7 +205,7 @@ fn asymetric_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_060_u32.into(),
         funds: 30_u32.into(),
     };
     let res = sudo(deps.as_mut(), mock_env(), msg.clone()).unwrap();
@@ -256,7 +256,7 @@ fn query_state() {
     let send_msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     sudo(deps.as_mut(), mock_env(), send_msg.clone()).unwrap();
@@ -343,7 +343,7 @@ fn undo_send() {
     let send_msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let undo_msg = SudoMsg::UndoSend {
diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/error.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/error.rs
index dc40f708d..367180baf 100644
--- a/x/ibc-rate-limit/contracts/rate-limiter/src/error.rs
+++ b/x/ibc-rate-limit/contracts/rate-limiter/src/error.rs
@@ -1,4 +1,4 @@
-use cosmwasm_std::{StdError, Timestamp};
+use cosmwasm_std::{StdError, Timestamp, Uint256};
 use thiserror::Error;
 
 #[derive(Error, Debug)]
@@ -9,10 +9,14 @@ pub enum ContractError {
     #[error("Unauthorized")]
     Unauthorized {},
 
-    #[error("IBC Rate Limit exceded for channel {channel:?} and denom {denom:?}. Try again after {reset:?}")]
+    #[error("IBC Rate Limit exceeded for {channel}/{denom}. Tried to transfer {amount} which exceeds capacity on the '{quota_name}' quota ({used}/{max}). Try again after {reset:?}")]
     RateLimitExceded {
         channel: String,
         denom: String,
+        amount: Uint256,
+        quota_name: String,
+        used: Uint256,
+        max: Uint256,
         reset: Timestamp,
     },
 
diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs
index 66a145b39..d5d76acb0 100644
--- a/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs
+++ b/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs
@@ -82,7 +82,7 @@ fn expiration() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -105,7 +105,7 @@ fn expiration() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -123,7 +123,7 @@ fn expiration() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 3_000_u32.into(),
+        channel_value: 3_300_u32.into(),
         funds: 300_u32.into(),
     };
 
@@ -162,7 +162,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -172,7 +172,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -188,7 +188,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
 
@@ -207,7 +207,7 @@ fn multiple_quotas() {
         let msg = SudoMsg::SendPacket {
             channel_id: format!("channel"),
             denom: format!("denom"),
-            channel_value: 100_u32.into(),
+            channel_value: 101_u32.into(),
             funds: 1_u32.into(),
         };
         let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -224,7 +224,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -240,7 +240,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -257,7 +257,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
@@ -272,7 +272,7 @@ fn multiple_quotas() {
     let msg = SudoMsg::SendPacket {
         channel_id: format!("channel"),
         denom: format!("denom"),
-        channel_value: 100_u32.into(),
+        channel_value: 101_u32.into(),
         funds: 1_u32.into(),
     };
     let cosmos_msg = cw_rate_limit_contract.sudo(msg);
diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/packet.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/packet.rs
new file mode 100644
index 000000000..6bc5b8cfe
--- /dev/null
+++ b/x/ibc-rate-limit/contracts/rate-limiter/src/packet.rs
@@ -0,0 +1,64 @@
+use cosmwasm_std::{Addr, Deps, Timestamp};
+use serde::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct Height {
+    /// Previously known as "epoch"
+    revision_number: Option<u64>,
+
+    /// The height of a block
+    revision_height: Option<u64>,
+}
+
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct FungibleTokenData {
+    denom: String,
+    amount: u128,
+    sender: Addr,
+    receiver: Addr,
+}
+
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct Packet {
+    pub sequence: u64,
+    pub source_port: String,
+    pub source_channel: String,
+    pub destination_port: String,
+    pub destination_channel: String,
+    pub data: FungibleTokenData,
+    pub timeout_height: Height,
+    pub timeout_timestamp: Option<Timestamp>,
+}
+
+impl Packet {
+    pub fn channel_value(&self, _deps: Deps) -> u128 {
+        // let balance = deps.querier.query_all_balances("address", self.data.denom);
+        // deps.querier.sup
+        return 125000000000011250 * 2;
+    }
+
+    pub fn get_funds(&self) -> u128 {
+        return self.data.amount;
+    }
+
+    fn local_channel(&self) -> String {
+        // Pick the appropriate channel depending on whether this is a send or a recv
+        return self.destination_channel.clone();
+    }
+
+    fn local_demom(&self) -> String {
+        // This should actually convert the denom from the packet to the osmosis denom, but for now, just returning this
+        return self.data.denom.clone();
+    }
+
+    pub fn path_data(&self) -> (String, String) {
+        let denom = self.local_demom();
+        let channel = if denom.starts_with("ibc/") {
+            self.local_channel()
+        } else {
+            "any".to_string() // native tokens are rate limited globally
+        };
+
+        return (channel, denom);
+    }
+}
diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs
index 523794648..e28fc1004 100644
--- a/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs
+++ b/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs
@@ -102,6 +102,15 @@ impl Flow {
         }
     }
 
+    /// returns the balance in a direction. This is used for displaying cleaner errors
+    pub fn balance_on(&self, direction: &FlowType) -> Uint256 {
+        let (balance_in, balance_out) = self.balance();
+        match direction {
+            FlowType::In => balance_in,
+            FlowType::Out => balance_out,
+        }
+    }
+
     /// If now is greater than the period_end, the Flow is considered expired.
     pub fn is_expired(&self, now: Timestamp) -> bool {
         self.period_end < now
@@ -182,6 +191,15 @@ impl Quota {
             None => (0_u32.into(), 0_u32.into()), // This should never happen, but ig the channel value is not set, we disallow any transfer
         }
     }
+
+    /// returns the capacity in a direction. This is used for displaying cleaner errors
+    pub fn capacity_on(&self, direction: &FlowType) -> Uint256 {
+        let (max_in, max_out) = self.capacity();
+        match direction {
+            FlowType::In => max_in,
+            FlowType::Out => max_out,
+        }
+    }
 }
 
 impl From<&QuotaMsg> for Quota {
@@ -209,6 +227,29 @@ pub struct RateLimit {
     pub flow: Flow,
 }
 
+// The channel value on send depends on the amount on escrow. The ibc transfer
+// module modifies the escrow amount by "funds" on sends before calling the
+// contract. This function takes that into account so that the channel value
+// that we track matches the channel value at the moment when the ibc
+// transaction started executing
+fn calculate_channel_value(
+    channel_value: Uint256,
+    denom: &str,
+    funds: Uint256,
+    direction: &FlowType,
+) -> Uint256 {
+    match direction {
+        FlowType::Out => {
+            if denom.contains("ibc") {
+                channel_value + funds // Non-Native tokens get removed from the supply on send. Add that amount back
+            } else {
+                channel_value - funds // Native tokens increase escrow amount on send. Remove that amount here
+            }
+        }
+        FlowType::In => channel_value,
+    }
+}
+
 impl RateLimit {
     /// Checks if a transfer is allowed and updates the data structures
     /// accordingly.
@@ -224,10 +265,22 @@ impl RateLimit {
         channel_value: Uint256,
         now: Timestamp,
     ) -> Result<Self, ContractError> {
+        // Flow used before this transaction is applied.
+        // This is used to make error messages more informative
+        let initial_flow = self.flow.balance_on(direction);
+
+        // Apply the transfer. From here on, we will updated the flow with the new transfer
+        // and check if  it exceeds the quota at the current time
+
         let expired = self.flow.apply_transfer(direction, funds, now, &self.quota);
         // Cache the channel value if it has never been set or it has expired.
         if self.quota.channel_value.is_none() || expired {
-            self.quota.channel_value = Some(channel_value)
+            self.quota.channel_value = Some(calculate_channel_value(
+                channel_value,
+                &path.denom,
+                funds,
+                direction,
+            ))
         }
 
         let (max_in, max_out) = self.quota.capacity();
@@ -236,6 +289,10 @@ impl RateLimit {
             true => Err(ContractError::RateLimitExceded {
                 channel: path.channel.to_string(),
                 denom: path.denom.to_string(),
+                amount: funds,
+                quota_name: self.quota.name.to_string(),
+                used: initial_flow,
+                max: self.quota.capacity_on(direction),
                 reset: self.flow.period_end,
             }),
             false => Ok(RateLimit {
diff --git a/x/ibc-rate-limit/ibc_middleware_test.go b/x/ibc-rate-limit/ibc_middleware_test.go
new file mode 100644
index 000000000..497916d8b
--- /dev/null
+++ b/x/ibc-rate-limit/ibc_middleware_test.go
@@ -0,0 +1,462 @@
+package ibc_rate_limit_test
+
+import (
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	ibc_rate_limit "github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit"
+
+	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
+	clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
+	ibctesting "github.com/cosmos/ibc-go/v3/testing"
+	"github.com/osmosis-labs/osmosis/v12/app"
+	"github.com/osmosis-labs/osmosis/v12/app/apptesting"
+	"github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/testutil"
+	"github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/types"
+	"github.com/stretchr/testify/suite"
+)
+
+type MiddlewareTestSuite struct {
+	apptesting.KeeperTestHelper
+
+	coordinator *ibctesting.Coordinator
+
+	// testing chains used for convenience and readability
+	chainA *osmosisibctesting.TestChain
+	chainB *osmosisibctesting.TestChain
+	path   *ibctesting.Path
+}
+
+// Setup
+func TestMiddlewareTestSuite(t *testing.T) {
+	suite.Run(t, new(MiddlewareTestSuite))
+}
+
+func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) {
+	osmosisApp := app.Setup(false)
+	return osmosisApp, app.NewDefaultGenesisState()
+}
+
+func NewTransferPath(chainA, chainB *osmosisibctesting.TestChain) *ibctesting.Path {
+	path := ibctesting.NewPath(chainA.TestChain, chainB.TestChain)
+	path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort
+	path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort
+	path.EndpointA.ChannelConfig.Version = transfertypes.Version
+	path.EndpointB.ChannelConfig.Version = transfertypes.Version
+	return path
+}
+
+func (suite *MiddlewareTestSuite) SetupTest() {
+	suite.Setup()
+	ibctesting.DefaultTestingAppInit = SetupTestingApp
+	suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2)
+	suite.chainA = &osmosisibctesting.TestChain{
+		TestChain: suite.coordinator.GetChain(ibctesting.GetChainID(1)),
+	}
+	// Remove epochs to prevent  minting
+	suite.chainA.MoveEpochsToTheFuture()
+	suite.chainB = &osmosisibctesting.TestChain{
+		TestChain: suite.coordinator.GetChain(ibctesting.GetChainID(2)),
+	}
+	suite.path = NewTransferPath(suite.chainA, suite.chainB)
+	suite.coordinator.Setup(suite.path)
+}
+
+// Helpers
+func (suite *MiddlewareTestSuite) MessageFromAToB(denom string, amount sdk.Int) sdk.Msg {
+	coin := sdk.NewCoin(denom, amount)
+	port := suite.path.EndpointA.ChannelConfig.PortID
+	channel := suite.path.EndpointA.ChannelID
+	accountFrom := suite.chainA.SenderAccount.GetAddress().String()
+	accountTo := suite.chainB.SenderAccount.GetAddress().String()
+	timeoutHeight := clienttypes.NewHeight(0, 100)
+	return transfertypes.NewMsgTransfer(
+		port,
+		channel,
+		coin,
+		accountFrom,
+		accountTo,
+		timeoutHeight,
+		0,
+	)
+}
+
+func (suite *MiddlewareTestSuite) MessageFromBToA(denom string, amount sdk.Int) sdk.Msg {
+	coin := sdk.NewCoin(denom, amount)
+	port := suite.path.EndpointB.ChannelConfig.PortID
+	channel := suite.path.EndpointB.ChannelID
+	accountFrom := suite.chainB.SenderAccount.GetAddress().String()
+	accountTo := suite.chainA.SenderAccount.GetAddress().String()
+	timeoutHeight := clienttypes.NewHeight(0, 100)
+	return transfertypes.NewMsgTransfer(
+		port,
+		channel,
+		coin,
+		accountFrom,
+		accountTo,
+		timeoutHeight,
+		0,
+	)
+}
+
+// Tests that a receiver address longer than 4096 is not accepted
+func (suite *MiddlewareTestSuite) TestInvalidReceiver() {
+	msg := transfertypes.NewMsgTransfer(
+		suite.path.EndpointB.ChannelConfig.PortID,
+		suite.path.EndpointB.ChannelID,
+		sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)),
+		suite.chainB.SenderAccount.GetAddress().String(),
+		strings.Repeat("x", 4097),
+		clienttypes.NewHeight(0, 100),
+		0,
+	)
+	_, ack, _ := suite.FullSendBToA(msg)
+	suite.Require().Contains(string(ack), "error",
+		"acknowledgment is not an error")
+	suite.Require().Contains(string(ack), sdkerrors.ErrInvalidAddress.Error(),
+		"acknowledgment error is not of the right type")
+}
+
+func (suite *MiddlewareTestSuite) FullSendBToA(msg sdk.Msg) (*sdk.Result, string, error) {
+	sendResult, err := suite.chainB.SendMsgsNoCheck(msg)
+	suite.Require().NoError(err)
+
+	packet, err := ibctesting.ParsePacketFromEvents(sendResult.GetEvents())
+	suite.Require().NoError(err)
+
+	err = suite.path.EndpointA.UpdateClient()
+	suite.Require().NoError(err)
+
+	res, err := suite.path.EndpointA.RecvPacketWithResult(packet)
+	suite.Require().NoError(err)
+
+	ack, err := ibctesting.ParseAckFromEvents(res.GetEvents())
+
+	err = suite.path.EndpointA.UpdateClient()
+	suite.Require().NoError(err)
+	err = suite.path.EndpointB.UpdateClient()
+	suite.Require().NoError(err)
+
+	return sendResult, string(ack), err
+}
+
+func (suite *MiddlewareTestSuite) FullSendAToB(msg sdk.Msg) (*sdk.Result, string, error) {
+	sendResult, err := suite.chainA.SendMsgsNoCheck(msg)
+	if err != nil {
+		return nil, "", err
+	}
+
+	packet, err := ibctesting.ParsePacketFromEvents(sendResult.GetEvents())
+	if err != nil {
+		return nil, "", err
+	}
+
+	err = suite.path.EndpointB.UpdateClient()
+	if err != nil {
+		return nil, "", err
+	}
+
+	res, err := suite.path.EndpointB.RecvPacketWithResult(packet)
+	if err != nil {
+		return nil, "", err
+	}
+
+	ack, err := ibctesting.ParseAckFromEvents(res.GetEvents())
+	if err != nil {
+		return nil, "", err
+	}
+
+	err = suite.path.EndpointA.UpdateClient()
+	if err != nil {
+		return nil, "", err
+	}
+	err = suite.path.EndpointB.UpdateClient()
+	if err != nil {
+		return nil, "", err
+	}
+
+	return sendResult, string(ack), nil
+}
+
+func (suite *MiddlewareTestSuite) AssertReceive(success bool, msg sdk.Msg) (string, error) {
+	_, ack, err := suite.FullSendBToA(msg)
+	if success {
+		suite.Require().NoError(err)
+		suite.Require().NotContains(string(ack), "error",
+			"acknowledgment is an error")
+	} else {
+		suite.Require().Contains(string(ack), "error",
+			"acknowledgment is not an error")
+		suite.Require().Contains(string(ack), types.ErrRateLimitExceeded.Error(),
+			"acknowledgment error is not of the right type")
+	}
+	return ack, err
+}
+
+func (suite *MiddlewareTestSuite) AssertSend(success bool, msg sdk.Msg) (*sdk.Result, error) {
+	r, _, err := suite.FullSendAToB(msg)
+	if success {
+		suite.Require().NoError(err, "IBC send failed. Expected success. %s", err)
+	} else {
+		suite.Require().Error(err, "IBC send succeeded. Expected failure")
+		suite.ErrorContains(err, types.ErrRateLimitExceeded.Error(), "Bad error type")
+	}
+	return r, err
+}
+
+func (suite *MiddlewareTestSuite) BuildChannelQuota(name, denom string, duration, send_precentage, recv_percentage uint32) string {
+	return fmt.Sprintf(`
+          {"channel_id": "channel-0", "denom": "%s", "quotas": [{"name":"%s", "duration": %d, "send_recv":[%d, %d]}] }
+    `, denom, name, duration, send_precentage, recv_percentage)
+}
+
+// Tests
+
+// Test that Sending IBC messages works when the middleware isn't configured
+func (suite *MiddlewareTestSuite) TestSendTransferNoContract() {
+	one := sdk.NewInt(1)
+	suite.AssertSend(true, suite.MessageFromAToB(sdk.DefaultBondDenom, one))
+}
+
+// Test that Receiving IBC messages works when the middleware isn't configured
+func (suite *MiddlewareTestSuite) TestReceiveTransferNoContract() {
+	one := sdk.NewInt(1)
+	suite.AssertReceive(true, suite.MessageFromBToA(sdk.DefaultBondDenom, one))
+}
+
+func (suite *MiddlewareTestSuite) initializeEscrow() (totalEscrow, expectedSed sdk.Int) {
+	osmosisApp := suite.chainA.GetOsmosisApp()
+	supply := osmosisApp.BankKeeper.GetSupplyWithOffset(suite.chainA.GetContext(), sdk.DefaultBondDenom)
+
+	// Move some funds from chainA to chainB so that there is something in escrow
+	// Each user has 10% of the supply, so we send most of the funds from one user to chainA
+	transferAmount := supply.Amount.QuoRaw(20)
+
+	// When sending, the amount we're sending goes into escrow before we enter the middleware and thus
+	// it's used as part of the channel value in the rate limiting contract
+	// To account for that, we subtract the amount we'll send first (2.5% of transferAmount) here
+	sendAmount := transferAmount.QuoRaw(40)
+
+	// Send from A to B
+	_, _, err := suite.FullSendAToB(suite.MessageFromAToB(sdk.DefaultBondDenom, transferAmount.Sub(sendAmount)))
+	suite.Require().NoError(err)
+	// Send from A to B
+	_, _, err = suite.FullSendBToA(suite.MessageFromBToA(sdk.DefaultBondDenom, transferAmount.Sub(sendAmount)))
+	suite.Require().NoError(err)
+
+	return transferAmount, sendAmount
+}
+
+func (suite *MiddlewareTestSuite) fullSendTest(native bool) map[string]string {
+	quotaPercentage := 5
+	suite.initializeEscrow()
+	// Get the denom and amount to send
+	denom := sdk.DefaultBondDenom
+	if !native {
+		denomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom("transfer", "channel-0", denom))
+		denom = denomTrace.IBCDenom()
+	}
+
+	osmosisApp := suite.chainA.GetOsmosisApp()
+
+	// This is the first one. Inside the tests. It works as expected.
+	channelValue := ibc_rate_limit.CalculateChannelValue(suite.chainA.GetContext(), denom, "transfer", "channel-0", osmosisApp.BankKeeper)
+
+	// The amount to be sent is send 2.5% (quota is 5%)
+	quota := channelValue.QuoRaw(int64(100 / quotaPercentage))
+	sendAmount := quota.QuoRaw(2)
+
+	fmt.Printf("Testing send rate limiting for denom=%s, channelValue=%s, quota=%s, sendAmount=%s\n", denom, channelValue, quota, sendAmount)
+
+	// Setup contract
+	suite.chainA.StoreContractCode(&suite.Suite)
+	quotas := suite.BuildChannelQuota("weekly", denom, 604800, 5, 5)
+	fmt.Println(quotas)
+	addr := suite.chainA.InstantiateContract(&suite.Suite, quotas)
+	suite.chainA.RegisterRateLimitingContract(addr)
+
+	// TODO: Remove native from MessafeFrom calls
+	// send 2.5% (quota is 5%)
+	fmt.Println("trying to send ", sendAmount)
+	suite.AssertSend(true, suite.MessageFromAToB(denom, sendAmount))
+
+	// send 2.5% (quota is 5%)
+	fmt.Println("trying to send ", sendAmount)
+	r, _ := suite.AssertSend(true, suite.MessageFromAToB(denom, sendAmount))
+
+	// Calculate remaining allowance in the quota
+	attrs := suite.ExtractAttributes(suite.FindEvent(r.GetEvents(), "wasm"))
+
+	used, ok := sdk.NewIntFromString(attrs["weekly_used_out"])
+	suite.Require().True(ok)
+
+	suite.Require().Equal(used, sendAmount.MulRaw(2))
+
+	// Sending above the quota should fail. We use 2 instead of 1 here to avoid rounding issues
+	suite.AssertSend(false, suite.MessageFromAToB(denom, sdk.NewInt(2)))
+	return attrs
+}
+
+// Test rate limiting on sends
+func (suite *MiddlewareTestSuite) TestSendTransferWithRateLimitingNative() {
+	suite.fullSendTest(true)
+}
+
+// Test rate limiting on sends
+func (suite *MiddlewareTestSuite) TestSendTransferWithRateLimitingNonNative() {
+	suite.fullSendTest(false)
+}
+
+// Test rate limits are reset when the specified time period has passed
+func (suite *MiddlewareTestSuite) TestSendTransferReset() {
+	// Same test as above, but the quotas get reset after time passes
+	attrs := suite.fullSendTest(true)
+	parts := strings.Split(attrs["weekly_period_end"], ".") // Splitting timestamp into secs and nanos
+	secs, err := strconv.ParseInt(parts[0], 10, 64)
+	suite.Require().NoError(err)
+	nanos, err := strconv.ParseInt(parts[1], 10, 64)
+	suite.Require().NoError(err)
+	resetTime := time.Unix(secs, nanos)
+
+	// Move chainA forward one block
+	suite.chainA.NextBlock()
+	suite.chainA.SenderAccount.SetSequence(suite.chainA.SenderAccount.GetSequence() + 1)
+
+	// Reset time + one second
+	oneSecAfterReset := resetTime.Add(time.Second)
+	suite.coordinator.IncrementTimeBy(oneSecAfterReset.Sub(suite.coordinator.CurrentTime))
+
+	// Sending should succeed again
+	suite.AssertSend(true, suite.MessageFromAToB(sdk.DefaultBondDenom, sdk.NewInt(1)))
+}
+
+// Test rate limiting on receives
+func (suite *MiddlewareTestSuite) fullRecvTest(native bool) {
+	quotaPercentage := 5
+	suite.initializeEscrow()
+	// Get the denom and amount to send
+	denom := sdk.DefaultBondDenom
+	if !native {
+		denomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom("transfer", "channel-0", denom))
+		denom = denomTrace.IBCDenom()
+	}
+
+	osmosisApp := suite.chainA.GetOsmosisApp()
+
+	// This is the first one. Inside the tests. It works as expected.
+	channelValue := ibc_rate_limit.CalculateChannelValue(suite.chainA.GetContext(), denom, "transfer", "channel-0", osmosisApp.BankKeeper)
+
+	// The amount to be sent is send 2.5% (quota is 5%)
+	quota := channelValue.QuoRaw(int64(100 / quotaPercentage))
+	sendAmount := quota.QuoRaw(2)
+
+	fmt.Printf("Testing recv rate limiting for denom=%s, channelValue=%s, quota=%s, sendAmount=%s\n", denom, channelValue, quota, sendAmount)
+
+	// Setup contract
+	suite.chainA.StoreContractCode(&suite.Suite)
+	quotas := suite.BuildChannelQuota("weekly", denom, 604800, 5, 5)
+	addr := suite.chainA.InstantiateContract(&suite.Suite, quotas)
+	suite.chainA.RegisterRateLimitingContract(addr)
+
+	// receive 2.5% (quota is 5%)
+	suite.AssertReceive(true, suite.MessageFromBToA(denom, sendAmount))
+
+	// receive 2.5% (quota is 5%)
+	suite.AssertReceive(true, suite.MessageFromBToA(denom, sendAmount))
+
+	// Sending above the quota should fail. We send 2 instead of 1 to account for rounding errors
+	suite.AssertReceive(false, suite.MessageFromBToA(denom, sdk.NewInt(2)))
+}
+
+func (suite *MiddlewareTestSuite) TestRecvTransferWithRateLimitingNative() {
+	suite.fullRecvTest(true)
+}
+
+func (suite *MiddlewareTestSuite) TestRecvTransferWithRateLimitingNonNative() {
+	suite.fullRecvTest(false)
+}
+
+// Test no rate limiting occurs when the contract is set, but not quotas are condifured for the path
+func (suite *MiddlewareTestSuite) TestSendTransferNoQuota() {
+	// Setup contract
+	suite.chainA.StoreContractCode(&suite.Suite)
+	addr := suite.chainA.InstantiateContract(&suite.Suite, ``)
+	suite.chainA.RegisterRateLimitingContract(addr)
+
+	// send 1 token.
+	// If the contract doesn't have a quota for the current channel, all transfers are allowed
+	suite.AssertSend(true, suite.MessageFromAToB(sdk.DefaultBondDenom, sdk.NewInt(1)))
+}
+
+// Test rate limits are reverted if a "send" fails
+func (suite *MiddlewareTestSuite) TestFailedSendTransfer() {
+	suite.initializeEscrow()
+	// Setup contract
+	suite.chainA.StoreContractCode(&suite.Suite)
+	quotas := suite.BuildChannelQuota("weekly", sdk.DefaultBondDenom, 604800, 1, 1)
+	addr := suite.chainA.InstantiateContract(&suite.Suite, quotas)
+	suite.chainA.RegisterRateLimitingContract(addr)
+
+	// Get the escrowed amount
+	osmosisApp := suite.chainA.GetOsmosisApp()
+	escrowAddress := transfertypes.GetEscrowAddress("transfer", "channel-0")
+	escrowed := osmosisApp.BankKeeper.GetBalance(suite.chainA.GetContext(), escrowAddress, sdk.DefaultBondDenom)
+
+	quota := escrowed.Amount.QuoRaw(100) // 1% of the escrowed amount
+
+	// Use the whole quota
+	coins := sdk.NewCoin(sdk.DefaultBondDenom, quota)
+	port := suite.path.EndpointA.ChannelConfig.PortID
+	channel := suite.path.EndpointA.ChannelID
+	accountFrom := suite.chainA.SenderAccount.GetAddress().String()
+	timeoutHeight := clienttypes.NewHeight(0, 100)
+	msg := transfertypes.NewMsgTransfer(port, channel, coins, accountFrom, "INVALID", timeoutHeight, 0)
+
+	// Sending the message manually because AssertSend updates both clients. We need to update the clients manually
+	// for this test so that the failure to receive on chain B happens after the second packet is sent from chain A.
+	// That way we validate that chain A is blocking as expected, but the flow is reverted after the receive failure is
+	// acknowledged on chain A
+	res, err := suite.chainA.SendMsgsNoCheck(msg)
+	suite.Require().NoError(err)
+
+	// Sending again fails as the quota is filled
+	suite.AssertSend(false, suite.MessageFromAToB(sdk.DefaultBondDenom, quota))
+
+	// Move forward one block
+	suite.chainA.NextBlock()
+	suite.chainA.SenderAccount.SetSequence(suite.chainA.SenderAccount.GetSequence() + 1)
+	suite.chainA.Coordinator.IncrementTime()
+
+	// Update both clients
+	err = suite.path.EndpointA.UpdateClient()
+	suite.Require().NoError(err)
+	err = suite.path.EndpointB.UpdateClient()
+	suite.Require().NoError(err)
+
+	// Execute the acknowledgement from chain B in chain A
+
+	// extract the sent packet
+	packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents())
+	suite.Require().NoError(err)
+
+	// recv in chain b
+	res, err = suite.path.EndpointB.RecvPacketWithResult(packet)
+
+	// get the ack from the chain b's response
+	ack, err := ibctesting.ParseAckFromEvents(res.GetEvents())
+	suite.Require().NoError(err)
+
+	// manually relay it to chain a
+	err = suite.path.EndpointA.AcknowledgePacket(packet, ack)
+	suite.Require().NoError(err)
+
+	// We should be able to send again because the packet that exceeded the quota failed and has been reverted
+	suite.AssertSend(true, suite.MessageFromAToB(sdk.DefaultBondDenom, sdk.NewInt(1)))
+}
diff --git a/x/ibc-rate-limit/ibc_module.go b/x/ibc-rate-limit/ibc_module.go
index c1df7c921..433826ddd 100644
--- a/x/ibc-rate-limit/ibc_module.go
+++ b/x/ibc-rate-limit/ibc_module.go
@@ -103,12 +103,27 @@ func (im *IBCModule) OnChanCloseConfirm(
 	return im.app.OnChanCloseConfirm(ctx, portID, channelID)
 }
 
+func ValidateReceiverAddress(packet channeltypes.Packet) error {
+	var packetData transfertypes.FungibleTokenPacketData
+	if err := json.Unmarshal(packet.GetData(), &packetData); err != nil {
+		return err
+	}
+	if len(packetData.Receiver) >= 4096 {
+		return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "IBC Receiver address too long. Max supported length is %d", 4096)
+	}
+	return nil
+}
+
 // OnRecvPacket implements the IBCModule interface
 func (im *IBCModule) OnRecvPacket(
 	ctx sdk.Context,
 	packet channeltypes.Packet,
 	relayer sdk.AccAddress,
 ) exported.Acknowledgement {
+	if err := ValidateReceiverAddress(packet); err != nil {
+		return channeltypes.NewErrorAcknowledgement(err.Error())
+	}
+
 	contract := im.ics4Middleware.GetParams(ctx)
 	if contract == "" {
 		// The contract has not been configured. Continue as usual
@@ -116,9 +131,10 @@ func (im *IBCModule) OnRecvPacket(
 	}
 	amount, denom, err := GetFundsFromPacket(packet)
 	if err != nil {
-		return channeltypes.NewErrorAcknowledgement("bad packet")
+		return channeltypes.NewErrorAcknowledgement("bad packet in rate limit's OnRecvPacket")
 	}
-	channelValue := im.ics4Middleware.CalculateChannelValue(ctx, denom)
+
+	channelValue := im.ics4Middleware.CalculateChannelValue(ctx, denom, packet)
 
 	err = CheckAndUpdateRateLimits(
 		ctx,
@@ -127,11 +143,11 @@ func (im *IBCModule) OnRecvPacket(
 		contract,
 		channelValue,
 		packet.GetDestChannel(),
-		denom,
+		denom, // We always use the packet's denom here, as we want the limits to be the same on both directions
 		amount,
 	)
 	if err != nil {
-		return channeltypes.NewErrorAcknowledgement(types.RateLimitExceededMsg)
+		return channeltypes.NewErrorAcknowledgement(types.ErrRateLimitExceeded.Error())
 	}
 
 	// if this returns an Acknowledgement that isn't successful, all state changes are discarded
diff --git a/x/ibc-rate-limit/ics4_wrapper.go b/x/ibc-rate-limit/ics4_wrapper.go
index bdf7e935a..453de40a4 100644
--- a/x/ibc-rate-limit/ics4_wrapper.go
+++ b/x/ibc-rate-limit/ics4_wrapper.go
@@ -53,9 +53,11 @@ func (i *ICS4Wrapper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capab
 
 	amount, denom, err := GetFundsFromPacket(packet)
 	if err != nil {
-		return sdkerrors.Wrap(err, "Rate limited SendPacket")
+		return sdkerrors.Wrap(err, "Rate limit SendPacket")
 	}
-	channelValue := i.CalculateChannelValue(ctx, denom)
+
+	channelValue := i.CalculateChannelValue(ctx, denom, packet)
+
 	err = CheckAndUpdateRateLimits(
 		ctx,
 		i.ContractKeeper,
@@ -63,11 +65,11 @@ func (i *ICS4Wrapper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capab
 		contract,
 		channelValue,
 		packet.GetSourceChannel(),
-		denom,
+		denom, // We always use the packet's denom here, as we want the limits to be the same on both directions
 		amount,
 	)
 	if err != nil {
-		return sdkerrors.Wrap(err, "Rate limited SendPacket")
+		return sdkerrors.Wrap(err, "bad packet in rate limit's SendPacket")
 	}
 
 	return i.channel.SendPacket(ctx, chanCap, packet)
@@ -84,6 +86,7 @@ func (i *ICS4Wrapper) GetParams(ctx sdk.Context) (contract string) {
 
 // CalculateChannelValue The value of an IBC channel. This is calculated using the denom supplied by the sender.
 // if the denom is not correct, the transfer should fail somewhere else on the call chain
-func (i *ICS4Wrapper) CalculateChannelValue(ctx sdk.Context, denom string) sdk.Int {
-	return i.bankKeeper.GetSupplyWithOffset(ctx, denom).Amount
+func (i *ICS4Wrapper) CalculateChannelValue(ctx sdk.Context, denom string, packet exported.PacketI) sdk.Int {
+	// The logic is etracted into a function here so that it can be used within the tests
+	return CalculateChannelValue(ctx, denom, packet.GetSourcePort(), packet.GetSourceChannel(), i.bankKeeper)
 }
diff --git a/x/ibc-rate-limit/rate_limit.go b/x/ibc-rate-limit/rate_limit.go
index 665f04b29..5c91e5ffe 100644
--- a/x/ibc-rate-limit/rate_limit.go
+++ b/x/ibc-rate-limit/rate_limit.go
@@ -2,10 +2,13 @@ package ibc_rate_limit
 
 import (
 	"encoding/json"
+	"strings"
 
 	wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
+	transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
 	"github.com/cosmos/ibc-go/v3/modules/core/exported"
 	"github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/types"
 )
@@ -15,11 +18,6 @@ var (
 	msgRecv = "recv_packet"
 )
 
-type PacketData struct {
-	Denom  string `json:"denom"`
-	Amount string `json:"amount"`
-}
-
 func CheckAndUpdateRateLimits(ctx sdk.Context, contractKeeper *wasmkeeper.PermissionedKeeper,
 	msgType, contract string,
 	channelValue sdk.Int, sourceChannel, denom string,
@@ -42,6 +40,7 @@ func CheckAndUpdateRateLimits(ctx sdk.Context, contractKeeper *wasmkeeper.Permis
 	}
 
 	_, err = contractKeeper.Sudo(ctx, contractAddr, sendPacketMsg)
+
 	if err != nil {
 		return sdkerrors.Wrap(types.ErrRateLimitExceeded, err.Error())
 	}
@@ -128,10 +127,41 @@ func BuildWasmExecMsg(msgType, sourceChannel, denom string, channelValue sdk.Int
 }
 
 func GetFundsFromPacket(packet exported.PacketI) (string, string, error) {
-	var packetData PacketData
+	var packetData transfertypes.FungibleTokenPacketData
 	err := json.Unmarshal(packet.GetData(), &packetData)
 	if err != nil {
 		return "", "", err
 	}
-	return packetData.Amount, packetData.Denom, nil
+	return packetData.Amount, GetLocalDenom(packetData.Denom), nil
+}
+
+func GetLocalDenom(denom string) string {
+	// Expected denoms in the following cases:
+	//
+	// send non-native: transfer/channel-0/denom -> ibc/xxx
+	// send native: denom -> denom
+	// recv (B)non-native: denom
+	// recv (B)native: transfer/channel-0/denom
+	//
+	if strings.HasPrefix(denom, "transfer/") {
+		denomTrace := transfertypes.ParseDenomTrace(denom)
+		return denomTrace.IBCDenom()
+	} else {
+		return denom
+	}
+}
+
+func CalculateChannelValue(ctx sdk.Context, denom string, port, channel string, bankKeeper bankkeeper.Keeper) sdk.Int {
+	if strings.HasPrefix(denom, "ibc/") {
+		return bankKeeper.GetSupplyWithOffset(ctx, denom).Amount
+	}
+
+	if channel == "any" {
+		// ToDo: Get all channels and sum the escrow addr value over all the channels
+		escrowAddress := transfertypes.GetEscrowAddress(port, channel)
+		return bankKeeper.GetBalance(ctx, escrowAddress, denom).Amount
+	} else {
+		escrowAddress := transfertypes.GetEscrowAddress(port, channel)
+		return bankKeeper.GetBalance(ctx, escrowAddress, denom).Amount
+	}
 }
diff --git a/x/ibc-rate-limit/testdata/rate_limiter.wasm b/x/ibc-rate-limit/testdata/rate_limiter.wasm
index caf63c41459ca8361691cf27ae6c738682946e40..e19651209c4009fd4bd73bae23f49c69424e91d3 100644
GIT binary patch
delta 74291
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
N{I=n@4nOqE{{r<#fm;9o

delta 70741
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
UUUjuw0~#;H?=JlM;|KcvFIw7UWB>pF

diff --git a/x/ibc-rate-limit/testutil/chain.go b/x/ibc-rate-limit/testutil/chain.go
new file mode 100644
index 000000000..3ab9c26f0
--- /dev/null
+++ b/x/ibc-rate-limit/testutil/chain.go
@@ -0,0 +1,96 @@
+package osmosisibctesting
+
+import (
+	"time"
+
+	"github.com/cosmos/cosmos-sdk/baseapp"
+	"github.com/cosmos/cosmos-sdk/client"
+	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	ibctesting "github.com/cosmos/ibc-go/v3/testing"
+	"github.com/cosmos/ibc-go/v3/testing/simapp/helpers"
+	"github.com/osmosis-labs/osmosis/v12/app"
+	abci "github.com/tendermint/tendermint/abci/types"
+	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
+)
+
+type TestChain struct {
+	*ibctesting.TestChain
+}
+
+// SendMsgsNoCheck overrides ibctesting.TestChain.SendMsgs so that it doesn't check for errors. That should be handled by the caller
+func (chain *TestChain) SendMsgsNoCheck(msgs ...sdk.Msg) (*sdk.Result, error) {
+	// ensure the chain has the latest time
+	chain.Coordinator.UpdateTimeForChain(chain.TestChain)
+
+	_, r, err := SignAndDeliver(
+		chain.TxConfig,
+		chain.App.GetBaseApp(),
+		chain.GetContext().BlockHeader(),
+		msgs,
+		chain.ChainID,
+		[]uint64{chain.SenderAccount.GetAccountNumber()},
+		[]uint64{chain.SenderAccount.GetSequence()},
+		chain.SenderPrivKey,
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	// SignAndDeliver calls app.Commit()
+	chain.NextBlock()
+
+	// increment sequence for successful transaction execution
+	err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1)
+	if err != nil {
+		return nil, err
+	}
+
+	chain.Coordinator.IncrementTime()
+
+	return r, nil
+}
+
+// SignAndDeliver signs and delivers a transaction without asserting the results. This overrides the function
+// from ibctesting
+func SignAndDeliver(
+	txCfg client.TxConfig, app *baseapp.BaseApp, header tmproto.Header, msgs []sdk.Msg,
+	chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey,
+) (sdk.GasInfo, *sdk.Result, error) {
+	tx, _ := helpers.GenTx(
+		txCfg,
+		msgs,
+		sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)},
+		helpers.DefaultGenTxGas,
+		chainID,
+		accNums,
+		accSeqs,
+		priv...,
+	)
+
+	// Simulate a sending a transaction and committing a block
+	app.BeginBlock(abci.RequestBeginBlock{Header: header})
+	gInfo, res, err := app.Deliver(txCfg.TxEncoder(), tx)
+
+	app.EndBlock(abci.RequestEndBlock{})
+	app.Commit()
+
+	return gInfo, res, err
+}
+
+// Move epochs to the future to avoid issues with minting
+func (chain *TestChain) MoveEpochsToTheFuture() {
+	epochsKeeper := chain.GetOsmosisApp().EpochsKeeper
+	ctx := chain.GetContext()
+	for _, epoch := range epochsKeeper.AllEpochInfos(ctx) {
+		epoch.StartTime = ctx.BlockTime().Add(time.Hour * 24 * 30)
+		epochsKeeper.DeleteEpochInfo(chain.GetContext(), epoch.Identifier)
+		_ = epochsKeeper.AddEpochInfo(ctx, epoch)
+	}
+}
+
+// GetOsmosisApp returns the current chain's app as an OsmosisApp
+func (chain *TestChain) GetOsmosisApp() *app.OsmosisApp {
+	v, _ := chain.App.(*app.OsmosisApp)
+	return v
+}
diff --git a/x/ibc-rate-limit/testutil/wasm.go b/x/ibc-rate-limit/testutil/wasm.go
new file mode 100644
index 000000000..2beabb9c0
--- /dev/null
+++ b/x/ibc-rate-limit/testutil/wasm.go
@@ -0,0 +1,70 @@
+package osmosisibctesting
+
+import (
+	"fmt"
+	"io/ioutil"
+
+	"github.com/stretchr/testify/require"
+
+	wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
+	wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
+	transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
+	"github.com/osmosis-labs/osmosis/v12/x/ibc-rate-limit/types"
+	"github.com/stretchr/testify/suite"
+)
+
+func (chain *TestChain) StoreContractCode(suite *suite.Suite) {
+	osmosisApp := chain.GetOsmosisApp()
+
+	govKeeper := osmosisApp.GovKeeper
+	wasmCode, err := ioutil.ReadFile("./testdata/rate_limiter.wasm")
+	suite.Require().NoError(err)
+
+	addr := osmosisApp.AccountKeeper.GetModuleAddress(govtypes.ModuleName)
+	src := wasmtypes.StoreCodeProposalFixture(func(p *wasmtypes.StoreCodeProposal) {
+		p.RunAs = addr.String()
+		p.WASMByteCode = wasmCode
+	})
+
+	// when stored
+	storedProposal, err := govKeeper.SubmitProposal(chain.GetContext(), src, false)
+	suite.Require().NoError(err)
+
+	// and proposal execute
+	handler := govKeeper.Router().GetRoute(storedProposal.ProposalRoute())
+	err = handler(chain.GetContext(), storedProposal.GetContent())
+	suite.Require().NoError(err)
+}
+
+func (chain *TestChain) InstantiateContract(suite *suite.Suite, quotas string) sdk.AccAddress {
+	osmosisApp := chain.GetOsmosisApp()
+	transferModule := osmosisApp.AccountKeeper.GetModuleAddress(transfertypes.ModuleName)
+	govModule := osmosisApp.AccountKeeper.GetModuleAddress(govtypes.ModuleName)
+
+	initMsgBz := []byte(fmt.Sprintf(`{
+           "gov_module":  "%s",
+           "ibc_module":"%s",
+           "paths": [%s]
+        }`,
+		govModule, transferModule, quotas))
+
+	contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(osmosisApp.WasmKeeper)
+	codeID := uint64(1)
+	creator := osmosisApp.AccountKeeper.GetModuleAddress(govtypes.ModuleName)
+	addr, _, err := contractKeeper.Instantiate(chain.GetContext(), codeID, creator, creator, initMsgBz, "rate limiting contract", nil)
+	suite.Require().NoError(err)
+	return addr
+}
+
+func (chain *TestChain) RegisterRateLimitingContract(addr []byte) {
+	addrStr, err := sdk.Bech32ifyAddressBytes("osmo", addr)
+	require.NoError(chain.T, err)
+	params, err := types.NewParams(addrStr)
+	require.NoError(chain.T, err)
+	osmosisApp := chain.GetOsmosisApp()
+	paramSpace, ok := osmosisApp.AppKeepers.ParamsKeeper.GetSubspace(types.ModuleName)
+	require.True(chain.T, ok)
+	paramSpace.SetParamSet(chain.GetContext(), &params)
+}
diff --git a/x/ibc-rate-limit/types/errors.go b/x/ibc-rate-limit/types/errors.go
index 67d81abeb..5394ce11e 100644
--- a/x/ibc-rate-limit/types/errors.go
+++ b/x/ibc-rate-limit/types/errors.go
@@ -5,8 +5,7 @@ import (
 )
 
 var (
-	RateLimitExceededMsg = "rate limit exceeded"
-	ErrRateLimitExceeded = sdkerrors.Register(ModuleName, 2, RateLimitExceededMsg)
+	ErrRateLimitExceeded = sdkerrors.Register(ModuleName, 2, "rate limit exceeded")
 	ErrBadMessage        = sdkerrors.Register(ModuleName, 3, "bad message")
 	ErrContractError     = sdkerrors.Register(ModuleName, 4, "contract error")
 )
-- 
GitLab