diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b01825915d7..b954ccf3947c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (x/staking/keeper) [#]18049(https://github.com/cosmos/cosmos-sdk/pull/18049) return early if Slash encounters zero tokens to burn. * (x/staking/keeper) [#18035](https://github.com/cosmos/cosmos-sdk/pull/18035) Hoisted out of the redelegation loop, the non-changing validator and delegator addresses parsing. * (keyring) [#17913](https://github.com/cosmos/cosmos-sdk/pull/17913) Add `NewAutoCLIKeyring` for creating an AutoCLI keyring from a SDK keyring. * (codec) [#17913](https://github.com/cosmos/cosmos-sdk/pull/17913) `codectypes.NewAnyWithValue` supports proto v2 messages. diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 9cdd62ef8b11..576f2c0bdb63 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -147,12 +147,26 @@ func (k Keeper) Slash(ctx context.Context, consAddr sdk.ConsAddress, infractionH tokensToBurn := math.MinInt(remainingSlashAmount, validator.Tokens) tokensToBurn = math.MaxInt(tokensToBurn, math.ZeroInt()) // defensive. + if tokensToBurn.IsZero() { + // Nothing to burn, we can end this route immediately! We also don't + // need to call the k.Hooks().BeforeValidatorSlashed hook as we won't + // be slashing at all. + logger.Info( + "no validator slashing because slash amount is zero", + "validator", validator.GetOperator(), + "slash_factor", slashFactor.String(), + "burned", tokensToBurn, + "validatorTokens", validator.Tokens, + ) + return math.NewInt(0), nil + } + // we need to calculate the *effective* slash fraction for distribution if validator.Tokens.IsPositive() { effectiveFraction := math.LegacyNewDecFromInt(tokensToBurn).QuoRoundUp(math.LegacyNewDecFromInt(validator.Tokens)) // possible if power has changed - if effectiveFraction.GT(math.LegacyOneDec()) { - effectiveFraction = math.LegacyOneDec() + if oneDec := math.LegacyOneDec(); effectiveFraction.GT(oneDec) { + effectiveFraction = oneDec } // call the before-slashed hook if err := k.Hooks().BeforeValidatorSlashed(ctx, operatorAddress, effectiveFraction); err != nil {