OrderBook

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

H-01 User has unreasonable buy/sell price

Author Revealed upon completion

Root + Impact

Description

Since the price of USDC is not directly pegged to the price of wETH, wBTC, or wSOL, and there is no validation on the _priceInUSDC and _amountToSell parameters for minimum values, sellers can use an extremely low USDC price to sell wBTC, wETH, wSOL far beyond their actual value. This can facilitate monetary transactions (money laundering).

function createSellOrder(
address _tokenToSell, // Choose token: Seller selects supported token (wETH, wBTC, or wSOL).
@> uint256 _amountToSell, // Amount of tokens to sell (must be > 0).
@> uint256 _priceInUSDC, // Total price (in USDC, must be > 0).
uint256 _deadlineDuration // Order expiration (max 3 days).
) public returns (uint256) {

Risk

Likelihood:

  • Reason 1:Malicious sellers and buyers engage in financial transactions and profit transfers (e.g., money laundering).

Impact:

  • Impact 1:Malicious sellers intentionally sell expensive WBTC to malicious buyers at an extremely low USDC price, completing profit transfers (e.g., money laundering).

Proof of Concept

For example:

  1. Assume that 1 wBTC = 110,000 USDC

  2. Due to the fact that in the createSellOrder function, the price of USDC is not directly pegged to the price of wETH, wBTC, wSOL, etc., a malicious seller can set _priceInUSDC = 1e6 USDC and _amountToSell = 1

  3. A malicious buyer can then use an extremely unreasonable price of 1 USDC to obtain 20 wBTC = 2,200,000 USDC. In other words: 1e6 USDC = 20e8 wBTC

  4. Impact: Malicious sellers and buyers can complete money laundering transactions!

function test_amountToSell() public {
// NOTE: SellOrder
vm.startPrank(alice);
wbtc.approve(address(book), 20e8);
uint256 aliceId = book.createSellOrder(address(wbtc), 20e8, 1e6, 2 days);
vm.stopPrank();
// NOTE: BuyOrder
vm.startPrank(dan);
usdc.approve(address(book), 200_000e6);
book.buyOrder(aliceId); // dan buys from alice
vm.stopPrank();
// NOTE: Result: 1e6 USDC exchanges for 20e8 wBTC
assert(wbtc.balanceOf(dan) == 20e8);
}

Recommended Mitigation

Use an AMM to peg the price of USDC to the prices of wETH, wBTC, wSOL, etc.

Support

FAQs

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