OrderBook

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

Gas Limit / Practicality for Extremely Large Orders

Description


While Solidity 0.8.0 protects against direct uint256 overflows by reverting, extremely large amountToSell or priceInUSDC values can lead to two issues: 1) Products in calculations (like priceInUSDC * FEE) potentially exceeding uint256 maximum, causing reverts; 2) Transactions involving massive numbers of tokens or values hitting Ethereum's block gas limit. This can make such orders uncreatable or unfillable.


Risk


Root Cause:

  1. uint256 Maximum: Even though vast, uint256 has a limit. Multiplications with large inputs can still exceed it.

  2. EVM Gas Limit: Operations on very large numbers or transfers of extreme quantities can consume excessive gas, causing transactions to fail.

Solidity

// Example: (order.priceInUSDC * FEE) could overflow uint256 if priceInUSDC is huge
function buyOrder(...) public {
// ...
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION; // Potential overflow of intermediate product
// ...
}
// Large amounts in safeTransferFrom also consume more gas.

Likelihood: Medium. While uint256 overflow is rare with typical values, hitting gas limits with extremely large real-world token amounts is more plausible.

Impact: Low to Medium.

  • Transaction Reversion: Orders involving values exceeding practical limits simply fail.

  • Loss of Functionality: Extremely high-value transactions might be impossible to execute.

  • Not a Direct Fund Loss: Funds are not stolen; transactions merely revert.


Proof of Concept


While direct uint256 overflows are theoretical for common values, consider the gas impact: A safeTransferFrom of an absurdly large token amount (e.g., 10^70 tokens) might hit the block gas limit, causing the createSellOrder or buyOrder transaction to revert, even if the numbers fit uint256.


Recommended Mitigation


Implement practical upper limits for amountToSell and priceInUSDC in createSellOrder and amendSellOrder. These limits should be well below type(uint256).max to ensure arithmetic operations remain safe and transactions stay within gas limits.

Diff

// --- Constants ---
uint26 public constant MAX_DEADLINE_DURATION = 3 days;
uint256 public constant FEE = 3;
uint256 public constant PRECISION = 100;
+ uint256 public constant MAX_ORDER_AMOUNT = 10**27; // Example upper bound
+ uint256 public constant MAX_ORDER_PRICE = 10**36; // Example upper bound
// ...
function createSellOrder(...) public returns (uint256) {
// ...
if (_amountToSell == 0) revert InvalidAmount();
if (_priceInUSDC == 0) revert InvalidPrice();
+ if (_amountToSell > MAX_ORDER_AMOUNT) revert InvalidAmount();
+ if (_priceInUSDC > MAX_ORDER_PRICE) revert InvalidPrice();
// ...
}
function amendSellOrder(...) public {
// ...
if (_newAmountToSell == 0) revert InvalidAmount();
if (_newPriceInUSDC == 0) revert InvalidPrice();
+ if (_newAmountToSell > MAX_ORDER_AMOUNT) revert InvalidAmount();
+ if (_newPriceInUSDC > MAX_ORDER_PRICE) revert InvalidPrice();
// ...
}

Choose MAX_ORDER_AMOUNT and MAX_ORDER_PRICE based on realistic token values and market expectations.


Reference Files:

  • src/OrderBook.sol

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.