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

Incorrect equality sign in `SettlementBranch::fillOffchainOrders` could lead loss for traders

Summary

The protocol uses the incorrect equality sign when determining the validity of an order's fill price, leading to a loss for the trading account.

Vulnerability Details

The SettlementBranch::fillOffchainOrders incorrectly implement the logic for fill price validity checks for account orders.
For reference, the order is a buy order when the sizeDelta is greater than zero.

ctx.isBuyOrder = ctx.offchainOrder.sizeDelta > 0;

The code below does the opposite of desired behaviour by traders.
link

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

Traders Desire: For buyOrder, fill our order when the price is less than or equal to the target (entry) price because that is most favorable to us. The lower the price a buyer can enter the market, the higher the potential profit they stand to make.

Code Implementation: For buyOrder, the fill price is valid if the target price is less than or equal to the fill price, effectively limiting the upside of traders.

Proof of Concept

As shown in the ASCII diagram below, the fill price according to the protocol effectively limits the potential upside of the trader, and can theoretically execute at the take-profit price, which betrays the reasoning behind the trade and could lead to a significant loss. On the other hand, the fill price for the trader maximizes their potential return.

TakeProfit ---------------------------------------------------------------------------- $20
^
|
|
fillPrice (Code implementation) |
|
|
v
TargetPrice (entry point)-------------------------------------------------------------- $10
^
|
|
fillPrice (traders desire) |
|
|
v
TargetPrice (entry point)-------------------------------------------------------------- $5

Impact

Execution of unfavourable trades leading to losses for traders

Tools Used

Manual

Recommendations

Flip the equality signs

- 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 about 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.