Illuminate contest - c3phas'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: 85/88

Findings: 1

Award: $62.46

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

FINDINGS

Cache the length of arrays in loops ~6 gas per iteration

Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.

The solidity compiler will always read the length of the array during each iteration. That is,

1.if it is a storage array, this is an extra sload operation (100 additional extra gas (EIP-2929 2) for each iteration except for the first), 2.if it is a memory array, this is an extra mload operation (3 additional gas for each iteration except for the first), 3.if it is a calldata array, this is an extra calldataload operation (3 additional gas for each iteration except for the first)

This extra costs can be avoided by caching the array length (in stack): When reading the length of an array, sload or mload or calldataload operation is only called once and subsequently replaced by a cheap dupN instruction. Even though mload , calldataload and dupN have the same gas cost, mload and calldataload needs an additional dupN to put the offset in the stack, i.e., an extra 3 gas. which brings this to 6 gas

Here, I suggest storing the arrayโ€™s length in a variable before the for-loop, and use it instead:

File: Lender.sol line 265

for (uint256 i = 0; i < o.length; ) {

The above should be modified to

uint256 length = o.length; for (uint256 i = 0; i < length; ) {

Something similar to my proposal has been implemented on line 108

++i costs less gas compared to i++ or i += 1 (~5 gas per iteration)

++i costs less gas compared to i++ or i += 1 for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.

i++ increments i and returns the initial value of i. Which means:

uint i = 1; i++; // == 1 but i == 2

But ++i returns the actual incremented value:

uint i = 1; ++i; // == 2 and i == 2 too, so no need for a temporary variable

In the first case, the compiler has to create a temporary variable (when used) for returning 1 instead of 2

Instances include:

File: Lender.sol line 96

unchecked { i++; }

The above should be modified to

unchecked { ++i; }

File: Lender.sol line 120

unchecked { i++; }

File: Lender.sol line 289

unchecked { i++; }

Use Custom Errors instead of Revert Strings to save Gas

Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met)

see Source

Custom errors have been used on most of the contracts and functions reviewed apart from the following places.

File: Lender.sol line 710

require (when != 0, 'no withdrawal scheduled');

File: Lender.sol line 712

require (block.timestamp >= when, 'withdrawal still on hold');
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