Venus Prime - tsvetanovv's results

Earn, borrow & lend on the #1 Decentralized Money Market on the BNB chain.

General Information

Platform: Code4rena

Start Date: 28/09/2023

Pot Size: $36,500 USDC

Total HM: 5

Participants: 115

Period: 6 days

Judge: 0xDjango

Total Solo HM: 1

Id: 290

League: ETH

Venus Protocol

Findings Distribution

Researcher Performance

Rank: 59/115

Findings: 1

Award: $32.27

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

32.2731 USDC - $32.27

Labels

bug
2 (Med Risk)
satisfactory
duplicate-556

External Links

Lines of code

https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L200-L230

Vulnerability details

Impact

The odds of an infinite loop happening are high. This will result in reaching the maximum block gas limit and the inability to execute the function.

Proof of Concept

In Prime.sol we have updateScores() function:

function updateScores(address[] memory users) external {
        if (pendingScoreUpdates == 0) revert NoScoreUpdatesRequired();
        if (nextScoreUpdateRoundId == 0) revert NoScoreUpdatesRequired();

        for (uint256 i = 0; i < users.length; ) {
            address user = users[i];

            if (!tokens[user].exists) revert UserHasNoPrimeToken();    
            if (isScoreUpdated[nextScoreUpdateRoundId][user]) continue;

            address[] storage _allMarkets = allMarkets;
            for (uint256 j = 0; j < _allMarkets.length; ) {
                address market = _allMarkets[j];
                _executeBoost(user, market);
                _updateScore(user, market);

                unchecked {
                    j++;
                }
            }

            pendingScoreUpdates--;
            isScoreUpdated[nextScoreUpdateRoundId][user] = true;

            unchecked {
                i++;
            }

            emit UserScoreUpdated(user);
        }
    }

This function iterates over a list of user addresses and updates their scores.

The possibility of an infinite loop comes from the following code:

208: if (isScoreUpdated[nextScoreUpdateRoundId][user]) continue;

This line of code checks whether a user's score has already been updated during the present update round. If so it is expected to pass to the next user. But this will not happen because i is incremented at the end of the function. This puts us in a situation where we will check the same user continuously until we reach the maximum gass limit of the block.

Note for the Judge

Why I think the report is valid Medium:

  • We see that the Known issue has a similar problem - Link. But there it is described as Low severity issue and it is about all for loops that call external calls. That means there may be a problem, but there may not be.
  • The Bot report does not describe the situation I have described and which will happen. There the situation is described only for external calls.
  • A few weeks ago a similar report I wrote on another protocol was recognized as a valid Medium - Link

Tools Used

Visual Studio Code

To solve this problem, it is best to move the increase of i in the normal way:

204: for (uint256 i = 0; i < users.length; i++) {

Assessed type

DoS

#0 - c4-pre-sort

2023-10-04T22:20:52Z

0xRobocop marked the issue as duplicate of #556

#1 - c4-judge

2023-11-01T19:51:29Z

fatherGoose1 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