diff --git a/testutil/keeper/emissions.go b/testutil/keeper/emissions.go index 988859c762..d016bc3740 100644 --- a/testutil/keeper/emissions.go +++ b/testutil/keeper/emissions.go @@ -105,3 +105,9 @@ func EmissionKeeperWithMockOptions( return k, ctx, sdkKeepers, zetaKeepers } + +func GetEmissionsBankMock(t testing.TB, keeper *keeper.Keeper) *emissionsmocks.EmissionBankKeeper { + cbk, ok := keeper.GetBankKeeper().(*emissionsmocks.EmissionBankKeeper) + require.True(t, ok) + return cbk +} diff --git a/x/emissions/keeper/msg_server_withdraw_emissions.go b/x/emissions/keeper/msg_server_withdraw_emissions.go index 25703de0c0..1fa1287540 100644 --- a/x/emissions/keeper/msg_server_withdraw_emissions.go +++ b/x/emissions/keeper/msg_server_withdraw_emissions.go @@ -23,7 +23,6 @@ func (k msgServer) WithdrawEmission(goCtx context.Context, msg *types.MsgWithdra if err != nil { return nil, errorsmod.Wrap(types.ErrInvalidAddress, err.Error()) } - // check if the undistributed rewards pool has enough balance to process this request. // This is just a preliminary check, the actual processing at endblock might still fail if the pool balance gets affected. undistributedRewardsBalance := k.GetBankKeeper().GetBalance(ctx, types.UndistributedObserverRewardsPoolAddress, config.BaseDenom) diff --git a/x/emissions/keeper/msg_server_withdraw_emissions_test.go b/x/emissions/keeper/msg_server_withdraw_emissions_test.go index 3fbf4cfda3..f547524b99 100644 --- a/x/emissions/keeper/msg_server_withdraw_emissions_test.go +++ b/x/emissions/keeper/msg_server_withdraw_emissions_test.go @@ -5,6 +5,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/cmd/zetacored/config" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" @@ -33,7 +34,7 @@ func TestMsgServer_WithdrawEmission(t *testing.T) { require.Equal(t, withdrawableEmission.Amount.String(), balance) }) - t.Run("unable to create withdraw emissions with invalid address", func(t *testing.T) { + t.Run("unable to withdraw emissions with invalid address", func(t *testing.T) { k, ctx, sk, _ := keepertest.EmissionsKeeper(t) msgServer := keeper.NewMsgServerImpl(*k) @@ -49,7 +50,7 @@ func TestMsgServer_WithdrawEmission(t *testing.T) { require.ErrorIs(t, err, types.ErrInvalidAddress) }) - t.Run("unable to create withdraw emissions if undistributed rewards pool does not have enough balance", func(t *testing.T) { + t.Run("unable to withdraw emissions if undistributed rewards pool does not have enough balance", func(t *testing.T) { k, ctx, _, _ := keepertest.EmissionsKeeper(t) msgServer := keeper.NewMsgServerImpl(*k) @@ -63,7 +64,7 @@ func TestMsgServer_WithdrawEmission(t *testing.T) { require.ErrorIs(t, err, types.ErrRewardsPoolDoesNotHaveEnoughBalance) }) - t.Run("unable to create withdraw emissions with invalid amount", func(t *testing.T) { + t.Run("unable to withdraw emissions with invalid amount", func(t *testing.T) { k, ctx, _, _ := keepertest.EmissionsKeeper(t) msgServer := keeper.NewMsgServerImpl(*k) withdrawableEmission := sample.WithdrawableEmissions(t) @@ -75,4 +76,35 @@ func TestMsgServer_WithdrawEmission(t *testing.T) { require.ErrorIs(t, err, types.ErrUnableToWithdrawEmissions) }) + t.Run("unable to withdraw emissions if SendCoinsFromModuleToAccount", func(t *testing.T) { + k, ctx, sk, _ := keepertest.EmissionKeeperWithMockOptions(t, keepertest.EmissionMockOptions{ + UseBankMock: true, + }) + bankMock := keepertest.GetEmissionsBankMock(t, k) + msgServer := keeper.NewMsgServerImpl(*k) + + withdrawableEmission := sample.WithdrawableEmissions(t) + k.SetWithdrawableEmission(ctx, withdrawableEmission) + err := sk.BankKeeper.MintCoins(ctx, types.UndistributedObserverRewardsPool, sdk.NewCoins(sdk.NewCoin(config.BaseDenom, withdrawableEmission.Amount))) + require.NoError(t, err) + + address, err := sdk.AccAddressFromBech32(withdrawableEmission.Address) + require.NoError(t, err) + + bankMock.On("SendCoinsFromModuleToAccount", + ctx, types.UndistributedObserverRewardsPool, address, sdk.NewCoins(sdk.NewCoin(config.BaseDenom, withdrawableEmission.Amount))). + Return(types.ErrUnableToWithdrawEmissions).Once() + bankMock.On("GetBalance", + ctx, mock.Anything, config.BaseDenom). + Return(sdk.NewCoin(config.BaseDenom, withdrawableEmission.Amount), nil).Once() + _, err = msgServer.WithdrawEmission(ctx, &types.MsgWithdrawEmission{ + Creator: withdrawableEmission.Address, + Amount: withdrawableEmission.Amount, + }) + + require.ErrorIs(t, err, types.ErrUnableToWithdrawEmissions) + balance := sk.BankKeeper.GetBalance(ctx, sdk.MustAccAddressFromBech32(withdrawableEmission.Address), config.BaseDenom).Amount.String() + require.Equal(t, sdk.ZeroInt().String(), balance) + }) + }