Skip to main content

Leverage (loop)

GET 

/v1/actions/loop/leverage

Open a leveraged position via borrow → swap → deposit. Identify the debt market with marketUidIn and collateral market with marketUidOut. Omit account for quote-only (returns data.quotes with price deltas). Include account to build full transaction calldata (populates actions with alternatives, transactions, and permissions).

Response actions fields (when account is provided):

  • alternatives: DEX aggregator swap transactions sorted best-output-first. Pick one to execute.
  • transactions: Pre-trade setup — mode/e-mode switch (Aave V3) or collateral enable (Venus). Empty if not needed.
  • permissions: ERC20 approvals (targeting the composer contract) and lender borrow delegations (targeting the lending protocol contract). Only missing approvals are returned. Execute these first.

Lista DAO fixed-term (brokered) markets: when marketUidIn is brokered, pass termId to open the loop's debt leg as a fixed-term broker loan. The collateral deposit leg is handled automatically (routed through the market's collateralProvider when set, e.g. slisBNB). Closing such a loop requires the loan's loanId on /v1/actions/loop/close.

Plain-text reference — GET /v1/actions/loop/leverage

Parameters

ParameterInTypeRequiredDescription
routequeryauto, bundler3, native, composer, proxynoWhich assembly to use, for lenders that have more than one. Morpho Blue only today.
  • (omitted)auto: prefer the protocol’s own tooling and fall back to the composer for anything it cannot express (a cross-market pair, a margin paid in a foreign asset, an EXACT_OUTPUT close, a chain with no bundler3 or no swap adapter).
  • bundler3 / native — force Morpho’s bundler3. A request it cannot serve becomes an ERROR instead of silently falling back, which is what makes the route testable.
  • composer / proxy — force the 1delta composer.

The default matters: the bundler3 route asks for setAuthorization(GeneralAdapter1), Morpho’s own audited adapter, where the composer route asks for a standing grant on ours. | | marketUidIn | query | string | yes | Market identifier for input side (lender:chainId:address). | | marketUidOut | query | string | yes | Market identifier for output side (lender:chainId:address). | | slippage | query | number | yes | Slippage tolerance (basis points) | | account | query | string | no | Account address. Include to build transaction, omit for quote-only. | | debtAmount | query | string | yes | Debt amount in wei | | payAsset | query | string | no | Asset to pay with (optional zap-in asset) | | payAmount | query | string | no | Pay amount in wei | | marginFromAccountId | query | integer | no | Dolomite only. Fund the margin from this existing Dolomite sub-account instead of the wallet, collapsing the open to ONE transaction: the transfer rides inside the leverage call and no deposit or token approval is emitted. Omit to pull payAmount from the wallet (two transactions — Dolomite's trader proxy can only move funds between the caller's own sub-accounts). 0 is the default sub-account and a valid source. Passing the trade account's own id is treated as absent, since the margin is already there. The source must hold payAmount of the pay asset or the transaction reverts. | | leverage | query | number | no | Target leverage multiplier | | usePendleMintRedeem | query | boolean | no | Use Pendle mint/redeem | | borrowMode | query | 0, 1, 2 | no | Borrow mode (0=NONE, 1=STABLE, 2=VARIABLE) | | termId | query | integer | no | Lista DAO fixed-term (brokered) debt markets only. Selects the fixed term to borrow for the loop's debt leg, from the debt market's terms[] rate card (the MarketTerm.termId). Required when marketUidIn is a brokered market — the borrow leg routes through the broker; ignored otherwise. | | posId | query | string | no | Twyne only. Which collateral vault to lever — a Twyne position is a contract the borrower deploys, and one account may own several in a market, each with its own collateral, debt and liquidation LTV. Omit when the account owns exactly one (or none). Passing none while owning several is refused rather than guessed. | | liqLtv | query | integer | no | Twyne only, and only when the account owns NO vault in this market yet. The liquidation LTV (1e4 scale) the position this call DEPLOYS will carry. The deploy runs as the first item of the same EVC batch, so a first-time borrower opens a leveraged position in one transaction; the response then carries createdPosition and a collateralVault address that does not exist until the transaction lands.

Defaults to the market’s LIVE ceiling (maxTwyneLTVs) — the extra LTV is the reason to borrow here, and the value is not a commitment: setTwyneLiqLTV moves it at any time with no cooldown, and lowering it RELEASES reserved credit and lowers what the borrower pays. Must sit inside the live band (externalLiqLTV × externalLiqBuffermaxTwyneLTVs); both bounds move, so a value is validated against a fresh read and refused by name rather than reverting ValueOutOfRange() on chain.

