The EggVault::depositEgg()
function lacks access control, allowing anyone to mark an NFT as "deposited" if it has been transferred to the vault. This enables malicious actors to steal deposited NFTs by front-running legitimate deposits or exploiting direct transfers to the vault.
Location:
EggVault::depositEgg(uint256 tokenId, address depositor)
Attack Scenarios:
Front-Running Legitimate Deposits
A user approves and calls EggHuntGame::depositEggToVault(tokenId)
.
An attacker monitors the mempool, sees the pending transferFrom
, and front-runs it with their own depositEgg(tokenId, attackerAddress)
.
The attacker becomes the "depositor" and can later withdraw the NFT.
Direct Transfer Exploit
If a user accidentally (or intentionally) sends an NFT directly to the vault via transferFrom(user, vault, tokenId)
, anyone can call depositEgg()
to claim ownership.
Root Cause:
The function does not verify if the caller is authorized EggHuntGame
contract.
It only checks if the NFT is in the vault (eggNFT.ownerOf(tokenId) == address(this)
), which is insufficient for security.
Loss of NFTs for legitimate users since attackers can irreversibly claim deposited NFTs.
Manual Review: Identified missing access control.
####*1. Restrict depositEgg
to EggHuntGame
Only
Add a modifier to ensure only the game contract can call depositEgg
:
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.