castVote can be called by anyone even those without votes
Governance#castVote can be called by anyone, even users that don't have any votes. Since the voting refund is per address, an adversary could use a large number of addresses to vote with zero votes to drain the vault.\\n```\\nfunction _castVote(address _voter, uint256 _proposalId, uint8 _support) internal returns (uint) {\\n    // Only Active proposals can be voted on\\n    if (state(_proposalId) != ProposalState.Active) revert InvalidStatus();\\n    \\n    // Only valid values for _support are 0 (against), 1 (for), and 2 (abstain)\\n    if (_support > 2) revert InvalidInput();\\n\\n    Proposal storage proposal = proposals[_proposalId];\\n\\n    // If the voter has already voted, revert        \\n    Receipt storage receipt = proposal.receipts[_voter];\\n    if (receipt.hasVoted) revert AlreadyVoted();\\n\\n    // Calculate the number of votes a user is able to cast\\n    // This takes into account delegation and community voting power\\n    uint24 votes = (staking.getVotes(_voter)).toUint24();\\n\\n    // Update the proposal's total voting records based on the votes\\n    if (_support == 0) {\\n        proposal.againstVotes = proposal.againstVotes + votes;\\n    } else if (_support == 1) {\\n        proposal.forVotes = proposal.forVotes + votes;\\n    } else if (_support == 2) {\\n        proposal.abstainVotes = proposal.abstainVotes + votes;\\n    }\\n\\n    // Update the user's receipt for this proposal\\n    receipt.hasVoted = true;\\n    receipt.support = _support;\\n    receipt.votes = votes;\\n\\n    // Make these updates after the vote so it doesn't impact voting power for this vote.\\n    ++totalCommunityScoreData.votes;\\n\\n    // We can update the total community voting power with no check because if you can vote, \\n    // it means you have votes so you haven't delegated.\\n    ++userCommunityScoreData[_voter].votes;\\n\\n    return votes;\\n}\\n```\\n\\nNowhere in the flow of voting does the function revert if the user calling it doesn't actually have any votes. staking#getVotes won't revert under any circumstances. Governance#_castVote only reverts if 1) the proposal isn't active 2) support > 2 or 3) if the user has already voted. The result is that any user can vote even if they don't have any votes, allowing users to maliciously burn vault funds by voting and claiming the vote refund.
Governance#_castVote should revert if msg.sender doesn't have any votes:\\n```\\n    // Calculate the number of votes a user is able to cast\\n    // This takes into account delegation and community voting power\\n    uint24 votes = (staking.getVotes(_voter)).toUint24();\\n\\n+   if (votes == 0) revert NoVotes();\\n\\n    // Update the proposal's total voting records based on the votes\\n    if (_support == 0) {\\n        proposal.againstVotes = proposal.againstVotes + votes;\\n    } else if (_support == 1) {\\n        proposal.forVotes = proposal.forVotes + votes;\\n    } else if (_support == 2) {\\n        proposal.abstainVotes = proposal.abstainVotes + votes;\\n    }\\n```\\n
Vault can be drained maliciously by users with no votes
```\\nfunction _castVote(address _voter, uint256 _proposalId, uint8 _support) internal returns (uint) {\\n    // Only Active proposals can be voted on\\n    if (state(_proposalId) != ProposalState.Active) revert InvalidStatus();\\n    \\n    // Only valid values for _support are 0 (against), 1 (for), and 2 (abstain)\\n    if (_support > 2) revert InvalidInput();\\n\\n    Proposal storage proposal = proposals[_proposalId];\\n\\n    // If the voter has already voted, revert        \\n    Receipt storage receipt = proposal.receipts[_voter];\\n    if (receipt.hasVoted) revert AlreadyVoted();\\n\\n    // Calculate the number of votes a user is able to cast\\n    // This takes into account delegation and community voting power\\n    uint24 votes = (staking.getVotes(_voter)).toUint24();\\n\\n    // Update the proposal's total voting records based on the votes\\n    if (_support == 0) {\\n        proposal.againstVotes = proposal.againstVotes + votes;\\n    } else if (_support == 1) {\\n        proposal.forVotes = proposal.forVotes + votes;\\n    } else if (_support == 2) {\\n        proposal.abstainVotes = proposal.abstainVotes + votes;\\n    }\\n\\n    // Update the user's receipt for this proposal\\n    receipt.hasVoted = true;\\n    receipt.support = _support;\\n    receipt.votes = votes;\\n\\n    // Make these updates after the vote so it doesn't impact voting power for this vote.\\n    ++totalCommunityScoreData.votes;\\n\\n    // We can update the total community voting power with no check because if you can vote, \\n    // it means you have votes so you haven't delegated.\\n    ++userCommunityScoreData[_voter].votes;\\n\\n    return votes;\\n}\\n```\\n