Offer Pre-Liquidation
Starting with v1.3.0, Morpho Borrow Positions open an earlier, privileged liquidation band between the safe LTV and the liquidation LTV. In this band, trusted proposers post standing, timelocked offers — a quantity of collateral in exchange for a quantity of debt repayment — and liquidators consume them through the same preLiquidate entrypoint used for proportional pre-liquidation.
This lets the protocol de-risk a position before it reaches the liquidation LTV, on terms the protocol itself proposes, while the proportional path above the liquidation LTV remains unchanged.
Three LTV Bands
Section titled “Three LTV Bands”Every Morpho Borrow Position is configured with two immutable thresholds: a safe LTV and a liquidation LTV (safeLtv < liquidationLtv ≤ market LLTV). A preLiquidate call accrues interest, then dispatches on the position’s current LTV:
| Band | Behavior |
|---|---|
LTV ≤ safeLtv |
Healthy — preLiquidate reverts with PositionHealthy(). |
safeLtv < LTV ≤ liquidationLtv |
Offer band — standing offers can be consumed. If none are fillable, the call reverts with NoConsumableOffer(). |
LTV > liquidationLtv |
Proportional pre-liquidation — the existing mechanism, behaviorally unchanged. |
graph LR
H["Healthy<br/>LTV ≤ safe LTV"] -->|"Safe LTV"| O["Offer Band<br/>offers consumable"]
O -->|"Liquidation LTV"| P["Proportional<br/>Pre-Liquidation"]
P -->|"Market LLTV"| M["Morpho<br/>Liquidation"]
style H fill:#16a34a,color:#fff
style O fill:#ca8a04,color:#fff
style P fill:#ea580c,color:#fff
style M fill:#dc2626,color:#fff
The safe LTV is also the operational ceiling for the Position Manager: borrows and collateral withdrawals must leave the position at or below it. So a position only enters the offer band through interest accrual or price movement — exactly the situations where a controlled, early de-risking is valuable.
Offers
Section titled “Offers”An offer is an authorization, not an escrow — no tokens are held by the offer itself. It states that up to remainingCollateral collateral tokens may be seized in exchange for repaying up to remainingDebtShares of the position’s Morpho borrow shares, at the fixed ratio implied by those two amounts. Offers are partially fillable.
Key properties:
- Debt is denominated in Morpho borrow shares, not loan-token units. As interest accrues, a fixed share amount converts to more loan tokens, so an offer’s effective price gradually worsens for the liquidator. An offer that drifts below profitability is simply skipped, and eventually expires.
- Timelocked — an offer becomes consumable only at
activeAt = proposalTime + timelock. The timelock is fixed at proposal time, so a later configuration change can never shorten an existing offer’s veto window. - Bounded — at most 32 offers can be live on a position at once, and an offer can live at most 365 days past its
activeAt.
Roles and the BorrowOffersRegistry
Section titled “Roles and the BorrowOffersRegistry”Offer roles and configuration live on a single protocol-wide BorrowOffersRegistry (deployed behind an ERC1967 proxy; see Deployments), shared by every borrow position:
| Actor | Power |
|---|---|
Proposer (PROPOSER_ROLE) |
Post offers on any position; revoke its own offers. |
Guardian (GUARDIAN_ROLE) |
Revoke any offer on any position — the veto during the timelock window, and the kill switch for a bad standing offer. |
| Registry owner | Grants/revokes roles, tunes configuration, and holds both powers above. |
Configuration is keyed by collateral token, not by position: the economics of a veto window and a bonus floor follow the collateral’s volatility and liquidity rather than the individual position.
| Setting | Default | Bounds | Change semantics |
|---|---|---|---|
| Offer timelock | 15 minutes | MIN_OFFER_TIMELOCK (15 min) to MAX_OFFER_TIMELOCK (7 days) |
Itself timelocked: a new value becomes effective only after the collateral’s current timelock elapses. Applies to future proposals only |
| Minimum offer bonus | DEFAULT_MIN_OFFER_BONUS_BPS (100 bps) |
0 to MAX_MIN_OFFER_BONUS_BPS (1000 bps) |
Effective immediately |
A collateral that was never configured reads the floor timelock and the default bonus, so the offer band is open by default rather than disabled.
The minimum bonus is not timelocked because it can only ever gate a consumption: it can skip a fill, never force or enlarge one. But that cuts both ways. Lowering the floor instantly re-admits standing offers that it had been gating, with no fresh veto window, since their terms were fixed at proposal and they already served their timelock. A guardian who wants an offer gone must revoke it, not rely on the floor to keep it unconsumable.
Proposing and Revoking
Section titled “Proposing and Revoking”// Proposer or registry owner. activeAt is fixed here from the collateral's// current effective timelock; expiresAt must be within 365 days of it.function proposeOffer(uint128 collateral, uint128 debtShares, uint40 expiresAt) external returns (uint8 id);
// Proposers may revoke their own offers at any time; guardians and the// registry owner may revoke any offer. Batched, and all-or-nothing.function revokeOffers(uint8[] calldata ids) external;An offer’s activeAt is stamped at proposal time and never moves, so a later timelock change cannot retroactively shorten a veto window that is already running.
Consuming Offers
Section titled “Consuming Offers”Liquidators use the same preLiquidate signature as proportional pre-liquidation — same inputs (exactly one of seizedAssets or repaidShares non-zero), same return values, and the same onPreLiquidate callback ordering, so existing flash-liquidation integrations work unchanged in the offer band.
When the position’s LTV is in the offer band, the call walks the consumable offers cheapest first (most favorable effective price for the position), filling each against the caller’s target. Each fill must:
- be strictly profitable for the liquidator and clear the collateral’s minimum bonus floor, and
- strictly reduce the position’s LTV.
The walk stops when the target is met, the position’s collateral or debt is exhausted, all offers are visited, or the next offer would fail the de-risking check. All fills settle in a single shares-mode Morpho repay, and the whole call reverts unless the aggregate fill strictly lowered the LTV.
Because of the skip/stop rules and conservative rounding, a call can underfill its target. Use previewConsume to simulate before sending. previewConsume simulates the walk only: the post-settlement LTV guard runs solely on the real call, so a dust-sized quote from the view can still revert there.
All fills are applied to the offer book as effects before the single Morpho repay, and the OfferConsumed events are emitted after the walk completes, in ascending order of effective price rather than slab-id order.
Worked Example
Section titled “Worked Example”A position sits at 84% LTV, between a safe LTV of 80% and a liquidation LTV of 88%. Two offers are live and past their timelock:
| Offer | Collateral offered | Debt shares requested | Effective bonus now |
|---|---|---|---|
#3 |
1,000 | worth 970 | 3.1% |
#7 |
500 | worth 493 | 1.4% |
A liquidator targets 1,200 of collateral. The walk visits #3 first (cheaper for the position), fills it entirely for 1,000 collateral against 970 of debt value, then moves to #7 and fills 200 of its 500 collateral against the proportional 197 of debt value. Both fills clear the 1% floor and both strictly lower the LTV, so the walk fills the target exactly.
Had #7 been priced at a 0.9% bonus, it would have been skipped, the call would have returned an underfill of 1,000, and #7 would have stayed in the book until either the accrual moved it further out of the money or it expired.
Note that a fixed share amount buys more loan-token debt as interest accrues, so every standing offer’s effective bonus decays over time. An offer that is unprofitable today may simply never become profitable again.
Views and Events
Section titled “Views and Events”| View | Use |
|---|---|
offers() / offer(id) / offerCount() |
Enumerate live offers (expired offers are pruned lazily — filter on expiresAt). |
isConsumable(id) |
Whether an offer would currently pass the consume gates, evaluated in isolation. |
previewConsume(seizedAssets, repaidShares) |
Simulate a consume walk for a target without mutating state. |
safeLtv() / liquidationLtv() |
The position’s band thresholds. |
To monitor the offer book, track OfferProposed, OfferRevoked, and OfferConsumed events on each borrow position.
For Liquidators, in Practice
Section titled “For Liquidators, in Practice”- A position with
safeLtv < LTV ≤ liquidationLtvis only liquidatable through standing offers. If the band is entered but no offer is fillable,preLiquidatereverts withNoConsumableOffer()— nothing to do until a proposer posts an offer or the LTV crosses the liquidation LTV. - In the offer band, your bonus is set by the offer’s terms (at least the collateral’s minimum bonus floor), not by the
1 - LTVproportional formula. - Above the liquidation LTV, everything works exactly as described in Pre-Liquidation.