Pieces Protocol

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

Buy orders vulnerable to front-running attacks

Summary:

The contract is vulnerable to front-running attacks when users attempt to buy orders, potentially leading to failed transactions and gas waste.

Vulnerability Details:

The buyOrder function does not implement any protection mechanisms against front-running attacks. An attacker can observe a buy order transaction, submit their own transaction with higher gas, and successfully buy the order before the original transaction is processed. As a result, the original transaction will fail, wasting gas and potentially causing frustration for the user.

Test Proof:

function testFrontRunningBuyOrder() public nftDivided {
ERC20Mock erc20Mock = ERC20Mock(tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address);
address attacker = makeAddr("attacker");
vm.deal(attacker, STARTING_USER_BALANCE);
vm.deal(USER2, STARTING_USER_BALANCE);
vm.startPrank(USER);
erc20Mock.approve(address(tokenDivider), AMOUNT);
tokenDivider.sellErc20(address(erc721Mock), 1 ether, 1e18);
vm.stopPrank();
uint256 fee = 1 ether / 100;
uint256 sellerFee = fee / 2;
uint256 totalRequired = 1 ether + sellerFee;
vm.startPrank(USER2);
uint256 user2Value = totalRequired;
uint256 orderIndex = 0;
address seller = USER;
vm.stopPrank();
vm.prank(attacker);
tokenDivider.buyOrder{value: totalRequired}(orderIndex, seller);
assertEq(tokenDivider.getBalanceOf(attacker, address(erc20Mock)), 1e18);
vm.expectRevert();
vm.prank(USER2);
tokenDivider.buyOrder{value: user2Value}(orderIndex, seller);
}

Impact:

This issue can lead to failed transactions and gas waste for users attempting to buy orders. This can be a significant concern for users who may lose confidence in the contract due to the unpredictability and additional costs associated with front-running attacks.

Tools Used:

Solidity, Foundry

Recommendations:

To address this issue, implement a protection mechanism against front-running attacks. One possible solution is to use a commit-reveal scheme, where users first commit to buying an order by providing the necessary information (e.g., order index, price, and their address) and then later reveal their commitment. The contract can then process the commitments in the order they were received, preventing front-running attacks.

Another solution is to use a batch processing mechanism, where the contract collects buy orders for a certain period (e.g., a few seconds) and then processes them in the order they were received. This can help prevent front-running attacks by ensuring that all buy orders are processed fairly and in the order they were submitted.

Updates

Lead Judging Commences

fishy Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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