OrderBook

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

[H-1] Sellers Can Buy Own Orders - Market Manipulation and Pump & Dump Attacks

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

## Summary
The OrderBook contract allows sellers to buy their own orders, enabling market manipulation
and pump & dump attacks. Attackers can create artificial trading volume and price movements
to trick other users into buying at inflated prices, leading to significant financial losses.
​
## Vulnerability Details
The `buyOrder()` function lacks a check to prevent sellers from purchasing their own orders:
​
​
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();
// MISSING: Check to prevent seller from buying own order
​
}
​
​
--Critical Issues:
- Sellers can buy their own orders to create fake volume
- Enables artificial price manipulation and pump & dump schemes
- Other users are tricked by fake buying pressure
- Classic market manipulation attack vector
​
## Impact
- Market manipulation: Artificial volume and price movements
- Pump & dump attacks: Attackers profit from inflated prices
- User deception: Other traders follow fake momentum
- Financial losses: Users buy at artificially inflated prices
- Protocol integrity: Compromises fair market operation
- Regulatory risk: Market manipulation is illegal in many jurisdictions
​
## Affected Functions
- `buyOrder()` - Lines 193-210 (missing self-buy prevention)

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Impact 2

Proof of Concept

# Proof of Concept
​
1. Attacker creates multiple sell orders at different price points
2. Attacker buys their own orders to create fake buying pressure
3. Other users see "volume" and "price movement"**
4. Users are tricked into buying at inflated prices
5. Attacker profits from the artificial price pump
​
## The Problem
​
No check prevents sellers from buying their own orders to manipulate the market:
​
​
// Lines 193-210: buyOrder()
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();
// Missing: if (order.seller == msg.sender) revert "Cannot buy own order";
// Attacker can buy their own orders to create fake volume
order.isActive = false;
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION; // 3% fee
// ... transfers happen
}
​
​
## Attack Scenario
​
- Attacker spends 1000 USDC on 33 fake trades (3% fees = 30 USDC)
- Creates artificial volume that tricks other users
- Price pumps 15%*due to perceived demand
- Attacker sells at inflated price for 1150 USDC
- Net profit: 150 USDC - 30 USDC = 120 USDC profit

Recommended Mitigation

# Mitigation
​
The `buyOrder()` function allows sellers to buy their own orders, enabling market manipulation
and pump & dump attacks that can trick other users into buying at inflated prices.
​
**Vulnerable Code:**
​
// Lines 193-210: buyOrder()
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();
// Missing check to prevent self-buy
}
​
​
--The Problem:
Attackers can buy their own orders to create fake volume and manipulate prices,
leading to pump & dump schemes that harm other users.
​
## How to Fix
​
Add a critical check to prevent sellers from buying their own orders:
​
​
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();
if (order.seller == msg.sender) revert("Cannot buy own order"); // CRITICAL: Prevent market manipulation
​
}
​
​
--The Fix:
Now sellers cannot buy their own orders, preventing market manipulation and protecting
users from pump & dump attacks.
​
## Alternative: Add Custom Error
​
error CannotBuyOwnOrder();
​
// In function:
if (order.seller == msg.sender) revert CannotBuyOwnOrder();
​
​
--Recommendation:
This fix is CRITICAL to prevent market manipulation and protect users from financial losses.
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!