OrderBook

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

Storage Inefficiency + Increased Costs

Description

  • Smart contracts should manage storage efficiently to minimize gas costs and contract size over time.

  • Completed orders (filled or cancelled) remain in storage permanently, consuming unnecessary storage slots and increasing contract interaction costs.

mapping(uint256 => Order) public orders; // Orders never deleted
function cancelSellOrder(uint256 _orderId) public {
order.isActive = false; // Order marked inactive but not deleted
// Order remains in storage permanently
}
function buyOrder(uint256 _orderId) public {
order.isActive = false; // Order marked inactive but not deleted
// Order remains in storage permanently
}

Risk

Likelihood:

  • After every order cancellation or purchase

  • As the protocol grows and processes more transactions over time

  • When the contract has been running for extended periods

Impact:

  • Increasing gas costs for contract interactions due to larger state size

  • Inefficient use of blockchain storage space

  • Higher costs for users as contract becomes more expensive to interact with

Proof of Concept

Storage Bloat Demonstration: This shows how completed orders unnecessarily consume storage space permanently.

function testStorageNotCleaned() public {
// Create and fill an order
vm.startPrank(alice);
weth.approve(address(book), 1e18);
uint256 orderId = book.createSellOrder(address(weth), 1e18, 3000e6, 1 days);
vm.stopPrank();
vm.startPrank(dan);
usdc.approve(address(book), 3000e6);
book.buyOrder(orderId);
vm.stopPrank();
// Order still exists in storage even though filled
OrderBook.Order memory order = book.getOrder(orderId);
assertEq(order.seller, alice);
assertEq(order.isActive, false);
// Order data is still consuming storage slots
}

Storage Impact Analysis:

  • Order struct: ~5 storage slots (160 bytes per order)

  • Permanent accumulation: Every order ever created/filled remains in storage

  • Gas cost increase: Larger state size increases transaction costs over time

  • Scaling problem: High-volume periods will permanently bloat contract state

  • No cleanup mechanism: Contract has no way to remove old, completed orders

Recommended Mitigation

Solution: Delete completed orders from storage to reduce bloat and get gas refunds.

function cancelSellOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
// ... validation checks ...
// Return locked tokens to the seller
IERC20(order.tokenToSell).safeTransfer(order.seller, order.amountToSell);
+ // Clear storage to get gas refund
+ delete orders[_orderId];
emit OrderCancelled(_orderId, order.seller);
}
function buyOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
// ... validation and transfers ...
totalFees += protocolFee;
+ // Clear storage to get gas refund
+ delete orders[_orderId];
emit OrderFilled(_orderId, msg.sender, order.seller);
}

Why this works:

  • Gas refunds: Deleting storage slots provides gas refunds (up to 19,200 gas per slot)

  • Prevents bloat: Keeps contract state size manageable as transaction volume grows

  • Lower future costs: Smaller state size means lower gas costs for all interactions

  • Clean architecture: Removes unnecessary data that serves no purpose after completion

Trade-offs to consider:

  • Historical data: Order details are no longer queryable after completion

  • Events remain: Order history still available through event logs

  • Alternative: Consider archival mechanism if historical data is needed

Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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