diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index 1a7d435841eb..10ab72790c5c 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -236,7 +236,8 @@ func (k BaseKeeper) SetDenomMetaData(ctx sdk.Context, denomMetaData types.Metada } // SendCoinsFromModuleToAccount transfers coins from a ModuleAccount to an AccAddress. -// It will panic if the module account does not exist. +// It will panic if the module account does not exist. An error is returned if +// the recipient address is black-listed or if sending the tokens fails. func (k BaseKeeper) SendCoinsFromModuleToAccount( ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, ) error { @@ -246,6 +247,10 @@ func (k BaseKeeper) SendCoinsFromModuleToAccount( panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule)) } + if k.BlockedAddr(recipientAddr) { + return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", recipientAddr) + } + return k.SendCoins(ctx, senderAddr, recipientAddr, amt) } diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index c250bdb2ef2e..fee8f2a77c85 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -95,6 +95,40 @@ func (suite *IntegrationTestSuite) TestSupply() { suite.Require().Equal(totalSupply, total) } +func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blacklist() { + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) + appCodec := app.AppCodec() + + // add module accounts to supply keeper + maccPerms := simapp.GetMaccPerms() + maccPerms[holder] = nil + maccPerms[authtypes.Burner] = []string{authtypes.Burner} + maccPerms[authtypes.Minter] = []string{authtypes.Minter} + maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} + maccPerms[randomPerm] = []string{"random"} + + addr1 := sdk.AccAddress([]byte("addr1_______________")) + + authKeeper := authkeeper.NewAccountKeeper( + appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName), + authtypes.ProtoBaseAccount, maccPerms, + ) + keeper := keeper.NewBaseKeeper( + appCodec, app.GetKey(types.StoreKey), authKeeper, + app.GetSubspace(types.ModuleName), map[string]bool{addr1.String(): true}, + ) + + baseAcc := authKeeper.NewAccountWithAddress(ctx, authtypes.NewModuleAddress("baseAcc")) + suite.Require().NoError(keeper.SetBalances(ctx, holderAcc.GetAddress(), initCoins)) + + keeper.SetSupply(ctx, types.NewSupply(initCoins)) + authKeeper.SetModuleAccount(ctx, holderAcc) + authKeeper.SetAccount(ctx, baseAcc) + + suite.Require().Error(keeper.SendCoinsFromModuleToAccount(ctx, holderAcc.GetName(), addr1, initCoins)) +} + func (suite *IntegrationTestSuite) TestSupply_SendCoins() { app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1}) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 356c022e4e26..0760533ab9f0 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -268,8 +268,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { // set an unbonding delegation with expiration timestamp beyond which the // unbonding delegation shouldn't be slashed ubdTokens := sdk.TokensFromConsensusPower(4) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, - time.Unix(0, 0), ubdTokens) + ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, time.Unix(0, 0), ubdTokens) app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) // slash validator for the first time diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index 493434527c94..f1ba552d9115 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -78,7 +78,6 @@ func TestMsgCreateValidator(t *testing.T) { } for _, tc := range tests { - t.Logf("Test: %s, pk=%t", tc.name, tc.pubkey) description := types.NewDescription(tc.moniker, tc.identity, tc.website, tc.securityContact, tc.details) msg, err := types.NewMsgCreateValidator(tc.validatorAddr, tc.pubkey, tc.bond, description, tc.CommissionRates, tc.minSelfDelegation) require.NoError(t, err)