NFT Dealers

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

Lack of Slippage Protection in `buy` function

Author Revealed upon completion

Root + Impact

Description

  • Normal Behavior: When a buyer initiates a transaction to purchase an NFT, they expect to pay the price that was displayed to them at the time of the call.


  • Specific Issue: The buy function does not include a maximum price parameter or a slippage check. Since the updatePrice function allows a seller to change the price of an active listing at any time, a malicious seller can observe a pending buy transaction in the mempool and front-run it by calling updatePrice to significantly increase the cost.

@> function buy(uint256 _listingId) external payable {...}

Risk

Likelihood: High

  • Reason 1: Transaction front-running is a common attack vector on public blockchains.

  • Reason 2: Sellers have a direct financial incentive to increase the price when they see a guaranteed buyer.

Impact: Medium

  • Impact 1: Financial Loss. Buyers may end up paying significantly more USDC than they intended.

  • Impact 2: Trust Erosion. Users may be hesitant to use a marketplace where prices can be manipulated during the "checkout" process.

Proof of Concept

function test_NoSlippageProtection() public revealed {
uint256 tokenId = 1;
uint32 initialPrice = 10e6;
uint32 newPrice = 100e6;
mintAndListNFTForTesting(tokenId, initialPrice);
address randomUser = makeAddr("randomUser");
deal(address(usdc), randomUser, 100e6);
// Before user could finish buy tx, price gets updated
vm.prank(userWithCash);
nftDealers.updatePrice(tokenId, newPrice);
vm.prank(randomUser);
usdc.approve(address(nftDealers), 100e6);
vm.prank(randomUser);
nftDealers.buy(tokenId);
assertEq(usdc.balanceOf(randomUser), 0, "Price Changed before user could finish tx");
}

Recommended Mitigation

Add a maxPrice parameter to the buy function and verify that the current listing price does not exceed it.

Support

FAQs

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

Give us feedback!