Platform: Code4rena
Start Date: 08/11/2022
Pot Size: $60,500 USDC
Total HM: 6
Participants: 72
Period: 5 days
Judge: Picodes
Total Solo HM: 2
Id: 178
League: ETH
Rank: 36/72
Findings: 1
Award: $80.83
🌟 Selected for report: 0
🚀 Solo Findings: 0
80.8321 USDC - $80.83
x = x + y
is more efficient than x += y
(same for subtracting)The amount of gas saved can be sizeable when repeated in a loop.
For example:
File: SeaportProxy.sol
Line 145-161
150 fee += orderFee;
Instead, you can change the code to the following:
150 fee = fee + orderFee;
Here are some more instances of this issue:
File: SeaportProxy.sol
Line 109
File: SeaportProxy.sol
Line 209
Consider the following example:
File: SeaportProxy.sol
Line 145-161
145 for (uint256 i; i < ordersLength; ) { 146 address currency = orders[i].currency; 147 uint256 orderFee = (orders[i].price * feeBp) / 10000; 148 149 if (currency == lastOrderCurrency) { 150 fee += orderFee; 151 } else { 152 if (fee > 0) _transferFee(fee, lastOrderCurrency, feeRecipient); 153 154 lastOrderCurrency = currency; 155 fee = orderFee; 156 } 157 158 unchecked { 159 ++i; 160 } 161 }
Since we know that fee
(Line 150) will not overflow, we can uncheck math and save the gas.
Instead, you can rewrite the code to the following:
unchecked { for (uint256 i; i < ordersLength; ++i) { address currency = orders[i].currency; uint256 orderFee = (orders[i].price * feeBp) / 10000; if (currency == lastOrderCurrency) { fee += orderFee; } else { if (fee > 0) _transferFee(fee, lastOrderCurrency, feeRecipient); lastOrderCurrency = currency; fee = orderFee; } } }
Here are the rest of the instances:
File: SeaportProxy.sol
Line 102-114
File: SeaportProxy.sol
Line 187-222
calldata
instead of memory
If you are not going to modify the parameter, you can pass it as calldata
to save gas (about 60 gas).
For example:
File: LooksRareProxy.sol
Line 108-109
OrderTypes.TakerOrder memory takerBid, OrderTypes.MakerOrder memory makerAsk,
Since these parameters aren't going to be modified, they can be passed as calldata instead:
OrderTypes.TakerOrder calldata takerBid, OrderTypes.MakerOrder calldata makerAsk,
Here is another instance of this issue:
File: SeaportProxy.sol
Line 227
storage
instead of memory
for structs and arraysstorage
costs less gas since copying a state struct in memory would incur as many SLOADs and MSTOREs as there are slots.
For example:
File: LooksRareProxy.sol
Line 90
OrderTypes.TakerOrder memory takerBid;
Instead of memory
, you can use storage
:
OrderTypes.TakerOrder storage takerBid;
Here are the rest of the instances:
File: LooksRareProxy.sol
Line 65-69
File: SeaportProxy.sol
Line 97-103
File: SeaportProxy.sol
Line 188-189
File: SeaportProxy.sol
Line 244-254
#0 - c4-judge
2022-11-21T18:46:59Z
Picodes marked the issue as grade-b
#1 - 0xhiroshi
2022-11-24T12:37:00Z
All addressed in other issues
#2 - c4-sponsor
2022-11-24T12:37:05Z
0xhiroshi requested judge review