Stader Labs - K42's results

Decentralized ETH liquid staking protocol with 4 ETH bond for anyone to be a node operator.

General Information

Platform: Code4rena

Start Date: 02/06/2023

Pot Size: $100,000 USDC

Total HM: 15

Participants: 75

Period: 7 days

Judge: Picodes

Total Solo HM: 5

Id: 249

League: ETH

Stader Labs

Findings Distribution

Researcher Performance

Rank: 55/75

Findings: 1

Award: $21.62

Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

21.6219 USDC - $21.62

Labels

bug
G (Gas Optimization)
grade-b
G-19

External Links

Gas (mana) Optimization Report by K42

Possible Optimization in Auction.sol

Scope = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/Auction.sol

Possible Optimization = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/Auction.sol#LL55C6-L57C10 -- Currently the createLot function checks whether the transferFrom function of the ERC20 token returns true. However, this is unnecessary because transferFrom will automatically revert if it fails, therefore you can change if (!IERC20(staderConfig.getStaderToken()).transferFrom(msg.sender, address(this), _sdAmount)) { revert SDTransferFailed(); } To IERC20(staderConfig.getStaderToken()).transferFrom(msg.sender, address(this), _sdAmount); this will save you some gas.

  • Estimated gas saved = 5,000 to 10,000 gas.

Possible Optimization in PermissionedNodeRegistry.sol

Scope = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PermissionedNodeRegistry.sol Possible Optimization = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PermissionedNodeRegistry.sol#LL67C1-L68C52 -- The UtilLib.checkNonZeroAddress() function is used multiple times to check if an address is not zero. However, in some cases, this check might be redundant. For example, in the initialize() function, the _admin and _staderConfig addresses are checked with UtilLib.checkNonZeroAddress(). But these addresses are also used to call functions or assign values, which would fail anyway if the addresses were zero. Removing these redundant checks could save gas, remove UtilLib.checkNonZeroAddress(_admin); and UtilLib.checkNonZeroAddress(_staderConfig); to save gas.

  • Estimated gas saved = Successful func call saves around 400 gas by removing these checks, unsuccessful func calls removing these checks saves around 20,000 gas.

Possible Optimizations in PermissionedPool.sol

Scope = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PermissionedPool.sol Possible Optimization 1 = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PermissionedPool.sol#LL41C1-L42C52 -- Similar to previous optimization, the UtilLib.checkNonZeroAddress() function is used multiple times to check if an address is not zero. However, in some cases, this check might be redundant. For example, in the initialize() function, the _admin and _staderConfig addresses are checked with UtilLib.checkNonZeroAddress(). But these addresses are also used to call functions or assign values, which would fail anyway if the addresses were zero. Removing these redundant checks could save gas, do this by removing UtilLib.checkNonZeroAddress(_admin); and UtilLib.checkNonZeroAddress(_staderConfig); change to require(_admin != address(0), "Admin address cannot be zero"); and require(_staderConfig != address(0), "StaderConfig address cannot be zero"); to be sure of optimized checks.

  • Estimated gas saved = 21,000 gas.

--

Possible Optimization in PoolUtils.sol

Scope = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PoolUtils.sol Possible Optimization = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/PoolUtils.sol#LL26C1-L27C52 -- Similar to the previous optimizations the UtilLib.checkNonZeroAddress() function is used multiple times to check if an address is not zero. However, these checks are redundant in the initialize() function, the _admin and _staderConfig addresses are checked with UtilLib.checkNonZeroAddress(). But these addresses are also used to call functions or assign values, which would fail anyway if the addresses were zero. Removing these redundant checks could save gas, therefore remove UtilLib.checkNonZeroAddress(_admin); and UtilLib.checkNonZeroAddress(_staderConfig); to save some gas.

  • Estimated gas saved = Up to 10,000 gas saved.

Possible Optimization in StaderOracle.sol

Scope = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/StaderOracle.sol Possible Optimization = https://github.com/code-423n4/2023-06-stader/blob/main/contracts/StaderOracle.sol#LL115C1-L123C10 -- In the submitExchangeRateData function, there are multiple revert conditions that are checked one after the other. These conditions could be combined using logical OR (||) to take advantage of short-circuit evaluation. If the first condition is met, the rest won't be evaluated, saving gas. Do this like by replacing if (isPORFeedBasedERData) { revert InvalidERDataSource(); } if (_exchangeRate.reportingBlockNumber >= block.number) { revert ReportingFutureBlockData(); } if (_exchangeRate.reportingBlockNumber % updateFrequencyMap[ETHX_ER_UF] > 0) { revert InvalidReportingBlock(); } with require( !isPORFeedBasedERData || _exchangeRate.reportingBlockNumber < block.number || _exchangeRate.reportingBlockNumber % updateFrequencyMap[ETHX_ER_UF] == 0, "InvalidERDataSource or ReportingFutureBlockData or InvalidReportingBlock" );

  • Estimated gas saved = Short-circuit evaluation can often save a significant amount of gas when conditions are frequently met early in the logical expression. This optimization could potentially save a few hundred gas per transaction, but the exact amount would need to be benchmarked.

#0 - c4-judge

2023-07-03T13:29:30Z

Picodes marked the issue as grade-b

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