The protocol assumes that if a listing is inactive, it must have been sold. However, the cancelListing function also sets isActive to false.
Normal Behavior: A user should cancel a listing to retrieve their locked collateral. They should only be able to collect a "sale price" if a buyer has actually transferred USDC into the contract for that specific listing.
Specific Issue: The collectUsdcFromSelling function does not verify how the listing became inactive. It simply checks !listing.isActive. A malicious user can list an NFT for a high price, immediately cancel it, and then call collectUsdcFromSelling to claim that high price from the protocol's global USDC pool (fees or other users' collateral).
Likelihood: High
Any user can perform this attack at any time.
It requires no external buyer or market activity.
Impact: High
Direct theft of protocol funds.
Paste this test function in NFTDealersTest.t.sol
The contract needs a way to distinguish between a Sold state and a Canceled state. You can add an isSold boolean to the Listing struct or use an enum for Status.
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.