The depositEgg()
function in the EggVault.sol contract is publically accessible and allow any caller to specify a depositor
address. This opens the contratc to a critical vulnerability where a malicious actor can hijack the depositor mapping and later withdraw the NFTs they do not own.
The function signature:
allows any caller to call the depositEgg() function with an arbitrary depositor address. The only validation performed is;
the above condition mererly verifies the NFT has been transferred to the EggVault contract but does not ensure that the depositor is the righgul owner or who transferred the NFT.
Attack Scenario:
A user transfers the NFT to the Vault contract.
Before they call the depositEgg()
, an attacker frontruns the transaction and calls-
depositEgg(uint256 tokenId, address attackerAddress)
Now the attacker has registered as the depositor.
Later, attacker can call the withdrawEgg(uint256 tokenId) function and takes the ownership of the NFT
High Severity
Complete loss of a token/NFT
Game integrity
The vulnerability is not mitigated by existing test cases
Manual code review
Logical simulation of race conditions and fron-running scenarios
Redesign the depositEgg()
function to enforce authorization:
Remove the depositor
paramater entirely
Use msg.sender
as the sole source of truth who is depositing the NFT
Perform the NFT transfer within the depositEgg()
function itself to enforce atomicity
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.