Eggstravaganza

First Flight #37
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: medium
Invalid

Reentrancy Risk in depositEggToVault()

Summary

The depositEggToVault() function in the EggHuntGame contract performs two external calls: one to transfer the NFT (transferFrom) and another to the external eggVault.depositEgg() function. These calls are performed sequentially without any reentrancy protection or internal state updates between them. This exposes the function to potential reentrancy vulnerabilities, especially if the eggVault contract or the NFT contract is upgraded or extended in the future.

Vulnerability Details

The function depositEggToVault() performs the following operations:

eggNFT.transferFrom(msg.sender, address(eggVault), tokenId);
eggVault.depositEgg(tokenId, msg.sender);

While currently neither EggstravaganzaNFT nor EggVault implements reentrant behavior, this pattern is dangerous:

  • eggNFT.transferFrom(...) may trigger onERC721Received() if the token is upgraded to be ERC721-compliant with a receiver hook.

  • eggVault.depositEgg(...) is a public, externally callable function that updates vault state based on caller-supplied input.

If a malicious contract owns an NFT and calls depositEggToVault(), it could attempt to re-enter the same function (or another sensitive one) via callback mechanisms — leading to inconsistent states, multiple deposits, or unauthorized actions, depending on how eggVault evolves.

This is a textbook violation of the checks-effects-interactions pattern and lacks protective measures like nonReentrant.

Impact

May lead to:

  • Reentrancy attacks

  • Double deposits

  • Inconsistent vault state

  • Stolen or misrecorded NFTs if not properly guarded

Tools Used

  • Manual code review

  • Pattern analysis based on known Solidity reentrancy issues

Recommendations

Add Reentrancy Protection: Inherit from OpenZeppelin's ReentrancyGuard and mark depositEggToVault() as nonReentrant:

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract EggHuntGame is Ownable, ReentrancyGuard {
function depositEggToVault(uint256 tokenId) external nonReentrant {...}
}
Updates

Lead Judging Commences

m3dython Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.