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: 93/102
Findings: 1
Award: $44.94
š Selected for report: 0
š Solo Findings: 0
š Selected for report: JCN
Also found by: 0xAce, 0xSmartContract, Aymen0909, K42, Rageur, Raihan, ReyAdmirado, SAAJ, SM3_SS, Sathish9098, Team_Rocket, Udsen, c3phas, codeslide, descharre, fatherOfBlocks, hunter_w3b, j4ld1na, lllu_23, matrix_0wl, naman1778, petrichor, pontifex, rapha, souilos, wahedtalash77
44.9387 USDC - $44.94
No | issue | instance |
---|---|---|
[Gā1] | Do not calculate constants | 1 |
[G-2] | State variables can be packed to use fewer storage slots | 1 |
[G-3] | UseĀ != 0Ā instead ofĀ > 0Ā for unsigned integer comparison | 13 |
[G-4] | Avoid usingĀ state variableĀ in emit | 3 |
[G-5] | Not using the named return variables when a function returns, wastes deployment gas | 2 |
[G-6] | Remove the initializer modifier | |
[G-7] | Use constants instead of type(uintx).max | 5 |
[G-8] | UseĀ calldataĀ instead ofĀ memory | 2 |
[Gā9] | Use double if statements instead of && | 8 |
[Gā10] | Can Make The Variable Outside The Loop To Save Gas | 10 |
[G-11] | Make 3 event parameters indexed when possible | 35 |
[G-12] | Use hardcode address instead address(this) | 17 |
[G-13] | Sort Solidity operations using short-circuit mode | 1 |
Due to how constant variables are implemented (replacements at compile-time), an expression assigned to a constant variable is recomputed each time that the variable is used, which wastes some gas.
File: /main/contracts/ExponentialNoError.sol 22 uint256 internal constant halfExpScale = expScale / 2;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/ExponentialNoError.sol#L22
The EVM works with 32 byte words. Variables less than 32 bytes can be declared next to eachother in storage and this will pack the values together into a single 32 byte storage slot (if the values combined are <= 32 bytes). If the variables packed together are retrieved together in functions we will effectively save ~2000 gas with every subsequent SLOAD for that storage slot. This is due to us incurring a Gwarmaccess (100 gas) versus a Gcoldsload (2100 gas).
Gas savings: 2000
123 address public shortfall;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VTokenInterfaces.sol#L123
File: /main/contracts/Lens/PoolLens.sol 462 if (deltaBlocks > 0 && borrowSpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L462
466 Double memory ratio = borrowAmount > 0 ? fraction(tokensAccrued, borrowAmount) : Double({ mantissa: 0 });
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L466
470 } else if (deltaBlocks > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L470
483 if (deltaBlocks > 0 && supplySpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L483
486 Double memory ratio = supplyTokens > 0 ? fraction(tokensAccrued, supplyTokens) : Double({ mantissa: 0 });
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L486
490 } else if (deltaBlocks > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L490
File: /main/contracts/Rewards/RewardsDistributor.sol 261 if (deltaBlocks > 0 && rewardTokenSpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L261
418 if (amount > 0 && amount <= rewardTokenRemaining) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L218
435 if (deltaBlocks > 0 && supplySpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L435
438 Double memory ratio = supplyTokens > 0
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L438 446 } else if (deltaBlocks > 0) {
463 if (deltaBlocks > 0 && borrowSpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L463
Using a state variable in SetOwner emits wastes gas.
File: /main/contracts/BaseJumpRateModelV2.sol 162 emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/BaseJumpRateModelV2.sol#L162
File: /main/contracts/MaxLoopsLimitHelper.sol 31 emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, maxLoopsLimit);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/MaxLoopsLimitHelper.sol#L31
File: /main/contracts/WhitePaperInterestRateModel.sol 40 emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/WhitePaperInterestRateModel.sol#L40
File: /main/contracts/Comptroller.sol 169 return results;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L169
1039 return allMarkets;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L1039
If we can just ensure that the initialize() function could only be called from within the constructor, we shouldnāt need to worry about it getting called again.
File: /main/contracts/Pool/PoolRegistry.sol 164 function initialize( VTokenProxyFactory vTokenFactory_, JumpRateModelFactory jumpRateFactory_, WhitePaperInterestRateModelFactory whitePaperFactory_, Shortfall shortfall_, address payable protocolShareReserve_, address accessControlManager_ ) external initializer {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Pool/PoolRegistry.sol#L164
File: /main/contracts/RiskFund/ProtocolShareReserve.sol 39 function initialize(address _protocolIncome, address _riskFund) external initializer {
File: /main/contracts/Rewards/RewardsDistributor.sol 111 function initialize( Comptroller comptroller_, IERC20Upgradeable rewardToken_, uint256 loopsLimit_, address accessControlManager_ ) external initializer {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L111
File: /main/contracts/RiskFund/RiskFund.sol 73 function initialize( address pancakeSwapRouter_, uint256 minAmountToConvert_, address convertibleBaseAsset_, address accessControlManager_, uint256 loopsLimit_ ) external initializer {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/RiskFund/RiskFund.sol#L73
File: /main/contracts/Shortfall/Shortfall.sol 131 function initialize( address convertibleBaseAsset_, IRiskFund riskFund_, uint256 minimumPoolBadDebt_, address accessControlManager_ ) external initializer {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L131
File: /main/contracts/VToken.sol 59 function initialize( address underlying_, ComptrollerInterface comptroller_, InterestRateModel interestRateModel_, uint256 initialExchangeRateMantissa_, string memory name_, string memory symbol_, uint8 decimals_, address admin_, address accessControlManager_, RiskManagementInit memory riskManagement, uint256 reserveFactorMantissa_ ) external initializer {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L59
262 if (supplyCap != type(uint256).max) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L262
351 if (borrowCap != type(uint256).max) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L351
File: /main/contracts/VToken.sol 1055 if (repayAmount == type(uint256).max) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1055
1314 startingAllowance = type(uint256).max;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1314
1331 if (startingAllowance != type(uint256).max) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1331
using calldata instead of memory for function arguments in external functions can help to reduce gas costs and improve the performance of your contracts.
154 function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L154
198 function setRewardTokenSpeeds( VToken[] memory vTokens, uint256[] memory supplySpeeds, uint256[] memory borrowSpeeds ) external {
755 if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L755
File: /main/contracts/Lens/PoolLens.sol 506 if (borrowerIndex.mantissa == 0 && borrowIndex.mantissa > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L506
526 if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L526
File: /main/contracts/Rewards/RewardsDistributor.sol 261 if (deltaBlocks > 0 && rewardTokenSpeed > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L261
348 if (supplierIndex == 0 && supplyIndex >= rewardTokenInitialIndex) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L348
386 if (borrowerIndex == 0 && borrowIndex >= rewardTokenInitialIndex) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L386
418 if (amount > 0 && amount <= rewardTokenRemaining) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L418
File: /main/contracts/VToken.sol 837 if (redeemTokens == 0 && redeemAmount > 0) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L837
615 uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L615
933 address rewardToken = address(rewardsDistributors[i].rewardToken());
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L933
1123 address rewardToken = address(rewardsDistributors[i].rewardToken());
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L1123
File: /main/contracts/Lens/PoolLens.sol 431 uint256 borrowReward = calculateBorrowerReward(
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L431
438 uint256 supplyReward = calculateSupplierReward(
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Lens/PoolLens.sol#L438
File: /main/contracts/Pool/PoolRegistry.sol 356 address comptroller = _poolsByID[i];
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Pool/PoolRegistry.sol#L356
File: /main/contracts/RiskFund/RiskFund.sol 168 address comptroller = address(vToken.comptroller());
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/RiskFund/RiskFund.sol#L168
174 uint256 swappedTokens = _swapAsset(vToken, comptroller, amountsOutMin[i], paths[i]);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/RiskFund/RiskFund.sol#L174
File: /main/contracts/Shortfall/Shortfall.sol 390 uint256 marketBadDebt = vTokens[i].badDebt();
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L390
393 uint256 usdValue = (priceOracle.getUnderlyingPrice(address(vTokens[i])) * marketBadDebt) / 1e18;
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L393
File: /main/contracts/BaseJumpRateModelV2.sol 45 event NewInterestParams( uint256 baseRatePerBlock, uint256 multiplierPerBlock, uint256 jumpMultiplierPerBlock, uint256 kink );
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/BaseJumpRateModelV2.sol#L45
File: /main/contracts/MaxLoopsLimitHelper.sol 16 event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/MaxLoopsLimitHelper.sol#L16
File: /main/contracts/Pool/PoolRegistry.sol 118 event PoolNameSet(address indexed comptroller, string oldName, string newName);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Pool/PoolRegistry.sol#L118
123 event PoolMetadataUpdated( address indexed comptroller, VenusPoolMetaData oldMetadata, VenusPoolMetaData newMetadata ); 132 event MarketAdded(address indexed comptroller, address vTokenAddress);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Pool/PoolRegistry.sol#L118
File: /main/contracts/RiskFund/ProtocolShareReserve.sol 22 event FundsReleased(address comptroller, address asset, uint256 amount);
File: /main/contracts/RiskFund/ReserveHelpers.sol 30 event AssetsReservesUpdated(address indexed comptroller, address indexed asset, uint256 amount);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/RiskFund/ReserveHelpers.sol#L30
57 event DistributedSupplierRewardToken( VToken indexed vToken, address indexed supplier, uint256 rewardTokenDelta, uint256 rewardTokenTotal, uint256 rewardTokenSupplyIndex ); 75 event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed); 78 event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed); 81 event RewardTokenGranted(address recipient, uint256 amount); 84 event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed); 87 event MarketInitialized(address vToken); 90 event RewardTokenSupplyIndexUpdated(address vToken); 93 event RewardTokenBorrowIndexUpdated(address vToken, Exp marketBorrowIndex); 96 event ContributorRewardsUpdated(address contributor, uint256 rewardAccrued);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Rewards/RewardsDistributor.sol#L57
47 event AmountOutMinUpdated(uint256 oldAmountOutMin, uint256 newAmountOutMin); 50 event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert); event TransferredReserveForAuction(address comptroller, uint256 amount); 56 event TransferredReserveForAuction(address comptroller, uint256 amount);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/RiskFund/RiskFund.sol#L47
75 event AuctionStarted( address indexed comptroller, uint256 auctionStartBlock, AuctionType auctionType, VToken[] markets, uint256[] marketsDebt, uint256 seizedRiskFund, uint256 startBidBps ); 86 event BidPlaced(address indexed comptroller, uint256 auctionStartBlock, uint256 bidBps, address indexed bidder); 89 event AuctionClosed( address indexed comptroller, uint256 auctionStartBlock, address indexed highestBidder, uint256 highestBidBps, uint256 seizedRiskFind, VToken[] markets, uint256[] marketDebt ); 100 event AuctionRestarted(address indexed comptroller, uint256 auctionStartBlock); 106 event MinimumPoolBadDebtUpdated(uint256 oldMinimumPoolBadDebt, uint256 newMinimumPoolBadDebt); 109 event WaitForFirstBidderUpdated(uint256 oldWaitForFirstBidder, uint256 newWaitForFirstBidder); 112 event NextBidderBlockLimitUpdated(uint256 oldNextBidderBlockLimit, uint256 newNextBidderBlockLimit); 115 event IncentiveBpsUpdated(uint256 oldIncentiveBps, uint256 newIncentiveBps);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L75
File: /main/contracts/VTokenInterfaces.sol 149 event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows); 154 event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance); 159 event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance); 164 event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows); 169 event RepayBorrow( address indexed payer, address indexed borrower, uint256 repayAmount, uint256 accountBorrows, uint256 totalBorrows ); 184 event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew); 191 event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew); 232 event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa); 237 event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa); 242 event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves); 247 event ReservesReduced(address indexed admin, uint256 reduceAmount, uint256 newTotalReserves); 252 event Transfer(address indexed from, address indexed to, uint256 amount); 262 event HealBorrow(address payer, address borrower, uint256 repayAmount); 267 event SweepToken(address token);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VTokenInterfaces.sol#L149
File: /main/contracts/Factories/VTokenProxyFactory.sol 26 event VTokenProxyDeployed(VTokenArgs args);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Factories/VTokenProxyFactory.sol#L26
File: /main/contracts/WhitePaperInterestRateModel.sol 29 event NewInterestParams(uint256 baseRatePerBlock, uint256 multiplierPerBlock);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/WhitePaperInterestRateModel.sol#L29
File: /main/contracts/BaseJumpRateModelV2.sol 98 revert Unauthorized(msg.sender, address(this), signature);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/BaseJumpRateModelV2.sol#L98
File: /main/contracts/Comptroller.sol 501 if (seizerContract == address(this)) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#501
504 if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#504
File: /main/contracts/VToken.sol 420 emit RepayBorrow(address(this), borrower, badDebtDelta, accountBorrowsPrev - badDebtDelta, totalBorrowsNew);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L420
527 uint256 balance = token.balanceOf(address(this));
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L527
749 comptroller.preMintHook(address(this), minter, mintAmount);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L749
842 comptroller.preRedeemHook(address(this), redeemer, redeemTokens);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L842
869 emit Transfer(redeemer, address(this), redeemTokens);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L869
879 comptroller.preBorrowHook(address(this), borrower, borrowAmount);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L879
936 comptroller.preRepayHook(address(this), borrower);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L936
1078 if (address(vTokenCollateral) == address(this)) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1078
1079 _seize(address(this), liquidator, borrower, seizeTokens);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1079
1104 comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1104
1134 emit Transfer(borrower, address(this), protocolSeizeTokens);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1134
1135 emit ReservesAdded(address(this), protocolSeizeAmount, totalReservesNew);
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1135
File: /main/contracts/Comptroller.sol 449 if (skipLiquidityCheck || isDeprecated(VToken(vTokenBorrowed))) {
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Comptroller.sol#L449
#0 - c4-judge
2023-05-18T17:58:48Z
0xean marked the issue as grade-b