vielite's blog

QA-04: Empty Validator Set Can Be Accepted in ValidatorSetFactory

March 30, 2026
1 min read
Table of Contents
monad-qa-04-empty-validator-set

Summary

ValidatorSetFactory::create accepts an empty validator list and returns a validator set whose total stake is zero.

Vulnerability details

2025-09-monad/bft/monad-validator/src/validator_set.rs
fn create(
&self,
validators: Vec<(NodeId<Self::NodeIdPubKey>, Stake)>,
) -> Result<Self::ValidatorSetType, Self::NodeIdPubKey> {
let mut vmap = BTreeMap::new();
let mut total_stake = Stake::ZERO;
for (node_id, stake) in validators.into_iter() {
let duplicate = vmap.insert(node_id, stake);
if duplicate.is_some() {
return Err(ValidatorSetError::DuplicateValidator(node_id));
}
total_stake += stake;
}
Ok(ValidatorSet {
validators: vmap,
total_stake,
})
}

Impact

Downstream quorum and threshold logic assumes meaningful stake totals. A zero-stake set can cause threshold checks to become unsatisfiable and create liveness issues.

Recommendation

Reject empty validator lists before constructing the validator set.