NFTDealers::collectUsdcFromSelling() does not consume the seller’s claim state for a sold listing, the same seller can repeatedly
withdraw the same payout from the contract.
The intended behavior is that once a listed NFT is sold, the seller should be able to collect the sale proceeds exactly once, receiving the sale amount minus fees plus any locked collateral tied to minting. After that payout is made, the listing should no longer allow further withdrawals.
The issue is that collectUsdcFromSelling() only verifies that the listing is inactive and that the caller is the recorded seller. It then recomputes the payout from listing.price and collateralForMinting[listing.tokenId], but it never marks the sale as claimed and never clears the collateral after paying it out. As a result, the seller can call the function again and receive the same payout multiple times as long as the contract still holds enough USDC.
Likelihood: High
The issue occurs after any successful sale.
The original seller remains permanently authorized to call the function, and no state change prevents repeated claims.
Impact: High
A seller can repeatedly withdraw the same sale proceeds and collateral, draining USDC held by the contract.
Each repeated claim also inflates totalFeesCollected, corrupting fee accounting.
The following test shows that after a successful sale, the seller can call collectUsdcFromSelling() multiple times for the same listing and receive the same payout each time.
Record that the seller has already claimed proceeds for a listing before transferring funds, and clear the collateral returned
as part of that payout so the same listing cannot be collected again.
collateral is not reset to zero after collecting USDC from sold NFT. No accounting for collected USDC
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.