OrderBook

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

Gas Grief Denial of Service in getOrderDetailsString

Root + Impact - The getOrderDetailsString function uses unbounded string concatenation which can cause out-of-gas errors for large order IDs or addresses, making the function unusable.

Description

  • The getOrderDetailsString function is designed to return human-readable order information.

  • The function uses abi.encodePacked with multiple string concatenations and conversions, which can consume excessive gas for large values.

// Root cause in the codebase
function getOrderDetailsString(uint256 _orderId) public view returns (string memory details) {
Order storage order = orders[_orderId];
if (order.seller == address(0)) revert OrderNotFound();
// ... token symbol logic ...
details = string(
abi.encodePacked( // @> Unbounded string concatenation can cause gas issues
"Order ID: ",
order.id.toString(), // @> Large order IDs create long strings
"\n",
"Seller: ",
Strings.toHexString(uint160(order.seller), 20), // @> Always 42 characters but still contributes
"\n",
"Selling: ",
order.amountToSell.toString(), // @> Large amounts create long strings
" ",
tokenSymbol,
"\n",
"Asking Price: ",
order.priceInUSDC.toString(), // @> Large prices create long strings
" USDC\n",
"Deadline Timestamp: ",
order.deadlineTimestamp.toString(), // @> Timestamp strings are long
"\n",
"Status: ",
status
)
);
return details;
}

Risk

Likelihood:

  • Order IDs increment indefinitely (_nextOrderId++)

  • Large token amounts and prices are common in DeF

Impact:

  • Function becomes unusable for large order IDs or amounts

  • Gas cost increases significantly over time

Proof of Concept - The following scenario demonstrates how gas consumption can make the function unusable:

// Scenario:
// 1. Contract has been running for months, _nextOrderId = 1000000
// 2. Order with large amounts: amountToSell = 1000000000000000000000 (1000 ETH)
// 3. Large price: priceInUSDC = 3000000000000 (3M USDC)
// 4. getOrderDetailsString() consumes excessive gas due to long number conversions
// 5. Function may hit gas limit and revert

Recommended Mitigation - Implement bounds checking and provide alternative representations for large values:

function getOrderDetailsString(uint256 _orderId) public view returns (string memory details) {
Order storage order = orders[_orderId];
if (order.seller == address(0)) revert OrderNotFound();
+ // Limit string length to prevent gas issues
+ if (order.id > 999999 || order.amountToSell > 1e24 || order.priceInUSDC > 1e12) {
+ return "Order details too large for string representation";
+ }
// ... rest of function with size limits
}
Updates

Lead Judging Commences

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

Appeal created

khandelwalmoksh787 Submitter
about 1 month ago
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.