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

Liquidatable accounts prevented from reducing positions

Vulnerability Details

In the OrderBranch.sol contract, specifically within the simulateTrade() function, there is a check that prevents liquidatable accounts from performing any trades, including those that would reduce their position and bring them back above the liquidation threshold:

OrderBranch.sol#L133-L136

// prevent liquidatable accounts from trading
>> if (TradingAccount.isLiquidatable(ctx.previousRequiredMaintenanceMarginUsdX18, marginBalanceUsdX18)) {
>> revert Errors.AccountIsLiquidatable(tradingAccountId);
}

This check is performed before considering the nature of the trade being attempted. As a result, it blocks all trading activity for accounts that have fallen below the liquidation threshold, even if the trade would improve their position.

The simulateTrade() function is a key component in the trading process, used by the createMarketOrder() function to validate and simulate trades before execution. By blocking all trades for liquidatable accounts, the system prevents these accounts from taking actions that could potentially save them from liquidation.

Impact

Accounts that could recover through position reduction are forced into liquidation.

Proof of Concept

  1. Alice's account falls slightly below the liquidation threshold due to market movements.

  2. Alice attempts to reduce her position to bring her account above the liquidation threshold.

  3. The simulateTrade() function is called as part of processing Alice's createMarketOrder() call.

  4. The function immediately reverts due to the liquidation check, without considering that Alice's trade would improve her position.

  5. Alice is unable to reduce her position and is subsequently liquidated.

Recommendations

Modify the simulateTrade() function to allow position-reducing trades for accounts below the liquidation threshold. This can be achieved by:

  1. Determine if the trade is reducing the position size.

  2. If the account is liquidatable but the trade is reducing the position, allow the simulation to continue.

+ bool isIncreasingPosition = Position.isIncreasing(tradingAccountId, marketId, sizeDelta);
if (TradingAccount.isLiquidatable(ctx.previousRequiredMaintenanceMarginUsdX18, marginBalanceUsdX18)) {
+ if (isIncreasingPosition) {
revert Errors.AccountIsLiquidatable(tradingAccountId);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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