Lend Midnight to Vault
LendMidnightToVaultCallback moves a lender out of a fixed-rate Midnight position and into an ERC-4626 vault. This can happen before maturity or after maturity.
Description
A lender holds a fixed-rate position on Morpho Midnight and wants to exit into a variable-rate vault, either before or after maturity. They post a sell (borrow) offer on Midnight to exit their lending position with this callback set as receiverIfMakerIsSeller. When the sell (borrow) offer fills, the callback receives the taker's payment and deposits it into an ERC-4626 compliant vault (typically a Morpho Vault-V2) on the lender's behalf.
Why an ERC-4626 vault, not Morpho Blue directly?
The simplest destination is a Morpho Vault-V2 that allocates 1:1 into a single Morpho Blue market: an unmanaged, immutable vault that mirrors one variable-rate market.
Targeting an ERC-4626 vault rather than a Morpho Blue market directly also keeps the callback generic: the same path supports the Money Market product, curated/managed vaults, and any third-party ERC-4626 strategy whose asset() matches the Midnight market's loan token.
Step-by-step callback execution
Before any take, the lender posts an exit sell (borrow) offer on the Midnight source market with receiverIfMakerIsSeller set to this callback. The offer carries the callback wiring; the take triggers it.
- Take: A taker fills the lender's exit sell (borrow) offer on Midnight by calling
MORPHO_MIDNIGHT.take(). The taker's payment (sellerAssets) lands on the callback because the offer'sreceiverIfMakerIsSellerpoints at it, and Morpho Midnight invokesonSellon the callback. - Validate the target vault: The vault's
asset()must equal the Midnight market'sloanToken. Otherwise the callback reverts withTokenMismatch. - Check the lender is debt-free on the source market: If the lender currently holds debt on the same Midnight market, the callback reverts with
PositionCrossing. The lender must remain a pure lender throughout the exit. - Calculate & transfer fee: A flat percentage fee is taken from
sellerAssets; if non-zero, it is transferred tofeeRecipient. When routed through the ratifier, the fee is forced to zero and this step is skipped. - Deposit into the vault: Approve the vault and call
deposit(sellerAssets - fee, seller). The lender receives the vault shares directly.
Example
A lender holds a fixed-rate lend position of 10,000 USDC on cbBTC/USDC · 30d (the source). They want to exit the fixed term and park the funds in USDC Vault-V2 at the variable rate.
- The lender posts an exit sell (borrow) offer for 10,000 USDC on
cbBTC/USDC · 30d, withreceiverIfMakerIsSellerset toLendMidnightToVaultCallback. - A taker fills the offer. The taker's 10,000 USDC payment (
sellerAssets) lands on the callback, and Midnight invokesonSell. - The callback confirms
USDC Vault-V2'sasset()is USDC, and that the lender holds no debt oncbBTC/USDC · 30d. - It calls
deposit(10,000 USDC − fee, lender)on the vault.
The lender ends the take holding vUSDC shares worth ~10,000 USDC in USDC Vault-V2, with their fixed-rate position on cbBTC/USDC · 30d closed.
Prerequisites
- The sell (borrow) offer's
receiverIfMakerIsSellermust point at this callback sosellerAssetslands here beforeonSellfires. - The lender must not be carrying debt on the same Midnight market at execution time.
- The target vault's underlying
asset()must equal the Midnight market'sloanToken.
The callback supports fee configuration via feeRate, but the Migration Ratifier caps Midnight exit flow fees at 0%, effectively disabling fees on ratifier-managed migrations (MAX_FEE_RATE_FIXED_TO_VARIABLE = 0). Any non-zero setFeeConfig for these callbacks reverts at the ratifier.