Platform: Code4rena
Start Date: 09/12/2022
Pot Size: $36,500 USDC
Total HM: 9
Participants: 69
Period: 3 days
Judge: Picodes
Total Solo HM: 2
Id: 190
League: ETH
Rank: 68/69
Findings: 1
Award: $25.05
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: ReyAdmirado
Also found by: 0xSmartContract, 0xTraub, Aymen0909, Englave, Mukund, RHaO-sec, RaymondFam, Rolezn, Sathish9098, Tomio, UdarTeam, chaduke, dharma09, gz627, martin, nadin, pavankv, rjs, saneryee
25.0472 USDC - $25.05
The PrePO code base is well-written and employs many common gas optimizations in sensible places. It was quite a challenge to find improvements ๐.
ID | Finding | Instances |
---|---|---|
G-01 | Single-child inheritance hierarchies can be flattened | 1 |
G-02 | x = x + y ย is more efficient thanย x += y; | 5 |
G-03 | Use named variables in function returns | 2 |
G-04 | Redundant return statement | 2 |
G-05 | Cache variables in hot loops | 1 |
Deployment Gas saved: โ Transaction Gas saved: โ
NFTScoreRequirement
has only one descendantDepositHook
is the only class to inherit from NFTScoreRequirement
. While it is good practice to separate concerns like this, it could be argued that this is a premature optimization until a second child contract has actually been implemented. Given that DepositHook
is a hot path for PrePO, and hooks cannot be set by 3rd parties, I would consider flattening this hierarchy for the deployment and transaction (JUMP/stack) gas savings until there is a second descendant of NFTScoreRequirement
.
7: contract NFTScoreRequirement is INFTScoreRequirement {
12: contract DepositHook is IDepositHook, AccountListCaller, NFTScoreRequirement, TokenSenderCaller, SafeAccessControlEnumerable {
x = x + y
ย is more efficient thanย x += y;
Deployment Gas saved: โ Transaction Gas saved: โ
31: globalNetDepositAmount += _amount; 32: userToDeposits[_sender] += _amount;
64: globalAmountWithdrawnThisPeriod += _amountBeforeFee;
71: userToAmountWithdrawnThisPeriod[_sender] += _amountBeforeFee;
60: score += IERC721(collection).balanceOf(account) > 0 ? collectionScore : 0;
Deployment Gas saved: โ Transaction Gas saved: โ
Declaring additional variables rather than using named return variables is a waste of deployment gas.
45: function deposit(address _recipient, uint256 _amount) external override nonReentrant returns (uint256) { ... 60: uint256 _collateralMintAmount = (_amountAfterFee * 1e18) / baseTokenDenominator; ... 63: return _collateralMintAmount; 64: }
55: function getAccountScore(address account) public view virtual override returns (uint256) { 56: uint256 score; ... 65: return score; 66: }
return
statementDeployment Gas saved: โ Transaction Gas saved: โ
If you set values for all named variable in a function return, it is not necessary to use the return
statement, see line 71 below:
59: function _createPairTokens( ... 64: ) internal returns (LongShortToken _newLongToken, LongShortToken _newShortToken) { ... 69: _newLongToken = new LongShortToken{salt: _longTokenSalt}(_longTokenName, _longTokenSymbol); 70: _newShortToken = new LongShortToken{salt: _shortTokenSalt}(_shortTokenName, _shortTokenSymbol); 71: return (_newLongToken, _newShortToken); // <-- remove 72: }
Alternatively, if you are just returning the default value, it is also redundant:
50: function getCollectionScore(IERC721 collection) external view virtual override returns (uint256) { 51: if (_collectionToScore.contains(address(collection))) return _collectionToScore.get(address(collection)); 52: return 0; // <-- remove 53: }
Deployment Gas saved: โ Transaction Gas saved: โ
Before:
25: for (uint256 i = 0; i < numCollections; ) { 26: require(scores[i] > 0, "score == 0"); 27: _collectionToScore.set(address(collections[i]), scores[i]); 28: unchecked { 29: ++i; 30: } 31: }
ยท-----------------------------------------------------------|---------------------------|-------------|-----------------------------ยท | Solc version: 0.8.7 ยท Optimizer enabled: true ยท Runs: 200 ยท Block limit: 30000000 gas โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท | Methods โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท | Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท eur (avg) โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท | DepositHook ยท setCollectionScores ยท 118079 ยท 118307 ยท 118155 ยท 3 ยท - โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
After:
25: uint256 score; 26: for (uint256 i = 0; i < numCollections; ) { 27: score = scores[i]; 28: require(score > 0, "score == 0"); 29: _collectionToScore.set(address(collections[i]), score); 30: unchecked { 31: ++i; 32: } 33: }
ยท-----------------------------------------|---------------------------|-------------|-----------------------------ยท | Solc version: 0.8.7 ยท Optimizer enabled: true ยท Runs: 200 ยท Block limit: 30000000 gas โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท | Methods โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท | Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท eur (avg) โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท | DepositHook ยท setCollectionScores ยท 118043 ยท 118271 ยท 118119 ยท 3 ยท - โ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
#0 - c4-judge
2022-12-19T11:59:13Z
Picodes marked the issue as grade-b