Caviar contest - ReyAdmirado's results

A fully on-chain NFT AMM that allows you to trade every NFT in a collection.

General Information

Platform: Code4rena

Start Date: 12/12/2022

Pot Size: $36,500 USDC

Total HM: 8

Participants: 103

Period: 7 days

Judge: berndartmueller

Id: 193

League: ETH

Caviar

Findings Distribution

Researcher Performance

Rank: 35/103

Findings: 1

Award: $179.23

Gas:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

179.2341 USDC - $179.23

Labels

bug
G (Gas Optimization)
grade-a
G-08

External Links

1. state variables should be cached in stack variables rather than re-reading them from storage

The instances below point to the second+ access of a state variable within a function. Caching of a state variable replace each Gwarmaccess (100 gas) with a much cheaper stack read. Other less obvious fixes/optimizations include having local memory caches of state variable structs, or having local caches of state variable contracts/addresses.

high chance of saving 100 gas for a low risk of losing 3, cache closeTimestamp before the second require (only if withdraw is not initiated we will lose 3 gas otherwise we will save 100)

2. Add unchecked {} for subtractions where the operands cannot underflow because of a previous require() or if statement

require(a <= b); x = b - a => require(a <= b); unchecked { x = b - a } if(a <= b); x = b - a => if(a <= b); unchecked { x = b - a } this will stop the check for overflow and underflow so it will save gas

can not underflow

checked in require L157

3. <x> += <y> costs more gas than <x> = <x> + <y>

Using the addition operator instead of plus-equals saves gas

4. can make the variable outside the loop to save gas

make the variable before the for loop and only give the value to it inside the loop

isValid

char

5. ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for-loop and while-loops

In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.

6. splitting require() statements that use && saves gas

this will have a large deployment gas cost but with enough runtime calls the split require version will be 3 gas cheaper

7. internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

_validateTokenIds

8. public functions not called by the contract should be declared external instead

Contracts are allowed to override their parents’ functions and change the visibility from external to public and can save gas by doing so.

destroy

create

mint

burn

price

withdraw

close

nftSell

nftBuy

nftRemove

nftAdd

9. before some functions we should check some variables for possible gas save

before transfer we should check for amount being 0 so the function doesnt run when its not gonna do anything. varaiables below have possibility of being 0

fractionalTokenOutputAmount

baseTokenOutputAmount

outputAmount

inputAmount

10. pre calculate instead of using operations to calculate

just pre calculate 160 - 4 * 4 and use it inside the code instead of using 2 operations

11. emit can be made cheaper

closeTimestamp costs 100 gas instead just use the value block.timestamp + CLOSE_GRACE_PERIOD given to it some line above or cache the value of this operation before to make it even cheaper

#0 - c4-judge

2022-12-30T13:38:34Z

berndartmueller marked the issue as grade-a

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