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: 97/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
In CultureIndex
while creating a new piece it's quorum votes are decided based upon the circulation supply of governance tokens at that moment.
function createPiece( ArtPieceMetadata calldata metadata, CreatorBps[] calldata creatorArray ) public returns (uint256) { ... newPiece.pieceId = pieceId; newPiece.totalVotesSupply = _calculateVoteWeight( erc20VotingToken.totalSupply(), erc721VotingToken.totalSupply() ); newPiece.totalERC20Supply = erc20VotingToken.totalSupply(); newPiece.metadata = metadata; newPiece.sponsor = msg.sender; newPiece.creationBlock = block.number; newPiece.quorumVotes = (quorumVotesBPS * newPiece.totalVotesSupply) / 10_000; // <------ ... }
Consider this scenario:
erc20VotingToken
supply and erc721VotingToken
supply will be 0
, an attacker creates large number of pieces.0
as ArtPiece.quorumVotes
value. Let's call these as null art pieces
.Now there could be two sub-scenarios.
Scenario A: No other pieces get listed on protocol
unpause
.unpause
call an auction will be created for the top voted null art piece.Scenario B: Some erc20 governance token supply gets released into market, other valid art pieces gets created and gets auctioned successfully.
settleCurrentAndCreateNewAuction
call, the last valid piece's auction gets settled and new auction gets created for any one of the null pieces (MaxHeap will return any one null piece as the top voted piece).In both of the scenarios an auction can be created for an art piece with 0
votes. This happened even when it was not possible to vote for any of those null tokens, i.e. voting was prohibited but auctioning was allowed.
Provided above
Manual review
In CultureIndex.dropTopVotedPiece
add this statement:
require(totalVoteWeights[piece.pieceId] != 0);
In CultureIndex.createPiece
add this statement:
require(newPiece.quorumVotes != 0);
Context
#0 - c4-pre-sort
2023-12-22T19:39:08Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-12-22T19:39:19Z
raymondfam marked the issue as duplicate of #16
#2 - c4-pre-sort
2023-12-24T15:11:17Z
raymondfam marked the issue as duplicate of #449
#3 - c4-judge
2024-01-06T16:02:36Z
MarioPoneder marked the issue as satisfactory