Game owner calling EggVault::setEggNFT to set new egg NFT address will overwrite EggVault::engNFT with the new egg NFT address. When players with existing eggs in the EggVault calls EggVault::withdrawEgg, the function attempts to withdraw the new egg NFTs (which does not exist) instead of the old egg NFT, and will revert with ERC721NonexistentToken(<tokenId>). Hence, players with existing eggs in the EggVault will be unable to withdraw thier eggs.
After game owner calls EggVault::setEggNFT to set new egg NFT address, the NFT address state variable EggVault::eggNFT will be overwritten with the new egg NFT address. As such, no functions of the old egg NFT can be called within the EggVault. Hence, all old egg NFTs held within the vault cannot be withdrawn from the EggVault.
Additionally, when a player that has existing eggs in the EggVault tries to call EggVault::withdrawEgg, the function calls eggNFT.transferFrom on #L45. This will attempt to transfer the new egg NFT to the player instead of the old egg NFT. However, the NFT does not exist, hence, the call will revert with ERC721NonexistentToken(<tokenId>)
Impact: High, player's eggs are locked in EggVault and unable to be withdrawn
Likelihood: Low, game owner is trusted
Severity: Medium
Place the following code into EggHuntGameTest.t.sol and run using:
forge test --mt testSetEggNFTBreaksVaultWithdrawal
Manual review
Consider removing the EggVault::setEggNFT function
Changing the NFT contract address doesn't update the storedEggs and eggDepositors mappings
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.