vielite's blog

QA-07: Unbounded Accumulation of Future Round Votes in VoteState

March 27, 2026
0 min read
Table of Contents
monad-qa-07-future-round-votes

Summary

VoteState::process_vote accepts votes for any round greater than or equal to earliest_round without applying a maximum future-round window.

Vulnerability details

2025-09-monad/bft/monad-consensus/src/vote_state.rs
if round < self.earliest_round {
return (None, ret_commands);
}
let round_state = self.pending_votes.entry(round).or_default();
let node_votes = round_state.node_votes.entry(*author).or_default();
node_votes.insert(vote_msg.sig);
let round_pending_votes = round_state.pending_votes.entry(vote).or_default();
round_pending_votes.insert(*author, vote_msg.sig);

Impact

Future-round entries can accumulate in pending_votes indefinitely when no QC advances the window. A malicious validator can exploit that to drive unbounded memory growth.

Recommendation

Apply round-window limits and treat duplicate or obviously abusive future-round votes as evidence or drop conditions.