Description:
The EggVault
contract allows players to deposit their NFTs using the depositEggToVault()
function, which first transfers the NFT to the vault and then calls depositEgg()
to register the deposit. However, there is a time window between the transfer and the registration in which an attacker may execute a transaction before the legitimate user completes the deposit.
This behavior creates a race condition, where an attacker can observe the NFT being transferred and front-run the deposit by calling depositEgg()
first, registering the NFT as their own. This allows the attacker to later withdraw the NFT, bypassing the ownership logic and violating user trust.
This vulnerability could be easily exploited by an automated bot that scans the mempool for NFT transfers to the EggVault contract. Upon detection, the bot can issue a high-priority transaction (with more gas) to front-run the user and falsely claim ownership of the token.
Impact:
Identity spoofing risk
: An attacker can falsely claim an NFT as their own without ever owning or transferring it.
Loss of asset ownership
: The attacker can withdraw an NFT they never deposited, leading to an unexpected and deceptive interaction with the system.
User confusion and trust loss
: The legitimate owner may lose access to their NFT, leading to frustration and lack of confidence in the contract’s integrity.
Proof of Concept:
In this test, alice
transfers the NFT manually to simulate a vulnerable scenario where an attacker front-runs the registration process.
Result:
Tools Used:
Manual review, Foundry
Recommended Mitigation:
To prevent unauthorized actors from registering NFTs as their own, it is recommended to restrict access to the EggVault::depositEgg
function, ensuring that only the trusted game contract (EggHuntGame)
can call it. This eliminates the race condition that allows attackers to front-run legitimate deposits.
The following code modification introduces a modifier that verifies the caller’s authenticity, and ensures that only the game contract can register deposited NFTs:
Additional note
: The depositEgg function is currently declared as public without being used internally. This unnecessarily exposes the function to arbitrary external calls. While this detail is already covered by the front-running vulnerability described earlier, it is highlighted here as an additional security and design improvement.
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.