20,000 USDC
View results
Submission Details
Severity: gas
Valid

Multiple accesses of a mapping/array should use a local variable cache.

Summary

Multiple accesses of a mapping/array should use a local variable cache.

Vulnerability Details

The instances below point to the second+ access of a value inside a mapping/array, within a function. Caching a mapping's value in a local storage or calldata variable when the value is accessed multiple times, saves ~42 gas per access due to not having to recalculate the key's keccak256 hash (Gkeccak256 - 30 gas) and that calculation's associated stack operations. Caching an array's struct avoids recalculating the array offsets into memory/calldata. Similar findings

Impact

There are 66 instances of this issue:

File: 2023-07-beedle/src/Lender.sol

145: if (p.outstandingLoans != pools[poolId].outstandingLoans)
148: uint256 currentBalance = pools[poolId].poolBalance;
167: if (pools[poolId].lender == address(0)) {
183: if (pools[poolId].lender != msg.sender) revert Unauthorized();
185: _updatePoolBalance(poolId, pools[poolId].poolBalance + amount);
187: IERC20(pools[poolId].loanToken).transferFrom(
199: if (pools[poolId].lender != msg.sender) revert Unauthorized();
201: _updatePoolBalance(poolId, pools[poolId].poolBalance - amount);
203: IERC20(pools[poolId].loanToken).transfer(msg.sender, amount);
211: if (pools[poolId].lender != msg.sender) revert Unauthorized();
213: pools[poolId].maxLoanRatio = maxLoanRatio;
222: if (pools[poolId].lender != msg.sender) revert Unauthorized();
224: pools[poolId].interestRate = interestRate;
234: bytes32 poolId = borrows[i].poolId;
235: uint256 debt = borrows[i].debt;
236: uint256 collateral = borrows[i].collateral;
263: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
264: pools[poolId].outstandingLoans += debt;
313: pools[poolId].poolBalance + loan.debt + lenderInterest
315: pools[poolId].outstandingLoans -= loan.debt;
389: pools[poolId].outstandingLoans += totalDebt;
399: pools[oldPoolId].poolBalance + loan.debt + lenderInterest
401: pools[oldPoolId].outstandingLoans -= loan.debt;
417: loans[loanId].lender = pool.lender;
418: loans[loanId].interestRate = pool.interestRate;
419: loans[loanId].startTimestamp = block.timestamp;
420: loans[loanId].auctionStartTimestamp = type(uint256).max;
421: loans[loanId].debt = totalDebt;
427: loans[loanId].debt,
428: loans[loanId].collateral,
449: loans[loanId].auctionStartTimestamp = block.timestamp;
479: if (pools[poolId].interestRate > currentAuctionRate) revert RateTooHigh();
487: if (pools[poolId].poolBalance < totalDebt) revert PoolTooSmall();
490: _updatePoolBalance(poolId, pools[poolId].poolBalance - totalDebt);
491: pools[poolId].outstandingLoans += totalDebt;
501: pools[oldPoolId].poolBalance + loan.debt + lenderInterest
503: pools[oldPoolId].outstandingLoans -= loan.debt;
519: loans[loanId].lender = msg.sender;
520: loans[loanId].interestRate = pools[poolId].interestRate;
521: loans[loanId].startTimestamp = block.timestamp;
522: loans[loanId].auctionStartTimestamp = type(uint256).max;
523: loans[loanId].debt = totalDebt;
529: loans[loanId].debt,
530: loans[loanId].collateral,
531: pools[poolId].interestRate,
576: pools[poolId].outstandingLoans -= loan.debt;
594: uint256 loanId = refinances[i].loanId;
595: bytes32 poolId = refinances[i].poolId;
598: loans[loanId].lender,
599: loans[loanId].loanToken,
600: loans[loanId].collateralToken
603: uint256 debt = refinances[i].debt;
604: uint256 collateral = refinances[i].collateral;
632: pools[oldPoolId].poolBalance + loan.debt + lenderInterest
634: pools[oldPoolId].outstandingLoans -= loan.debt;
637: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
638: pools[poolId].outstandingLoans += debt;
660: loans[loanId].debt = debt;
687: loans[loanId].collateral = collateral;
689: loans[loanId].interestRate = pool.interestRate;
691: loans[loanId].startTimestamp = block.timestamp;
693: loans[loanId].auctionStartTimestamp = type(uint256).max;
695: loans[loanId].auctionLength = pool.auctionLength;
697: loans[loanId].lender = pool.lender;
699: pools[poolId].poolBalance -= debt;
734: pools[poolId].poolBalance = newBalance;

Tools Used

Automated review

Recommendations

Use a local variable cache.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.