The EggVault::depositEgg function allows any address to claim ownership of deposited NFTs by setting themselves as the depositor, enabling theft of NFTs that have been transferred to the vault.
The depositEgg function is public and accepts an arbitrary depositor address without any access control or verification:
The function only checks that:
The NFT is owned by the vault
The NFT hasn't already been deposited
It does not verify who is calling the function or that the depositor parameter is legitimate. This allows anyone to claim ownership of an NFT that has been transferred to the vault but not yet registered in the storedEggs mapping.
Alice calls EggHuntGame::depositEggToVault(tokenId) to deposit her NFT
The function transfers the NFT to the vault and then calls eggVault.depositEgg(tokenId, msg.sender)
Mallory monitors the mempool and sees Alice's transaction
Mallory front-runs Alice's transaction with a direct call to eggVault.depositEgg(tokenId, mallory)
Mallory's transaction completes first, registering Mallory as the depositor
Alice's transaction fails with "Egg already deposited" error
Mallory can now call withdrawEgg(tokenId) to steal Alice's NFT
Allows theft of NFTs that have been transferred to the vault
Undermines the core security model of the vault system
Creates a race condition for depositing NFTs
Users could lose valuable assets
Manual code review
Implement proper access control on the depositEgg function:
Front-running depositEgg allows deposit ownership hijacking.
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.