OrderBook

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

Order deadline can be extended indefinitely

Root + Impact

Description

  • The amendSellOrder function is designed to allow order owners to modify their orders including extending deadlines, with a MAX_DEADLINE_DURATION limit to prevent excessively long-running orders.

  • The function calculates the new deadline from the current block.timestamp rather than from the original order creation time, allowing sellers to repeatedly extend their orders beyond the intended maximum duration by calling the function multiple times before expiration.

Order storage order = orders[_orderId];
// ...
if (_newDeadlineDuration == 0 || _newDeadlineDuration > MAX_DEADLINE_DURATION) revert InvalidDeadline();
// ...
@> uint256 newDeadlineTimestamp = block.timestamp + _newDeadlineDuration;
// ...
order.deadlineTimestamp = newDeadlineTimestamp;

Risk

Likelihood:

  • This vulnerability will occur whenever sellers want to keep their orders active beyond the intended maximum duration and repeatedly call amendSellOrder before expiration

  • Sellers can exploit this immediately after order creation by strategically timing their amendments to continuously extend deadlines

Impact:

  • Complete circumvention of the MAX_DEADLINE_DURATION security control allowing indefinite order extensions

  • Potential market manipulation through artificially prolonged order availability

  • Undermining of the protocol's intended order lifecycle management

  • Possible griefing attacks where sellers can maintain stale orders indefinitely

Proof of Concept

This test demonstrates how a seller can extend their order deadline indefinitely by repeatedly calling amendSellOrder before expiration:

function test_amendSellOrder_canExtendDeadlineIndefinitely() external {
// user creates an order with a deadline set to 2 days
vm.startPrank(seller_wbtc);
wbtc.approve(address(book), WBTC_AMOUNT);
book.createSellOrder(address(wbtc), 2e8, 20_000e6, 2 days);
vm.stopPrank();
vm.warp(block.timestamp + 1 days);
// user extends the deadline by another 2 days after 1 day has passed
vm.prank(seller_wbtc);
book.amendSellOrder(1, 2e8, 20_000e6, 2 days);
vm.warp(block.timestamp + 1.5 days);
// 2.5 days have passed and the order status is still active
string memory orderDetailsString = book.getOrderDetailsString(1);
console2.log(orderDetailsString);
// Order ID: 1
// Seller: 0x9eb98786f3c392b6d5017ca7fa4dc695401d5f38
// Selling: 200000000 wBTC
// Asking Price: 20000000000 USDC
// Deadline Timestamp: 259201
// Status: Active
}

Recommended Mitigation

Add a createdAt field to track order creation time and enforce deadline limits based on the original creation timestamp rather than current time:

struct Order {
uint256 id;
address seller;
address tokenToSell;
uint256 amountToSell;
uint256 priceInUSDC;
uint256 deadlineTimestamp;
+ uint256 createdAt;
bool isActive;
}
// In createSellOrder:
orders[orderId] = Order({
id: orderId,
seller: msg.sender,
tokenToSell: _tokenToSell,
amountToSell: _amountToSell,
priceInUSDC: _priceInUSDC,
deadlineTimestamp: deadlineTimestamp,
+ createdAt: block.timestamp,
isActive: true,
});
// In amendSellOrder:
uint256 newDeadlineTimestamp = block.timestamp + _newDeadlineDuration;
+ uint256 maxAllowedDeadline = order.createdAt + MAX_DEADLINE_DURATION;
+ if (newDeadlineTimestamp > maxAllowedDeadline) revert InvalidDeadline();
Updates

Lead Judging Commences

yeahchibyke Lead Judge
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.