Illuminate contest - _Adam's results

Your Sole Source For Fixed-Yields.

General Information

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

Illuminate

Findings Distribution

Researcher Performance

Rank: 46/88

Findings: 2

Award: $142.95

🌟 Selected for report: 0

🚀 Solo Findings: 0

[L01] Two Step Admin Changes

When implementing access control changes recommend two step processes to protect against mistakenly transfering to the wrong address.

Redeemer.sol#L62-L65 MarketPlace.sol#L109-L112 Lender.sol#L129-L131

[L02] Events for Important State Changes

Recommend adding event for when contract is paused/unpaused. Lender.sol#L734-L737

[N01] Incorrect Natspec

Redeemer.sol#L89 - @notice is for the wrong function

[G01] Setting a mapping to its default value is cheaper to use delete

Based on this test in remix you can save ~511 gas in deployment costs and ~6 gas on each function call by using delete instead of setting to default value.

contract Test { mapping (address => uint256) public withdrawals; function test(address a) external { withdrawals[a] = 0; (Deployment cost: 180,368, Execution cost: 27,820) vs delete withdrawals[a]; (Deployment cost: 179,857, Execution cost: 27,814) } }

Instances where delete mapping[x]; can be implemented: Lender.sol#L670 Lender.sol#L699 Lender.sol#L714

[G02] Revert statements can be moved earlier

The variable amount isn't used in the revert statement and can be moved after. This will save an external call if the revert statement fails. Redeemer.sol#L120-L123

The variable principle isn't used in the revert statement and can be moved after. This will save an external call if the revert statement fails. Redeemer.sol#L164-L174

[G03] Pre Increments in Loops

In for loops pre increments can also be used to save a small amount of gas per iteration. I ran a test in remix using a for loop and found the deployment savings of 497 gas and ~5 gas per iteration.

contract Test { function loopTest() external { for (uint256 i; i < 1; i++) { (Deployment cost: 118,408, Cost on function call: 24,532) vs for (uint256 i; i < 1; ++i) { (Deployment cost: 117,911, Cost on function call: 24,527) } } }

For loops that can use pre increments: Lender.sol#L96 Lender.sol#L120 Lender.sol#L289

[G04] Custom Errors

Custom Errors are used throughout most of the contracts but their are still a couple of revert strings that can be replaced. Based on a test in remix, replacing a single revert string with a custom error saved 12,404 gas in deployment cost and 86 gas on each function call.

contract Test { uint256 a; function check() external { require(a != 0, "check failed"); } } (Deployment cost: 114,703, Cost on Function call: 23,392) vs contract Test { uint256 a; error checkFailed(); function check() external { if (a != 0) revert checkFailed(); } } (Deployment cost: 102,299, Cost on Function call: 23,306)

Instances where custom errors can be used instead of require statements: Lender.sol#L710 Lender.sol#L712

[G05] Marking Restricted Functions Payable

Functions that will always revert when regular users call them (Such as any with the authorized modifier) can be marked payable to save a small amount of gas (~24 Gas when function is called based on remix test)

MarketPlace.sol#L74 MarketPlace.sol#L98 MarketPlace.sol#L109 MarketPlace.sol#L123 Lender.sol#L78-L82 Lender.sol#L107 Lender.sol#L129 Lender.sol#L137 Lender.sol#L145 Lender.sol#L156 Lender.sol#L662 Lender.sol#L687 Lender.sol#L698 Lender.sol#L708 Lender.sol#L734 Redeemer.sol#L62 Redeemer.sol#L70 Redeemer.sol#L81 Redeemer.sol#L92 Redeemer.sol#L281

[G06] x = x + y is Cheaper than x += y

Based on test in remix you can save ~1,007 gas on deployment and ~15 gas on execution cost if you use x = x + y over x += y (Is only true for storage variables).

contract Test { uint256 x = 1; function test() external { x += 3; (Deployment Cost: 153,124, Execution Cost: 30,369) vs x = x + 1; (Deployment Cost: 152,117, Execution Cost: 30,354) } }

Instances where x = x + y can be implemented: Lender.sol#L294 Lender.sol#L340 Lender.sol#L404 Lender.sol#L461 Lender.sol#L514 Lender.sol#L572 Lender.sol#L621

[G07] Minimize SLOAD's

Whenever using a storage variable more than once in a function you can save ~97 gas per use. (normally 100 gas each use vs 103 gas to SLOAD/MSTORE for the first use and then only 3 gas for further uses)

Lender.sol#L146-L147 - can cache marketPlace (save ~97 gas) Lender.sol#L681 - can cache feenominator (save ~97 gas) Redeemer.sol#L134-L136 - can cache lender (save ~97 gas) Redeemer.sol#L177-L180 - can cache lender (save ~97 gas) Redeemer.sol#L221-L224 - can cache lender (save ~97 gas) Redeemer.sol#L256-L259 - can cache lender (save ~97 gas)

[G08] Public Functions that can be External

The following function is never called in their contracts and can be switched to external to save gas: Redeemer.sol#L275-L281

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter