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: 34/109
Findings: 2
Award: $525.56
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: zzykxx
Also found by: 8olidity, IllIllI, Lambda, berndartmueller, bytehat, devtooligan, hansfriese, imare, obront, philogy, shung, tonisives, zdhu, zkhorse
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/ArtGobblers.sol/#L562
If VRF sunsets/becomes unresponsive while you are in the middle of waiting for a seed, the Random Provider can never be upgraded. This means you can never call revealGobblers
again, because gobblerRevealsData.waitingForSeed
is stuck in true
state.
upgradeRandProvider
requires gobblerRevealsData.waitingForSeed
to be false.
function upgradeRandProvider(RandProvider newRandProvider) external onlyOwner { // Revert if waiting for seed, so we don't interrupt requests in flight. if (gobblerRevealsData.waitingForSeed) revert SeedPending(); ...
gobblerRevealsData.waitingForSeed
can only be set to false in acceptRandomSeed
. This method requires that the caller is the randomness provider.
function acceptRandomSeed(bytes32, uint256 randomness) external { // The caller must be the randomness provider, revert in the case it's not. if (msg.sender != address(randProvider)) revert NotRandProvider(); ...
This means that if the VRF sunsets while you are waiting for a random seed, you can never upgrade your random provider. acceptRandomSeed
will never be called and waitingForSeed
will never be set to false.
It is possible that VRF1 will stop accepting randomness requests when sunsetting. However, ChainLink is a third party, and should not be relied upon for the functioning of this project.
ChainLink could also have issues where their system stops working and they need to upgrade their contracts. Then the ArtGobblers will also be stuck, because you need to upgrade the ChainlinkV1RandProvider
. This could not be done because the waitingForSeed
is stuck in true
state.
vscode
Remove if (gobblerRevealsData.waitingForSeed) revert SeedPending();
in upgradeRandProvider
(https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/ArtGobblers.sol/#L562)
Other option is to add a delay (24 hours for example), after which random provider can be upgraded, even if gobblerRevealsData is waiting for a seed.
#0 - Shungy
2022-09-27T17:46:00Z
Duplicate: https://github.com/code-423n4/2022-09-artgobblers-findings/issues/279 Potentially duplicate: https://github.com/code-423n4/2022-09-artgobblers-findings/issues/351
#1 - GalloDaSballo
2022-09-29T21:29:44Z
🌟 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
claimGobbler - team needs to make 300 extra wallets to claim their tokens
Since claiming is for 1 gobbler for 1 address, then the team can only claim 1 gobbler to their cold wallet. This means the core team needs to create 300 wallet addresses and withdraw the gobblers separately.
This takes some gas and considerable human effort and adds security risk with management for this amount of wallets.
You could also consider creating a for loop to retrieve all of the gobblers in a single function call.
consider adding update Chainlink fee method
Currently fee is fixed. If Chainlink changes their fee, then the randomness request could possibly fail. You would need to deploy a new RandomProvider.
VRF1 is deprecated
According to https://docs.chain.link/docs/vrf/v1/security/, the VRF1 is deprecated, meaning VRF2 should be preferred.
Art Gobblers uses V1.
Deprecated products are more likely to be discontinued. This does not seem like a big problem because you can update your random provider.
disable PagesERC721.approve/setApprovalForAll
, since it is not used in the transferFrom function
If you approve an NFT spender, you should be able to transfer the token. However, in transferFrom
, the function will revert, because it checks only owner, not approval.
function transferFrom( address from, address to, uint256 id ) public { require(from == _ownerOf[id], "WRONG_FROM");
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/utils/token/PagesERC721.sol/#L103
setApprovalForAll
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/utils/token/PagesERC721.sol/#L94
also in ArtGobblers
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/ArtGobblers.sol/#L885
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/ArtGobblers.sol/#L733
However, if you disable the setApprovedForAll
, then you would remove a possibility where users would delegate their art. For instance they could delegate their Pages NFT to a DAO, which would then gobble them.
This is currently impossible, because you check mg.sender
in the gobble()
function. To enable this kind of NFT delegation, you would need to check the approval here as well.
function gobble() external { // The caller must own the gobbler they're feeding. if (owner != msg.sender) revert OwnerMismatch(owner);
https://github.com/code-423n4/2022-09-artgobblers/blob/main/src/ArtGobblers.sol/#L733
disable gobbling of ERC1155
Pages are ERC721. There is no obvious reason to allow gobbling of ERC1155.
#0 - GalloDaSballo
2022-10-06T19:27:36Z
Teams has the reserve
Good idea but I think it's invalid as there's a wrapper contract that enables dealing with it
See above
R
R
I'd assume if they wanted to force only gobbling of pages, they'd hardcode the address
Neat report with good intentions, lacks nuance and more findings, good start
#1 - GalloDaSballo
2022-10-06T19:27:43Z
2R