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;