Lucene search

K
code423n4Code4renaCODE423N4:2023-09-VENUS-FINDINGS-ISSUES-670
HistoryOct 04, 2023 - 12:00 a.m.

function 'accrueInterest(address vToken)' allows too many rewards to be allocated

2023-10-0400:00:00
Code4rena
github.com
6
accrueinterest
prime contract
unauthorized allocation
excessive rewards
malicious users
vulnerability
code vulnerability
proof of concept
exploitation
security issue
security document

AI Score

6.9

Confidence

High

Lines of code

Vulnerability details

Impact

Malicious users can increase the number of rewards they receive within a block.

Proof of Concept

In the Prime contract, markets[vToken].rewardIndex is used to determine how many rewards are allocated to Prime token holders, and its value can only be changed by accrueInterest(address vToken)(After the market is being added).

    function accrueInterest(address vToken) public {
        if (!markets[vToken].exists) revert MarketNotSupported();

        address underlying = _getUnderlying(vToken);

        IPrimeLiquidityProvider _primeLiquidityProvider = IPrimeLiquidityProvider(primeLiquidityProvider);

        uint256 totalIncomeUnreleased = IProtocolShareReserve(protocolShareReserve).getUnreleasedFunds(
            comptroller,
            IProtocolShareReserve.Schema.SPREAD_PRIME_CORE,
            address(this),
            underlying
        );

        uint256 distributionIncome = totalIncomeUnreleased - unreleasedPSRIncome[underlying];

        _primeLiquidityProvider.accrueTokens(underlying);
        uint256 totalAccruedInPLP = _primeLiquidityProvider.tokenAmountAccrued(underlying);
        uint256 unreleasedPLPAccruedInterest = totalAccruedInPLP - unreleasedPLPIncome[underlying];

        distributionIncome += unreleasedPLPAccruedInterest;

        if (distributionIncome == 0) {
            return;
        }

        unreleasedPSRIncome[underlying] = totalIncomeUnreleased;
        unreleasedPLPIncome[underlying] = totalAccruedInPLP;

        uint256 delta;
        if (markets[vToken].sumOfMembersScore > 0) {
            delta = ((distributionIncome * EXP_SCALE) / markets[vToken].sumOfMembersScore);
        }

        markets[vToken].rewardIndex = markets[vToken].rewardIndex + delta;
    }

As written in the code, whenaccrueInterest(address vToken) is called, a quantity proportional to distributionIncome is added to markets[vToken].rewardIndex.
Here is a way to allocate more rewards to users:(We assume that next operations are performed by a user with reward to claim)
1.call Prime.accrueInterest(address vToken) to claim reward legally.
At this time, unreleasedPLPIncome[underlying] = _primeLiquidityProvider.tokenAmountAccrued(underlying).
2.call Prime.claimInterest(address vToken, address user) to claim his reward, and the amount must exceed asset.balanceOf(address(this))+IProtocolShareReserve(protocolShareReserve).releaseFunds(comptroller, assets),so unreleasedPLPIncome[underlying] is set to 0. At the same time, tokenAmountAccrued[token] in primeLiquidityProvider is set to 0.
3.call Prime.accrueInterest(address vToken) again,
_primeLiquidityProvider.accrueTokens(underlying);
will do nothing this time.
distributionIncome present non-zero values because unreleasedPLPIncome[underlying] is set to 0 but _primeLiquidityProvider.tokenAmountAccrued(underlying) still provide a non-zero value.

It is worth noting that the exploitation of this vulnerability may be simpler than the above steps.

Tools Used

VSCODE

Assessed type

Error


The text was updated successfully, but these errors were encountered:

All reactions

AI Score

6.9

Confidence

High