OrderBook

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

Duplicate Addresses

Root + Impact

Description

  • Normal behavior: The constructor should validate that each provided token address is non‐zero and unique, then initialize the core tokens (wETH, wBTC, wSOL, USDC) and owner correctly.

  • Issue: Originally, the constructor only checked for zero‐address inputs but did not prevent two or more of the token parameters from being the same address. This can lead to ambiguous order labeling and UI/log confusion.

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();
}
@> // Missing check here to ensure all four addresses are distinct
if (_owner == address(0)) {
revert InvalidAddress();
}
}

Risk

Likelihood:

  • Reason 1: Deploy scripts with misconfigured environment variables can assign the same address to both _weth and _wbtc.

  • Reason 2: A malicious owner could intentionally alias wETH as wBTC to defraud buyers.

Impact:

  • Impact 1: Loss of Funds: A buyer sends USDC expecting to receive wBTC but instead gets wETH, causing financial loss or unexpected asset exposure.

  • Impact 2: Operational misinterpretation: Analytics or on-chain watchers could misclassify traded assets, undermining reporting accuracy.

Proof of Concept

Because we passed the same address for both _weth and _wbtc, the contract thought it was listing wBTC but was in fact holding the wETH token. When the buyer calls buyOrder(1), they see ‘Bought wBTC’ in the UI but actually get wETH—locking in a loss or at least an unwanted asset swap.

// Deploy with duplicate addresses:
address shared = 0xAbCDeF...; // the wETH contract
new OrderBook(shared, shared, wsolAddr, usdcAddr, ownerAddr);
// Buyer browses UI, sees “Sell wBTC” at price 100 000 USDC.
// They call buyOrder(1), sending 100 000 USDC.
// In reality:
orders[1].tokenToSell == shared; // wETH
safeTransfer(msg.sender, amountToSell); // buyer receives wETH, not wBTC

Recommended Mitigation

By rejecting deployments where any two of the token parameters are identical,
we guarantee that each order’s symbol and underlying contract always match.
That fail-fast behavior prevents a mis-labeled ‘wBTC’ order from actually routing wETH to buyers

if (_weth == address(0) || _wbtc == address(0) || _wsol == address(0) || _usdc == address(0)) {
revert InvalidToken();
}
- // no duplicate-address check
+ // ensure all four token inputs are distinct
+ if (
+ _weth == _wbtc || _weth == _wsol || _weth == _usdc ||
+ _wbtc == _wsol || _wbtc == _usdc ||
+ _wsol == _usdc
+ ) {
+ revert DuplicateAddresses();
+ }
if (_owner == address(0)) {
revert InvalidAddress();
}
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.