Skip to main content

Morpho Blue

Code

Morpho Blue Github repository

Market Parameters

Market id

The market id is a bytes32 keccak256 hash of the 5 parameters of a market. It is used to identify a market in Morpho Blue.

type Id is bytes32;

To get the id from the parameters, a temporary solution is to execute this gist, or retrieve the id at market creation.

Market struct

The market struct is defined as follows:

struct Market {
uint128 totalSupplyAssets;
uint128 totalSupplyShares;
uint128 totalBorrowAssets;
uint128 totalBorrowShares;
uint128 lastUpdate;
uint128 fee;
}

It contains the state of a market. totalBorrowAssets & totalSupplyAssets accrues the interest of the market only until last interest accrual, while totalBorrowShares & totalSupplyShares are representing the total shares distributed over lenders / borrowers.

MarketParams struct

The majority of the entrypoints accept a MarketParams struct as parameter. This struct is defined as follows:

struct MarketParams {
address loanToken;
address collateralToken;
address oracle;
address irm;
uint256 lltv;
}

As an integrator, you need to recover these 5 parameters to interact with Morpho Blue. You can also use the idToMarketParams view function to recover the parameters of a given market from the bytes32 id.

Functions

setOwner

    function setOwner(address newOwner) external;

Sets newOwner as owner of the contract.

  • Warning: No two-step transfer ownership.
  • Warning: The owner can be set to the zero address.

Parameters:

NameTypeDescription
newOwneraddressThe new owner address.

enableIrm

   function enableIrm(address irm) external;

Enables irm as a possible IRM for market creation.

  • Warning: It is not possible to disable an IRM.

Parameters:

NameTypeDescription
irmaddressThe irm address to enable.

enableLltv

    function enableLltv(uint256 lltv) external;

Enables lltv as a possible LLTV for market creation.

  • Warning: It is not possible to disable a LLTV.

Parameters:

NameTypeDescription
lltvuint256The lltv value to enable (18 decimals).

setFee

    function setFee(MarketParams memory marketParams, uint256 newFee) external;

Sets the newFee for the given market marketParams.

  • Warning: The recipient can be the zero address.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market parameters.
newFeeuint256The new fee value.

setFeeRecipient

    function setFeeRecipient(address newFeeRecipient) external;

Sets newFeeRecipient as feeRecipient of the fee.

  • Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.
  • Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.

Parameters:

NameTypeDescription
newFeeRecipientaddressThe address of the new fee recipient.

createMarket

function createMarket(MarketParams memory marketParams) external;

Creates the market defined by marketParams.

Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees Morpho behaves as expected:

  • The token should be ERC20 compliant, except that it can omit return values on transfer and transferFrom.
  • The token balance of Morpho should only decrease on transfer and transferFrom. In particular, tokens with burn functions are not supported.
  • The token should not re-enter Morpho on transfer nor transferFrom.
  • The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount on transfer and transferFrom. In particular, tokens with fees on transfer are not supported.
  • The IRM should not re-enter Morpho.
  • The oracle should return a price with the correct scaling.

Here is a list of properties on the market's dependencies that could break Morpho's liveness properties:

  • The token can revert on transfer and transferFrom for a reason other than an approval or balance issue.
  • A very high amount of assets (~1e35) supplied or borrowed can make the computation of toSharesUp and toSharesDown overflow.
  • The IRM can revert on borrowRate.
  • A very high borrow rate returned by the IRM can make the computation of interest in _accrueInterest overflow.
  • The oracle can revert on price. Note that this can be used to prevent borrow, withdrawCollateral and liquidate from being used under certain market conditions.
  • A very high price returned by the oracle can make the computation of maxBorrow in _isHealthy overflow, or the computation of assetsRepaid in liquidate overflow.
  • The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to the point where totalBorrowShares is very large and borrowing overflows.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market parameters

supply

function supply(
MarketParams memory marketParams,
uint256 assets,
uint256 shares,
address onBehalf,
bytes memory data
) external returns (uint256 assetsSupplied, uint256 sharesSupplied);

Supplies assets or shares on behalf of onBehalf, optionally calling back the caller's onMorphoSupply function with the given data.

  • Either assets or shares should be zero. Most usecases should rely on assets as an input so the caller is guaranteed to have assets tokens pulled from their balance, but the possibility to mint a specific amount of shares is given for full compatibility and precision.

  • Supplying a large amount can revert for overflow.

  • Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage. Consider using the assets parameter to avoid this.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to supply assets to.
assetsuint256The amount of assets to supply.
sharesuint256The amount of shares to mint.
onBehalfaddressThe address that will own the increased supply position.
databytesArbitrary data to pass to the onMorphoSupply callback. Pass empty data if not needed.

Return Values:

