Platform: Code4rena
Start Date: 20/09/2022
Pot Size: $100,000 USDC
Total HM: 4
Participants: 109
Period: 7 days
Judge: GalloDaSballo
Id: 163
League: ETH
Rank: 78/109
Findings: 1
Award: $55.20
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0x52, 0x5rings, 0xNazgul, 0xRobocop, 0xSmartContract, 0xdeadbeef, 0xsanson, 8olidity, Amithuddar, Aymen0909, B2, B353N, CertoraInc, Ch_301, Chom, CodingNameKiki, Deivitto, ElKu, Funen, JC, JohnnyTime, Kresh, Lambda, Noah3o6, RaymondFam, ReyAdmirado, RockingMiles, Rolezn, Sm4rty, SuldaanBeegsi, Tadashi, TomJ, Tomio, V_B, Waze, __141345__, a12jmx, ak1, arcoun, asutorufos, aviggiano, berndartmueller, bharg4v, bin2chen, brgltd, bulej93, c3phas, catchup, cccz, ch0bu, cryptonue, cryptphi, csanuragjain, delfin454000, devtooligan, djxploit, durianSausage, eighty, erictee, exd0tpy, fatherOfBlocks, giovannidisiena, hansfriese, ignacio, joestakey, ladboy233, lukris02, m9800, malinariy, martin, minhtrng, obront, oyc_109, pedr02b2, pedroais, pfapostol, philogy, prasantgupta52, rbserver, ronnyx2017, rotcivegaf, rvierdiiev, sach1r0, shung, simon135, throttle, tnevler, tonisives, wagmi, yixxas, zkhorse, zzykxx, zzzitron
55.1985 USDC - $55.20
Issue | Risk | Instances | |
---|---|---|---|
1 | Immutable state variables lack zero value (address or uint) checks | Low | 7 |
2 | Risk of reentrancy in the transferFrom function from the PagesERC721 contract | Low | 1 |
Constructors should check that the values written in an immutable state variables variable are not zero (for uint) or the zero address (for addresses).
Instances include:
File: src/ArtGobblers.sol
File: src/Goo.sol
File: src/Pages.sol
Add non-zero address checks in the constructors for the instances aforementioned.
transferFrom
function from the PagesERC721
contract :When the owner calls the pages ERC721 transferFrom function the old approver address can reenter the function to modify the transfer receiver address, this is possible because the transferFrom
function doesn't respect the CEI (check-effect-interact) best practice as the approver is deleted after assigning the new owner.
Instances occurs in the code below :
File: src/utils/token/PagesERC721.sol Line 98-125
function transferFrom( address from, address to, uint256 id ) public { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll(from, msg.sender) || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); }
The old approver is deleted after the ERC721 ownership has been transferred and thus the old approver can reenter the function to transfer the token from the new owner to another address.
The transferFrom
function should be modified as follow :
function transferFrom( address from, address to, uint256 id ) public { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll(from, msg.sender) || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } // @audit delete the old approver first delete getApproved[id]; _ownerOf[id] = to; emit Transfer(from, to, id); }
#0 - GalloDaSballo
2022-10-04T22:03:51Z
L
Disputed, no external call is performed in the code you linked
#1 - GalloDaSballo
2022-10-04T22:03:55Z
L