Skip to main content
migrate_from_blend moves a Blend V2 position to XOXNO in one transaction. The controller repays your Blend debt, withdraws your Blend collateral and non-collateral supply, deposits what it withdrew as XOXNO collateral, and runs a final health check before it persists anything. If any step fails, the whole transaction rolls back on both protocols.

Entrypoint

At least one of {collateral_assets, supply_assets, debt_caps} must be non-empty.

Atomic flow

  1. Repay Blend debt (internal zero-fee strategy borrow)
  2. Withdraw Blend collateral / supply
  3. Supply into XOXNO
  4. Health factor / LTV check
One controller call. Any revert rolls back Blend and XOXNO changes.

Debt sourcing

Migration does not use the flash-loan receiver pattern. It uses an internal zero-fee strategy borrow:

Refund reconciliation

debt_caps are upper bounds, not exact debt amounts. You set each cap at or above the real Blend debt, and Blend refunds whatever it did not need. The controller detects that refund by balance delta (reconcile_debt_refunds) and repays it straight back down (repay_debt_from_controller). So your migrated XOXNO debt equals your actual Blend debt, not the cap you passed. Over-sizing a cap costs you nothing.

Looped positions

When the same token is both collateral and debt (for example USDC collateral plus USDC debt), the controller uses a two-phase submit:
  1. Phase 1 — repay debt with an isolated balance snapshot so refunds do not alias with withdrawals.
  2. Phase 2 — withdraw collateral and supply with a fresh snapshot.
The same asset may appear in both collateral_assets and debt_caps — that is the looped case above. What is not allowed is listing the same asset twice within debt_caps, which reverts with #7 AssetsAreTheSame.

Blend request types

Non-collateral Blend supply becomes collateral on XOXNO. XOXNO has no non-collateral supply concept.

Authorization

Reentry guard

guarded_submit sets FlashLoanOngoing during Blend calls. Mutating controller entrypoints reject reentry while the guard is set (#400 FlashLoanOngoing).

Governance

Blend pools are allow-listed through governance:
Query approval with is_blend_pool_approved(blend_pool). Only governance-approved Blend pools can migrate.

Events

Failure modes

Example invoke

Set each debt_cap to at least the actual Blend debt for that asset. Use get_account_positions and Blend views to size caps before invoking.

Next

Strategies

Multiply, swap debt, swap collateral, and repay-with-collateral flows.

Flash loans

The flash-loan receiver pattern — distinct from migration’s zero-fee borrow.

Accounts and risk

Account model, health factor, and spoke constraints after migration.

Controller ABI

Full migrate_from_blend signature and related admin entrypoints.