NameTypeDescription
assetsSupplieduint256The amount of assets supplied.
sharesSupplieduint256The amount of shares minted.

withdraw

function withdraw(
MarketParams memory marketParams,
uint256 assets,
uint256 shares,
address onBehalf,
address receiver
) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);

Withdraws assets or shares on behalf of onBehalf to receiver.

  • Either assets or shares should be zero. To withdraw max, pass the shares's balance of onBehalf.

  • msg.sender must be authorized to manage onBehalf's positions.

  • Withdrawing an amount corresponding to more shares than supplied will revert for underflow.

  • It is advised to use the shares input when withdrawing the full position to avoid reverts due to conversion roundings between shares and assets.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to withdraw assets from.
assetsuint256The amount of assets to withdraw.
sharesuint256The amount of shares to burn.
onBehalfaddressThe address of the owner of the supply position.
receiveraddressThe address that will receive the withdrawn assets.

Return Values:

NameTypeDescription
assetsWithdrawnuint256The amount of assets withdrawn.
sharesWithdrawnuint256The amount of shares burned.

borrow

function borrow(
MarketParams memory marketParams,
uint256 assets,
uint256 shares,
address onBehalf,
address receiver
) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);

Borrows assets or shares on behalf of onBehalf to receiver.

  • Either assets or shares should be zero. Most usecases should rely on assets as an input so the caller is guaranteed to borrow assets of tokens, but the possibility to mint a specific amount of shares is given for full compatibility and precision.

  • msg.sender must be authorized to manage onBehalf's positions.

  • Borrowing a large amount can revert for overflow.

  • Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage. Consider using the assets parameter to avoid this.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to borrow assets from.
assetsuint256The amount of assets to borrow.
sharesuint256The amount of shares to mint.
onBehalfaddressThe address that will own the increased borrow position.
receiveraddressThe address that will receive the borrowed assets.

Return Values:

NameTypeDescription
assetsBorroweduint256The amount of assets borrowed.
sharesBorroweduint256The amount of shares minted.

repay

function repay(
MarketParams memory marketParams,
uint256 assets,
uint256 shares,
address onBehalf,
bytes memory data
) external returns (uint256 assetsRepaid, uint256 sharesRepaid);

Repays assets or shares on behalf of onBehalf, optionally calling back the caller's onMorphoReplay function with the given data.

  • Either assets or shares should be zero. To repay max, pass the shares's balance of onBehalf.

  • Repaying an amount corresponding to more shares than borrowed will revert for underflow.

  • It is advised to use the shares input when repaying the full position to avoid reverts due to conversion roundings between shares and assets.

  • An attacker can front-run a repay with a small repay making the transaction revert for underflow.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to repay assets from.
assetsuint256The amount of assets to repay.
sharesuint256The amount of shares to burn.
onBehalfaddressThe address of the owner of the debt position.
databytesArbitrary data to pass to the onMorphoRepay callback. Pass empty data if not needed.

Return Values:

NameTypeDescription
assetsRepaiduint256
sharesRepaiduint256The amount of shares burned.

supplyCollateral

function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data)
external;

Supplies assets of collateral on behalf of onBehalf, optionally calling back the caller's onMorphoSupplyCollateral function with the given data.

  • Interest are not accrued since it's not required and it saves gas.

  • Supplying a large amount can revert for overflow.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to supply collateral to.
assetsuint256The amount of assets to supply.
onBehalfaddressThe address that will own the increased collateral position.
databytesArbitrary data to pass to the onMorphoSupplyCollateral callback. Pass empty data if not needed.

withdrawCollateral

function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver)
external;

Withdraws assets of collateral on behalf of onBehalf to receiver.

  • msg.sender must be authorized to manage onBehalf's positions.

  • Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market to withdraw collateral from.
assetsuint256The amount of assets to withdraw.
onBehalfaddressThe address that owns the collateral position.
receiveraddressThe address that will receive the collateral assets.

liquidate

function liquidate(
MarketParams memory marketParams,
address borrower,
uint256 seizedAssets,
uint256 repaidShares,
bytes memory data
) external returns (uint256, uint256);

Liquidates the given repaidShares of debt asset or seize the given seizedAssets of collateral on the given market marketParams of the given borrower's position, optionally calling back the caller's onMorphoLiquidate function with the given data.

  • Either seizedAssets or repaidShares should be zero.

  • Seizing more than the collateral balance will underflow and revert without any error message.

  • Repaying more than the borrow balance will underflow and revert without any error message.

  • An attacker can front-run a liquidation with a small repay making the transaction revert for underflow.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market of the position.
borroweraddressThe owner of the position.
seizedAssetsuint256The amount of collateral to seize.
repaidSharesuint256The amount of shares to repay.
databytesArbitrary data to pass to the onMorphoLiquidate callback. Pass empty data if not needed.

