Skip to main content

Contract overview

FlashLeverage
The main contract users interact with. Handles the full position lifecycle: opening, adjusting, and closing. Also manages fees, LTV validation, UserProxy creation, market configuration, and admin controls. Inherits MarketPositionManager, SwapManager, ReentrancyGuard, and Ownable2Step.
MarketPositionManager
Abstract base for all Morpho protocol interactions. Houses the flash loan callback handler (onMorphoFlashLoan), collateral supply and withdrawal, borrow and repay logic, position queries, share-to-asset conversion, and market parameter storage. FlashLeverage inherits from this.
SwapManager
Handles token swaps through whitelisted external aggregators. No internal AMM. Delegates to routers like KyberSwap, Odos, or Pendle Router using encoded calldata. Validates router approval and verifies output meets minTokenOut before completing any swap.
UserProxy
An EIP-1167 minimal clone deployed per position. Holds the position’s Morpho collateral and debt in isolation. During normal operation, only FlashLeverage can call it. Manual Mode unlocks direct access for the position owner. Includes a recover() function for tokens accidentally sent to the proxy or accumulated as external rewards.
FlashLeverageRouter
Entry point for users who do not hold the collateral token. Combines a token swap and a leverage() call into one transaction. Also integrates with Morpho Public Allocator for vault liquidity reallocation before opening a position.

Inheritance

FlashLeverage
├── MarketPositionManager
│   └── SwapManager
├── ReentrancyGuard (OpenZeppelin)
└── Ownable2Step (OpenZeppelin)

Key structs

LeveragePosition — stored per user per position ID
  • open: bool
  • marketId: Id
  • userProxy: address
  • amountDepositedInLoanToken: uint256, tracks cumulative deposits for yield fee calculation
  • amountReturnedInLoanToken: uint256
LeverageParams — input for leverage()
  • marketId, amountCollateral, amountFlashLoan, swapData, minTokenOut
MarketConfig
  • marketId: Id
  • isCorrelated: bool
SwapData
  • extRouter: address
  • extCalldata: bytes

Key functions

leverage(user, params)
Opens a new position. Takes a user address, so anyone can open a position on behalf of another. Transfers collateral in, deploys a UserProxy for the position, flash-loans the borrow amount, swaps to additional collateral, supplies the total to Morpho, and borrows to repay the flash loan. Deposit fee applied here for non-correlated markets.
deleverage(positionId, amountCollateral, swapData, minTokenOut)
Closes a position. Position owner only. Flash-loans the full outstanding debt, repays Morpho, withdraws collateral, swaps to loan token, deducts yield fee on profit for correlated markets, and returns the remainder to the caller.
increaseLeverage(positionId, amountFlashLoan, swapData, minTokenOut)
Amplifies an existing position. Position owner only. Flash-loans additional funds, swaps to collateral, supplies the additional collateral, and borrows to repay.
supplyCollateral(user, positionId, amountCollateral)
Adds collateral to reduce LTV. Callable by anyone for any position. Deposit fee applies for non-correlated markets. Updates amountDepositedInLoanToken for accurate fee accounting.
repay(user, positionId, amountRepay, borrowShares)
Repays debt on a position. Callable by anyone. Deposit fee applies for non-correlated markets.
borrow(positionId, amountBorrow)
Extracts loan tokens from an existing position. Position owner only. Non-correlated markets only. Blocked on correlated pairs to preserve yield accounting integrity.
withdrawCollateral(positionId, amountWithdraw)
Removes collateral from a position. Position owner only. LTV is validated after withdrawal. Yield fee applies on correlated markets if profit is realized.
enableManualMode(userProxy)
Owner only. Unlocks a specific UserProxy so the position owner can interact with Morpho directly. Used for emergency recovery upon user request.

Flash loan callback

All flash loan operations funnel into a single onMorphoFlashLoan(uint256 amountLoan, bytes calldata data) callback. The data payload encodes an Action enum (LEVERAGE or UNLEVERAGE) that routes execution to _handleLeverage() or _handleDeleverage() in MarketPositionManager. The callback validates msg.sender == address(i_morpho) before executing any logic.

Constants

ConstantValueDescription
LIQUIDATION_BUFFER0.25%Subtracted from market LLTV to set max allowed LTV. Immutable.
MAX_YIELD_FEE10%Hard cap on yield fee. Immutable.
MAX_DEPOSIT_FEE1%Hard cap on deposit fee. Immutable.
If a Morpho market has a liquidation LTV of 90%, the protocol caps positions at 89.75% LTV.

Libraries

Math.sol — Fixed-point arithmetic at 18-decimal precision. Used for fee and LTV calculations throughout. TokenHelper.sol — Safe ERC20 transfer utilities. Uses address(0) as the convention for native ETH. Error.sol — Custom error definitions for all revert conditions across the protocol.