Platform: Code4rena
Start Date: 16/02/2023
Pot Size: $144,750 USDC
Total HM: 17
Participants: 154
Period: 19 days
Judge: Trust
Total Solo HM: 5
Id: 216
League: ETH
Rank: 135/154
Findings: 1
Award: $42.07
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: c3phas
Also found by: 0x3b, 0x6980, 0x73696d616f, 0xSmartContract, 0xackermann, 0xhacksmithh, 0xsomeone, Bnke0x0, Bough, Budaghyan, Darshan, DeFiHackLabs, Deivitto, GalloDaSballo, JCN, LethL, Madalad, MiniGlome, Morraez, P-384, PaludoX0, Phantasmagoria, Praise, RHaO-sec, Rageur, RaymondFam, ReyAdmirado, Rickard, Rolezn, SaeedAlipoor01988, Saintcode_, Sathish9098, TheSavageTeddy, Tomio, Viktor_Cortess, abiih, arialblack14, atharvasama, banky, codeislight, cryptonue, ddimitrov22, dec3ntraliz3d, descharre, dharma09, emmac002, favelanky, hl_, hunter_w3b, kaden, kodyvim, matrix_0wl, oyc_109, pavankv, scokaf, seeu, yamapyblack
42.0697 USDC - $42.07
[G-1] Using private rather than public for constants.
CollateralConfig.sol#L21 CollateralConfig.sol#L25
StabilityPool.sol#L150 StabilityPool.sol#L197
ReaperVaultV2.sol#L40-L41 ReaperVaultV2.sol#L73-L76
ReaperBaseStrategyv4.sol#L23-L25 ReaperBaseStrategyv4.sol#L49-L52
[G-2] Packing structs ref
[G-3] Use a more recent version of Solidity
Use a Solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value.
Use a Solidity version of at least 0.8.12 to get string.concat() to be used instead of abi.encodePacked(<str>,<str>).
Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions.
[G-4] Should use arguments instead of state variable
[G-5] Use assembly to check for address(0) ActivePool.sol#L93
LUSDToken.sol LUSDToken.sol LUSDToken.sol LUSDToken.sol LUSDToken.sol
ReaperVaultV2.sol ReaperVaultV2.sol
[G-6] initialize() :_MCRs AND _CCRs SHOULD BE CACHED
function initialize( address[] calldata _collaterals, uint256[] calldata _MCRs, uint256[] calldata _CCRs ) external override onlyOwner { require(!initialized, "Can only initialize once"); require(_collaterals.length != 0, "At least one collateral required"); require(_MCRs.length == _collaterals.length, "Array lengths must match"); //@audit gas: should cache "_MCRs" (SLOAD 1) require(_CCRs.length == _collaterals.length, "Array lenghts must match"); //@audit gas: should cache "_CCRs" (SLOAD 1)
for(uint256 i = 0; i < _collaterals.length; i++) { address collateral = _collaterals[i]; checkContract(collateral); collaterals.push(collateral); Config storage config = collateralConfig[collateral]; config.allowed = true; uint256 decimals = IERC20(collateral).decimals(); config.decimals = decimals; require(_MCRs[i] >= MIN_ALLOWED_MCR, "MCR below allowed minimum"); //@audit gas: should cache "_MCRs" (SLOAD 2) config.MCR = _MCRs[i]; require(_CCRs[i] >= MIN_ALLOWED_CCR, "CCR below allowed minimum"); //@audit gas: should cache "_CCRs" (SLOAD 2) config.CCR = _CCRs[i]; emit CollateralWhitelisted(collateral, decimals, _MCRs[i], _CCRs[i]); } initialized = true; }
[G-7] updateCollateralRatios() : _MCR & _CCR SHOULD ME CACHED
function updateCollateralRatios( address _collateral, uint256 _MCR, uint256 _CCR ) external onlyOwner checkCollateral(_collateral) { Config storage config = collateralConfig[_collateral]; require(_MCR <= config.MCR, "Can only walk down the MCR"); //@audit gas: should cache "_MCR" (SLOAD 1) require(_CCR <= config.CCR, "Can only walk down the CCR"); //@audit gas: should cache "_CCR" (SLOAD 1) require(_MCR >= MIN_ALLOWED_MCR, "MCR below allowed minimum"); //@audit gas: should cache "_MCR" (SLOAD 2) config.MCR = _MCR; require(_CCR >= MIN_ALLOWED_CCR, "CCR below allowed minimum"); //@audit gas: should cache "_CCR" (SLOAD 2) config.CCR = _CCR; emit CollateralRatiosUpdated(_collateral, _MCR, _CCR); }
[G-8] _requireSufficientCollateralBalanceAndAllowance() : IERC20(_collateral) SHOLUD BE CACHED
function _requireSufficientCollateralBalanceAndAllowance(address _user, address _collateral, uint _collAmount) internal view { require(IERC20(_collateral).balanceOf(_user) >= _collAmount, "BorrowerOperations: Insufficient user collateral balance"); //@audit gas: should cache "IERC20(_collateral)" (SLOAD 1) require(IERC20(_collateral).allowance(_user, address(this)) >= _collAmount, "BorrowerOperations: Insufficient collateral allowance"); //@audit gas: should cache "IERC20(_collateral)" (SLOAD 2) }
[G-9] withdraw() : _amount SHOULD BE CACHED
function (uint256 _amount) external override returns (uint256 loss) { require(msg.sender == vault, "Only vault can withdraw"); require(_amount != 0, "Amount cannot be zero"); //@audit gas: should cache "l_amount" (SLOAD 1) require(_amount <= balanceOf(), "Ammount must be less than balance"); //@audit gas: should cache "_amount" (SLOAD 2)
#0 - c4-judge
2023-03-09T18:21:24Z
trust1995 marked the issue as grade-b