OrderBook

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

Persistent Order Storage (Gas Inefficiency)

Root + Impact

Description

  • After an order is filled or cancelled, its data remains in the orders mapping, even though isActive is set to false. For example, cancelSellOrder does:

order.isActive = false;
IERC20(order.tokenToSell).safeTransfer(order.seller, order.amountToSell);

The struct Order for that orderId is never removed or deleted. Over time, the orders mapping will accumulate inactive orders, consuming extra storage. This is a gas/storage inefficiency: looking up orders or iterating (if any) will deal with stale data. It also makes the total state larger than necessary.

Risk

Likelihood:

  • every executed order (cancelled or filled) stays in storage indefinitely.

Impact:

  • wasted storage increases blockchain state size and can incur slightly higher gas costs if orders are accessed or cleared in future extensions. It does not directly cause a security issue but is an inefficiency.

Proof of Concept

// Seller creates and immediately cancels an order
uint256 orderId = orderBook.createSellOrder(tokenAddress, 10, 100, 1000);
orderBook.cancelSellOrder(orderId);
// Now orders[orderId].isActive == false, but orders[orderId].amountToSell == 10, etc.
// The order data remains in storage despite being inactive.

Recommended Mitigation

function cancelSellOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
// ... validations ...
order.isActive = false;
IERC20(order.tokenToSell).safeTransfer(order.seller, order.amountToSell);
+ delete orders[_orderId]; // remove order data from storage
emit OrderCancelled(_orderId, order.seller);
}
function buyOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
// ... validations and transfers ...
totalFees += protocolFee;
+ delete orders[_orderId]; // remove order after it is filled
emit OrderFilled(_orderId, msg.sender, order.seller);
}

After completing an order (either cancellation or purchase), use delete orders[_orderId] to clear the struct. This refunds some gas (storage clear) and prevents stale data buildup.

Updates

Lead Judging Commences

yeahchibyke Lead Judge
15 days ago
yeahchibyke Lead Judge 11 days ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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