Closed sherlock-admin3 closed 3 months ago
bin2chen
Medium
The poke() does not filter out the killed gauge. It still takes up a certain percentage of the votes, resulting in fewer votes and fewer rewards.
poke()
gauge
We can try poke() for a quick way to remember the percentage of votes.
function poke(uint _tokenId) external onlyNewEpoch(_tokenId) { require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, _tokenId) || msg.sender == governor); lastVoted[_tokenId] = block.timestamp; address[] memory _poolVote = poolVote[_tokenId]; uint _poolCnt = _poolVote.length; uint256[] memory _weights = new uint256[](_poolCnt); for (uint i = 0; i < _poolCnt; i ++) { @> _weights[i] = votes[_tokenId][_poolVote[i]]; } _vote(_tokenId, _poolVote, _weights); } function _vote(uint _tokenId, address[] memory _poolVote, uint256[] memory _weights) internal { _reset(_tokenId); uint _poolCnt = _poolVote.length; uint256 _weight = IVotingEscrow(_ve).balanceOfNFT(_tokenId); uint256 _totalVoteWeight = 0; uint256 _totalWeight = 0; uint256 _usedWeight = 0; for (uint i = 0; i < _poolCnt; i++) { @> _totalVoteWeight += _weights[i]; }
But poke() doesn't determine if the pool is still valid, and it still has the appropriate percentage. But an invalid gauge can't get a reward.
pool
If poke() contains a gauge that has already been killed, a portion of the reward will always be lost.
https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/Voter.sol#L234
Manual Review
function _vote(uint _tokenId, address[] memory _poolVote, uint256[] memory _weights) internal { _reset(_tokenId); uint _poolCnt = _poolVote.length; uint256 _weight = IVotingEscrow(_ve).balanceOfNFT(_tokenId); uint256 _totalVoteWeight = 0; uint256 _totalWeight = 0; uint256 _usedWeight = 0; for (uint i = 0; i < _poolCnt; i++) { + if (isGauge[gauges[_poolVote[i]]) { _totalVoteWeight += _weights[i]; + } }
Duplicate of #477
bin2chen
Medium
poke() be killed gauge still has the some percentage
Summary
The
poke()
does not filter out the killedgauge
. It still takes up a certain percentage of the votes, resulting in fewer votes and fewer rewards.Vulnerability Detail
We can try
poke()
for a quick way to remember the percentage of votes.But
poke()
doesn't determine if thepool
is still valid, and it still has the appropriate percentage. But an invalidgauge
can't get a reward.Impact
If
poke()
contains agauge
that has already been killed, a portion of the reward will always be lost.Code Snippet
https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/Voter.sol#L234
Tool used
Manual Review
Recommendation
Duplicate of #477