Platform: Code4rena
Start Date: 03/05/2022
Pot Size: $30,000 USDC
Total HM: 6
Participants: 93
Period: 3 days
Judge: gzeon
Id: 118
League: ETH
Rank: 64/93
Findings: 2
Award: $45.77
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: defsec
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0x52, 0xDjango, 0xf15ers, 0xkatana, 0xliumin, AuditsAreUS, BowTiedWardens, CertoraInc, Cr4ckM3, Funen, GimelSec, Hawkeye, IllIllI, Kulk0, M0ndoHEHE, MaratCerby, Picodes, Ruhum, TerrierLover, TrungOre, VAD37, WatchPug, berndartmueller, broccolirob, catchup, cccz, cryptphi, csanuragjain, delfin454000, dirk_y, eccentricexit, ellahi, fatherOfBlocks, gzeon, hake, hansfriese, hickuphh3, horsefacts, hubble, hyh, ilan, joestakey, kebabsec, kenta, kenzo, leastwood, m9800, marximimus, minhquanym, oyc_109, p4st13r4, pauliax, pedroais, peritoflores, plotchy, rajatbeladiya, reassor, rfa, robee, rotcivegaf, samruna, shenwilly, shung, simon135, sorrynotsorry, sseefried, teddav, throttle, tintin, unforgiven, z3s
30.2759 USDC - $30.28
_msgSender
and msg.sender
Examples:
🌟 Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xProf, 0xc0ffEE, 0xf15ers, 0xkatana, 0xliumin, ACai, AlleyCat, CertoraInc, Cityscape, Cr4ckM3, DavidGialdi, Dinddle, FSchmoede, Funen, GimelSec, Hawkeye, IllIllI, Kulk0, M0ndoHEHE, MaratCerby, MiloTruck, Picodes, RoiEvenHaim, Tadashi, TerrierLover, TrungOre, VAD37, WatchPug, antonttc, catchup, defsec, delfin454000, dirk_y, eccentricexit, ellahi, fatherOfBlocks, gzeon, hake, hansfriese, hickuphh3, horsefacts, ilan, joestakey, kebabsec, kenta, kenzo, marximimus, minhquanym, noobie, oyc_109, p4st13r4, pauliax, rajatbeladiya, reassor, rfa, robee, rotcivegaf, saian, samruna, shenwilly, shung, simon135, slywaters, sorrynotsorry, throttle, unforgiven, z3s
15.491 USDC - $15.49
nonReentrant
keywordsThe only way to mint is to interact with the Minter, so you only need either the Minter functions either the mint
function to be nonReentrant
.
nonReentrant
keywords and _checkOnERC721Received
during mintFirst, to me _checkOnERC721Received
is mostly useful as a safeguard for NFT traders during the NFT lifecycle, and to me using this process during mint is a useless gas overhead as you don't expect smart contracts to mint by error. Furthermore from past reentrancy attacks it seems this standard has done more harm than good during mint phases. Basically you could use _mint
instead of _safeMint
Assuming you remove it, you'd save the external call, and as well all the nonReentrant
keywords as it's the only arbitrary external call you're doing.
Concerned code:
Pausable
inheritance could be removedYou already have a way to pause all critical functions which is to use setPhaseTimes
, so you don't really need to use Pausable
and whenNotPaused
tokenId
stack variable could be removedThis stack variable could be removed: https://github.com/code-423n4/2022-05-runes/blob/060b4f82b79c8308fe65674a39a07c44fa586cd3/contracts/ForgottenRunesWarriorsGuild.sol#L102
(Needs a bit of rework). Currently you allow for partial refunds, which is costing you one SLOAD per refund as you need to write in daAmountRefunded
. If you remove this feature (so refunds are either done or not), then you can use booleans to store if the refund of someone has been processed or not.
Then you can use bitmaps -using a uint256 to store 256 booleans as bits- (for example https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol or https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol) to store the booleans indicating if refunds have been processed or not. If done wisely, you could end up having only 1 SLOAD and 1 SWRITE per 256 address, which would save you a ton of gas.
Basically when refunding for a batch, you’ll just need to subprocess by batch of 256 address, load the corresponding uint in the bitmap, and save it at the end of the sub processing.
Very fan of the on-chain storage trick you came up with !