OrderBook

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

H-04 SellOrder: If there are no buyers, the seller can continuously amend the SellOrder, extending the validity of the sell order indefinitely.

Root + Impact

Description

In the amendSellOrder function, there is no time interval limit for modifying the SellOrder! If there are no buyers, the seller can repeatedly amend the newDeadlineDuration, causing the sell order’s validity to be extended indefinitely (3 days + 3 days + 3 days + ...). This bypasses the MAX_DEADLINE_DURATION limit on the SellOrder and breaks the intended functionality of the protocol!

@> uint256 public constant MAX_DEADLINE_DURATION = 3 days; // Max duration from now for a deadline
function amendSellOrder(
uint256 _orderId,
uint256 _newAmountToSell,
uint256 _newPriceInUSDC,
@> uint256 _newDeadlineDuration
) public {
...
...
@> if (_newDeadlineDuration == 0 || _newDeadlineDuration > MAX_DEADLINE_DURATION) revert InvalidDeadline();
...
...
@> order.deadlineTimestamp = newDeadlineTimestamp;
emit OrderAmended(_orderId, _newAmountToSell, _newPriceInUSDC, newDeadlineTimestamp);
}

Risk

Likelihood:

  • Reason 1: The seller can operate amendSellOrder without any time restrictions, modifying the sell order.

Impact:

  • Impact 1: This causes the sell order’s validity to be extended indefinitely, bypassing the MAX_DEADLINE_DURATION limit, breaking the protocol’s intended functionality!

Proof of Concept

function test_newDeadlineDuration() public {
// Alice creates a sell order for WBTC
vm.startPrank(alice);
wbtc.approve(address(book), 2e8);
uint256 aliceId = book.createSellOrder(address(wbtc), 2e8, 180_000e6, 3 days);
string memory aliceOrderDetails_1 = book.getOrderDetailsString(aliceId);
console2.log(aliceOrderDetails_1);
vm.stopPrank();
vm.warp(block.timestamp + 3 days - 1);
vm.prank(alice);
// NOTE: newDeadlineDuration = 3 days
book.amendSellOrder(aliceId, 1.75e8, 175_000e6, 3 days);
string memory aliceOrderDetails_2 = book.getOrderDetailsString(aliceId);
console2.log(aliceOrderDetails_2);
vm.warp(block.timestamp + 3 days - 1);
vm.prank(alice);
// NOTE: newDeadlineDuration = 3 days
book.amendSellOrder(aliceId, 1.75e8, 175_000e6, 3 days);
string memory aliceOrderDetails_3 = book.getOrderDetailsString(aliceId);
console2.log(aliceOrderDetails_3);
// `3 days + 3 days + 3 days + ...`
}

Output:

[PASS] test_newDeadlineDuration() (gas: 329879)
Logs:
Order ID: 1
Seller: 0xaf6db259343d020e372f4ab69cad536aaf79d0ac
Selling: 200000000 wBTC
Asking Price: 180000000000 USDC
@> Deadline Timestamp: 259201
Status: Active
Order ID: 1
Seller: 0xaf6db259343d020e372f4ab69cad536aaf79d0ac
Selling: 175000000 wBTC
Asking Price: 175000000000 USDC
@> Deadline Timestamp: 518400
Status: Active
Order ID: 1
Seller: 0xaf6db259343d020e372f4ab69cad536aaf79d0ac
Selling: 175000000 wBTC
Asking Price: 175000000000 USDC
@> Deadline Timestamp: 777599
Status: Active

Recommended Mitigation

  1. Set a total validity period to prevent the SellOrder from remaining valid indefinitely.

  2. Add a time interval for the amendSellOrder function to prevent continuous modifications in a short period.

Updates

Lead Judging Commences

yeahchibyke Lead Judge
8 days ago
yeahchibyke Lead Judge 4 days ago
Submission Judgement Published
Invalidated
Reason: Design choice

Appeal created

0x27281m Submitter
4 days ago
yeahchibyke Lead Judge
3 days ago
0x27281m Submitter
3 days ago
yeahchibyke Lead Judge about 10 hours ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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