From a5b7f7f31f32df8fd2e949444505ba899b202889 Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Tue, 1 Oct 2024 20:23:54 -0500 Subject: [PATCH] fix(x/evmstaking): endblock unbond branch check (#163) * fix(x/evmstaking): branch condition on max spendable * test(x/evmstaking): add expected call in tests --- client/x/evmstaking/keeper/abci.go | 24 +++++++++++++----------- client/x/evmstaking/keeper/abci_test.go | 2 ++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/client/x/evmstaking/keeper/abci.go b/client/x/evmstaking/keeper/abci.go index bbe4a64c..802fa771 100644 --- a/client/x/evmstaking/keeper/abci.go +++ b/client/x/evmstaking/keeper/abci.go @@ -95,8 +95,8 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { return nil, errors.Wrap(err, "delegator address from bech32") } - maxAmount := k.bankKeeper.SpendableCoin(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount - if maxAmount.IsZero() { + spendableAmount := k.bankKeeper.SpendableCoin(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount + if spendableAmount.IsZero() { log.Warn(ctx, "No spendable coins for undelegation", errors.New("no spendable coins for undelegation"), "delegator", entry.delegatorAddress, @@ -106,23 +106,25 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { continue } - if entry.amount.LT(maxAmount) { - maxAmount = entry.amount - log.Warn(ctx, "Undelegation amount is less than max amount", - errors.New("undelegation amount is less than max amount"), + // If the requested undelegation amount is greater than the spendable amount, set the real undelegation amount to + // the total spendable amount. + if entry.amount.GT(spendableAmount) { + entry.amount = spendableAmount + log.Warn(ctx, "Spendable amount is less than the requested undelegation amount", + errors.New("spendable amount is less than the requested undelegation amount"), "delegator", entry.delegatorAddress, "validator", entry.validatorAddress, - "original_amount", entry.amount.String(), - "max_amount", maxAmount.String()) + "requested_amount", entry.amount.String(), + "spendable_amount", spendableAmount.String()) } log.Debug(ctx, "Adding undelegation to withdrawal queue", "delegator", entry.delegatorAddress, "validator", entry.validatorAddress, - "max_amount", maxAmount.String()) + "amount", entry.amount.String()) // Burn tokens from the delegator - _, coins := IPTokenToBondCoin(maxAmount.BigInt()) + _, coins := IPTokenToBondCoin(entry.amount.BigInt()) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, delegatorAddr, types.ModuleName, coins) if err != nil { return nil, errors.Wrap(err, "send coins from account to module") @@ -145,7 +147,7 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) { entry.delegatorAddress, entry.validatorAddress, delEvmAddr, - maxAmount.Uint64(), + entry.amount.Uint64(), )) if err != nil { return nil, err diff --git a/client/x/evmstaking/keeper/abci_test.go b/client/x/evmstaking/keeper/abci_test.go index d300159f..dcf1dba4 100644 --- a/client/x/evmstaking/keeper/abci_test.go +++ b/client/x/evmstaking/keeper/abci_test.go @@ -247,6 +247,7 @@ func (s *TestSuite) TestEndBlock() { // Mock staking.EndBlocker s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil) // Mock evmstaking.EndBlocker + s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(10))) s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(errors.New("failed to send coins to module")) return nil, []abcitypes.ValidatorUpdate{ @@ -273,6 +274,7 @@ func (s *TestSuite) TestEndBlock() { // Mock staking.EndBlocker s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil) // Mock evmstaking.EndBlocker + s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(10))) s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(nil) s.BankKeeper.EXPECT().BurnCoins(gomock.Any(), types.ModuleName, gomock.Any()).Return(errors.New("failed to burn coins"))