Eggstravaganza

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

Possible state inconsistency in `EggVault::withdrawEgg`, leading to NFT loss

Summary

In the EggVault::withdrawEgg function, there is a change in state made before an external call EggstravaganzaNFT::transferFrom. This can result in an inconsistent state if the call runs out of gas or reverts after the state is changed but before the external call.

Vulnerability Details

If the call runs out of gas once the state has been changed, but before the call to EggstravaganzaNFT::transferFrom, this can lead to a state inconsistency.

/// @notice Allows the depositor to withdraw their egg from the vault.
function withdrawEgg(uint256 tokenId) public {
require(storedEggs[tokenId], "Egg not in vault");
require(eggDepositors[tokenId] == msg.sender, "Not the original depositor");
storedEggs[tokenId] = false;
delete eggDepositors[tokenId];
/// Fails here.
eggNFT.transferFrom(address(this), msg.sender, tokenId);
emit EggWithdrawn(msg.sender, tokenId);
}

This will result in storedEggs[tokenId] = false and deletion of the mapping eggDepositors[tokenId] but the NFT not being transferred, leading to the loss of the NFT as subsequent calls to EggVault::withdrawEgg will revert on require(storedEggs[tokenId], "Egg not in vault");.

Impact

Loss of Player NFT.

Tools Used

Manual review.

Recommendations

Change the state only if the external call is successful:

/// @notice Allows the depositor to withdraw their egg from the vault.
function withdrawEgg(uint256 tokenId) public {
require(storedEggs[tokenId], "Egg not in vault");
require(eggDepositors[tokenId] == msg.sender, "Not the original depositor");
// Attempt the transfer first
try eggNFT.transferFrom(address(this), msg.sender, tokenId) {
// Only update state if the transfer succeeded
storedEggs[tokenId] = false;
delete eggDepositors[tokenId];
emit EggWithdrawn(msg.sender, tokenId);
} catch {
revert("Egg transfer failed");
}
}
Updates

Lead Judging Commences

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

Support

FAQs

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

Give us feedback!