OrderBook

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

[L-3] The `withdrawFees`, `buyOrder`, `amendSellOrder` and `createSellOrder` functions in the `OrderBook` contract do not follow the Checks-Effects-Interactions (CEI) Pattern

Description:
The functions withdrawFees, buyOrder, and createSellOrder in the OrderBook contract currently perform external calls—such as token transfers—before updating the contract’s internal state. This approach is contrary to the Checks-Effects-Interactions (CEI) pattern, a widely recommended best practice in smart contract development. The CEI pattern dictates that all necessary checks (such as input validation and access control) and all updates to the contract’s internal state should be completed prior to any external interactions, including calls to other contracts or token transfers. By not adhering to this pattern, the contract increases its exposure to certain classes of vulnerabilities.

Impact:
Failure to follow the CEI pattern can expose the contract to reentrancy attacks and other unexpected behaviors. If an external contract is called before the internal state is updated, a malicious contract could exploit this by re-entering the function (or another function that depends on the same state) and manipulating the contract’s state in an unintended way. This could potentially result in the loss of funds, double-withdrawals, or inconsistent contract state. Even if the contract is not directly vulnerable to reentrancy, performing external calls before state updates can make the code harder to reason about and audit, increasing the risk of subtle bugs or future vulnerabilities as the codebase evolves.

Recommended Mitigation:
It is strongly recommended to refactor the withdrawFees, amendSellOrder, and buyOrder functions to strictly follow the Checks-Effects-Interactions pattern, as has been suggested for the createSellOrder function. Specifically, ensure that all input validation, access control, and updates to the contract’s internal state are performed before any external calls, such as token transfers or calls to other contracts. This reduces the attack surface for reentrancy and makes the contract’s behavior more predictable and secure. Additionally, consider reviewing all functions that interact with external contracts to ensure they follow this pattern, and document the rationale for the order of operations to aid future audits and maintenance. Adhering to CEI not only improves security but also enhances the clarity and maintainability of the contract code.

unction createSellOrder(
address _tokenToSell,
uint256 _amountToSell,
uint256 _priceInUSDC,
uint256 _deadlineDuration
) public returns (uint256) {
if (!allowedSellToken[_tokenToSell]) revert InvalidToken();
if (_amountToSell == 0) revert InvalidAmount();
if (_priceInUSDC == 0) revert InvalidPrice();
if (_deadlineDuration == 0 || _deadlineDuration > MAX_DEADLINE_DURATION)
revert InvalidDeadline();
uint256 deadlineTimestamp = block.timestamp + _deadlineDuration;
uint256 orderId = _nextOrderId++;
- IERC20(_tokenToSell).safeTransferFrom(
- msg.sender,
- address(this),
- _amountToSell
- );
orders[orderId] = Order({
id: orderId,
seller: msg.sender,
tokenToSell: _tokenToSell,
amountToSell: _amountToSell,
priceInUSDC: _priceInUSDC,
deadlineTimestamp: deadlineTimestamp,
isActive: true
});
+ IERC20(_tokenToSell).safeTransferFrom(
+ msg.sender,
+ address(this),
+ _amountToSell
+ );
emit OrderCreated(
orderId,
msg.sender,
_tokenToSell,
_amountToSell,
_priceInUSDC,
deadlineTimestamp
);
return orderId;
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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