The buyOrder function does not have a refund mechanism in place in case of a failure after receiving Ether but before completing the token transfer.
If the transfer to the seller or the owner fails, the Ether is not refunded to the user.
This results in loss of funds for the buyer, even if the order is not completed successfully.
This results in loss of funds for the buyer, even if the order is not completed successfully.
Introduce a refund mechanism to ensure that the user gets their Ether back in case of a failure during the transaction process.
function buyOrder(uint256 orderIndex, address seller) external payable {
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();
}
uint256 buyerRefundAmount = msg.value;
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);
(bool success, ) = payable(order.seller).call{value: (order.price - sellerFee)}("");
if (!success) {
revert TokenDivider__TransferFailed();
}
(bool taxSuccess, ) = payable(owner()).call{value: fee}("");
if (!taxSuccess) {
revert TokenDivider__TransferFailed();
}
bool tokenSuccess = IERC20(order.erc20Address).transfer(msg.sender, order.amount);
if (!tokenSuccess) {
payable(msg.sender).transfer(buyerRefundAmount);
revert TokenDivider__TokenTransferFailed();
}
}