Venus Protocol Isolated Pools - DeliChainSec's results

Earn, Borrow & Lend on the #1 Decentralized Money Market on the BNB Chain

General Information

Platform: Code4rena

Start Date: 08/05/2023

Pot Size: $90,500 USDC

Total HM: 17

Participants: 102

Period: 7 days

Judge: 0xean

Total Solo HM: 4

Id: 236

League: ETH

Venus Protocol

Findings Distribution

Researcher Performance

Rank: 4/102

Findings: 2

Award: $5,287.96

🌟 Selected for report: 1

🚀 Solo Findings: 1

Awards

66.5871 USDC - $66.59

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-320

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/BaseJumpRateModelV2.sol#L23 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/WhitePaperInterestRateModel.sol#L17

Vulnerability details

Vulnerability Details

Blocks per year calculations in WhitePaperInterestRateModel improperly assume 15 seconds block time, while on Binance Smart Chain it’s ~3 seconds. This has grave consequences, because it is used in calculating borrower’s interest rate and liquidity provider supply rate.

WhitePaperInterestRateModel uses following calculations to get blocks per year:

(365*24*60*60)/15 = 2102400

contract WhitePaperInterestRateModel is InterestRateModel {
    uint256 private constant BASE = 1e18;

    /**
     * @notice The approximate number of blocks per year that is assumed by the interest rate model
     */
    uint256 public constant blocksPerYear = 2102400;

However proper calculations are:

(365*24*60*60)/3 = 10512000, which is properly set in BaseJumpRateModelV2:

abstract contract BaseJumpRateModelV2 is InterestRateModel {
    uint256 private constant BASE = 1e18;
    ...
    /**
     * @notice The approximate number of blocks per year that is assumed by the interest rate model
     */
    uint256 public constant blocksPerYear = 10512000;

Impact

Borrowers pay only 20% for borrows, and liquidity providers loose 80% yield for providing assets to the pool. This disincentivizes users from participating in the pools using WhitePaperInterestRateModel. Additionally, this leads to an undesired situation, where users borrow from 5x less expensive markets and provide liquidity using the borrowed funds, leading to market discrepancies (overly exploited whitepaper rate pools, and overly supplied jump rate based pools). Because whitepaper interest rate don’t increase borrow rate together with utilization, it reaches 100%, disallowing LPs to unstake their borrowed assets, effectively locking them in the protocol.

Proof of Concept

  1. Venus team adds new isolated pools: ETH-DAI using whitepaper interest rates, and ETH-USDC using jump rate interest model. Both are having similar amounts of assets after few days after deploying them on mainnet.
  2. Users seeing discrepancies between two pools start to perform arbitrage - borrow on ETH-DAI pool and supplying it to ETH-USDC, earning additional profit risk free.
  3. Utilization ratio in ETH-DAI pool reaches 100%. It’s 5x cheaper than in ETH-USDC, and it’s still profitable, as long as supply rate is bigger than 20% there. Such high utilization means that there are no free funds for ETH-DAI liquidity providers to withdraw their liquidity, effective locking their funds.

Tools Used

Manual analysis

Update blocksPerYear constant to 10512000:

   uint256 public constant blocksPerYear = 10512000;

Assessed type

Other

#0 - c4-judge

2023-05-16T09:19:17Z

0xean marked the issue as primary issue

#1 - c4-judge

2023-05-16T09:21:19Z

0xean marked the issue as duplicate of #559

#2 - c4-judge

2023-06-05T14:02:52Z

0xean marked the issue as satisfactory

#3 - c4-judge

2023-06-05T14:38:22Z

0xean changed the severity to 2 (Med Risk)

#4 - c4-judge

2023-06-05T14:38:32Z

0xean changed the severity to 3 (High Risk)

Findings Information

🌟 Selected for report: DeliChainSec

Labels

bug
2 (Med Risk)
satisfactory
selected for report
sponsor confirmed
M-01

Awards

5221.3704 USDC - $5,221.37

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L158-L202 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L467-L470 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L213

Vulnerability details

Vulnerability Details

When protocol’s bad debt is auctioned off with 10% incentive at the beginning. A user who gives the best bid, wins. The auction ends when at least one account placed a bid, and current block number is bigger than nextBidderBlockLimit:

function closeAuction(address comptroller) external nonReentrant {
        Auction storage auction = auctions[comptroller];

        require(_isStarted(auction), "no on-going auction");
        require(
            block.number > auction.highestBidBlock + nextBidderBlockLimit && auction.highestBidder != address(0),
            "waiting for next bidder. cannot close auction"
        );

nextBidderBlockLimit is set to 10 in the initializer, which means that other users have only 30 seconds to place better bid. Now, this is a serious problem, because stuffing whole block with dummy transactions is very cheap on Binance Smart Chain. According to https://www.cryptoneur.xyz/en/gas-fees-calculator 15M gas - whole block - costs 14$~15$ on BSC. This makes a malicious user occasion to cheaply prohibit other users to overbid them, winning the auction at the least favorable price for the protocol. Because BSC is centralized blockchain, there are no private mempools and bribes directly to the miners (like in FlashBots), hence other users are very limited concerning the prohibitive actions.

Impact

The protocol overpays for bad debt, loosing value

Proof of Concept

  1. Pool gathered 100’000$ bad debt and it’s eligible for auction
  2. A malicious user frontruns others and places first bid with the least possible amount (bad debt + 10% incentive).
  3. The user sends dozens of dummy transactions with increased gas price, only to fill up whole block space for 11 blocks
  4. At the end, the user sends a transaction to close auction, getting the bad debt + 10% incentive.

Tools Used

Manual analysis

There are at least three options to resolve this issue:

  1. make he bidding window much higher at the beginning, like 1000 blocks
  2. make bidding window very high at the beginning, decreasing it, the more attractive the new bid is
  3. make bidding window dependent on the money at stake, to disincentivize block stuffing

Assessed type

Other

#0 - c4-sponsor

2023-05-23T21:41:47Z

chechu marked the issue as sponsor confirmed

#1 - c4-judge

2023-06-05T14:28:34Z

0xean 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