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
Rank: 10/102
Findings: 4
Award: $1,520.34
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0x73696d616f
Also found by: 0xadrii, 0xbepresent, 0xkazim, J4de, peanuts, pontifex, rvierdiiev, volodya
192.105 USDC - $192.11
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L1307
_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.
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();
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
🌟 Selected for report: 0x73696d616f
Also found by: 0xadrii, 0xbepresent, 0xkazim, J4de, peanuts, pontifex, rvierdiiev, volodya
192.105 USDC - $192.11
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L755
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.
manual
+ oracle.updatePrice(vToken); // If collateral factor != 0, fail if price == 0 if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) { revert PriceError(address(vToken)); }
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
🌟 Selected for report: 0xStalin
Also found by: J4de, rvierdiiev
1084.4385 USDC - $1,084.44
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L469-L472
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.
manual
It is recommended that if the liquidation quantity exceeds the upper limit, the liquidation quantity takes the upper limit value.
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
🌟 Selected for report: fs0c
Also found by: 0xnev, BPZ, Brenzee, J4de, Team_Rocket, peanuts, rvierdiiev, yongskiws
192.105 USDC - $192.11
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L393
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
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; }
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)
51.6843 USDC - $51.68
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1476
_totalSupply
is 0 and the initial initialExchangeRateMantissa
is 1:1_totalSupply
is 1, underlying.balanceOf(address(this))
is 1_totalSupply
is 1, underlying.balanceOf(address(this))
is 2cashPlusBorrowsMinusReserves
= 2/1 = 2, and the user gets 1000/2=500 vTokens.manual
Maintain totalCash
yourself instead of using underlying.balanceOf(address(this))
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)