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
Rank: 55/75
Findings: 1
Award: $21.62
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: JCN
Also found by: 0x70C9, 0xSmartContract, 0xWaitress, 0xhacksmithh, DavidGiladi, K42, LaScaloneta, Rageur, Raihan, SAAJ, SAQ, SM3_SS, Sathish9098, Tomio, bigtone, c3phas, ernestognw, etherhood, koxuan, matrix_0wl, mgf15, naman1778, niser93, petrichor, piyushshukla, sebghatullah, shamsulhaq123
21.6219 USDC - $21.62
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.
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.
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.
--
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.
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" );
#0 - c4-judge
2023-07-03T13:29:30Z
Picodes marked the issue as grade-b