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

Gas Optimizations

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) // @audit - [GAS] should save pools[poolId] to memory
148: uint256 currentBalance = pools[poolId].poolBalance; // @audit - [GAS] should save pools[poolId] to memory
167: if (pools[poolId].lender == address(0)) { // @audit - [GAS] should save pools[poolId] to memory
183: if (pools[poolId].lender != msg.sender) revert Unauthorized(); // @audit - [GAS] should save pools[poolId] to memory
185: _updatePoolBalance(poolId, pools[poolId].poolBalance + amount); // @audit - [GAS] should save pools[poolId] to memory
187: IERC20(pools[poolId].loanToken).transferFrom( // @audit - [GAS] should save pools[poolId] to memory
199: if (pools[poolId].lender != msg.sender) revert Unauthorized(); // @audit - [GAS] should save pools[poolId] to memory
202: _updatePoolBalance(poolId, pools[poolId].poolBalance - amount); // @audit - [GAS] should save pools[poolId] to memory
205: IERC20(pools[poolId].loanToken).transfer(msg.sender, amount); // @audit - [GAS] should save pools[poolId] to memory
265: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt); // @audit - [GAS] should use `pool` instead of `pools[poolId]`
429: loans[loanId].debt, // @audit - [GAS] should use `loan` instead of `loans[loanId]`
430: loans[loanId].collateral, // @audit - [GAS] should use `loan` instead of `loans[loanId]`
481: if (pools[poolId].interestRate > currentAuctionRate) revert RateTooHigh(); // @audit - [GAS] should save pools[poolId] to memory
489: if (pools[poolId].poolBalance < totalDebt) revert PoolTooSmall(); // @audit - [GAS] should save pools[poolId] to memory
531: loans[loanId].debt, // @audit - [GAS] should be `totalDebt`
532: loans[loanId].collateral, // @audit - [GAS] should be `loan.collateral`
533: pools[poolId].interestRate, // @audit - [GAS] should be `pool.interestRate`
600: loans[loanId].lender, // @audit - [GAS] should save loans[loanId] to memory
601: loans[loanId].loanToken, // @audit - [GAS] should save loans[loanId] to memory
602: loans[loanId].collateralToken // @audit - [GAS] should save loans[loanId] to memory
639: _updatePoolBalance(poolId, pools[poolId].poolBalance - debt); // @audit - [GAS] Can be replaced by `pool`
File: Staking.sol
65: if (_balance > balance) { // @audit - [GAS] should cache balance value
66: uint256 _diff = _balance - balance; // @audit - [GAS] should cache balance value
85: supplyIndex[recipient] = index; // @audit - [GAS] should cache index value
86: uint256 _delta = index - _supplyIndex; // @audit - [GAS] should cache index value

[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;

Support

FAQs

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