diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index f346bc3d976..0d8b2747ad0 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -239,6 +239,10 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t } token := sdk.NewCoin(denom, transferAmount) + if k.bankKeeper.BlockedAddr(receiver) { + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", receiver) + } + // unescrow tokens escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) if err := k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)); err != nil { diff --git a/modules/apps/transfer/keeper/relay_test.go b/modules/apps/transfer/keeper/relay_test.go index 697059bf629..f220fba1be2 100644 --- a/modules/apps/transfer/keeper/relay_test.go +++ b/modules/apps/transfer/keeper/relay_test.go @@ -167,6 +167,16 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { {"tries to unescrow more tokens than allowed", func() { amount = sdk.NewInt(1000000) }, true, false}, + + // - coin being sent to module address on chainA + {"failure: receive on module account", func() { + receiver = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName).String() + }, false, false}, + + // - coin being sent back to original chain (chainB) to module address + {"failure: receive on module account on source chain", func() { + receiver = suite.chainB.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName).String() + }, true, false}, } for _, tc := range testCases { diff --git a/modules/apps/transfer/types/expected_keepers.go b/modules/apps/transfer/types/expected_keepers.go index fd0f7df76c3..5e31e72338b 100644 --- a/modules/apps/transfer/types/expected_keepers.go +++ b/modules/apps/transfer/types/expected_keepers.go @@ -22,6 +22,7 @@ type BankKeeper interface { BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + BlockedAddr(addr sdk.AccAddress) bool } // ChannelKeeper defines the expected IBC channel keeper