Return Values:

NameTypeDescription
assetsSeizeduint256The amount of assets seized.
assetsRepaiduint256The amount of assets repaid.

flashLoan

function flashLoan(address token, uint256 assets, bytes calldata data) external;

Executes a flash loan.

  • Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all markets combined, plus donations).
  • Warning: Not ERC-3156 compliant but compatibility is easily reached: a. flashFee is zero. b. maxFlashLoan is the token's balance of this contract. c. The receiver of assets is the caller.

Parameters:

NameTypeDescription
tokenaddressThe token to flash loan.
assetsuint256The amount of assets to flash loan.
databytesArbitrary data to pass to the onMorphoFlashLoan callback.

setAuthorization

function setAuthorization(address authorized, bool newIsAuthorized) external;

Sets the authorization for authorized to manage msg.sender's positions.

Parameters:

NameTypeDescription
authorizedaddressThe authorized address.
newIsAuthorizedboolThe new authorization status.

setAuthorizationWithSig


struct Authorization {
address authorizer;
address authorized;
bool isAuthorized;
uint256 nonce;
uint256 deadline;
}

struct Signature {
uint8 v;
bytes32 r;
bytes32 s;
}

function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external;

Sets the authorization for authorization.authorized to manage authorization.authorizer's positions.

  • Warning: Reverts if the signature has already been submitted.

  • The signature is malleable, but it has no impact on the security here.

  • The nonce is passed as argument to be able to revert with a different error message.

Authorization struct

NameTypeDescription
authorizeraddressThe address authorizing the authorization.
authorizedaddressThe address to authorize.
isAuthorizedboolThe new authorization status.
nonceuint256The nonce of the authorizer.
deadlineuint256The deadline after which the signature is invalid.

Parameters:

NameTypeDescription
authorizationAuthorizationThe authorization to set.
signatureSignatureThe signature to validate.

accrueInterest

function accrueInterest(MarketParams memory marketParams) external;

Accrues interest for the given market marketParams.

Parameters:

NameTypeDescription
marketParamsMarketParamsThe market parameters.

Views Functions

DOMAIN_SEPARATOR

function DOMAIN_SEPARATOR() external view returns (bytes32);

The EIP-712 domain separator.

  • Warning: Every EIP-712 signed message based on this domain separator can be reused on another chain sharing the same chain id because the domain separator would be the same.

Return Values:

TypeDescription
bytes32The EIP-712 domain separator.

owner

    function owner() external view returns (address);

The owner of the contract.

  • It has the power to change the owner.
  • It has the power to set fees on markets and set the fee recipient.
  • It has the power to enable but not disable IRMs and LLTVs.

Return Values:

TypeDescription
addressThe owner of the contract.

feeRecipient

    function feeRecipient() external view returns (address);

The fee recipient of all markets.

  • The recipient receives the fees of a given market through a supply position on that market.

Return Values:

TypeDescription
addressThe fee recipient address.

isIrmEnabled

    function isIrmEnabled(address irm) external view returns (bool);

Whether the irm is enabled.

Parameters:

NameTypeDescription
irmaddressThe irm address.

Return Values:

TypeDescription
boolBoolean equals to true if irm is enabled, false otherwise.

isLltvEnabled

    function isLltvEnabled(uint256 lltv) external view returns (bool);

Whether the lltv is enabled.

Parameters:

NameTypeDescription
lltvaddressThe lltv address.

Return Values:

TypeDescription
boolBoolean equals to true if lltv is enabled, false otherwise.

isAuthorized

    function isAuthorized(address authorizer, address authorized) external view returns (bool);

Whether authorized is authorized to modify authorizer's position on all markets.

  • Anyone is authorized to modify their own positions, regardless of this variable.

Parameters:

NameTypeDescription
authorizeraddressThe authorizer address.
authorizedaddressThe authorized address.

Return Values:

TypeDescription
boolBoolean equals to true if authorized address is authorized to modify authorizer's position, false otherwise.

nonce

    function nonce(address authorizer) external view returns (uint256);

The authorizer's current nonce. Used to prevent replay attacks with EIP-712 signatures.

Parameters:

NameTypeDescription
authorizeraddressThe authorizer address.

Return Values:

TypeDescription
uint256The current nonce value.

extSloads

function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);

Returns the data stored on the different slots.

Parameters:

NameTypeDescription
slotsbytes32[]The array of slots to retrieve the data stored into.

Return Values:

TypeDescription
bytes32[]The data stored.

idToMarketParams

function idToMarketParams(Id id)
external
view
returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);

The market params corresponding to id.

  • This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer 2s by creating a wrapper contract with functions that take id as input instead of marketParams.

Parameters:

NameTypeDescription
idIdThe market id

