Platform: Code4rena
Start Date: 21/04/2022
Pot Size: $100,000 USDC
Total HM: 18
Participants: 60
Period: 7 days
Judge: gzeon
Total Solo HM: 10
Id: 112
League: ETH
Rank: 21/60
Findings: 1
Award: $497.00
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: joestakey
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xkatana, 0xmint, Dravee, Funen, IllIllI, MaratCerby, NoamYakov, Tadashi, TerrierLover, Tomio, WatchPug, catchup, defsec, fatherOfBlocks, hake, horsefacts, kenta, oyc_109, pauliax, rayn, rfa, robee, saian, securerodd, simon135, slywaters, sorrynotsorry, tin537, z3s
496.9982 USDC - $497.00
Title: Using calldata
to store struct data type can save gas
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/pool/LiquidityPool.sol#L481 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/AddressProvider.sol#L422 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/AddressProvider.sol#L415 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/AddressProvider.sol#L186
Recommended Mitigation Steps:
Change memory
to calldata
========================================================================
Title: Using != is more gas efficient
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/BkdLocker.sol#L90-L91 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/BkdLocker.sol#L253 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/pool/LiquidityPool.sol#L401 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/pool/LiquidityPool.sol#L471
Recommended Mitigation Steps:
if (userBalance != 0) {
========================================================================
Title: Gas improvement on returning totalEthRequired
value
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/Controller.sol#L112
Recommended Mitigation Steps:
by setting totalEthRequired
in returns and deleting L#114 and L#120 can save gas
function getTotalEthRequiredForGas(address payer) external view override returns (uint256 totalEthRequired) { //@audit-info: set here // solhint-disable-previous-line ordering //@audit-info: remove this line address[] memory actions = addressProvider.allActions(); uint256 numActions = actions.length; for (uint256 i = 0; i < numActions; i++) { totalEthRequired += IAction(actions[i]).getEthRequiredForGas(payer); } //@audit-info: remove this line }
========================================================================
Title: unnecessary value set. the default value of uint is 0.
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/BkdLocker.sol#L133 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/Controller.sol#L114 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/Controller.sol#L117 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrow.sol#L92-L93
Recommended Mitigation Steps: remove 0 value can save gas
========================================================================
Title: Using delete statement to empty curRewardTokenData.userShares
can save gas
Proof of Concept: https://github.com/code-423n4/2022-04-jpegd/blob/main/contracts/farming/LPFarming.sol#L357 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/BkdLocker.sol#L214 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/pool/LiquidityPool.sol#L389
Recommended Mitigation Steps:
delete curRewardTokenData.userShares[msg.sender];
========================================================================
Title: better increment
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/Controller.sol#L117 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/strategies/ConvexStrategyBase.sol#L313
Recommended Mitigation Steps:
Change to ++i
can save gas
========================================================================
Title: Gas improvement on calling SafeERC20.function
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/pool/Erc20Pool.sol#L8 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/BkdLocker.sol#L16
Recommended Mitigation Steps:
by removing L#8 and directly call SafeERC20
Example L#35:
SafeERC20.safeTransferFrom(_underlying, from, address(this), amount);
========================================================================
Title: Using > is cheaper than >=
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/AmmConvexGauge.sol#L173
Recommended Mitigation Steps:
just use >
can save gas
========================================================================
Title: Unnecessary MSTORE timeElapsed
and currentRate
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/AmmGauge.sol#L144-L146
Recommended Mitigation Steps:
By passing block.timestamp - uint256(ammLastUpdated)
directly to L#148 without storing it to timeElapsed
can save gas without damaging readability of the code
ammStakedIntegral += (currentRate * (block.timestamp - uint256(ammLastUpdated)).scaledDiv(totalStaked);
========================================================================
Title: Caching .length
for loop can save gas
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrow.sol#L93 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/strategies/ConvexStrategyBase.sol#L313 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/strategies/ConvexStrategyBase.sol#L380 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L188
Recommended Mitigation Steps: Change to:
uint256 Length = amounts.length; for (uint256 i = 0; i < Length; i++) {
========================================================================
Title: Unused lib
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrowRevocable.sol#L24
Recommended Mitigation Steps: remove unused can save gas
========================================================================
Title: Using +=
to increase value on var
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrow.sol#L101-L102 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrow.sol#L106-L107 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/tokenomics/VestedEscrow.sol#L143
Recommended Mitigation Steps: Change to:
initialLockedSupply += totalAmount; unallocatedSupply -= totalAmount;
========================================================================
Title: Using unchecked to calculate requiredWithdrawal
in withdraw()
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/vault/Vault.sol#L125
Recommended Mitigation Steps:
availableUnderlying_
value was checked that it won't < than amount
so using unchecked can save gas:
unchecked{ uint256 requiredWithdrawal = amount - availableUnderlying_; }
========================================================================
Title: Using if statement instead else if can save gas
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/vault/Vault.sol#L788
Recommended Mitigation Steps:
if (allocatedUnderlying > totalUnderlying.scaledMul(upperBound)) { // withdraw funds from strategy uint256 withdrawAmount = allocatedUnderlying - target; strategy.withdraw(withdrawAmount); currentAllocated = _computeNewAllocated(currentAllocated, withdrawAmount); } if (allocatedUnderlying < totalUnderlying.scaledMul(lowerBound)) { //@audit-info: Replacing else if with if statement here // allocate more funds to strategy uint256 depositAmount = target - allocatedUnderlying; _transfer(address(strategy), depositAmount); currentAllocated += depositAmount; strategy.deposit(); }
========================================================================
Title: Using multiple require
instead &&
can save gas
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/strategies/ConvexStrategyBase.sol#L273-L276 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L359-L362 https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L676
Recommended Mitigation Steps:
require(token_ != address(_CVX), Error.INVALID_TOKEN_TO_ADD); require(token_ != address(underlying), Error.INVALID_TOKEN_TO_ADD); require(token_ != address(_CRV), Error.INVALID_TOKEN_TO_ADD);
========================================================================
Title: Using unchecked and prefix increment
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L188
Recommended Mitigation Steps:
for (uint256 i = 0; i < protocols.length;) { bytes32 protocolKey = _getProtocolKey(protocols[i]); _setConfig(protocolKey, handlers[i]); _updateTopUpHandler(protocols[i], address(0), handlers[i]); unchecked{ ++i; //@audit-info: Place here with unchecked } } }
========================================================================
Title: Using storage
to declare Struct variable inside function
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L548
Recommended Mitigation Steps:
instead of caching ExecuteLocalVars
to memory. read it directly from storage.
ExecuteLocalVars storage vars;
========================================================================
Title: Using msg.sender
directly is more effective
Proof of Concept: https://github.com/code-423n4/2022-04-backd/blob/main/backd/contracts/actions/topup/TopUpAction.sol#L280
Recommended Mitigation Steps:
Using msg.sender
directly instead of caching it to payer
. delete L#280 and replace all payer
with msg.sender
========================================================================