The EggstravaganzaNFT contract lacks validation to ensure token ID uniqueness during minting. Combined with the EggHuntGame’s reliance on a non-persistent eggCounter, this allows attackers to mint duplicate token IDs, overwriting existing NFTs and transferring ownership illegitimately.
Attack Vector: Exploitation of non-unique token ID generation.
Flawed Token ID Management in EggHuntGame:
The game contract uses a simple eggCounter to assign token IDs:
eggCounter++;
eggsFound[msg.sender] += 1;
eggNFT.mintEgg(msg.sender, eggCounter);
If the counter resets (e.g., after a game restart) or is reused, duplicate IDs are generated.
Missing Uniqueness Check in EggstravaganzaNFT:
The mintEgg() function does not validate if a token ID already exists:
function mintEgg(address to, uint256 tokenId) external returns (bool) {
require(msg.sender == gameContract, "Unauthorized minter");
_mint(to, tokenId); // No check for existing tokenId
totalSupply += 1;
return true;
}
NFT Theft: Attackers can mint tokens with IDs matching existing ones, overwriting ownership and stealing assets.
Permanent Asset Loss: Legitimate owners lose access to their NFTs without recourse, as the overwrite is irreversible.
Manual Code Review
Enforce Token ID Uniqueness
function mintEgg(address to, uint256 tokenId) external returns (bool) {
require(msg.sender == gameContract, "Unauthorized minter");
require(!_exists(tokenId), "Token ID already exists"); // Add uniqueness check
_mint(to, tokenId);
totalSupply += 1;
return true;
}
Use Non-Resettable Token ID Generation
// Store eggCounter in persistent storage
uint256 private _persistentEggCounter;
function searchForEgg() external {
// ...
_persistentEggCounter++;
eggNFT.mintEgg(msg.sender, _persistentEggCounter);
}
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.