Ignored when a position already exists — moving an existing dial is /v1/actions/twyne/set-liq-ltv. | | accountId | query | string | no | Account ID (Init Capital) | | selectedMode | query | integer | no | Position mode for new positions (Init Capital) |

Response 200

FieldTypeDescription
successTrue
dataobjectInformational data (quotes, simulation results, etc.)
data.lenderstringProtocol identifier
data.quotesobject[]Candidate routes, best output first. Execute exactly one.
data.quotes[].deltasobject
data.quotes[].deltas.aggregatorstringAggregator source
data.quotes[].deltas.tradeInputnumberTrade input amount
data.quotes[].deltas.tradeOutputnumberTrade output amount
data.quotes[].deltas.deltasobjectBalance deltas
data.quotes[].rateImpactobject[]Projected interest-rate impact per market for THIS quote (its own trade amounts). Omitted if IRM data is unavailable.
data.quotes[].rateImpact[].marketUidstringMarket identifier (format: lender:chainId:address)
data.quotes[].rateImpact[].utilizationobjectA current/projected pair for a single rate metric.
data.quotes[].rateImpact[].borrowRateobjectA current/projected pair for a single rate metric.
data.quotes[].rateImpact[].depositRateobjectA current/projected pair for a single rate metric.
data.rateImpactobject[]Projected interest-rate impact per market. Single-market actions produce 1 entry; loop actions produce 2. Null if IRM data is unavailable.
data.rateImpact[].marketUidstringMarket identifier (format: lender:chainId:address)
data.rateImpact[].utilizationobjectA current/projected pair for a single rate metric.
data.rateImpact[].utilization.currentnumberCurrent value
data.rateImpact[].utilization.projectednumberProjected value after the action
data.rateImpact[].borrowRateobjectA current/projected pair for a single rate metric.
data.rateImpact[].borrowRate.currentnumberCurrent value
data.rateImpact[].borrowRate.projectednumberProjected value after the action
data.rateImpact[].depositRateobjectA current/projected pair for a single rate metric.
data.rateImpact[].depositRate.currentnumberCurrent value
data.rateImpact[].depositRate.projectednumberProjected value after the action
data.lenderstringProtocol identifier
data.quotesobject[]Candidate routes, best output first. Execute exactly one.
data.quotes[].deltasobject
data.quotes[].deltas.aggregatorstringAggregator source
data.quotes[].deltas.tradeInputnumberTrade input amount
data.quotes[].deltas.tradeOutputnumberTrade output amount
data.quotes[].deltas.deltasobjectBalance deltas
data.quotes[].txobjectAn EVM transaction ready to sign and broadcast. Send to, data and value as-is; do not re-encode them.
data.quotes[].tx.tostringTarget contract address
data.quotes[].tx.datastringEncoded calldata
data.quotes[].tx.valuestringETH value to send with the transaction
data.quotes[].tx.descriptionstringHuman-readable label. For alternatives, this is the aggregator name (e.g. "Paraswap"). For transactions, describes the setup action (e.g. "Switch e-mode to 1").
data.quotes[].rateImpactobject[]Projected interest-rate impact per market for THIS quote (its own trade amounts). Omitted if IRM data is unavailable.
data.quotes[].rateImpact[].marketUidstringMarket identifier (format: lender:chainId:address)
data.quotes[].rateImpact[].utilizationobjectA current/projected pair for a single rate metric.

Example response

{
"success": true,
"data": {
"lender": "AAVE_V3",
"quotes": [
{
"deltas": {
"aggregator": "string",
"tradeInput": 1.0,
"tradeOutput": 1.0,
"deltas": {}
},
"rateImpact": [
{
"marketUid": "AAVE_V3:8453:0x4200000000000000000000000000000000000006",
"utilization": {
"current": 1.0,
"projected": 1.0
},
"borrowRate": {
"current": 1.0,
"projected": 1.0
},
"depositRate": {
"current": 1.0,
"projected": 1.0
}
}
]
}
],
"rateImpact": [
{
"marketUid": "AAVE_V3:8453:0x4200000000000000000000000000000000000006",
"utilization": {
"current": 1.0,
"projected": 1.0
},
"borrowRate": {
"current": 1.0,
"projected": 1.0
},
"depositRate": {
"current": 1.0,
"projected": 1.0
}
}
]
},
"actions": {
"transactions": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"alternatives": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"permissions": [
{
"to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string",
"spender": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
]
}
}

Request

Responses

Quote or full build response