buy() and mintNft() both accept ETH (payable) even though all payment flows use USDC exclusively. Neither function reads or refunds msg.value.
Any ETH sent alongside either call is accepted by the contract and becomes permanently inaccessible. There is no ETH withdrawal function anywhere in the contract.
Likelihood: Medium
Users who interact with NFT marketplaces often send ETH by habit or mistake, particularly when using wallets or scripts that do not distinguish between ETH- and ERC20-denominated purchases.
Front-end interfaces that do not explicitly zero value on the transaction can silently pass non-zero ETH.
Impact: Medium
Every ETH sent to buy() is permanently lost from the sender's perspective; the contract provides no way to recover it.
The owner also cannot retrieve trapped ETH: withdrawFees() only moves USDC.
A buyer sends 1 ETH alongside a USDC purchase. The buy completes successfully, the NFT is transferred, but the 1 ETH is now permanently held by the contract with no withdrawal path.
Remove payable from both buy() and mintNft(). Since neither function uses ETH, there is no reason to accept it. Accidental ETH sends will then revert immediately rather than being silently trapped.
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.
The contest is complete and the rewards are being distributed.