Venus Prime - Aymen0909'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: 109/115

Findings: 1

Award: $4.37

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L174-L194 https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L930-L936

Vulnerability details

Impact

The getPendingInterests function is using IVToken(market).underlying() to get the underlying token address returned but this will not handle the case of VBNB/WBNB as it is done _getUnderlying which will result in the wrong underlying token being returned when dealing with VBNB market which will be misleading to users and parties relying on the returned values in their respective protocols

Proof of Concept

The issue occurs in the getPendingInterests function below :

function getPendingInterests(address user) external returns (PendingInterest[] memory pendingInterests) {
    address[] storage _allMarkets = allMarkets;
    PendingInterest[] memory pendingInterests = new PendingInterest[](_allMarkets.length);

    for (uint256 i = 0; i < _allMarkets.length; ) {
        address market = _allMarkets[i];
        uint256 interestAccrued = getInterestAccrued(market, user);
        uint256 accrued = interests[market][user].accrued;

        pendingInterests[i] = PendingInterest({
            //@audit should use _getUnderlying(market) to handle VBNB/WBNB
            market: IVToken(market).underlying(),
            amount: interestAccrued + accrued
        });

        unchecked {
            i++;
        }
    }

    return pendingInterests;
}

As you can see the call directly IVToken(market).underlying() to the market underlying token address but this will not work with the VBNB market, as it's handled differently in the _getUnderlying function below :

function _getUnderlying(address vToken) internal view returns (address) {
    //@audit `VBNB/WBNB` is a special market
    if (vToken == VBNB) {
        return WBNB;
    } else {
        return IVToken(vToken).underlying();
    }
}

Thus the getPendingInterests function could return a wrong address (or zero address) when dealing with VBNB/WBNB market, this can cause problems for users or other protocols relying on the returned data (token address & accrued rewards) in their logic.

Tools Used

Manual review

To avoid this issue you should use _getUnderlying function to get underlying token address in getPendingInterests.

Assessed type

Context

#0 - c4-pre-sort

2023-10-05T01:59:04Z

0xRobocop marked the issue as duplicate of #101

#1 - c4-judge

2023-11-01T20:21:41Z

fatherGoose1 marked the issue as satisfactory

#2 - c4-judge

2023-11-03T01:45:20Z

fatherGoose1 changed the severity to QA (Quality Assurance)

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