Skip to main content

Delayed Liquidation Gate

The Delayed Liquidation Gate gives borrowers a grace period before a liquidation can be triggered onchain, reducing the risk of immediate liquidation the moment a position first becomes unhealthy. Lenders and borrowers can create a custom market that uses this gate by setting it as the liquidatorGate, after which Morpho Midnight only permits liquidations that originate from this contract.

The grace period gives borrowers a window to add collateral or repay debt before any liquidator can seize their position. For example, a borrower with a 30-day USDC position briefly dips below their liquidation LTV during a 5% ETH flash crash. Under a gate configured with a 1-hour grace period, the borrower has 60 minutes to restore position health before liquidation becomes possible.

Risk for lenders

Lenders filling offers configured with a delayed liquidation gate take on additional price risk. If collateral value falls sharply during the grace period, bad debt becomes more likely. The grace period must also be started onchain: until someone calls startGracePeriod, no liquidation can happen, even if the position is already unhealthy. Lenders can require lower LLTVs or higher rates to compensate for these risks.

Delayed liquidation steps

Morpho Midnight calls canLiquidate(caller) before allowing any liquidation; the gate's implementation returns true only when caller == address(this), which forces liquidators to call liquidate() on the gate. The gate enforces the grace and liquidation windows, then forwards the call to Morpho Midnight and handles token flows in the resulting onLiquidate callback.

Delayed liquidation timeline: a keeper calls startGracePeriod when the borrower is unhealthy, opening a 6-hour grace period during which the borrower may heal. When the grace period ends, an equally long liquidation period opens, first as a 1-minute priority window reserved for the priorityLiquidator (if one was supplied), then as open liquidation where any caller may invoke liquidate().
  1. Start grace period: Once a borrower's debt exceeds the maximum allowed by collateral value and LLTV, any keeper can call startGracePeriod(id, borrower, priorityLiquidator) to begin the countdown. The call reverts if a grace or liquidation period is already active for this borrower-market pair; a new one can only start once the previous GRACE_PERIOD + LIQUIDATION_PERIOD window has fully elapsed. The priorityLiquidator argument is optional and is explained in the priority window step below.
  2. Grace period: For GRACE_PERIOD seconds after the start, no caller, including the priorityLiquidator, can liquidate the position; any liquidate() call reverts with LiquidationNotAllowed. This window gives the borrower time to add collateral, repay debt, or otherwise restore position health before liquidation becomes possible.
  3. Priority window: When the grace period ends, the liquidation period opens. The optional priorityLiquidator supplied to startGracePeriod exists to incentivize keepers to make that call: if one was set and the borrower is still unhealthy, the first PRIORITY_PERIOD seconds (capped at 60 seconds) are reserved for that address, and any other caller is rejected with LiquidationNotAllowed. Leaving the argument empty opens liquidation to any caller immediately when the grace period ends.
  4. Open liquidation: After PRIORITY_PERIOD elapses (or immediately, if no priority liquidator was set), the rest of the LIQUIDATION_PERIOD is open to any caller. Liquidators call liquidate(market, collateralIndex, seizedAssets, repaidUnits, borrower, data) on the gate.

When liquidate() is called, the gate validates timing, then calls MORPHO_MIDNIGHT.liquidate(). Inside the resulting onLiquidate callback, the gate transfers seized collateral to the liquidator, optionally invokes the liquidator's own onLiquidate callback (when data is non-empty) so they can sell collateral for loan tokens, then pulls loan tokens from the liquidator and approves Morpho Midnight to reclaim them.

Position health is re-checked at the moment liquidate() is called, not when the grace period was started. Two consequences follow:

  • If the borrower restores health during the grace period and the position remains healthy through the liquidation window, no liquidation can occur, even though the gate's timing window is open. The liquidation call reverts on Morpho Midnight's health check, and a fresh startGracePeriod is required if the position becomes unhealthy again later.
  • If the borrower adds collateral during the grace period but the position falls back below the LLTV during the liquidation window, the position can be liquidated immediately, with no additional grace period.
Post-maturity liquidations

After the market's maturity timestamp, liquidate() on the gate always proceeds regardless of grace or liquidation period state. This ensures lenders can recover funds from matured, unpaid positions.

Key Parameters

Parameters are set at deployment from the factory and are immutable.

  • GRACE_PERIOD: Duration in seconds that borrowers have to restore position health before liquidation becomes possible.
  • LIQUIDATION_PERIOD: Duration in seconds during which liquidation is allowed after the grace period expires.
  • PRIORITY_PERIOD: Duration at the start of the liquidation window during which only the priorityLiquidator supplied to startGracePeriod may call liquidate().

Factory Deployment

Delayed Liquidation Gates are deployed via the DelayedLiquidationGateFactory using CREATE2 for deterministic addresses.

Factory constraints:

  • Minimum period: 60 seconds (MIN_PERIOD).
  • Maximum period: 72 hours (MAX_PERIOD).
  • Both GRACE_PERIOD and LIQUIDATION_PERIOD must be within [MIN_PERIOD, MAX_PERIOD].
  • PRIORITY_PERIOD is capped at MIN_PERIOD (at most 60 seconds).
  • LIQUIDATION_PERIOD must be at least PRIORITY_PERIOD + MIN_PERIOD, guaranteeing at least one minute of open-liquidation time after any priority window.