Pieces Protocol

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

Reentrancy risk in buyOrder function

Summary

buyOrder function is prone to a reentrancy attack

Vulnerability Details

The buyOrder function transfers Ether before updating the state

Impact

Reentrancy attacks can exploit this

Tools Used

Github Copilot

Recommendations

Rewrite the function using the CEI pattern

function buyOrder(uint256 orderIndex, address seller) external payable nonReentrant {\
if (seller == address(0)) {\
revert TokenDivider\_\_InvalidSeller();\
}
SellOrder memory order = s_userToSellOrders[seller][orderIndex];
if (msg.value < order.price) {
revert TokenDivider__IncorrectEtherAmount();
}
uint256 fee = order.price / 100;
uint256 sellerFee = fee / 2;
if (msg.value < order.price + sellerFee) {
revert TokenDivider__InsuficientEtherForFees();
}
// Update state before external calls
balances[msg.sender][order.erc20Address] += order.amount;
s_userToSellOrders[seller][orderIndex] = s_userToSellOrders[seller][
s_userToSellOrders[seller].length - 1
];
s_userToSellOrders[seller].pop();
emit OrderSelled(msg.sender, order.price);
// Transfer The Ether
(bool success, ) = payable(order.seller).call{
value: (order.price - sellerFee)
}("");
require(success, "Transfer to seller failed");
(bool taxSuccess, ) = payable(owner()).call{value: fee}("");
require(taxSuccess, "Transfer to owner failed");
IERC20(order.erc20Address).transfer(msg.sender, order.amount);
}
Updates

Lead Judging Commences

fishy Lead Judge 8 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Reentrancy

Appeal created

fishy Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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