You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While two of the three for loops in Lender.sol are implemented in almost the most gas efficient way there is still some more improvement to add. For example using ++i instead of i++ can save a good chunk of gas, especially if the loop is long running
Remove custom errors with string parameters and use specific custom errors instead
Proof of concept
The advantage of using custom errors is that they do not need strings to describe their purpose. Strings are gas inefficient so it is cheaper to use separate well-naimed custom errors instead of reusing one by passing it a string.
Impact
Using specific custom errors will decrease the gas cost when fuction executions fail.
Recomendation
Avoid using strings as paramenters in custom errors. Instead use separate custom errors for the different cases.
The EVM works with 256bit/32byte words. Every operation is based on these base units. If the data used is smaller, further operation are needed to downscale from 256 bits to 8 bits.
Impact
Remove the redundant gas costs of the low-level EVM convertions of uint256 units to uint8.
Recommendations
Replace each uint8 with uint256 (except the ones in structs).
Change visibility modifier of public functions to external
Proof of concept
External function are cheaper than public ones. Functions that are not being invoked from inside the contract have no reason to be declared as public and not external.
Impact
Save gas on each currently public function call where the function is not being used in the contract in its life cycle.
Recommendations
Change public functions visibility modifiers to external where the function have to be so.
Gas optimisations
For loop gas optimisation
Proof of concept
While two of the three for loops in Lender.sol are implemented in almost the most gas efficient way there is still some more improvement to add. For example using ++i instead of i++ can save a good chunk of gas, especially if the loop is long running
Impact
Gas savings for protocol users.
Recommendations
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L265
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L265
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L96
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L120
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L289
The third loop in Lender.sol can be written this way
Hardcode uint256 max value calculation using type(uint256).max
Proof of concept
Storing uint256 max value as a variable in functions is unnecessary. It can be avoided by simply hardcoding it where needed.
Impact
It will reduce gas cost for the user and remove a redundant variable.
Recommendations
Hardcode uint256 max value instead of storing it in a separate variable. Use type(uint256).max as it is the cheapest way to calculate it.
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L84
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L93
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L112
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L117
Remove all require with string error expressions and use custom errors instead
Proof of concept
Using custom errors (introduced in Solidity 0.8) is more gas efficient than having require expressions with error strings.
Impact
This can be helpful for external integrations’ error handling and can save some gas for the end-user if the transaction reverts.
Recommendations
Replace require expressions in Lender.sol with custom errors
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L710
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L712
Example with custom errors:
Remove custom errors with string parameters and use specific custom errors instead
Proof of concept
The advantage of using custom errors is that they do not need strings to describe their purpose. Strings are gas inefficient so it is cheaper to use separate well-naimed custom errors instead of reusing one by passing it a string.
Impact
Using specific custom errors will decrease the gas cost when fuction executions fail.
Recomendation
Avoid using strings as paramenters in custom errors. Instead use separate custom errors for the different cases.
The code from the example above can be applied on the following lines in Lender.sol
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L209-L211
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L269-L271
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L332-L334
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L392-L394
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L447-L449
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L501-L505
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L558-L560
Other places where string parameters can be avoided in custom errors
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L20
https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L29
https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L31
https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L14
https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L16
Use immutable keyword
Proof of concept
Notice the missing immutable keyword in Reedemer.
Impact
Less gas is being payed each time referencing an immutable variable than a storage one.
Recommendations
Add the missing immutable keyword in front of apwineAddr as it is not being changed any time during the smart contract life cycle.
https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L33
X = X + Y is cheaper than X += Y
Proof of concept
Although doing the same thing the second syntax appears to cost less gas units.
Impact
Less gas being payed when increasing numbers.
Recommendations
Use
x = x + y
instead ofx += y
Examples in function lend in Lender.sol:
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L279
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L283
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L285
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L294
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L340
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L404
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L461
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L514
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L572
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L621
uint256 instead of uint8
Proof of concept
The EVM works with 256bit/32byte words. Every operation is based on these base units. If the data used is smaller, further operation are needed to downscale from 256 bits to 8 bits.
Impact
Remove the redundant gas costs of the low-level EVM convertions of uint256 units to uint8.
Recommendations
Replace each uint8 with uint256 (except the ones in structs).
Example:
All the lend functions use uint8
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L192
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L247
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L317
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L377
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L433
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L486
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L545
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L597
Change visibility modifier of public functions to external
Proof of concept
External function are cheaper than public ones. Functions that are not being invoked from inside the contract have no reason to be declared as public and not external.
Impact
Save gas on each currently public function call where the function is not being used in the contract in its life cycle.
Recommendations
Change public functions visibility modifiers to external where the function have to be so.
Examples in Lender.sol:
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L172
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L198
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L255
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L326
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L384
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L442
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L494
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L554
https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L602
The text was updated successfully, but these errors were encountered: