NFT Dealers

First Flight #58
Beginner FriendlyFoundry
100 EXP
Submission Details
Impact: medium
Likelihood: medium

ETH can be permanently locked in payable functions

Author Revealed upon completion

Because mintNft() and buy() are payable but never handle msg.value and there’s no ETH withdrawal function, any ETH sent to them gets permanently stuck in the contract.


Description

  • Behavior:
    mintNft() and buy() should only transfer USDC and mint/transfer NFTs, without accepting or holding ETH.

  • Issue:
    Both functions are marked payable, but the contract never uses msg.value and provides no ETH withdrawal path, so any ETH sent is permanently locked.

@> function mintNft() external payable onlyWhenRevealed onlyWhitelisted {
...
}
@> function buy(uint256 _listingId) external payable {
...
}

Risk

Likelihood:

  • Reaon 1: Occurs when users or integrators send ETH alongside mintNft() or buy() by mistake, since the functions are payable and accept value.

  • Reason 2: Occurs during UI or script usage that forwards a default value amount, causing ETH to be sent even though the contract never handles it

Impact:

  • Impact 1: Users permanntly lose any ETH accidentally sent to mintNft() or buy().

  • Impact 2: The protocol can’t recover or refund those funds because there is no ETH withdrawal path.

Proof of Concept

/*
PoC Activities :
1) Slither (trailofbits/eth-security-toolbox): ran static analysis on src/NFTDealers.sol and flagged locked-ether.
2) Foundry (via Slither): compiled the project during analysis.
3) Manual review: confirmed mintNft() and buy() are payable, msg.value is unused, and no ETH withdraw path exists.
4) PoC transaction: sent ETH to mintNft() or buy() and verified ETH remains stuck in the contract.
*/

Recommended Mitigation

Remove payable from both functions:
- function mintNft() external payable onlyWhenRevealed onlyWhitelisted {
+ function mintNft() external onlyWhenRevealed onlyWhitelisted {
...
}
- function buy(uint256 _listingId) external payable {
+ function buy(uint256 _listingId) external {
...
}

Support

FAQs

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

Give us feedback!