In the LiquidationBranch.sol contract, the liquidateAccounts() function is responsible for liquidating accounts that have fallen below the required maintenance margin. This function iterates through a list of account IDs, checks if each account is liquidatable, and if so, proceeds with the liquidation process.
A critical part of this process is the call to deductAccountMargin(), which is responsible for deducting the required margin from the account's collateral. However, there is a discrepancy in the parameters passed to this function.
The pnlUsdX18 parameter in the deductAccountMargin() call is currently set to requiredMaintenanceMarginUsdX18:
LiquidationBranch.sol#L150-L161
However, this value represents the required maintenance margin, not the account's unrealized PnL. The correct value to use here should be accountTotalUnrealizedPnlUsdX18, which is calculated earlier in the function.
This incorrect parameter leads to a scenario where accounts are over-liquidated if their required maintenance margin is greater than their unrealized PnL. In such cases, the protocol would be deducting more collateral from the account than necessary, causing undue losses to the user being liquidated. Otherwise, it will lead to user being under-liquidated if their required maintenance margin is lower than their unrealized PnL, leading to a loss for the procotol.
Accounts may be over-liquidated, causing losses to users, or under-liquidated, causing losses to the protocol.
An account's position becomes liquidatable.
The liquidateAccounts() function is called with this account's ID.
The function calculates requiredMaintenanceMarginUsdX18 and accountTotalUnrealizedPnlUsdX18.
When calling deductAccountMargin(), requiredMaintenanceMarginUsdX18 is passed instead of accountTotalUnrealizedPnlUsdX18.
If requiredMaintenanceMarginUsdX18 > accountTotalUnrealizedPnlUsdX18, more collateral than necessary is deducted.
The user suffers unnecessary losses due to over-liquidation.
An account's position becomes liquidatable.
The liquidateAccounts() function is called with this account's ID.
The function calculates requiredMaintenanceMarginUsdX18 and accountTotalUnrealizedPnlUsdX18.
When calling deductAccountMargin(), requiredMaintenanceMarginUsdX18 is passed instead of accountTotalUnrealizedPnlUsdX18.
If requiredMaintenanceMarginUsdX18 < accountTotalUnrealizedPnlUsdX18, fewer collateral than necessary is deducted.
The protocol suffers losses due to under-liquidation of the user.
Replace the pnlUsdX18 parameter in the deductAccountMargin() function call with accountTotalUnrealizedPnlUsdX18:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.