Open c4-bot-3 opened 11 months ago
raymondfam marked the issue as sufficient quality report
raymondfam marked the issue as primary issue
Duplicated submissions come with various/opposing scenarios originating from the same root cause.
raymondfam marked the issue as high quality report
one potential solution here is to let the DAO vote to axe the vote weight of malicious pieces that attempt to do this
in any case, assuming most actors in the community are good, the artists can just garner more votes than the malicious piece to bypass this issue
rocketman-21 (sponsor) acknowledged
Imho we cannot rely on most community members acting in good faith 100% of the time to prevent this from happening, therefore I am leaning more towards Medium
severity since the protocol and good faith actors can be negatively impacted by this attack.
Furthermore, there is currently no way to easily circumvent this problem.
MarioPoneder marked the issue as satisfactory
MarioPoneder marked the issue as selected for report
right @MarioPoneder but it assumes malicious vote weight > the remaining vote weight of "good" active users > quorum.
It assumes these "good users" are unable to vote for a good piece to reach the top voted piece spot
imo there could be some severe edge cases where voter apathy paired with a low quorum could make this possible, but with a sufficient active voting base and a solid quorum, I don't think the assumption that a malicious user will always be able to have the largest amount of vote weight vs. everyone else actually holds up in a real world scenario?
if quorum is low and voter turnout is low that's a different story
it's a balancing act - if the quorum is too high this can happen in any case. I think this is fair on second thought in some edge cases, just not sure how to fix
Hi @MarioPoneder Thanks for judging this contest.
The explained scenario can be produced as PoC but it doesn't realistic for an active protocol with tens/hundreds of users.
For this to happen:
Besides,
Note that the malicious user that does the attack, doesn’t lose any funds, as he is just paying to buy the voting token
This implies the attack is not costly but it is incorrect since the voting token is not transferable. The attacker can not sell or swap these tokens. "Just paying to buy voting token" is in fact a huge cost for the token that worths nothing in terms of money. Also it needs to be more than everyone else's total voting power to actually perform this attack. If community can surpass the attacker's fake token's vote count, the attacker must create another fake art piece and must buy additional voting power.
Thanks everyone for their input!
I agree that the attack path is rather hand-wavy. However, the described problem can also occur naturally without an attacker.
See report:
This scenario can happen naturally, without anyone being malicious and the attack doesn't rely on the fact that anyone can call buyToken , it just makes it easier.
See sponsor:
it's a balancing act - if the quorum is too high this can happen in any case. I think this is fair on second thought in some edge cases, just not sure how to fix
As the report also comes with a PoC (even though with an attacker) that proves that the protocol can be brought into this state, maintaining Medium severity seems appropriate.
https://github.com/collectivexyz/revolution-protocol/pull/89
fix here to not pause the auction fully, but let the community try to garner enough votes, and adds createAuction function
Lines of code
https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/CultureIndex.sol#L519-L534
Vulnerability details
Impact
CultureIndex
is responsible for the creation, voting and dropping (auctioning off) art pieces.Let’s focus on
dropTopVotedPiece
. The function is used by theAuctionHouse
to take the top voted art piece, drop it and auction it off.Notice how the top voted piece is retrieved and then we check if
totalVoteWeight > quorumVotes
. This is used to check if the piece has reached it’s quorum, which is cached during creation.Notice that for
quorumVotes
we use theerc20VotingToken.totalSupply
,erc721VotingToken.totalSupply
andquorumVotesBPS
.Knowing all this, a malicious user can do the following to break
dropTopVotedPiece
under certain conditions.He will call
ERC20TokenEmitter#buyToken
to buy the voting token, which in turn will inflate theerc20VotingToken.totalSupply
, which will also increase thenewPiece.quorumVotes
.After this he will create a new bogus art piece and its quorum votes will be inflated. (We are assuming that no one wants to vote for the art piece as it’s a bogus/fake art piece)
He will then vote for his new piece, making it the top voted piece, but the piece won’t reach it’s quorum so it cannot be dropped.
At this point one of the following can occur:
duration
so users will also have to wait for the auction to terminate, get settled and then the protocol can continue normally, which will waste time and increase the duration of the DoS.quorumVotes
for the piece will be different and it isn’t even sure that the new piece will be accepted under the new market conditions.All 3 of the scenarios are bad for the normal execution of the protocol and especially under scenario 1, can leave pieces to just rot, as they can never be reached.
Note that the malicious user that does the attack, doesn’t lose any funds, as he is just paying to buy the voting token, also the attack scenario can happen on it’s own naturally, without the use of
buyToken
, but it will still lead to 1 of the 3 followup scenarios.This scenario can happen naturally, without anyone being malicious and the attack doesn't rely on the fact that anyone can call
buyToken
, it just makes it easier.The sponsor has stated that in the future there will contracts that interface with
buyToken
, so even if access control is added to the function, it still won't fix the issue.Proof of Concept
Create a folder inside
revolution/test
calledCustomTests
, create a new file calledCustomTests.t.sol
, paste the following inside and runforge test --mt testTopVotedPieceCantReachQuorum -vvvv
Tools Used
Manual Review Foundry
Recommended Mitigation Steps
There isn't a very elegant way to fix this, as this is how a Max Heap is supposed to function. One way is to add an admin function that can forcefully drop a piece from the Max Heap.
Assessed type
DoS