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

Martentista :: annouceWinner() Handling Multiple TokenIDs with Equal Votes, Prioritizing First Occurrence as winner

Summary

Martentista :: annouceWinner() The criteria is the tokenid which have maximum number of votes is the winner . But it can be possible that there is more then one tokenid's which contain maximum number of votes. It means these must be declared as winner and prize pool must be equally distributed in both.

Vulnerability Details

When two token id's holds maximum number of votes .The winner is always the id which comes first according to sequence .
example : I will use four sponsor which have unique token id's.

  1. The tokenid of first sponsor is zero and it holds one vote.

  2. The tokenid of second sponsor is one and it holds one vote.

  3. The tokenid of third sponsor is two and it holds two votes.

  4. The tokenid of fourth sponsor is three and it holds two votes.
    According to contract logic the tokenid have maximum number of votes is the winner .It means token id: 3 and token id : 4 both must be the winner becuase they hold maximum number of votes.But according to announce winner function logic only tokenid 3 is choosen as the winner because it always store the token id in winner if next one have greater number of votes then current one .But token id 4 have equal number of votes then 3.

Impact

Code Snippet

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++) {
        // @audit 
        if (voteCounts[_tokenIds[i]] > maxVotes) {
            maxVotes = voteCounts[_tokenIds[i]];
            winnerTokenId = _tokenIds[i];
        }
    }

    list = _martenitsaMarketplace.getListing(winnerTokenId);
    _healthToken.distributeHealthToken(list.seller, 1);

    emit WinnerAnnounced(winnerTokenId, list.seller);
}

Poc

    function test_AnnounceWinner() public listMartenitsa1 {
    vm.startPrank(a);
    voting.voteForMartenitsa(0);
    vm.stopPrank();
    vm.startPrank(b);
    voting.voteForMartenitsa(1);
    vm.stopPrank();
    vm.startPrank(c);
    voting.voteForMartenitsa(2);
    vm.stopPrank();
    vm.startPrank(d);
    voting.voteForMartenitsa(2);
    vm.stopPrank();
    vm.startPrank(e);
    voting.voteForMartenitsa(3);
    vm.stopPrank();
    vm.startPrank(f);
    voting.voteForMartenitsa(3);
    vm.stopPrank();

    vm.warp(block.timestamp + 1 days + 1);
    vm.recordLogs();
    voting.announceWinner();

    Vm.Log[] memory entries = vm.getRecordedLogs();
    address winner = address(uint160(uint256(entries[0].topics[2])));
    console.log("winner is " , winner);
}

modifier listMartenitsa1() {
    vm.startPrank(chasy);
    martenitsaToken.createMartenitsa("bracelet");
    marketplace.listMartenitsaForSale(0, 1 wei);
    vm.stopPrank();
    vm.startPrank(jack);
    martenitsaToken.createMartenitsa("bracelet");
    marketplace.listMartenitsaForSale(1, 1 wei);
    vm.stopPrank();
    vm.startPrank(mahi);
    martenitsaToken.createMartenitsa("bracelet");
    marketplace.listMartenitsaForSale(2, 1 wei);
    vm.stopPrank();
    vm.startPrank(pawan);
    martenitsaToken.createMartenitsa("bracelet");
    marketplace.listMartenitsaForSale(3, 1 wei);
    vm.stopPrank();
   _;
 }

Tools Used

Foundry

Recommendations

Its recommended to make the winner array instead of winner variable.So that it can store more then one winners because its also possible then two or more token id's have same maximum number of votes.

Updates

Lead Judging Commences

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

Tie in voting is not considered

Support

FAQs

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