Shorts flagged for liquidation can not be liquidated in the last and final hour of the liquidation timeline, resulting in the liquidation flag being reset and requiring the short to be flagged again.
If a short's collateral ratio is below the primary liquidation threshold (determined by the LibAsset.primaryLiquidationCR
function, by default set to 400%
), anyone can flag the position for liquidation by calling the MarginCallPrimaryFacet.flagShort
function.
Subsequently, the short position owner has a certain amount of time, specifically, 10 hours
(configured and determined by the LibAsset.firstLiquidationTime
function), to repay the loan and bring the collateral ratio back above the primary liquidation threshold. If the short position owner fails to do so, the short position can be liquidated by calling the MarginCallPrimaryFacet.liquidate
function.
The specific criteria for the liquidation eligibility are defined and determined in the MarginCallPrimaryFacet._canLiquidate
function.
contracts/facets/MarginCallPrimaryFacet.sol#L387
This function checks in lines 387-389 if the elapsed time (timeDiff
) since the short was updated is equal or greater than the reset liquidation time (resetLiquidationTime
), which is by default set to 16 hours
. In this case, the short position has not been liquidated in time and has to be flagged again.
However, this condition conflicts with the isBetweenSecondAndResetLiquidationTime
criteria in lines 394-395, specifically, the timeDiff <= resetLiquidationTime
check. If the timeDiff
value is equal to resetLiquidationTime
, both conditions, in line 387 as well as the check in line 395, are true
. Due to line 387 taking precedence, the liquidation is considered outdated and the short position has to be flagged again.
Based on the check in lines 67-69 of the flagShort
function, it is evident that a short position flagged for liquidation requires re-flagging only if the timeDiff
value is greater (>
) than the reset liquidation time (resetLiquidationTime
):
contracts/facets/MarginCallPrimaryFacet.sol#L67-L69
Thus, the check in line 387 is incorrect, leading to prematurely resetting the short's liquidation flagging status.
As the timestamps are in hours
, and the liquidation timeline is relatively short, having an off-by-one error in the liquidation timeline can lead to a significant impact on the liquidations. Concretely, attempting to liquidate a short position in the last hour of the timeline, i.e., timeDiff = 16
, is not possible.
Manual Review
Consider using >
instead of >=
in line 387 to prevent the liquidation timeline from overlapping with the bounds check in line 395.
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.