Beginner FriendlyFoundryGameFi
100 EXP
View results
Submission Details
Severity: low
Valid

Producer with tokenId - 0 will be declared winner in case no one votes during the voting period and still receives 1 Health Token

Summary

There maybe a scenario when no one votes for any of the Martenitsa Token, and due to missing checks inside MartenitsaVoting::announceWinner, the producer with token id - 0 will be announced as winner and will get 1 Health Token.

Vulnerability Details

The vulnerability is present in the announceWinner function in MartenitsaVoting contract where it fails to check whether the final winnerTokenId decided has votes which are greater than 0.

Due to this missing check, for the case when no one votes for any token listing, leads to producer with tokenId - 0 being declared as winner and receiving 1 Health Token.

Thus, that producer will be declared as winner and will also received Health Token even though the votes were 0.

Impact

Producer with token id - 0 will be declared winner and receive 1 Health Token.

PoC

Add the test in the file: test/MartenitsaVoting.t.sol

Run the test:

forge test --mt test_token0_DeclaredWinnerEvenThoughNoOneVotedForAnyToken
event WinnerAnnounced(uint256 indexed winnerTokenId, address indexed winner);
function test_token0_DeclaredWinnerEvenThoughNoOneVotedForAnyToken() public listMartenitsa {
// voting started by owner
voting.startVoting();
// no one voted
// voting period ends
vm.warp(block.timestamp + voting.duration());
uint256 initHealthToken = healthToken.balanceOf(chasy);
// owner announces winner
vm.expectEmit(true, true, false, false, address(voting));
emit WinnerAnnounced(0, chasy);
voting.announceWinner();
assertEq(healthToken.balanceOf(chasy), initHealthToken + 1e18);
}

Tools Used

Manual Review, Foundry Unit Test

Recommendations

Revert in case the maxVotes after calculation comes out to be 0 which represents no one voted.

function announceWinner() external onlyOwner {
require(block.timestamp >= startVoteTime + duration, "The voting is active");
uint256 winnerTokenId;
uint256 maxVotes = 0;
for (uint256 i = 0; i < _tokenIds.length; i++) {
if (voteCounts[_tokenIds[i]] > maxVotes) {
maxVotes = voteCounts[_tokenIds[i]];
winnerTokenId = _tokenIds[i];
}
}
+ require(maxVotes > 0, "Winner cannot be declared!");
list = _martenitsaMarketplace.getListing(winnerTokenId);
_healthToken.distributeHealthToken(list.seller, 1);
emit WinnerAnnounced(winnerTokenId, list.seller);
}
Updates

Lead Judging Commences

bube Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

`tokenId=0` wins the voting

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.