Spare Navy Cod
High
The hook BeforeValidatorSlashed
calls AddSlashedValidator
in the epoching module. The problem is that none of these functions track whether the validator is already slashed or not. As a result second slash call store.Set(valAddr, power)
overwrites the same key with the same power and (worse) inflate the total slashed power slashedVotingPower + power
.
func (k Keeper) AddSlashedValidator(ctx context.Context, valAddr sdk.ValAddress) error {
epochNumber := k.GetEpoch(ctx).EpochNumber
store := k.slashedValSetStore(ctx, epochNumber)
thisVotingPower, err := k.GetValidatorVotingPower(ctx, epochNumber, valAddr)
if err != nil {
panic(errorsmod.Wrap(types.ErrMarshal, err.Error()))
}
thisVotingPowerBytes, err := sdkmath.NewInt(thisVotingPower).Marshal()
if err != nil {
panic(errorsmod.Wrap(types.ErrMarshal, err.Error()))
}
// insert into "set of slashed addresses" as KV pair, where
// - key: valAddr
// - value: thisVotingPower
store.Set(valAddr, thisVotingPowerBytes)
// add voting power
slashedVotingPower := k.GetSlashedVotingPower(ctx, epochNumber)
if err != nil {
// we don't panic here since it's possible that the most powerful validator outside the validator set enrols to the validator after this validator is slashed.
return err
}
k.setSlashedVotingPower(ctx, epochNumber, slashedVotingPower+thisVotingPower)
return nil
}
See the function : https://github.com/sherlock-audit/2024-12-babylon/blob/main/babylon/x/epoching/keeper/epoch_slashed_val_set.go#L56C1-L81C2
Inflated slashedVotingPower
can trigger threshold events prematurely (e.g., crossing 1/3 or 2/3) preventing the system for achieving enough voting power.
As far as I understand, a cosmos validator can be slashed multiple times in one epoch (which extends over multiple blocks) if he performs more "slahable" events. If the slashing is partial (slashFactor) validators stake is partially slashed, however his voting power in epoching module is always used fully.
Check that valAddr
is not already included in the storage to avoid two slashing updates.
Or/and do not append new value to the total sum