Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Incorrect Absolute Value Usage in PnL Liquidation Causes Excessive Collateral Deduction

Summary

In the LiquidationBranch.sol contract. The liquidation process incorrectly calculates the Profit and Loss (PnL) by using the absolute value of the account's unrealized PnL. This leads to overcharging the liquidated account, causing excessive collateral to be deducted.

Vulnerability Details

In the liquidateAccounts function, the parameter pnlUsdX18 is computed as:

ctx.accountTotalUnrealizedPnlUsdX18.abs().intoUD60x18().add(ctx.requiredMaintenanceMarginUsdX18)

Here, accountTotalUnrealizedPnlUsdX18 (which can be negative) is converted to its absolute value before being added to the required maintenance margin. This is incorrect because:

  • If the unrealized PnL is negative (a loss), taking the absolute value treats it as a gain. This falsely inflates the pnlUsdX18, leading to a larger deduction from the account's collateral than warranted.

  • The unrealized loss is already reflected in the margin balance (marginBalanceUsdX18). Using the absolute value here effectively penalizes the user twice for the same loss.

Impact

Liquidated users lose more collateral than necessary due to the miscalculation. This results in financial harm to users and undermines trust in the protocol's liquidation fairness. Repeated incidents could lead to loss of users and reputational damage.

Tools Used

Manual code review and analysis of the liquidation logic, focusing on PnL handling during margin deduction.

Recommendations

Correct the PnL Calculation:
Replace the absolute value with the actual unrealized PnL value. If the PnL is negative (a loss), it should reduce the pnlUsdX18 instead of increasing it. Adjust the calculation as follows:

// Convert the signed PnL to UD60x18 properly, considering its sign
UD60x18 pnlContribution = ctx.accountTotalUnrealizedPnlUsdX18 < SD59x18_ZERO
? ctx.accountTotalUnrealizedPnlUsdX18.abs().intoUD60x18()
: UD60x18_ZERO;
pnlUsdX18 = pnlContribution.add(ctx.requiredMaintenanceMarginUsdX18);

This ensures that only losses (negative PnL) contribute to the deduction, aligning with the actual impact on the margin balance. Additionally, review the deductAccountMargin function to confirm it correctly handles the PnL contribution in the context of liquidation.

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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