Tenor Adapter
The Tenor Adapter enables batching Tenor and Morpho Midnight operations into a single atomic transaction through Morpho's Bundler3. It wraps Morpho Midnight operations, ratifier configuration, and Tenor Router batch execution into passthrough functions that maintain correct callback routing.
For example, a borrower initiating a new position can approve tokens, supply collateral, take a sell offer (a borrower's offer to borrow), and configure auto-renewal in a single transaction through the adapter. If any step fails, the entire bundle reverts and the borrower is back where they started.
The recommended way to construct these batches is via the Tenor SDK, which handles ABI encoding, authorization routing, and call ordering. Hand-rolling a Bundler3 multicall is supported but error-prone.
Bundle Composition
A Tenor bundle is a Bundler3.multicall composing calls across several adapters:
TenorAdapter: Tenor and Morpho Midnight operations (this page).AuthorizationAdapter: protocol authorizations and ratifier configuration. See Authorization Adapter below.GeneralAdapter1: Morpho's standard adapter. Used for ERC-20transferFrom(with Permit2), native ETH wrap/unwrap, ERC-4626 vault deposits/withdrawals, and Morpho Blue operations.CoreAdapter: Morpho's base adapter thatGeneralAdapter1extends. Used for native ETH transfers and ERC-20 transfers from adapter balance.
Token approvals and setIsAuthorized grants are scoped to these adapters (plus renewal callback contracts). They are never granted to Bundler3 itself: Bundler3 is a stateless dispatcher, and any approval it held would become available to every adapter routed through it.
Direct Morpho Blue supply / borrow / repay / withdraw are not exposed through the Tenor SDK. The Blue surface is touched indirectly: Blue↔Midnight migrations bridge via a GeneralAdapter1 flash loan, with the renewal callback contracts handling the Blue side internally.
Benefits of the Tenor Adapter
All Tenor operations go through the adapter rather than calling contracts directly, for two reasons.
- Callback routing. Bundler3 callbacks must come from the same address that was called. Passthrough functions ensure the adapter is
msg.senderto Tenor contracts, so callbacks flow back correctly. - Atomic execution. Multiple operations can be batched into a single transaction, with all-or-nothing execution.
Morpho Midnight Operations
The adapter exposes passthrough functions for core Morpho Midnight operations.
- midnightRepay: Repay debt. Pass
type(uint256).maxasassetsto repay using the adapter's full loan-token balance, or asdebtto repay the initiator's entire current debt. - midnightSupplyCollateral: Supply collateral from the adapter's balance. Supports
type(uint256).maxto use the adapter's full balance. - midnightWithdrawCollateral: Withdraw collateral on behalf of the initiator. Supports
type(uint256).maxto withdraw the initiator's full collateral. - midnightWithdraw: Withdraw loan assets from a market on behalf of the initiator. Supports
type(uint256).maxto withdraw the initiator's full credit after position update (slashing + continuous fee accrual). - midnightSetConsumed: Set the consumed amount for an offer group (used for atomic cancel + downstream action). Passing
type(uint256).maxcancels all offers in the group. - midnightFlashLoan: Execute a flash loan on Morpho Midnight.
Long-lived authorizations (granting Midnight or IntentSettler access to other contracts) are handled by a separate adapter. See Authorization Adapter below.
Taking offers is done through the adapter's execute function (see Batch Take Execution below). The adapter does not expose a standalone midnightTake.
Ratifier Configuration
The adapter exposes passthrough functions for managing renewal parameters on the Migration Intent Ratifier.
- renewalSetParams: Sets renewal parameters on behalf of the initiator.
- renewalResetParams: Clears renewal parameters.
These passthroughs ensure the adapter is msg.sender to the ratifier, so the adapter is the contract the initiator authorizes.
Batch Take Execution
The adapter's execute function batches multiple take actions in a single transaction. See Tenor Router for the full call signature, fill semantics, and per-batch invariants. The initiator (the original EOA) is resolved as the taker for MIDNIGHT_TAKE actions and as the onBehalf passed into IntentSettler.take for TAKE_ON_BEHALF actions.
Callback Handling
The adapter implements callback interfaces that let it reenter Bundler3 from inside a Morpho Midnight operation. This is what enables batch operations (Bundler3.multicall) within a callback (e.g. supplying collateral, taking another offer, or repaying source debt as part of the same take).
- onBuy. Triggered when a buy offer is taken.
- onSell. Triggered when a sell offer is taken.
- onRepay. Triggered during repay operations.
- onLiquidate. Triggered during liquidations.
- onFlashLoan. Triggered during flash loans.
All callbacks validate that msg.sender == MORPHO_MIDNIGHT, so only Morpho Midnight itself can invoke them. This prevents third parties from spoofing callbacks to manipulate the adapter's state.
Authorization Adapter
AuthorizationAdapter is a separate standalone Bundler3 adapter for granting or revoking long-lived authorizations from inside a bundle. Use it as part of a one-shot setup bundle so users don't need separate out-of-bundle approval transactions.
It exposes four passthroughs, all called on the initiator's behalf:
- midnightSetIsAuthorized: Authorize another contract on Morpho Midnight (e.g. a callback or the Tenor Adapter).
- renewalSetIsAuthorized: Authorize a ratifier on
IntentSettler(e.g. the Migration Intent Ratifier). - setterRatifierSetIsRootRatified: Ratify (or un-ratify) an offer-tree root on a Midnight setter ratifier.
- ecrecoverRatifierCancelRoot: Cancel a previously-signed offer-tree root on a Midnight ecrecover ratifier.
A single Midnight setIsAuthorized grant gives the target contract the ability to act on every Midnight market the user has positions in, and to overwrite the user's renewal params on the ratifier (since the ratifier reuses Midnight's auth mapping). Only authorize contracts whose code you have audited and whose ABI you understand.