Platform: Code4rena
Start Date: 29/06/2022
Pot Size: $50,000 USDC
Total HM: 20
Participants: 133
Period: 5 days
Judge: hickuphh3
Total Solo HM: 1
Id: 142
League: ETH
Rank: 54/133
Findings: 2
Award: $79.74
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: xiaoming90
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xSolus, 0xf15ers, 0xsanson, AmitN, Bnke0x0, BowTiedWardens, Chom, David_, ElKu, Funen, GalloDaSballo, GimelSec, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Nethermind, Picodes, ReyAdmirado, Sneakyninja0129, StErMi, TomJ, Treasure-Seeker, TrungOre, Waze, Yiko, _Adam, __141345__, antonttc, async, aysha, catchup, cccz, cryptphi, csanuragjain, danb, datapunk, defsec, delfin454000, dirk_y, doddle0x, durianSausage, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, horsefacts, hubble, itsmeSTYJ, joestakey, oyc_109, pedroais, peritoflores, rajatbeladiya, reassor, robee, rokinot, samruna, saneryee, sashik_eth, shenwilly, shung, simon135, sseefried, unforgiven, zer0dot, zzzitron
58.5734 USDC - $58.57
function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); }
Should be overridden in PuttyV2Nft.sol
function _burn(uint256 id) internal override virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); }
// set balanceOf to max for all users function balanceOf(address owner) public pure override returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return type(uint256).max; }
Currently
function tokenURI(uint256 id) public view override returns (string memory) { require(_ownerOf[id] != address(0), "URI query for NOT_MINTED token"); return string.concat(baseURI, Strings.toString(id)); }
_ownerOf is internal and not allowed to use in openzeppelin standard (is a private instead of internal). So, we should change to ownerOf(id) for best practice.
function tokenURI(uint256 id) public view override returns (string memory) { require(ownerOf(id) != address(0), "URI query for NOT_MINTED token"); return string.concat(baseURI, Strings.toString(id)); }
🌟 Selected for report: GalloDaSballo
Also found by: 0v3rf10w, 0x1f8b, 0xA5DF, 0xDjango, 0xHarry, 0xKitsune, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xkatana, 0xsanson, ACai, Aymen0909, Bnke0x0, BowTiedWardens, Chom, ElKu, Fitraldys, Funen, Haruxe, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Picodes, PwnedNoMore, Randyyy, RedOneN, ReyAdmirado, Ruhum, Sm4rty, StErMi, StyxRave, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, Yiko, _Adam, __141345__, ajtra, ak1, apostle0x01, asutorufos, c3phas, cRat1st0s, catchup, codetilda, cryptphi, datapunk, defsec, delfin454000, durianSausage, exd0tpy, fatherOfBlocks, gogo, grrwahrr, hake, hansfriese, horsefacts, ignacio, jayfromthe13th, joestakey, ladboy233, m_Rassska, mektigboy, minhquanym, mrpathfindr, natzuu, oyc_109, rajatbeladiya, reassor, rfa, robee, rokinot, sach1r0, saian, sashik_eth, simon135, slywaters, swit, z3s, zeesaw, zer0dot
21.1705 USDC - $21.17
This reduce gas cost as show here https://forum.openzeppelin.com/t/a-collection-of-gas-optimisation-tricks/19966/5
Caching the length in for loops:
for loop postcondition can be made unchecked Gas savings: roughly speaking this can save 30-40 gas per loop iteration. For lengthy loops, this can be significant!
for (uint256 i = 0; i < orders.length; i++) { positionIds[i] = fillOrder(orders[i], signatures[i], floorAssetTokenIds[i]); }
Can be optimized to
uint256 ordersLength = orders.length; for (uint256 i = 0; i < ordersLength;) { positionIds[i] = fillOrder(orders[i], signatures[i], floorAssetTokenIds[i]); unchecked { i++; } }
This reduce gas cost as show here https://forum.openzeppelin.com/t/a-collection-of-gas-optimisation-tricks/19966/5
Solidity 0.8.4 introduced custom errors. They are more gas efficient than revert strings, when it comes to deployment cost as well as runtime cost when the revert condition is met. Use custom errors instead of revert strings for gas savings.
Any require statement in your code can be replaced with custom error for example,
require(msg.value == order.strike, "Incorrect ETH amount sent");
Can be replaced with
// declare error before contract declaration error IncorrectETHAmount(); if (msg.value != order.strike) revert IncorrectETHAmount();