Venus Prime - tonisives'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: 95/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/b11d9ef9db8237678567e66759003138f2368d23/contracts/Tokens/Prime/PrimeLiquidityProvider.sol/#L216 https://github.com/code-423n4/2023-09-venus/blob/b11d9ef9db8237678567e66759003138f2368d23/contracts/Tokens/Prime/PrimeLiquidityProvider.sol/#L192

Vulnerability details

Impact

releaseFunds will be locked for a sweeped token.

Proof of Concept

  • accrueTokens() stores the accrued token balance to tokenAmountAccrued
  • tokenAmountAccrued will then be used in releaseFunds
  • admin can sweep any token at any time
  • in the releaseFunds, there will then be 2 problems
    1. It tries to accrueTokens, which will revert with underflow. This is because balance of the contract will be less than tokenAmountAccrued

      function accrueTokens(address token_) public {
      		uint256 balance = IERC20Upgradeable(token_).balanceOf(address(this));
      	  uint256 balanceDiff = balance - tokenAmountAccrued[token_]; // << underflow
    2. It wants to transfer out tokenAmountAccrued. This will be more than token balance at that point and it will fail.

function sweepToken(IERC20Upgradeable token_, address to_, uint256 amount_) external onlyOwner {
    uint256 balance = token_.balanceOf(address(this));
    if (amount_ > balance) {
        revert InsufficientBalance(amount_, balance);
    }

    emit SweepToken(address(token_), to_, amount_);

    token_.safeTransfer(to_, amount_);
}

https://github.com/code-423n4/2023-09-venus/blob/b11d9ef9db8237678567e66759003138f2368d23/contracts/Tokens/Prime/PrimeLiquidityProvider.sol/#L216

function releaseFunds(address token_) external {
    if (msg.sender != prime) revert InvalidCaller();
    if (paused()) {
        revert FundsTransferIsPaused();
    }

    accrueTokens(token_);
    uint256 accruedAmount = tokenAmountAccrued[token_];
    tokenAmountAccrued[token_] = 0;

    emit TokenTransferredToPrime(token_, accruedAmount);

    IERC20Upgradeable(token_).safeTransfer(prime, accruedAmount);
}

https://github.com/code-423n4/2023-09-venus/blob/b11d9ef9db8237678567e66759003138f2368d23/contracts/Tokens/Prime/PrimeLiquidityProvider.sol/#L192

Tools Used

Manual Review

Restrict admin to not be able to sweep tokens that have an amount in tokenAmountAccrued. Since these funds are distributed to the users, then admin should not have access to them at all ideally.

Assessed type

Access Control

#0 - c4-pre-sort

2023-10-07T00:20:55Z

0xRobocop marked the issue as duplicate of #42

#1 - c4-judge

2023-10-31T17:09:53Z

fatherGoose1 changed the severity to QA (Quality Assurance)

#2 - c4-judge

2023-11-03T02:29:16Z

fatherGoose1 marked the issue as grade-b

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