Revolution Protocol - AkshaySrivastav's results

A protocol to empower communities to raise funds, fairly distribute governance, and maximize their impact in the world.

General Information

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

Collective

Findings Distribution

Researcher Performance

Rank: 97/110

Findings: 1

Award: $7.22

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

7.2215 USDC - $7.22

Labels

bug
2 (Med Risk)
satisfactory
sufficient quality report
edited-by-warden
duplicate-449

External Links

Lines of code

https://github.com/code-423n4/2023-12-revolutionprotocol/blob/d42cc62b873a1b2b44f57310f9d4bbfdd875e8d6/packages/revolution/src/CultureIndex.sol#L226-L234

Vulnerability details

Impact

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:

  1. At the initial phase of Revolution protocol when erc20VotingToken supply and erc721VotingToken supply will be 0, an attacker creates large number of pieces.
  2. All these pieces will have 0 as ArtPiece.quorumVotes value. Let's call these as null art pieces.
  3. Interesting things to note here, due to this condition no user ever will be able to vote on any of these null pieces.

Now there could be two sub-scenarios.

Scenario A: No other pieces get listed on protocol

  1. The admin calls unpause.
  2. As per the current design of MaxHeap, any one these null voted tokens will be a top voted piece (since all piece has 0 votes).
  3. In the admin's 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.

  1. After a while the MaxHeap contains no valid art pieces, as all valid ones gets auctioned.
  2. In the subsequent 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.

Proof of Concept

Provided above

Tools Used

Manual review

In CultureIndex.dropTopVotedPiece add this statement: require(totalVoteWeights[piece.pieceId] != 0);

In CultureIndex.createPiece add this statement: require(newPiece.quorumVotes != 0);

Assessed type

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter