Venus Protocol Isolated Pools - J4de'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: 10/102

Findings: 4

Award: $1,520.34

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: 0x73696d616f

Also found by: 0xadrii, 0xbepresent, 0xkazim, J4de, peanuts, pontifex, rvierdiiev, volodya

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-486

Awards

192.105 USDC - $192.11

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L1307

Vulnerability details

Impact

_getHypotheticalLiquiditySnapshot function is used to calculate the health of all vToken collateral of the user. The problem here is accrueInterest function is not being called to update the interest when all vTokens are counted. As a result, the user's position is healthier than the actual situation.

Proof of Concept

  1. The user has borrowed a lot of vTokens and has reached the liquidation threshold
  2. However, since the interest has not been updated, the user himself is healthy, and it is still possible to redeem and borrow

Tools Used

manual

    function _getHypotheticalLiquiditySnapshot(
        address account,
        VToken vTokenModify,
        uint256 redeemTokens,
        uint256 borrowAmount,
        function(VToken) internal view returns (Exp memory) weight
    ) internal view returns (AccountLiquiditySnapshot memory snapshot) {
        // For each asset the account is in
        VToken[] memory assets = accountAssets[account];
        uint256 assetsCount = assets.length;

        for (uint256 i; i < assetsCount; ++i) {
            VToken asset = assets[i];
+           asset.accrueInterest();

Assessed type

Other

#0 - c4-judge

2023-05-17T21:31:53Z

0xean marked the issue as duplicate of #104

#1 - c4-judge

2023-06-05T14:19:45Z

0xean changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-06-05T14:20:05Z

0xean marked the issue as satisfactory

#3 - c4-judge

2023-06-08T17:12:57Z

0xean marked the issue as duplicate of #486

Findings Information

🌟 Selected for report: 0x73696d616f

Also found by: 0xadrii, 0xbepresent, 0xkazim, J4de, peanuts, pontifex, rvierdiiev, volodya

Labels

bug
2 (Med Risk)
partial-50
duplicate-486

Awards

192.105 USDC - $192.11

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L755

Vulnerability details

Impact

File: Comptroller.sol
 754         // If collateral factor != 0, fail if price == 0
 755 >>      if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {
 756             revert PriceError(address(vToken));
 757         }

The price should be updated before getUnderlyingPrice. This can cause setCollateralFactor to succeed if the actual price is 0, or fail if the actual price is not 0.

Proof of Concept

Tools Used

manual

+       oracle.updatePrice(vToken);
        // If collateral factor != 0, fail if price == 0
        if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {
            revert PriceError(address(vToken));
        }

Assessed type

Invalid Validation

#0 - c4-judge

2023-05-18T11:46:09Z

0xean marked the issue as duplicate of #88

#1 - c4-judge

2023-06-05T14:09:50Z

0xean marked the issue as satisfactory

#2 - c4-judge

2023-06-08T14:39:51Z

0xean marked the issue as duplicate of #486

#3 - c4-judge

2023-06-08T14:41:33Z

0xean marked the issue as partial-50

Findings Information

🌟 Selected for report: 0xStalin

Also found by: J4de, rvierdiiev

Labels

bug
2 (Med Risk)
satisfactory
duplicate-255

Awards

1084.4385 USDC - $1,084.44

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L469-L472

Vulnerability details

Impact

File: Comptroller.sol
 469         uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);
 470         if (repayAmount > maxClose) {
 471             revert TooMuchRepay();
 472         }

When repayAmount > maxClose, liquidation occurs revert. Attackers can use this mechanism to front-run liquidate a little wei to avoid liquidation.

Proof of Concept

  1. Alias liquidates Bob's position
  2. Bob front-run liquidate a little
  3. Alias's repayAmount > maxClose, then revert

Tools Used

manual

It is recommended that if the liquidation quantity exceeds the upper limit, the liquidation quantity takes the upper limit value.

Assessed type

DoS

#0 - c4-judge

2023-05-17T20:25:33Z

0xean marked the issue as duplicate of #255

#1 - c4-judge

2023-06-05T14:24:17Z

0xean marked the issue as satisfactory

Findings Information

🌟 Selected for report: fs0c

Also found by: 0xnev, BPZ, Brenzee, J4de, Team_Rocket, peanuts, rvierdiiev, yongskiws

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-222

Awards

192.105 USDC - $192.11

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L393

Vulnerability details

Impact

File: Shortfall.sol
389         for (uint256 i; i < marketsCount; ++i) {
390             uint256 marketBadDebt = vTokens[i].badDebt();
391
392             priceOracle.updatePrice(address(vTokens[i]));
393 >>          uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / 1e18;
394
395             poolBadDebt = poolBadDebt + usdValue;
396             auction.markets[i] = vTokens[i];
397             auction.marketDebt[vTokens[i]] = marketBadDebt;
398             marketsDebt[i] = marketBadDebt;
399         }

The precision of UnderlyingToken may not be 1e18

Proof of Concept

Tools Used

manual

        for (uint256 i; i < marketsCount; ++i) {
            uint256 marketBadDebt = vTokens[i].badDebt();

            priceOracle.updatePrice(address(vTokens[i]));
-           uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / 1e18;
+           uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / UnderlyingToken.decimals();

            poolBadDebt = poolBadDebt + usdValue;
            auction.markets[i] = vTokens[i];
            auction.marketDebt[vTokens[i]] = marketBadDebt;
            marketsDebt[i] = marketBadDebt;
        }

Assessed type

Decimal

#0 - c4-judge

2023-05-17T16:49:50Z

0xean marked the issue as duplicate of #468

#1 - c4-judge

2023-06-05T14:17:27Z

0xean marked the issue as satisfactory

#2 - c4-judge

2023-06-05T14:42:12Z

0xean changed the severity to 2 (Med Risk)

Findings Information

🌟 Selected for report: LokiThe5th

Also found by: 0x8chars, Co0nan, Cryptor, J4de, Josiah, Norah, Parad0x, QiuhaoLi, RaymondFam, bin2chen, fs0c, qpzm, thekmj, volodya, xuwinnie

Awards

51.6843 USDC - $51.68

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-220

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1476

Vulnerability details

Impact

Proof of Concept

  1. Assume that the current _totalSupply is 0 and the initial initialExchangeRateMantissa is 1:1
  2. The attacker mint 1, _totalSupply is 1, underlying.balanceOf(address(this)) is 1
  3. The attacker transfers 1 underlying token to this contract, _totalSupply is 1, underlying.balanceOf(address(this)) is 2
  4. The user expects mint 1000 and transfers 1000 underlying tokens. At this time, cashPlusBorrowsMinusReserves = 2/1 = 2, and the user gets 1000/2=500 vTokens.

Tools Used

manual

Maintain totalCash yourself instead of using underlying.balanceOf(address(this))

Assessed type

Other

#0 - c4-judge

2023-05-17T12:01:03Z

0xean marked the issue as duplicate of #314

#1 - c4-judge

2023-05-17T12:01:11Z

0xean marked the issue as partial-25

#2 - c4-judge

2023-06-05T14:08:29Z

0xean marked the issue as satisfactory

#3 - c4-judge

2023-06-05T14:37:43Z

0xean changed the severity to 2 (Med Risk)

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