Return Values:

NameTypeDescription
loanTokenaddressThe loan token of the market.
collateralTokenaddressThe collateral token of the market.
oracleaddressThe oracle of the market.
irmaddressThe IRM of the market.
lltvuint256The LLTV of the market.

market

function market(Id id)
external
view
returns (
uint128 totalSupplyAssets,
uint128 totalSupplyShares,
uint128 totalBorrowAssets,
uint128 totalBorrowShares,
uint128 lastUpdate,
uint128 fee
);

The market state corresponding to id.

  • Interest are not accrued, and assets values are not updated. Their values are the one at the last update.

  • One can use the MorphoBalancesLib to accrue interests

Parameters:

NameTypeDescription
idIdThe market id

Return Values:

NameTypeDescription
totalSupplyAssetsuint128The total supply assets of the market.
totalSupplySharesuint128The total supply shares of the market.
totalBorrowAssetsuint128The total borrow assets of the market.
totalBorrowSharesuint128The total borrow shares of the market.
lastUpdateuint128The last update timestamp of the market.
feeuint128The fee of the market.

position

function position(Id id, address user)
external
view
returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);

The state of the position of user on the market corresponding to id.

Parameters:

NameTypeDescription
idIdThe market id.
useraddressThe user address.

Return Values:

NameTypeDescription
supplySharesuint256The total supply shares of the user on a given market.
borrowSharesuint128The total borrow shares of the user on a given market.
collateraluint128The total collateral assets of the user on a given market.

MorphoBalancesLib

note

The MorphoBalancesLib is a library that allows you to accrue interest and update the assets values of a market. You can easily retrieve market amounts and user balances with interests.

The Github code is available here

expectedMarketBalances

function expectedMarketBalances(IMorpho morpho, MarketParams memory marketParams)
internal
view
returns (
uint256 totalSupplyAssets,
uint256 totalSupplyShares,
uint256 totalBorrowAssets,
uint256 totalBorrowShares
);

Returns the expected market balances of a market after having accrued interests, defined in Market.

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected balances from.

Return Values:

NameTypeDescription
totalSupplyAssetsuint256The total supply assets of the market (with interests accrued).
totalSupplySharesuint256The total supply shares of the market.
totalBorrowAssetsuint256The total borrow assets of the market (with interests accrued).
totalBorrowSharesuint256The total borrow shares of the market.

expectedTotalSupplyAssets

function expectedTotalSupplyAssets(IMorpho morpho, MarketParams memory marketParams)
internal
view
returns (uint256 totalSupplyAssets);

Returns the expected total supply assets of a market after having accrued interests.

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected total supply from.

Return Values:

NameTypeDescription
totalSupplyAssetsuint256The total supply assets of the market (with interests accrued).

expectedTotalBorrowAssets

function expectedTotalBorrowAssets(IMorpho morpho, MarketParams memory marketParams)
internal
view
returns (uint256 totalBorrowAssets);

Returns the expected total borrow assets of a market after having accrued interests.

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected total borrow from.

Return Values:

NameTypeDescription
totalBorrowAssetsuint256The total borrow assets of the market (with interests accrued).

expectedTotalSupplyShares

function expectedTotalSupplyShares(IMorpho morpho, MarketParams memory marketParams)
internal
view
returns (uint256 totalSupplyShares);

Returns the expected total supply shares of a market after having accrued interests.

  • It can grow only if fees > 0

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected total supply from.

Return Values:

NameTypeDescription
totalSupplySharesuint256The total supply shares of the market (with interests accrued).

expectedSupplyAssets

function expectedSupplyAssets(IMorpho morpho, MarketParams memory marketParams, address user)
internal
view
returns (uint256)

Returns the expected supply assets of a user on a market after having accrued interests.

  • Warning: Wrong for feeRecipient because their supply shares increase is not taken into account.

  • Warning: Withdrawing using the expected supply assets can lead to a revert due to conversion roundings from assets to shares.

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected supply assets from.
useraddressThe user to get the expected supply assets from.

Return Values:

NameTypeDescription
supplyAssetsuint256The supply assets of the user (with interests accrued).

expectedBorrowAssets

function expectedBorrowAssets(IMorpho morpho, MarketParams memory marketParams, address user)
internal
view
returns (uint256)

Returns the expected borrow assets of a user on a market after having accrued interests.

  • Warning: The expected balance is rounded up, so it may be greater than the market's expected total borrow assets.

Parameters:

NameTypeDescription
morphoIMorphoThe Morpho contract (injected when used as library).
marketParamsMarketParamsThe market to get the expected borrow assets from.
useraddressThe user to get the expected borrow assets from.

Return Values:

NameTypeDescription
borrowBalanceuint256The borrow assets of the user (with interests accrued).