Platform: Code4rena
Start Date: 13/12/2023
Pot Size: $36,500 USDC
Total HM: 18
Participants: 110
Period: 8 days
Judge: 0xTheC0der
Id: 311
League: ETH
Rank: 100/110
Findings: 1
Award: $7.22
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: deth
Also found by: 00xSEV, 0xCiphky, 0xHelium, ABAIKUNANBAEV, Aamir, AkshaySrivastav, King_, Pechenite, SpicyMeatball, Tricko, ast3ros, ayden, bart1e, deth, fnanni, ke1caM, mahdirostami, peanuts, pep7siup, pontifex, ptsanev, roland, rvierdiiev, y4y
7.2215 USDC - $7.22
https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/CultureIndex.sol#L313-L322 https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/CultureIndex.sol#L292-L298
The order of pieces at the MaxHeap is determined by the number of votes they received. But the required quorum for each pieceId may differ due to different totalSupply at the time of creation. Thus, the zero position can be taken by a pieceId that has more votes, but does not reach a quorum, and other pieceIds with sufficient quorum will not be able to get into the auction.
The MaxHeap
contract sorts the pieceId
according to the size of the value
.
The number of user votes is used as value
.
uint256 weight = _getPastVotes(voter, pieces[pieceId].creationBlock); require(weight > minVoteWeight, "Weight must be greater than minVoteWeight"); votes[pieceId][voter] = Vote(voter, weight); totalVoteWeights[pieceId] += weight; uint256 totalWeight = totalVoteWeights[pieceId]; // TODO add security consideration here based on block created to prevent flash attacks on drops? maxHeap.updateValue(pieceId, totalWeight);
Pieces with index zero are included in the auction, i.e. the maximum number of votes from all pieceId
s. But it is also checked that the play has received enough votes to pass a quorum. This logic is done in the CultureIndex.dropTopVotedPiece
function.
ICultureIndex.ArtPiece memory piece = getTopVotedPiece(); require(totalVoteWeights[piece.pieceId] >= piece.quorumVotes, "Does not meet quorum votes to be dropped.");
Quorum is defined as the percentage of the total number of votes at the time of creation of the pieceId
.
newPiece.quorumVotes = (quorumVotesBPS * newPiece.totalVotesSupply) / 10_000;
Therefore, for different pieceIds
, the quorum size may differ, as well as the maximum number of votes. Accordingly, a situation may occur when a pieceID with a large number of votes, but with insufficient quorum, is located above other pieces, with a smaller number of maximum allowed votes determined at the time of creation.
Manual review
Consider using the ratio of the number of votes to the required quorum for ordering at the MaxHeap binary tree.
Governance
#0 - c4-pre-sort
2023-12-23T03:03:50Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-12-23T03:03:58Z
raymondfam marked the issue as duplicate of #16
#2 - c4-pre-sort
2023-12-24T15:11:31Z
raymondfam marked the issue as duplicate of #449
#3 - c4-judge
2024-01-06T16:03:36Z
MarioPoneder marked the issue as satisfactory