When an NFT is sold, its status in the listing is set to false; at that point, the seller can call collectUsdcFromSelling() to receive their previous collateral and the sale proceeds.
In the collectUsdcFromSelling function, it only checks if the current listing.isActive is false; only inactive listings can proceed with subsequent operations. Currently, besides the selling operation which sets listing.isActive to false, the cancelListing operation also sets listing.isActive to false. This presents a problem: the seller can actively cancel the listing and
collectUsdcFromSelling does not restrict usage to only newly sold NFTs awaiting collection, allowing cancelListed NFTs to also be used for collection, ultimately leading to financial losses.
Likelihood:
The likelihood of this vulnerability being exploited is High because this vulnerability can be exploited as long as the seller has unactivated NFTs.
Impact:
In this collectUsdcFromSelling vulnerability, an attacker can exploit it to steal all the funds held in the contract. This results in the collateral provided by all whitelisted users when minting NFTs being emptied, and the funds being stolen. Furthermore, after the seller receives payment, s_listings[_listingId].seller is not updated to reflect the new buyer. This prevents all subsequent sellers from receiving payment, while the original seller can withdraw funds indefinitely. This poses a significant obstacle to both finances and business operations.
Simulate two whitelisted users (one of whom is an attacker who is also a whitelisted user), mint NFTs, and list them for sale. This ensures the contract has collateralized assets. In a real attack, the attacker would monitor the contract's asset situation in real-time. Our Proof of Concept (POC) simulates this here.
The attacker lists an NFT and sets a price.
The attacker delists this NFT, making it inactive.
Based on the contract's balance, the attacker repeatedly calls collectUsdcFromSelling, continuously stealing (collateral + product profit - fees) from the platform until the contract can no longer pay related fees.
Add a state to the list. After a buyer purchases the item, set sellerConfirmation to true. This indicates that the seller needs to confirm and collect payment.
In collectUsdcFromSelling, add a check to see if sellerConfirmation is true. If it is not true, it means the NFT has not been sold yet and the payment collection operation should not be performed.
At the same time, update listing.seller to the most recent buyer's account, indicating that the ownership has been transferred.
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.