Borrow Midnight Renewal Callback
BorrowMidnightRenewalCallback migrates a borrow position from a source Morpho Midnight market (for example, one maturing in 2 days) to a target Morpho Midnight market with a later maturity (for example, 30 days), in a single transaction.
Description
Both markets sit on Morpho Midnight. The borrower posts a sell (borrow) offer in the target market (the one maturing in 30 days in the example above) with the callback set as the proceeds receiver. When that sell (borrow) offer is filled, the callback uses the loan-token proceeds to repay the source debt (the position maturing in 2 days) and moves shared collateral from the source market to the target market.
Step-by-step callback execution
Before any take, the borrower posts a renewal sell (borrow) offer on the target market with receiverIfMakerIsSeller set to this callback. The offer carries the callback wiring; the take triggers it.
- Take: A taker fills the borrower's renewal sell (borrow) offer on the target market by calling
MORPHO_MIDNIGHT.take(). The loan-token proceeds (sellerAssets) land on the callback because the offer'sreceiverIfMakerIsSellerpoints at it, and Morpho Midnight then invokesonSellon the callback. - Validation: The callback checks that source and target markets share the same
loanToken. Collaterals listed in both markets are auto-detected and will migrate; collaterals listed only on the source are skipped and stay on the source. - Fee: A fee is derived from the offer tick (an effective-price fee applied to the interest portion only). When the callback is routed through the Migration Intent Ratifier, the ratifier sets the fee rate. Used directly, the offer creator encodes the fee themselves.
- Repay source debt: The callback repays the source obligation with
sellerAssets - fee. It reads the borrower's current source debt first and reverts withExcessRepaymentif the encoded units would overpay. It also reverts withZeroAmountif the source debt is already zero. - Move collateral: For each shared collateral token, the callback withdraws pro-rata from the source market (scaled by
repaidUnits / sourceDebtBefore) and supplies it on the target market. On the final fill (when the repay closes the source debt entirely) it moves the full remaining balance to avoid leaving dust.
Prerequisites
Before the take can succeed, the borrower must:
- Authorize the callback. A single authorization covers both source and target markets, since they live on the same Midnight instance.
- Post a sell (borrow) offer on the target market with
receiverIfMakerIsSellerset to this callback's address.
Collaterals listed on the source but not on the target will not be migrated. After the renewal, the borrower can call withdrawCollateral on the source market to recover collateral assets in the source market that were not accepted in the target market.
Routing
The natural taker of a borrower's target sell (borrow) renewal offer is a lender, since taking that offer means providing loan tokens at the offered rate. A keeper can also match the offer against an existing target lend offer in the RFQ if that results in a positive spread (MEV profit).
When posting a renewal offer, the borrower prices it as the implied combined rate of closing the source position at par early plus borrowing in target, not as a standalone target borrow rate. The X% on the target sell (borrow) offer reflects that combined effective rate.
Taker net rate (lender)
When a lender takes the borrower's target sell (borrow) renewal offer, they lend at the offered rate X%. If the lender already holds a position in the source market, or can enter a source-side lending position at a rate above par (0%) in the same transaction, they can capture an extra source-side return: the callback repays the borrower's source debt at par, letting the lender exit the source position atomically and pocket the source-side rate on top.
Example. Borrower's target sell (borrow) offer at X% = 6%. A lender takes the offer and lends at 6% on the target. In the same transaction, the lender also exits a source-side lend position at 5%, atomically unlocked when the callback repays the source debt at par. The lender's net effective rate is 6% on the target plus the source-side profit on top.
Keeper
A third party keeper doesn't want to hold lend exposure; they match existing offers when a positive net spread exists.
- Read the borrower's target sell (borrow) offer at
X%. - Find a target buy (lend) offer at
Y%and compute the target spreadX − Y. - Optionally take a source-side sell (borrow) offer at a positive rate
S%in the same transaction: the keeper enters a source-side lend position, and when the callback repays the borrower's source debt at par, that position settles instantly at its full term value, locking inS%of source-side interest for the keeper. - Match the target offers via
MORPHO_MIDNIGHT.take()whenever the target spread plus any source-side profit covers gas.
Even when the target leg alone is unprofitable (X − Y ≤ 0 or below gas), a positive source-side leg can cover the shortfall and make the trade profitable overall.
In the Migration Intent Ratifier context, the keeper can take on behalf of the borrower against a lend offer in the RFQ, executing as soon as the combined spread exceeds gas.
Example. Borrower's target sell (borrow) offer at X% = 6% and a matching target buy (lend) offer at Y% = 2%. The 4% gross spread is the keeper's profit headroom. The keeper matches both offers atomically: the borrower rolls into the 6% target borrow, the lender lends at 2%, and the keeper pockets whatever remains of the 4% spread after gas. If the target legs alone don't clear gas, the keeper can also take a source-side sell (borrow) offer at e.g. S% = 3%; the callback repays the source debt at par, settling the keeper's source position at full term value and adding 3% of interest to the bottom line.