The mintEgg()
function in the EggstravaganzaNFT contract allows the authorized game contract to mint NFTs with arbitrary token IDs. However, the function lacks a check to prevent duplicate token IDs. If the game contract is buggy or compromised, it could mint a token ID that already exists, violating ERC721 invariants and breaking core assumptions in wallets, marketplaces, and dapps.
The mintEgg()
function is restricted to be callable only by the gameContract
:
However, there is no check to ensure the tokenId
is unique before minting. While the current game implementation (EggHuntGame
) increments the tokenId
with each mint, nothing in the NFT contract enforces this.
If a malicious or misconfigured gameContract
bypasses eggCounter
and uses arbitrary token IDs, it may succeed in minting overlapping or unordered tokens unless _exists()
is manually checked.
Token ID collisions can:
Cause ownerOf()
and tokenURI()
to behave inconsistently.
Break compatibility with ERC721 indexers and wallets.
Lead to unexpected reverts, loss of access, or game logic inconsistencies.
Attackers (or bugs) could attempt to re-mint an already distributed token, undermining uniqueness guarantees.
Manual code review
ERC721 standard invariants
Add an _exists(tokenId)
check to ensure token ID uniqueness:
This ensures any contract calling mintEgg()
cannot accidentally or maliciously re-mint an existing NFT.
Setup Steps
Deploy EggstravaganzaNFT
, mint a token via the legitimate game contract with token ID 1
.
Use setGameContract(...)
to assign MaliciousGame
as the new game contract.
Call reMintExistingEgg(...)
with token ID 1
.
Result
Without a _exists()
check, mintEgg()
reverts internally. This can:
Cause game or frontend errors
Be exploited for denial-of-service scenarios
Create ambiguity in token lifecycle guarantees
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.