Platform: Code4rena
Start Date: 21/06/2022
Pot Size: $55,000 USDC
Total HM: 29
Participants: 88
Period: 5 days
Judge: gzeon
Total Solo HM: 7
Id: 134
League: ETH
Rank: 42/88
Findings: 1
Award: $147.51
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xkowloon, Bnke0x0, ElKu, Fitraldys, Funen, GalloDaSballo, IllIllI, JC, Kaiziron, Lambda, MadWookie, Noah3o6, Nyamcil, RoiEvenHaim, TomJ, Tomio, UnusualTurtle, Waze, _Adam, ajtra, asutorufos, bardamu, c3phas, catchup, datapunk, defsec, delfin454000, fatherOfBlocks, grGred, hake, hansfriese, hyh, ignacio, joestakey, kebabsec, ladboy233, oyc_109, pashov, poirots, rfa, robee, sach1r0, samruna, sashik_eth, simon135, slywaters, z3s, zer0dot
147.5086 USDC - $147.51
Solidity does not recognize null as a value, so uint variables are initialized to zero. Setting a uint variable to zero is redundant and can waste gas.
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L265
Remove the redundant zero initialization
uint256 i;
instead of uint256 i = 0;
Combining require statement conditions with && logic uses unnecessary gas. It is better to split up each part of the logical statement into a separate require statements
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L79
Use separate require statements instead of concatenating with &&
Using > 0
uses slightly more gas than using != 0
. Use != 0
when comparing uint variables to zero, which cannot hold values below zero
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L662
Replace > 0
with != 0
to save gas
Using a prefix increment (++i) instead of a postfix increment (i++) saves gas for each loop cycle and so can have a big gas impact when the loop executes on a large number of elements.
Locations where this was found include 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#L283 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L64
Use prefix not postfix to increment in a loop
For loops that use i++ do not need to use safemath for this operation because the loop would run out of gas long before this point. Making this addition operation unsafe using unchecked saves gas.
Sample code to make the for loop increment unsafe
for (uint i = 0; i < length; i = unchecked_inc(i)) { // do something that doesn't change the value of i } function unchecked_inc(uint i) returns (uint) { unchecked { return i + 1; } }
Idea borrowed from https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc#the-increment-in-for-loop-post-condition-can-be-made-unchecked
Locations where this was found include 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#L283 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L64
Make the increment in for loops unsafe to save gas
Identifying a constructor as payable saves gas. Constructors should only be called by the admin or deployer and should not mistakenly receive ETH. Constructors can be payable to save gas.
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L61 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L44 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L23 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L21 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L53 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20.sol#L39
Add payable to these functions for gas savings
An internal function can save gas vs. a modifier. A modifier inlines the code of the original function but an internal function does not.
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L722 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L731 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L300 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L138 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L247
Use internal functions in place of modifiers to save gas.
Using type(uint256).max uses less gas than other options for this constant value. Source https://forum.openzeppelin.com/t/using-the-maximum-integer-in-solidity/3000/13
Locations where this was found include 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#L112
Use type(uint256).max
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled.
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Element.sol#L28 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Element.sol#L29 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L25 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L54 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L76 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L77 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L118 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L141 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L142 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Swivel.sol#L17 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Swivel.sol#L18 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L715 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L27 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L55 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L76 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L77 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L23 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L50 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L71 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L72
Replace bool variables with uints
From the solidity docs
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Swivel.sol#L8 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L30 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L87 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L168 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L193 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L248 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L312 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L369 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L422 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L474 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L477 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L530 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L579 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L629 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L715 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Lender.sol#L731 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Cast.sol#L8 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L98 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L133 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L177 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L192 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L194 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L196 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L283 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Interfaces.sol#L293 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L36 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L108 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L159 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L207 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Redeemer.sol#L241 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Interfaces.sol#L9 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Interfaces.sol#L98 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Interfaces.sol#L133 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L23 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L55 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L21 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L73 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L98 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L140 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L155 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L170 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/MarketPlace.sol#L185
Replace smaller int or uint variables with uint256 variables
Solidity errors introduced in version 0.8.4 can save gas on revert conditions https://blog.soliditylang.org/2021/04/21/custom-errors/ https://twitter.com/PatrickAlphaC/status/1505197417884528640
Locations where this was found include https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L41 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L71 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Safe.sol#L134 https://github.com/code-423n4/2022-06-illuminate/blob/main/lender/Cast.sol#L9 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L44 https://github.com/code-423n4/2022-06-illuminate/blob/main/redeemer/Safe.sol#L71 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L39 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/Safe.sol#L66 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L56 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20Permit.sol#L78 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L100 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L116 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC5095.sol#L139 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20.sol#L116 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20.sol#L152 https://github.com/code-423n4/2022-06-illuminate/blob/main/marketplace/ERC20.sol#L189
Replace require blocks with new solidity errors described in https://blog.soliditylang.org/2021/04/21/custom-errors/u
The contracts are all written entirely in solidity. Writing contracts with vyper instead of solidity can save gas.
Source https://twitter.com/eiber_david/status/1515737811881807876 doggo demonstrates https://twitter.com/fubuloubu/status/1528179581974417414?t=-hcq_26JFDaHdAQZ-wYxCA&s=19
Write some or all of the contracts in vyper to save gas