diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index 161295d0b70..a0b4f965f4c 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -231,6 +231,10 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t } token := sdk.NewCoin(denom, sdk.NewIntFromUint64(data.Amount)) + 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 4c383f0948f..ea8ffd58d2f 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 d7881642c12..7343294d002 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