Nested Finance contest - Waze's results

The one-stop Defi app to build, manage and monetize your portfolio.

General Information

Platform: Code4rena

Start Date: 15/06/2022

Pot Size: $35,000 USDC

Total HM: 1

Participants: 36

Period: 3 days

Judge: Jack the Pug

Total Solo HM: 1

Id: 137

League: ETH

Nested Finance

Findings Distribution

Researcher Performance

Rank: 22/36

Findings: 1

Award: $83.14

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

83.1436 USDC - $83.14

Labels

bug
G (Gas Optimization)
sponsor confirmed
valid

External Links

#1 Use require instead &&

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L66

use require instead of && for efficient gas cost. change it from

require( address(_nestedAsset) != address(0) && address(_nestedRecords) != address(0) && address(_reserve) != address(0) && address(_feeSplitter) != address(0) && address(_weth) != address(0) && _operatorResolver != address(0) && address(_withdrawer) != address(0), "NF: INVALID_ADDRESS" );

to

require(address(_nestedAsset) != address(0),"NF: INVALID_ADDRESS"); require(address(_nestedRecords) != address(0),"NF: INVALID_ADDRESS"); require(address(_reserve) != address(0),"NF: INVALID_ADDRESS"); require(address(_feeSplitter) != address(0),"NF: INVALID_ADDRESS"); require(address(_weth) != address(0),"NF: INVALID_ADDRESS"); require( _operatorResolver != address(0),"NF: INVALID_ADDRESS"); require(address(_withdrawer) != address(0),"NF: INVALID_ADDRESS");

#2 Change to storage

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L123

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L248

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L466

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L52

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L101

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L33

Use storage instead of memory to reduce the gas fee.

bytes32[] memory operatorsCache = operators;

to

bytes32[] storage operatorsCache = operators;

apply to others.

#3 Looping

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L124

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L651

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L56

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L37

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L234

default uint is 0 so remove unnecassary explicit can reduce gas. caching the array length can reduce gas it caused access to a local variable is more cheap than query storage / calldata / memory in solidity. pre increment ++i more cheaper gas than post increment i++. i suggest to use pre increment.

#4 Default value and increment

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L136

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L196

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L315

default uint is 0 so remove unnecassary explicit can reduce gas pre increment ++i more cheaper gas than post increment i++. i suggest to use pre increment.

#5 Inequality

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L286

non strict inequality are cheaper than strict one. i suggest to use >= or <= instead of > and < if possible.

#6 Caching names.length

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/OperatorResolver.sol#L57

caching the names.length can reduce gas it caused access to a local variable is more cheap than query storage / calldata / memory in solidity and it use twice.

#7 Cache the cacheTmp.implementation

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L62-L64

cache the cacheTmp.implementation to the memory for reduce the gas fee because it use multiple times.

#8 Use calldata

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L93

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/BeefyVaultOperator.sol#L13

In the external functions where the function argument is read-only, the function() has an inputed parameter that using memory, if this function didnt change the parameter, its cheaper to use calldata then memory. so we suggest to change it.

#9 Division

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol#L275

A division by 2 can be calculated by shifting one to the right. The div opcode used 5 gas and SHR opcode used 3 gas. Solidity's division operation also includes a division-by-0 prevention by pass using shifting. so i suggest to use >>1.

#10 Sort struct

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Yearn/YearnVaultStorage.sol#L6-L9

shorting the struct can reduce gas cost, so change it from

struct CurvePool { address poolAddress; uint96 poolCoinAmount; address lpToken;

to

struct CurvePool { uint96 poolCoinAmount; address poolAddress; address lpToken;

#11 Short the string

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L243-L244

reduce size of string error message to bytes32 for cheap gas if possible.

#12 Caching the targets.length

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L319-L320

caching the targets.length can reduce gas it caused access to a local variable is more cheap than query storage / calldata / memory in solidity and it use twice.

require(targets.length == values.length, "TimelockController: length mismatch"); require(targets.length == datas.length, "TimelockController: length mismatch");

i suggest to add uint256 _targets = targets.length;

uint256 _targets = targets.length; require(_targets == values.length, "TimelockController: length mismatch"); require(_targets == datas.length, "TimelockController: length mismatch");

#0 - Yashiru

2022-06-22T15:31:24Z

6 Caching names.length (Confirmed)

Gas optimization confirmed

#1 - obatirou

2022-06-22T16:11:49Z

8 Use calldata (disputed)

Examples are not relevant:

  • For constructor of BeefyVaultOperator we cannot use calldata (either storage or memory for contructor)
  • For callOperator, MixinOperatorResolver we modify the variable hence we cannot use calldata

#2 - Yashiru

2022-06-23T08:22:08Z

5 Inequality (Confirmed)

Gas optimization confirmed

#3 - Yashiru

2022-06-24T11:42:42Z

12 Caching the targets.length (Duplicated)

Duplicated of #49 at TimelockControllerEmergency.sol

#4 - obatirou

2022-06-24T12:56:27Z

11 Short the string (duplicated)

Duplicate of point 2 from issue #62

#5 - Yashiru

2022-06-24T13:33:40Z

9 Division (Duplicated)

Duplicated of #89 at Use Shift Right/Left instead of Division/Multiplication

#6 - Yashiru

2022-06-24T15:41:29Z

3 Looping (Disputed)

Duplicated of #2 at For loop optimizaion

4 Default value and increment (Disputed)

Duplicated of #2 at For loop optimizaion

#7 - maximebrugel

2022-06-24T15:44:26Z

10 Sort struct (Disputed)

Two addresses can't be packed (20 bytes and 20 bytes).

#8 - obatirou

2022-06-24T15:49:48Z

#9 - maximebrugel

2022-06-24T16:19:36Z

7 Cache the cacheTmp.implementation (Acknowledged)

#10 - Yashiru

2022-06-27T10:20:06Z

2 Change to storage (Confirmed)

  • NestedFactory.sol#L248: Disputed, nestedRecords.getAssetTokens() can't return storage datas, data location must be "memory" or "calldata" for return parameter in function
  • NestedFactory.sol#L466: Disputed, callOperator() can't return storage datas, data location must be "memory" or "calldata" for return parameter in function
  • MixinOperatorResolver.sol#L52 Disputed, resolverOperatorsRequired() can't return storage datas, data location must be "memory" or "calldata" for return parameter in function
  • MixinOperatorResolver.sol#L101 Disputed, abi.decode() can't return storage datas, data location must be "memory" or "calldata" for return parameter in function
  • MixinOperatorResolver.sol#L33 Disputed, resolverOperatorsRequired() can't return storage datas, data location must be "memory" or "calldata" for return parameter in function
  • NestedFactory.sol#L123: Confirmed
    • Before optimization 0
    • After optimization 1
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