The EggVault
contract implements a mutable reference to the EggstravaganzaNFT
contract via the setEggNFT
function, which allows the owner to change the NFT contract address at any time without proper safeguards or migration mechanisms. This creates a risk of user assets becoming permanently inaccessible.
The setEggNFT
function allows the owner to change the NFT contract address without any restrictions:
The vulnerability stems from the vault's state management design. The contract maintains mappings (storedEggs
and eggDepositors
) that track deposited NFTs by their token IDs, but these mappings remain unchanged when the NFT contract reference is updated. This creates a critical state inconsistency between the vault's internal records and the actual NFT ownership. When users attempt to withdraw their NFTs after an address change, the withdrawEgg
function will attempt to transfer tokens from the new NFT contract, which either doesn't have those tokens or assigns them to different owners.
Users' deposited NFTs could become permanently locked in the vault
The withdrawal function will fail for all previously deposited NFTs
The system lacks synchronization between EggHuntGame and EggVault, creating a potential for permanent inconsistency
The interaction between EggHuntGame and EggVault would break, as EggHuntGame has no mechanism to update its reference to the NFT contract
Loss of user assets and trust in the platform
User A deposits an NFT (tokenId=1) into the vault
The owner changes the eggNFT address to a new contract
User A attempts to withdraw their NFT
The withdrawal fails because:
The vault tries to transfer tokenId=1 from the new NFT contract
The new contract either doesn't have tokenId=1 or it belongs to a different user
The NFT remains locked in the vault with no way to retrieve it
While restoring the original NFT address would make previously deposited NFTs accessible again (as failed withdrawal attempts revert the entire transaction), this depends on the owner's ability to recognize and rectify the issue promptly
Manual review
Make the eggNFT address immutable after deployment to prevent any possibility of address changes:
If address changes must be supported, implement a proper migration mechanism:
Add a timelock for address changes to give users time to withdraw assets
Implement a function to migrate all deposited NFTs to the new contract
Create an emergency withdrawal function that works regardless of the current NFT address
Add version control and compatibility checks:
Track NFT contract versions
Ensure new contracts maintain backward compatibility
Implement a coordinated upgrade process across all related contracts
Add circuit breakers:
Implement a pause mechanism to halt deposits during migration
Add an emergency mode that allows only withdrawals during critical issues
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.