LooksRare Aggregator contest - shark's results

An NFT aggregator protocol.

General Information

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

LooksRare

Findings Distribution

Researcher Performance

Rank: 36/72

Findings: 1

Award: $80.83

Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: IllIllI

Also found by: 0x1f8b, Aymen0909, CloudX, Rolezn, aviggiano, carlitox477, datapunk, gianganhnguyen, shark, tnevler, zaskoh

Labels

bug
G (Gas Optimization)
grade-b
judge review requested
G-07

Awards

80.8321 USDC - $80.83

External Links

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

Math should be unchecked if overflowing is not a possibility

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

Use 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

Use storage instead of memory for structs and arrays

storage 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

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