Eggstravaganza

First Flight #37
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: medium
Invalid

NFT Overwrite/Theft

Summary

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.

Vulnerability Details

Attack Vector: Exploitation of non-unique token ID generation.

  1. 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.

  2. 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;
    }

Impact

  1. NFT Theft: Attackers can mint tokens with IDs matching existing ones, overwriting ownership and stealing assets.

  2. Permanent Asset Loss: Legitimate owners lose access to their NFTs without recourse, as the overwrite is irreversible.

Tools Used

Manual Code Review

Recommendations

  1. 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;
    }

  2. Use Non-Resettable Token ID Generation

    // Store eggCounter in persistent storage
    uint256 private _persistentEggCounter;

    function searchForEgg() external {
    // ...
    _persistentEggCounter++;
    eggNFT.mintEgg(msg.sender, _persistentEggCounter);
    }

Updates

Lead Judging Commences

m3dython Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!