OrderBook

First Flight #43
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Lack of Price Slippage Protection

Summary

The OrderBook contract allows buyers to execute orders without slippage protection, which could lead to unexpected price disparities in volatile markets.

Description

In traditional order book systems, especially those dealing with volatile assets like cryptocurrencies, slippage protection is crucial to ensure that trades execute at prices close to what users expect. The current implementation of the buyOrder function lacks any mechanism for slippage protection, meaning buyers are forced to accept the exact price set by the seller when the order was created, regardless of market conditions at the time of execution. This becomes problematic in volatile markets where token prices can change rapidly. A buyer might initiate a transaction to purchase an order, but by the time the transaction is mined, the market price of the token could have changed significantly. Without slippage protection, the buyer has no way to specify a maximum price they are willing to pay, potentially leading to trades executing at unfavourable prices.

Step-by-step analysis

  1. A seller creates a sell order with a specific price in USDC.

  2. Market conditions change, causing the actual value of the token to differ from the order price.

  3. A buyer decides to purchase the order, but has no mechanism to specify a maximum slippage they are willing to accept.

  4. If market conditions are unfavourable, the buyer might end up paying significantly more than the current market value.

Severity classification

  • Impact: Medium - Buyers could execute trades at unfavourable prices, but the exact price is known before execution.

  • Likelihood: Medium - Market conditions frequently change rapidly in cryptocurrency markets, making price disparities common.

File name with issue

OrderBook.sol

Code with issue

function buyOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
// Validation checks
if (order.seller == address(0)) revert OrderNotFound();
if (!order.isActive) revert OrderNotActive();
if (block.timestamp >= order.deadlineTimestamp) revert OrderExpired();
order.isActive = false;
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION;
uint256 sellerReceives = order.priceInUSDC - protocolFee;
iUSDC.safeTransferFrom(msg.sender, address(this), protocolFee);
iUSDC.safeTransferFrom(msg.sender, order.seller, sellerReceives);
IERC20(order.tokenToSell).safeTransfer(msg.sender, order.amountToSell);
totalFees += protocolFee;
emit OrderFilled(_orderId, msg.sender, order.seller);
}

Recommendation

Implement a slippage protection mechanism in the buyOrder function that allows buyers to specify a maximum price they are willing to pay. This will prevent trades from executing at unfavourable prices due to market volatility.

Code to fix the problem

function buyOrderWithSlippage(uint256 _orderId, uint256 _maxPriceInUSDC) public {
Order storage order = orders[_orderId];
// Validation checks
if (order.seller == address(0)) revert OrderNotFound();
if (!order.isActive) revert OrderNotActive();
if (block.timestamp >= order.deadlineTimestamp) revert OrderExpired();
if (order.priceInUSDC > _maxPriceInUSDC) revert("Price exceeds maximum acceptable price");
order.isActive = false;
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION;
uint256 sellerReceives = order.priceInUSDC - protocolFee;
iUSDC.safeTransferFrom(msg.sender, address(this), protocolFee);
iUSDC.safeTransferFrom(msg.sender, order.seller, sellerReceives);
IERC20(order.tokenToSell).safeTransfer(msg.sender, order.amountToSell);
totalFees += protocolFee;
emit OrderFilled(_orderId, msg.sender, order.seller);
}

The proposed fix adds a new function buyOrderWithSlippage that includes a parameter for the maximum price the buyer is willing to pay. The function checks that the order's price does not exceed this maximum before executing the trade. This allows buyers to protect themselves from unfavourable price movements.

Updates

Lead Judging Commences

yeahchibyke Lead Judge
4 months ago
yeahchibyke Lead Judge 4 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.