DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: high
Valid

Incorrect Fill Price Validation in `fillOffchainOrders()` Function

Summary

A discrepancy exists between the implemented fill price validation logic and the comments in the fillOffchainOrders function of the SettlementBranch contract. This discrepancy could lead to incorrect order execution, financial losses, and market manipulation.

Vulnerability Details

The code checks if the fill price is valid based on whether the order is a buy or sell order.

ctx.isFillPriceValid = (ctx.isBuyOrder && ctx.offchainOrder.targetPrice <= ctx.fillPriceX18.intoUint256())
|| (!ctx.isBuyOrder && ctx.offchainOrder.targetPrice >= ctx.fillPriceX18.intoUint256());

While the comment states that

// if the order increases the trading account's position (buy order), the fill price must be less than or
// equal to the target price, if it decreases the trading account's position (sell order), the fill price
// must be greater than or equal to the target price.for buy orders, the fill price must be less than or equal to the target price, and for sell orders, the fill price must be greater than or equal to the target price.

The implemented logic is totally opposite of what is described in the comments.

Impact

The discrepancy between the intended validation logic and the implemented code can lead to malicious actors exploiting this discrepancy to execute buy orders with prices higher than the target price or sell orders with prices lower than the target price, causing financial losses.

Tools Used

Manual Review

Recommendations

Ensure that the validation logic accurately reflects the intended behavior. The correct logic should be;

- ctx.isFillPriceValid = (ctx.isBuyOrder && ctx.offchainOrder.targetPrice <= ctx.fillPriceX18.intoUint256())
- || (!ctx.isBuyOrder && ctx.offchainOrder.targetPrice >= ctx.fillPriceX18.intoUint256());
+ ctx.isFillPriceValid = (ctx.isBuyOrder && ctx.offchainOrder.targetPrice >= ctx.fillPriceX18.intoUint256())
+ || (!ctx.isBuyOrder && ctx.offchainOrder.targetPrice <= ctx.fillPriceX18.intoUint256());
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

fillOffchainOrders inverses the comparison between `fillPrice` and `targetPrice`

Support

FAQs

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

Give us feedback!