Open c4-bot-8 opened 11 months ago
raymondfam marked the issue as sufficient quality report
raymondfam marked the issue as duplicate of #266
raymondfam marked the issue as not a duplicate
raymondfam marked the issue as primary issue
raymondfam marked the issue as high quality report
same issue as other maxheap issues
rocketman-21 (sponsor) confirmed
rocketman-21 (sponsor) disputed
actually upon further inspection this is how it should function
time that the pieces were inserted has no weight to the order in which they are extracted
just because pieceId 4 and 5 both have 10 votes, the MaxHeap does not guarantee that the 4th will be extracted first even if it reached 10 votes first.
MarioPoneder changed the severity to QA (Quality Assurance)
See comment on previous primary issue: https://github.com/code-423n4/2023-12-revolutionprotocol-findings/issues/266#issuecomment-1879666356
MarioPoneder marked the issue as grade-b
Hi @MarioPoneder,
as per your comment on issue 266; this one has a runnable PoC to clearly identify what is wrong with the MaxHeap.extractMax
function and how it introduces unfair auctions for art-pieces as some might reach top-voted before other pieces but will not be auctioned first (and might never get the chance to be auctioned)!
I kindly ask you to take a second look and re-evaluate this issue,
Thanks!
Thank you for your comment!
This is an edge-case of 2 or more art prices getting the same votes, see also #582.
Furthermore, MaxHeap is not designed to respect insertion order, only the votes.
Nevertheless this is a valid feature suggestion and therefore QA seems appropriate.
Lines of code
https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/MaxHeap.sol#L136-L151 https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/MaxHeap.sol#L156-L164
Vulnerability details
Impact
Revolution protocol is meant to enable users from adding their art pieces to be voted on and auctioned if the piece passes voting quorum, then the auction proceeds are distributed between the relevant parties (the creators and the protocol).
The entry point for users is to add their art piece by calling
CulturalIndex.createPiece
function with the art piece metadat and an array of creators addresses, and each added art piece is going to be added to a MaxHeap data structure (saved in theMaxHeap
contract) where pieces are arranged as a nodes of parents and children, where the top of the tree is the art pieces with the highest votes and the corresponding childs of that parent is of pieces with lower votes, and with each vote; the MaxHeap rearrange the values to preserve the max heap characteristics.When the art piece got votes >= quorum votes; it's dropped by the
AuctionHouse
to be auctioned by theAuctionHouse
contract, this process requires theMaxHeap
to extract the top voted art piece to be auctioned.The process of dropping the top voted art piece is not automatic; meaning that it waits anyone to call
AuctionHouse.settleCurrentAndCreateNewAuction
function to start the process.But it was noticed that if there's three art pieces with an equal number of votes, and this number is the highest votes number, then it's assumed that the first art piece that reached this number is the one to be dropped and auctioned first, then the second one that reached the maximum votes then the third one,.. but it was noticed that the behaviour of
MaxHeap.extractMax
doesn't work as intended:Proof of Concept
Code Instances:
MaxHeap.updateValue function
MaxHeap.extractMax function
Foundry PoC:
testDoesItWorkCorrectly
test inside theMaxHeapTestSuite
test contract that resides in theMaxHeap.t.sol
test file which is located in the following directorypackages/revolution/test/max-heap/MaxHeap.t.sol
:Explained scenario:
maxHeap.extractMax
function is called, where it extracted the maximum piece which is piece#1.maxHeap.extractMax
function is called again to extract the next maximum piece: it's supposed to extract piece#4 as it was the first piece to reach the highest votes before piece#5; but it extracted piece#5 instead.Test result:
Tools Used
Manual Review.
Recommended Mitigation Steps
Update
MaxHeap.extractMax
function to handle this case.Assessed type
Context