Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Invalid

Incorrect msg.value check in buyOrder() leading to potential transaction reverts

Summary

The buyOrder() function does not correctly handle the msg.value check, potentially causing the transaction to revert if the buyer sends sufficient ETH to cover the price and seller's fee, but not the tax fee.

Vulnerability Details

Link : https://github.com/Cyfrin/2025-01-pieces-protocol/blob/4ef5e96fced27334f2a62e388a8a377f97a7f8cb/src/TokenDivider.sol#L278

In the buyOrder function, the following check is used:

if(msg.value < order.price + sellerFee) {
revert TokenDivider__InsuficientEtherForFees();
}

However, this check is incorrect because in the protocol the seller pays the fee for selling the NFT which is a common practice in marketplaces where sellers bear a portion of the transaction costs.

(bool successToSeller, ) = payable(order.seller).call{value: (order.price - sellerFee)}("");

Link: https://github.com/Cyfrin/2025-01-pieces-protocol/blob/4ef5e96fced27334f2a62e388a8a377f97a7f8cb/src/TokenDivider.sol#L292

The tax fee ( 1% of the price ), which is transferred to the contract owner, is not included in the check.

Impact

  • If the buyer sends enough ETH to cover the price and seller’s fee, but not the tax fee, the transaction will fail, causing the buyer to be unable to purchase the item, even though they have provided enough ETH for the item and seller’s share.

  • This behavior can negatively impact user experience, as buyers may be unaware of the exact amount needed, leading to failed transactions and confusion.

Tools Used

  • Manual review

Recommendations

Modify the if condition to ensure that the buyer sends enough ETH to cover both the price and the tax fee (but not the seller's fee, which is deducted later => seller pays for it).

function buyOrder(uint256 orderIndex, address seller) external payable {
...
uint256 fee = order.price / 100;
uint256 sellerFee = fee / 2;
- if(msg.value < order.price + sellerFee) {
+ if(msg.value < order.price + fee) {
revert TokenDivider__InsuficientEtherForFees();
}
...
}
Updates

Lead Judging Commences

fishy Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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