remove_validator (smart-contracts/ink/lib.rs:1025-1031) pops the account from the validators vec but does nothing to in-flight request_voters / miner_active_request / pending_swap_votes entries.
Meanwhile get_required_votes (smart-contracts/ink/lib.rs:121-131) recomputes quorum from the new, smaller validator count, and record_vote (smart-contracts/ink/lib.rs:162-171) never checks validator-set membership — it just appends to the stored voter list.
Net effect: a compromised validator V gets removed; any round V previously voted on now has its bar lowered and still counts V's vote. If V voted on several in-flight reserve rounds before removal, those rounds can reach quorum with fewer legitimate votes than expected.
Direction: bump a validator_set_version on every add/remove and tag votes with the version, counting only same-version votes; or sweep request_voters / pending-vote maps for the removed account on removal.
remove_validator(smart-contracts/ink/lib.rs:1025-1031) pops the account from thevalidatorsvec but does nothing to in-flightrequest_voters/miner_active_request/pending_swap_votesentries.Meanwhile
get_required_votes(smart-contracts/ink/lib.rs:121-131) recomputes quorum from the new, smaller validator count, andrecord_vote(smart-contracts/ink/lib.rs:162-171) never checks validator-set membership — it just appends to the stored voter list.Net effect: a compromised validator V gets removed; any round V previously voted on now has its bar lowered and still counts V's vote. If V voted on several in-flight reserve rounds before removal, those rounds can reach quorum with fewer legitimate votes than expected.
Direction: bump a
validator_set_versionon every add/remove and tag votes with the version, counting only same-version votes; or sweeprequest_voters/ pending-vote maps for the removed account on removal.