NFT Dealers

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

updatePrice() breaks MIN_PRICE invariant allowing invalid underpriced listings

Author Revealed upon completion

Root + Impact

updatePrice() does not enforce MIN_PRICE, allowing sellers to bypass protocol pricing constraints and create invalid listings below the minimum threshold.


Description

The normal behavior of the protocol enforces a minimum listing price (MIN_PRICE) when a seller creates a listing, ensuring that all NFTs are listed above a predefined economic threshold.

However, the updatePrice() function does not enforce this same constraint. As a result, a seller can first create a valid listing and then update its price to a value below MIN_PRICE, breaking a core protocol invariant and bypassing intended economic rules.

function updatePrice(uint256 _listingId, uint32 _newPrice) external {
Listing storage listing = s_listings[_listingId];
require(msg.sender == listing.seller, "Not seller");
require(listing.isActive, "Listing not active");
@> listing.price = _newPrice; // Missing validation: _newPrice >= MIN_PRICE
}

Risk

Likelihood: High

  • Sellers frequently adjust listing prices after creation as part of normal marketplace behavior

  • The function is permissionless for the seller and does not include any constraint on the new price


Impact: Medium

  • Sellers can bypass the minimum price restriction, violating protocol rules and assumptions

  • Market integrity is degraded, and external integrations (frontends, bots, indexers) may rely on incorrect assumptions about valid pricing


Proof of Concept

// Assume MIN_PRICE = 100
// Step 1: Create a valid listing
nftDealers.createListing(tokenId, 100);
// Step 2: Update price below minimum
nftDealers.updatePrice(listingId, 1);
// Step 3: Listing remains active with invalid price
// Invariant broken: price < MIN_PRICE

Recommended Mitigation

Add a validation to enforce the minimum price constraint during updates:

require(_newPrice >= MIN_PRICE, "Price below minimum");

Updated function:

function updatePrice(uint256 _listingId, uint32 _newPrice) external {
Listing storage listing = s_listings[_listingId];
require(msg.sender == listing.seller, "Not seller");
require(listing.isActive, "Listing not active");
require(_newPrice >= MIN_PRICE, "Price below minimum");
listing.price = _newPrice;
}

Support

FAQs

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

Give us feedback!