OrderBook

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

Missing Allowed Token Mapping for USDC

Root + Impact

Description

  • The OrderBook contract should enable sellers to list supported ERC20 tokens (wETH, wBTC, wSOL) for sale in exchange for USDC, ensuring buyers can also purchase them by paying the exact USDC amount, with both sell and payment tokens recognized as valid by the contract.

  • When a User indulges any function that tries checking allowedSellToken[usdcAddress] will return false simply because there's no boolean value, even though USDC is meant to be the primary payment method. Transaction reverses when buyers attempt to submit USDC especially if the contract checks **allowedSellToken,**while initializing allowed ERC20 tokens for trading, USDC is assigned to the iUSDC variable but is not marked as an allowed sell token in the allowedSellToken mapping, unlike other tokens such as WETH, WBTC, and WSOL.

// Root cause in the codebase with @> marks to highlight the relevant section
constructor(address _weth, address _wbtc, address _wsol, address _usdc, address _owner) Ownable(_owner) {
if (_weth == address(0) || _wbtc == address(0) || _wsol == address(0) || _usdc == address(0)) {
revert InvalidToken();
}
if (_owner == address(0)) {
revert InvalidAddress();
}
iWETH = IERC20(_weth);
allowedSellToken[_weth] = true;
iWBTC = IERC20(_wbtc);
allowedSellToken[_wbtc] = true;
iWSOL = IERC20(_wsol);
allowedSellToken[_wsol] = true;
//@>audit this is where the error is
iUSDC = IERC20(_usdc);

Risk

Likelihood:

(H) - Most likely to happen since it's a simple mistake during development phase. There's no guard to detect missing tokens in the allowed list, and users may assume USDC works as expected.


Impact:

(H) - Critical logic (e.g. fulfilling orders, accepting payments) may silently fail, especially if USDC is meant to be the primary currency for transactions. This could cause fund locks or a complete halt in trading.

USDC is not added to the allowedSellToken mapping and very importantly USDC-based trades will also fail, breaking core order book logic.


Proof of Concept - Broken USDC Logic in OrderBook Due to Missing Mapping


You can get this in order.t.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/OrderBook.sol"; // adjust this path to your contract
contract OrderBookTest is Test {
OrderBook public orderBook;
address public weth = address(0x1);
address public wbtc = address(0x2);
address public wsol = address(0x3);
address public usdc = address(0x4); // mock USDC address
function setUp() public {
// Deploy the contract with mock token addresses
orderBook = new OrderBook(weth, wbtc, wsol, usdc);
}
function testUSDCIsAllowed() public {
bool isAllowed = orderBook.allowedSellToken(usdc);
assertTrue(isAllowed, "USDC should be marked as an allowed sell token");
}
function testInvalidTokenIsNotAllowed() public {
address fakeToken = address(0x999);
bool isAllowed = orderBook.allowedSellToken(fakeToken);
assertFalse(isAllowed, "Unregistered token should not be allowed");
}
}

Recommended Mitigation

The allowedSellToken mapping acts as a whitelist for tradable tokens in the marketplace. Without setting allowedSellToken[_usdc] = true, any attempt to by users to trade using USDC will fail runtime checks, even if the token address is valid and the ERC20 contract is functional.

constructor(address _weth, address _wbtc, address _wsol, address _usdc, address _owner) Ownable(_owner) {
require(_weth != address(0) && _wbtc != address(0) && _wsol != address(0) && _usdc != address(0), "Invalid token");
require(_owner != address(0), "Invalid owner");
iWETH = IERC20(_weth);
allowedSellToken[_weth] = true;
iWBTC = IERC20(_wbtc);
allowedSellToken[_wbtc] = true;
iWSOL = IERC20(_wsol);
allowedSellToken[_wsol] = true;
iUSDC = IERC20(_usdc);
allowedSellToken[_usdc] = true; // ✅ FIX applied
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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