Platform: Code4rena
Start Date: 05/10/2022
Pot Size: $50,000 USDC
Total HM: 2
Participants: 80
Period: 5 days
Judge: GalloDaSballo
Id: 168
League: ETH
Rank: 79/80
Findings: 1
Award: $32.65
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xNazgul, 0xSmartContract, Aymen0909, Heuss, Lambda, Pheonix, RaymondFam, ReyAdmirado, Ruhum, Shinchan, Shishigami, __141345__, adriro, ajtra, c3phas, ch0bu, cryptostellar5, d3e4, enckrish, gogo, halden, lucacez, mcwildy, medikko, neko_nyaa, pedr02b2, pfapostol, ret2basic, rvierdiiev, saian, sakman, sakshamguruji
32.6464 USDC - $32.65
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. source Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past.
File: ReentrancyGuarded.sol line 10
bool reentrancyLock = false;
File: ExecutionDelegate.sol line 18
mapping(address => bool) public contracts;
File: ExecutionDelegate.sol line 19
mapping(address => bool) public revokedApproval;
File: BlurExchange.sol line 71
mapping(bytes32 => bool) public cancelledOrFilled;
The code can be optimized by minimising the number of SLOADs. SLOADs are expensive 100 gas compared to MLOADs/MSTOREs(3gas). Storage value should get cached in memory
PolicyManager.sol.viewWhitelistedPolicies: _whitelistedPolicies.length() should be cached - _whitelistedPolicies is a storage array
File: PolicyManager.sol Line 71
_whitelistedPolicies.length()
New value of nonces[msg.sender] should be saved in additional memory variable
File: BlurExchange.sol Line 208
nonces[msg.sender] += 1;
// Used
emit NonceIncremented(msg.sender, nonces[msg.sender]);
// Used
The size parameter can be used instead of variable length
File: PolicyManager.sol Line 69
uint256 length = size;
++i costs less gas compared to i++ or i += 1 for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration)
File: PolicyManager.sol Line 77 File: EIP712.sol line 77 File: MerkleVerifier.sol line 38 File: BlurExchange.sol line 199
The majority of Solidity for loops increment a uint256 variable that starts at 0. These increment operations never need to be checked for over/underflow because the variable will never reach the max number of uint256 (will run out of gas long before that happens). The default over/underflow check wastes gas in every iteration of virtually every for loop . eg.
File: PolicyManager.sol line 77 File: EIP712.sol line 77 File: MerkleVerifier.sol line 38 File: BlurExchange.sol line 199
Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met). Custom errors are defined using the error statement, which can be used inside and outside of contracts (including interfaces and libraries). see source
File: PolicyManager.sol line 26
require(!_whitelistedPolicies.contains(policy), "Already whitelisted");
File: PolicyManager.sol line 37
require(_whitelistedPolicies.contains(policy), "Not whitelisted");
File: ExecutionDelegate.sol line 22
require(contracts[msg.sender], "Contract is not approved to make transfers");
File: ExecutionDelegate.sol line 77
require(revokedApproval[from] == false, "User has revoked approval");
File: ExecutionDelegate.sol line 92
require(revokedApproval[from] == false, "User has revoked approval");
File: ExecutionDelegate.sol line 108
require(revokedApproval[from] == false, "User has revoked approval");
File: ExecutionDelegate.sol line 124
require(revokedApproval[from] == false, "User has revoked approval");
File: BlurExchange.sol line 36
require(isOpen == 1, "Closed");
File: BlurExchange.sol line 139-143
File: BlurExchange.sol line 219
require(address(_executionDelegate) != address(0), "Address cannot be zero");
File: BlurExchange.sol line 228
require(address(_policyManager) != address(0), "Address cannot be zero");
File: BlurExchange.sol line 237
require(_oracle != address(0), "Address cannot be zero");
File: BlurExchange.sol line 318
require(block.number - order.blockNumber < blockRange, "Signed block number out of range");
File: BlurExchange.sol line 407
require(v == 27 || v == 28, "Invalid v parameter");
File: BlurExchange.sol line 424
require(policyManager.isPolicyWhitelisted(sell.matchingPolicy), "Policy is not whitelisted");
File: BlurExchange.sol line 428
require(policyManager.isPolicyWhitelisted(buy.matchingPolicy), "Policy is not whitelisted");
File: BlurExchange.sol line 431
require(canMatch, "Orders cannot be matched");
File: BlurExchange.sol line 482
require(totalFee <= price, "Total amount of fees are more than the price");
File: BlurExchange.sol line 534
require(_exists(collection), "Collection does not exist");
File: PolicyManager.sol line 72
length = _whitelistedPolicies.length() - cursor;
File: BlurExchange.sol line 208
nonces[msg.sender] += 1;
File: BlurExchange.sol line 221
insted of:
emit NewExecutionDelegate(executionDelegate);
use:
emit NewExecutionDelegate(_executionDelegate);
File: BlurExchange.sol line 230 File: BlurExchange.sol line 239 File: BlurExchange.sol line 247
#0 - GalloDaSballo
2022-10-24T00:45:03Z
5k
300
Rest 150
5450