OrderBook

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

Cool Down Period for amend Order

Root + Impact

Normal Behavior

In the expected behavior of the amendSellOrder() function, a seller should be able to amend their sell order (i.e., update the amount, price, or deadline) occasionally to reflect new market conditions or correct a mistake. These amendments are intended to be infrequent and meaningful, not continuous or manipulative.

issue / Problem

The current implementation does not enforce any cool-off period between consecutive amendments made by the same seller. This means a seller can amend their order multiple times in rapid succession. While buyers or off-chain orderbooks are processing the current state of an order, the seller can change critical fields like price or amount repeatedly, resulting in:

  • Market manipulation

  • Orderbook desynchronization

  • Frontrunning opportunities

Description

  • In a typical order-based marketplace, sellers should be able to amend their orders to reflect market conditions. However, such changes are expected to be occasional and not intended for high-frequency manipulation.

    The current implementation of amendSellOrder() allows the seller to modify an order’s parameters (amount, price, and deadline) without any enforced time interval between successive calls. This lack of rate limiting enables sellers to rapidly and repeatedly change their orders in response to market movements, mempool observations, or bot activity.

    This can lead to unfair trading conditions and undermines the integrity of off-chain orderbooks and frontend interfaces that rely on a consistent view of the order state.

function amendSellOrder(...) public nonReentrant {
...
@> // No rate-limiting or cool-off logic exists here
@> // Sellers can call this repeatedly in the same block
...
order.amountToSell = _newAmountToSell;
order.priceInUSDC = _newPriceInUSDC;
order.deadlineTimestamp = newExpiry;
+ order.lastAmendedAt = block.timestamp;
}

Risk

Likelihood:

  • In competitive trading environments, sellers or bots will attempt to outpace one another by frequently amending orders.

  • This behavior is trivially executable since the contract does not restrict amendment frequency.

Impact:

  • May lead to financial loss or unfair execution for buyers.

  • Breaks consistency between on-chain state and off-chain display, especially in marketplaces or DEX aggregators.

  • Opens the door for automated sellers to exploit predictable buyer behavior using mempool scanning.

Proof of Concept

  • Off-chain orderbook UIs and buyers typically cache or act on the last seen order state.

  • Since the seller can update the order any number of times in the same block or within seconds, they can manipulate the pricing dynamically to their advantage.

  • This opens the door for mempool-based frontrunning where a seller observes incoming buyer transactions and adjusts the order before confirmation.

  • It can result in unfair price execution, orderbook desync, and ultimately a loss of trust in the protocol or marketplace.

// Seller posts an order with price = 100 USDC
amendSellOrder(orderId, 1000, 100e6, 3600);
// Frontend displays order at this price to buyer
// Seller's bot immediately updates price multiple times
amendSellOrder(orderId, 1000, 90e6, 3600);
amendSellOrder(orderId, 1000, 120e6, 3600);
amendSellOrder(orderId, 1000, 80e6, 3600);
// Buyer, relying on the first seen price, sends a buyOrder()
// Seller's bot has changed the price before buy executes

Recommended Mitigation

This solution ensures:

+ uint256 public constant COOLDOWN_PERIOD = 1 hours;
struct Order {
...
+ uint256 lastAmendedAt;
}
function amendSellOrder(...) public nonReentrant {
+ if (block.timestamp < order.lastAmendedAt + COOLDOWN_PERIOD) {
+ revert CooldownInEffect();
+ }
// Update order details
order.amountToSell = _newAmountToSell;
order.priceInUSDC = _newPriceInUSDC;
order.deadlineTimestamp = newExpiry;
+ order.lastAmendedAt = block.timestamp;
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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