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
4 months ago
yeahchibyke Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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