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: 16/110
Findings: 3
Award: $509.45
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: osmanozdemir1
Also found by: 0xG0P1, King_, SpicyMeatball, hals, ktg, rvierdiiev
494.8735 USDC - $494.87
Art piece will have inflated quorum which might be impossible to reach
Consider the following POC
function testArtPieceCreatedWithExcessQuorumVotesRequirement() public { vm.stopPrank(); //create art piece uint256 firstPieceId = voter1Test.createDefaultArtPiece(); //Auction the created art piece (piece passes quorum) vm.startPrank(address(dao)); auction.unpause(); //verb token is minted for auction console2.log(erc721Token.totalSupply()); // 1 //create new art piece uint256 secondPiece = voter1Test.createDefaultArtPiece(); //quorum is 200000000000000000 as the newly minted verb token is included in token total supply //used for calculating quorum console2.log(cultureIndex.getPieceById(secondPiece).quorumVotes); //200000000000000000 //auction ends with no bids and token is burned vm.warp(block.timestamp + auction.duration() + 1); auction.pause(); auction.settleAuction(); vm.stopPrank(); //token supply is back to 0 since minted token is burned //but the previously created piece's quorum is still 200000000000000000 which is impossible to reach currently console2.log(erc721Token.totalSupply()); // 0 console2.log(cultureIndex.getPieceById(secondPiece).quorumVotes); //200000000000000000 //subsequent pieces are created with correct quorum uint256 fourth = voter1Test.createDefaultArtPiece(); console2.log(cultureIndex.getPieceById(fourth).quorumVotes); //0 }
The above tests demonstrates that the second created piece has an inflated quorum which might be impossible to reach.
Manual Review
Consider subtracting the verb token balanceOf for the auction contract from the erc721Token total supply when a new art piece is being created (i.e taking a snapshot of all distributed tokens at art piece creation).
Invalid Validation
#0 - c4-pre-sort
2023-12-22T05:53:07Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-12-22T05:53:30Z
raymondfam marked the issue as duplicate of #260
#2 - c4-pre-sort
2023-12-24T05:35:22Z
raymondfam marked the issue as not a duplicate
#3 - c4-pre-sort
2023-12-24T05:35:32Z
raymondfam marked the issue as duplicate of #18
#4 - c4-judge
2024-01-08T21:43:03Z
MarioPoneder marked the issue as duplicate of #409
#5 - c4-judge
2024-01-08T21:51:20Z
MarioPoneder marked the issue as unsatisfactory: Insufficient quality
#6 - c4-judge
2024-01-08T21:52:07Z
MarioPoneder marked the issue as satisfactory
#7 - c4-judge
2024-01-10T18:31:31Z
MarioPoneder marked the issue as not a duplicate
#8 - c4-judge
2024-01-10T18:31:43Z
MarioPoneder marked the issue as duplicate of #168
#9 - c4-judge
2024-01-10T18:32:36Z
MarioPoneder changed the severity to 3 (High Risk)
🌟 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
For all tokens created before the first successful auction the quorum votes required to be dropped and put for auction is 0 and can therefore be auctioned off without needing to pass any vote quorun requirement
function testFirstCreatedPiecesPassQuorumCheck() public { uint256 firstPieceId = voter1Test.createDefaultArtPiece(); uint256 secondPieceId = voter2Test.createDefaultArtPiece(); uint256 ThirdPieceId = voter1Test.createDefaultArtPiece(); vm.startPrank(address(dao)); auction.unpause(); vm.warp(block.timestamp + auction.duration() + 1); auction.settleCurrentAndCreateNewAuction(); vm.deal(address(11), 1 ether); vm.startPrank(address(11)); auction.createBid{ value: 1 ether }(secondPieceId, address(11)); // Assuming first auction's verbId is 0 vm.stopPrank(); vm.warp(block.timestamp + auction.duration() + 1); auction.settleCurrentAndCreateNewAuction(); vm.warp(block.timestamp + auction.duration() + 1); auction.settleCurrentAndCreateNewAuction(); console2.log(erc721Token.totalSupply()); uint256 pieceId = voter2Test.createDefaultArtPiece(); console2.log(cultureIndex.getPieceById(pieceId).quorumVotes); //202166659585650220 }
The above POC demonstrates that all the tokens minted before the first successful action can be dropped and auctioned off as verb tokens even though they have not been voted on by any users. It is also possible in extreme cases that the first "n" number of auctions is unsuccessful hence, no erc721 or erc20 tokens are disperced causing the total supply of tokens needed to calculate quorum votes required to evaluate to zero, therefore allowing all tokens created during that period to be dropped without quorum requirements.
Manual Review
Consider airdropping some erc20 voting tokens to some verified/trusted addresses before creating any art pieces in the culture index.
Invalid Validation
#0 - c4-pre-sort
2023-12-22T06:48:05Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2023-12-22T06:48:43Z
raymondfam marked the issue as sufficient quality report
#2 - c4-pre-sort
2023-12-22T06:48:50Z
raymondfam marked the issue as duplicate of #16
#3 - c4-pre-sort
2023-12-24T15:11:09Z
raymondfam marked the issue as duplicate of #449
#4 - c4-judge
2024-01-06T15:59:54Z
MarioPoneder marked the issue as satisfactory
🌟 Selected for report: 0xmystery
Also found by: 00xSEV, 0xCiphky, 0xDING99YA, 0xhitman, ABAIKUNANBAEV, Aamir, BARW, IllIllI, King_, MrPotatoMagic, Pechenite, SovaSlava, SpicyMeatball, Topmark, Ward, ZanyBonzy, ast3ros, bart1e, cheatc0d3, deth, developerjordy, hals, imare, kaveyjoe, ktg, leegh, osmanozdemir1, peanuts, roland, rvierdiiev, shaka, sivanesh_808, spacelord47
7.359 USDC - $7.36
The current max heap implementation has some irregularities:
The heap size is incremented on every insert, however there is no bound or limit put on the heap size which can cause it to grow indefinitely and therefore make insertions or heapify functions use up a large amount of gas or even the entire contract balance in extreme cases
The culture index adds an art piece to our max heap on every creation, these art pieces have to gain a number of votes before they can be dropped from the heap and minted, some art pieces might never gain enough votes and end up stuck in the heap for an indefinite amount of time, therefore taking up space in storage and making heap operations more expensive
According to traditional max heap implementations max heaps beginning at index 0 are more expensive to operate on because they include an extra find calculation for each side. As demonstrated by the table below
root at 0 | root at 1 | |
---|---|---|
left child | index*2 + 1 | index*2 |
right child | index*2 + 2 | index*2 + 1 |
parent | (index-1)/2 | index/2 |
Context
#0 - c4-pre-sort
2023-12-22T18:56:29Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-12-22T18:57:18Z
raymondfam marked the issue as duplicate of #111
#2 - c4-pre-sort
2023-12-24T03:24:25Z
raymondfam marked the issue as duplicate of #519
#3 - c4-pre-sort
2023-12-24T04:39:00Z
raymondfam marked the issue as duplicate of #15
#4 - c4-judge
2024-01-06T18:07:02Z
MarioPoneder changed the severity to QA (Quality Assurance)
#5 - c4-judge
2024-01-07T16:40:21Z
MarioPoneder marked the issue as grade-b