Description: A contestant calls EggHuntGame::depositEggToVault to deposit the egg they received from EggHuntGame::searchForEgg. EggHuntGame::depositEggToVault, in turn, transfers ownership of the egg NFT to the vault and then calls EggVault::depositEgg. Since EggVault::depositEgg doesn't have proper access checking, this transaction is susceptible to an MEV front-run attack and the depositor's address can be replaced with the attacker's address in the second parameter of the call to EggVault::depositEgg.
Impact: An attacker can steal any egg being deposited in the vault.
Proof of Concept:
When a victim calls EggHuntGame::depositEggToVault, that function will call EggVault::depositEgg. When this transaction appears in the mempool, an attacker can:
See that the game contract is calling EggVault::depositEgg with a specific token id and the depositor address (victim).
Copies the game contract's transaction and changes the depositor address in depositEgg(uint256 tokenId, address depositor) to their own address.
Front-runs the game contract's transaction by submitting the altered transaction with a higher gas price.
Effectively, steals the credit for the egg deposit.
Add the following unit test to EggHuntGameTest.t.sol:
Run the unit test: forge test --mt testMEVAttackDepositEgg
Recommended Mitigation:
Combine the NFT transfer and deposit registration into a single atomic transaction in EggVault::depositEgg.
RemoveeggNFT.transferFrom from EggHuntGame::depositEggToVault and add it EggVault::depositEgg.
Remove address depositor from EggVault::depositEgg.
Replace all references to depositor to msg.sender.
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.