Gas Optimizations
|
Issue |
Instances |
| [GAS-01] |
Increments can be unchecked |
25 |
| [GAS-02] |
Increments can be unchecked |
6 |
| [GAS-03] |
Setting the constructor to payable |
5 |
| [GAS-04] |
<x> += <y> Costs More Gas Than <x> = <x> + <y> For State Variables |
11 |
[GAS-01] State variables should be cached in memory rather than re-reading them from storage
The instances below point to the second+ access of a state variable within a function. Caching of a state variable replaces each Gwarmaccess (100 gas) with a much cheaper stack or memory read.
Instances (25):
File: 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();
202: _updatePoolBalance(poolId, pools[poolId].poolBalance - amount);
205: IERC20(pools[poolId].loanToken).transfer(msg.sender, amount);
265: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
429: loans[loanId].debt,
430: loans[loanId].collateral,
481: if (pools[poolId].interestRate > currentAuctionRate) revert RateTooHigh();
489: if (pools[poolId].poolBalance < totalDebt) revert PoolTooSmall();
531: loans[loanId].debt,
532: loans[loanId].collateral,
533: pools[poolId].interestRate,
600: loans[loanId].lender,
601: loans[loanId].loanToken,
602: loans[loanId].collateralToken
639: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
File: Staking.sol
65: if (_balance > balance) {
66: uint256 _diff = _balance - balance;
85: supplyIndex[recipient] = index;
86: uint256 _delta = index - _supplyIndex;
[GAS-02] Increments can be unchecked
Increments in for loops as well as some uint256 iterators cannot realistically overflow as this would require too many iterations, so this can be unchecked.
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP.
Instances (6):
File: Lender.sol
233: for (uint256 i = 0; i < borrows.length; i++) {
293: for (uint256 i = 0; i < loanIds.length; i++) {
359: for (uint256 i = 0; i < loanIds.length; i++) {
438: for (uint256 i = 0; i < loanIds.length; i++) {
549: for (uint256 i = 0; i < loanIds.length; i++) {
592: for (uint256 i = 0; i < refinances.length; i++) {
[GAS-03] Setting the constructor to payable
Saves ~13 gas per instance
Instances (5):
File: Beedle.sol
11: constructor() ERC20("Beedle", "BDL") ERC20Permit("Beedle") Ownable(msg.sender) {
File: Fees.sol
19: constructor(address _weth, address _staking) {
File: Lender.sol
73: constructor() Ownable(msg.sender) {
File: Staking.sol
31: constructor(address _token, address _weth) Ownable(msg.sender) {
File: utils/Ownable.sol
14: constructor(address _owner) {
[GAS-04] <x> += <y> Costs More Gas Than <x> = <x> + <y> For State Variables
Using the addition operator instead of plus-equals saves 113 gas
Same for -=, *= and /=.
Instances (11):
File: Lender.sol
263: pools[poolId].outstandingLoans += debt;
314: pools[poolId].outstandingLoans -= loan.debt;
388: pools[poolId].outstandingLoans += totalDebt;
400: pools[oldPoolId].outstandingLoans -= loan.debt;
490: pools[poolId].outstandingLoans += totalDebt;
502: pools[oldPoolId].outstandingLoans -= loan.debt;
575: pools[poolId].outstandingLoans -= loan.debt;
633: pools[oldPoolId].outstandingLoans -= loan.debt;
637: pools[poolId].outstandingLoans += debt;
698: pools[poolId].poolBalance -= debt;