Skip to content

Morpho Blue

Connector for Morpho Blue lending protocol.

almanak.framework.connectors.morpho_blue

Morpho Blue Connector.

This module provides adapters and utilities for interacting with Morpho Blue, a permissionless lending protocol that allows creating isolated lending markets.

Morpho Blue Features: - Isolated lending markets with customizable parameters - Supply assets to earn yield (lending) - Supply collateral for borrowing - Borrow against collateral - Flash loans - No intermediary tokens (no aTokens)

Supported Chains: - Ethereum - Base

Example

from almanak.framework.connectors.morpho_blue import ( MorphoBlueAdapter, MorphoBlueConfig, MorphoBlueReceiptParser, MorphoBlueSDK, create_adapter_with_prices, ) from decimal import Decimal

Initialize adapter with prices

config = MorphoBlueConfig( chain="ethereum", wallet_address="0x...", ) prices = {"wstETH": Decimal("2500"), "USDC": Decimal("1")} adapter = create_adapter_with_prices(config, prices)

Get market info

markets = adapter.get_markets() print(f"Available markets: {len(markets)}")

Build a supply collateral transaction

result = adapter.supply_collateral( market_id="0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc", amount=Decimal("1.0"), )

Parse transaction receipts

parser = MorphoBlueReceiptParser() events = parser.parse_receipt(receipt)

Use SDK for on-chain reads

sdk = MorphoBlueSDK(chain="ethereum") position = sdk.get_position(market_id, user_address) print(f"Supply shares: {position.supply_shares}")

MorphoBlueAdapter

MorphoBlueAdapter(
    config: MorphoBlueConfig,
    price_oracle: PriceOracle | None = None,
    token_resolver: TokenResolver | None = None,
)

Adapter for Morpho Blue lending protocol.

This adapter provides methods for interacting with Morpho Blue: - Supply/withdraw assets (lending) - Supply/withdraw collateral - Borrow/repay assets - Health factor calculations - On-chain position and market state reading (via SDK)

Example

Production usage with real prices

config = MorphoBlueConfig( chain="ethereum", wallet_address="0x...", price_provider={"USDC": Decimal("1"), "wstETH": Decimal("3500")}, ) adapter = MorphoBlueAdapter(config)

Read on-chain position

position = adapter.get_position_on_chain(market_id) print(f"Collateral: {position.collateral}")

Supply collateral

result = adapter.supply_collateral( market_id="0x...", amount=Decimal("1.0"), )

For testing only (with placeholder prices)

config = MorphoBlueConfig( chain="ethereum", wallet_address="0x...", allow_placeholder_prices=True, enable_sdk=False, # Disable SDK for unit tests ) adapter = MorphoBlueAdapter(config)

Initialize the adapter.

Parameters:

Name Type Description Default
config MorphoBlueConfig

Adapter configuration

required
price_oracle PriceOracle | None

Optional price oracle callback. If not provided, uses config.price_provider dict or placeholder prices.

None
token_resolver TokenResolver | None

Optional TokenResolver instance. If None, uses singleton.

None

sdk property

sdk: Any

Get the SDK instance (lazy initialization).

Returns:

Type Description
Any

MorphoBlueSDK instance

Raises:

Type Description
RuntimeError

If SDK is disabled

get_position_on_chain

get_position_on_chain(
    market_id: str, user: str | None = None
) -> MorphoBluePosition

Get user position from on-chain data.

Requires SDK to be enabled.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str | None

User address (defaults to wallet_address)

None

Returns:

Type Description
MorphoBluePosition

MorphoBluePosition with supply, borrow, and collateral data

get_market_state_on_chain

get_market_state_on_chain(
    market_id: str,
) -> MorphoBlueMarketState

Get market state from on-chain data.

Requires SDK to be enabled.

Parameters:

Name Type Description Default
market_id str

Market identifier

required

Returns:

Type Description
MorphoBlueMarketState

MorphoBlueMarketState with current market totals

get_market_params_on_chain

get_market_params_on_chain(
    market_id: str,
) -> MorphoBlueMarketParams

Get market parameters from on-chain data.

Requires SDK to be enabled.

Parameters:

Name Type Description Default
market_id str

Market identifier

required

Returns:

Type Description
MorphoBlueMarketParams

MorphoBlueMarketParams with loan token, collateral token, oracle, IRM, LLTV

discover_markets_on_chain

discover_markets_on_chain() -> list[str]

Discover all markets from on-chain events.

Requires SDK to be enabled.

Returns:

Type Description
list[str]

List of market IDs (bytes32 hex strings)

get_supply_assets_on_chain

get_supply_assets_on_chain(
    market_id: str, user: str | None = None
) -> Decimal

Get user's supply amount in assets (not shares) from on-chain.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str | None

User address (defaults to wallet_address)

None

Returns:

Type Description
Decimal

Supply amount in asset units

get_borrow_assets_on_chain

get_borrow_assets_on_chain(
    market_id: str, user: str | None = None
) -> Decimal

Get user's borrow amount in assets (not shares) from on-chain.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str | None

User address (defaults to wallet_address)

None

Returns:

Type Description
Decimal

Borrow amount in asset units

supply

supply(
    market_id: str,
    amount: Decimal,
    on_behalf_of: str | None = None,
    shares_mode: bool = False,
) -> TransactionResult

Build a supply transaction for lending assets.

Supplies loan tokens to the market to earn interest.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount to supply (in token units) or shares if shares_mode=True

required
on_behalf_of str | None

Address to credit (defaults to wallet_address)

None
shares_mode bool

If True, amount represents shares instead of assets

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

withdraw

withdraw(
    market_id: str,
    amount: Decimal,
    receiver: str | None = None,
    on_behalf_of: str | None = None,
    shares_mode: bool = False,
    withdraw_all: bool = False,
) -> TransactionResult

Build a withdraw transaction for withdrawing supplied assets.

Withdraws loan tokens from the market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount to withdraw (in token units) or shares if shares_mode=True

required
receiver str | None

Address to receive tokens (defaults to wallet_address)

None
on_behalf_of str | None

Address to debit (defaults to wallet_address)

None
shares_mode bool

If True, amount represents shares instead of assets

False
withdraw_all bool

If True, withdraws all supplied assets

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

supply_collateral

supply_collateral(
    market_id: str,
    amount: Decimal,
    on_behalf_of: str | None = None,
) -> TransactionResult

Build a supply collateral transaction.

Supplies collateral tokens to the market for borrowing.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount of collateral to supply (in token units)

required
on_behalf_of str | None

Address to credit (defaults to wallet_address)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

withdraw_collateral

withdraw_collateral(
    market_id: str,
    amount: Decimal,
    receiver: str | None = None,
    on_behalf_of: str | None = None,
    withdraw_all: bool = False,
) -> TransactionResult

Build a withdraw collateral transaction.

Withdraws collateral tokens from the market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount of collateral to withdraw (in token units)

required
receiver str | None

Address to receive tokens (defaults to wallet_address)

None
on_behalf_of str | None

Address to debit (defaults to wallet_address)

None
withdraw_all bool

If True, withdraws all collateral

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

borrow

borrow(
    market_id: str,
    amount: Decimal,
    receiver: str | None = None,
    on_behalf_of: str | None = None,
    shares_mode: bool = False,
) -> TransactionResult

Build a borrow transaction.

Borrows loan tokens from the market against collateral.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount to borrow (in token units) or shares if shares_mode=True

required
receiver str | None

Address to receive tokens (defaults to wallet_address)

None
on_behalf_of str | None

Address to debit (defaults to wallet_address)

None
shares_mode bool

If True, amount represents shares instead of assets

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

repay

repay(
    market_id: str,
    amount: Decimal,
    on_behalf_of: str | None = None,
    shares_mode: bool = False,
    repay_all: bool = False,
) -> TransactionResult

Build a repay transaction.

Repays borrowed loan tokens to the market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
amount Decimal

Amount to repay (in token units) or shares if shares_mode=True

required
on_behalf_of str | None

Address with debt (defaults to wallet_address)

None
shares_mode bool

If True, amount represents shares instead of assets

False
repay_all bool

If True, repays full debt

False

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

flash_loan

flash_loan(
    token: str, amount: Decimal, callback_data: bytes = b""
) -> TransactionResult

Build a flash loan transaction.

Borrows assets in a flash loan that must be repaid within the same transaction.

Note: Flash loans require a callback contract to receive and repay the loan. The callback_data is passed to the flash loan receiver.

Parameters:

Name Type Description Default
token str

Token symbol or address to borrow

required
amount Decimal

Amount to borrow

required
callback_data bytes

Data passed to flash loan receiver callback

b''

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

liquidate

liquidate(
    market_id: str,
    borrower: str,
    seized_assets: Decimal,
    repaid_shares: Decimal | None = None,
    callback_data: bytes = b"",
) -> TransactionResult

Build a liquidation transaction.

Liquidates an unhealthy position by repaying debt and seizing collateral.

In Morpho Blue, liquidators specify the amount of collateral to seize, and the protocol calculates how much debt to repay based on the oracle price and liquidation incentive.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
borrower str

Address of the borrower to liquidate

required
seized_assets Decimal

Amount of collateral to seize (in collateral token units)

required
repaid_shares Decimal | None

Optional amount of debt shares to repay (if 0, uses seized_assets)

None
callback_data bytes

Data passed to liquidation callback (for flash liquidations)

b''

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

set_authorization

set_authorization(
    authorized: str, is_authorized: bool
) -> TransactionResult

Build a set authorization transaction.

Authorizes another address to manage positions on behalf of the caller.

Parameters:

Name Type Description Default
authorized str

Address to authorize/deauthorize

required
is_authorized bool

Whether to grant or revoke authorization

required

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

get_market_info

get_market_info(market_id: str) -> dict[str, Any] | None

Get information about a market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required

Returns:

Type Description
dict[str, Any] | None

Market info dictionary or None if not found

get_markets

get_markets() -> dict[str, dict[str, Any]]

Get all known markets for the current chain.

Returns:

Type Description
dict[str, dict[str, Any]]

Dictionary mapping market_id to market info

get_market_params

get_market_params(
    market_id: str,
) -> MorphoBlueMarketParams | None

Get market parameters for a market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required

Returns:

Type Description
MorphoBlueMarketParams | None

MorphoBlueMarketParams or None if not found

calculate_health_factor

calculate_health_factor(
    collateral_amount: Decimal,
    collateral_price_usd: Decimal,
    debt_amount: Decimal,
    debt_price_usd: Decimal,
    lltv: Decimal,
) -> MorphoBlueHealthFactor

Calculate health factor for a position.

Health Factor = (Collateral Value * LLTV) / Debt Value

Parameters:

Name Type Description Default
collateral_amount Decimal

Amount of collateral

required
collateral_price_usd Decimal

Price of collateral in USD

required
debt_amount Decimal

Amount of debt

required
debt_price_usd Decimal

Price of debt token in USD

required
lltv Decimal

Liquidation LTV (0-1 scale)

required

Returns:

Type Description
MorphoBlueHealthFactor

MorphoBlueHealthFactor with calculated values

build_approve_transaction

build_approve_transaction(
    token: str,
    amount: Decimal | None = None,
    spender: str | None = None,
) -> TransactionResult

Build an ERC20 approve transaction.

Parameters:

Name Type Description Default
token str

Token symbol or address to approve

required
amount Decimal | None

Amount to approve (None for max)

None
spender str | None

Address to approve (defaults to Morpho Blue contract)

None

Returns:

Type Description
TransactionResult

TransactionResult with transaction data

MorphoBlueConfig dataclass

MorphoBlueConfig(
    chain: str,
    wallet_address: str,
    default_slippage_bps: int = 50,
    rpc_url: str | None = None,
    price_provider: dict[str, Decimal] | None = None,
    allow_placeholder_prices: bool = False,
    enable_sdk: bool = True,
)

Configuration for Morpho Blue adapter.

Attributes:

Name Type Description
chain str

Blockchain network (ethereum, base)

wallet_address str

User wallet address

default_slippage_bps int

Default slippage tolerance in basis points

rpc_url str | None

Optional RPC URL. If not provided, uses ALCHEMY_API_KEY.

price_provider dict[str, Decimal] | None

Optional dict mapping token symbols to USD prices. Required for health factor calculations in production.

allow_placeholder_prices bool

If True, allows using placeholder prices for testing. DO NOT use in production.

enable_sdk bool

If True, initializes the SDK for on-chain reads. Requires RPC access.

__post_init__

__post_init__() -> None

Validate configuration.

MorphoBlueHealthFactor dataclass

MorphoBlueHealthFactor(
    collateral_value_usd: Decimal,
    debt_value_usd: Decimal,
    lltv: Decimal,
    health_factor: Decimal,
    max_borrow_usd: Decimal = Decimal("0"),
)

Health factor calculation for a Morpho Blue position.

Attributes:

Name Type Description
collateral_value_usd Decimal

Value of collateral in USD

debt_value_usd Decimal

Value of debt in USD

lltv Decimal

Liquidation LTV of the market

health_factor Decimal

Calculated health factor

max_borrow_usd Decimal

Maximum borrowable amount

is_healthy property

is_healthy: bool

Check if position is healthy (HF >= 1).

liquidation_threshold_usd property

liquidation_threshold_usd: Decimal

Get the USD debt level at which liquidation would occur.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

MorphoBlueInterestRateMode

Bases: IntEnum

Morpho Blue uses a single interest rate model per market.

Unlike Aave, Morpho Blue markets have a single adaptive interest rate determined by the IRM (Interest Rate Model) contract.

MorphoBlueMarketParams dataclass

MorphoBlueMarketParams(
    loan_token: str,
    collateral_token: str,
    oracle: str,
    irm: str,
    lltv: int,
)

Market parameters for Morpho Blue.

In Morpho Blue, each market is uniquely identified by these 5 parameters. The market_id is derived as: keccak256(abi.encode(loan_token, collateral_token, oracle, irm, lltv))

Attributes:

Name Type Description
loan_token str

Address of the asset being borrowed

collateral_token str

Address of the collateral asset

oracle str

Address of the price oracle

irm str

Address of the interest rate model

lltv int

Liquidation LTV (in 1e18 scale, e.g., 860000000000000000 = 86%)

to_tuple

to_tuple() -> tuple[str, str, str, str, int]

Convert to tuple for ABI encoding.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

MorphoBlueMarketState dataclass

MorphoBlueMarketState(
    market_id: str,
    total_supply_assets: Decimal = Decimal("0"),
    total_supply_shares: Decimal = Decimal("0"),
    total_borrow_assets: Decimal = Decimal("0"),
    total_borrow_shares: Decimal = Decimal("0"),
    last_update: int = 0,
    fee: Decimal = Decimal("0"),
)

State of a Morpho Blue market.

Attributes:

Name Type Description
market_id str

Unique identifier for the market

total_supply_assets Decimal

Total assets supplied to the market

total_supply_shares Decimal

Total supply shares

total_borrow_assets Decimal

Total assets borrowed from the market

total_borrow_shares Decimal

Total borrow shares

last_update int

Timestamp of last interest accrual

fee Decimal

Protocol fee (in 1e18 scale)

utilization property

utilization: Decimal

Calculate market utilization rate.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

MorphoBluePosition dataclass

MorphoBluePosition(
    market_id: str,
    supply_shares: Decimal = Decimal("0"),
    borrow_shares: Decimal = Decimal("0"),
    collateral: Decimal = Decimal("0"),
)

User position in a Morpho Blue market.

Attributes:

Name Type Description
market_id str

Market identifier

supply_shares Decimal

User's supply shares

borrow_shares Decimal

User's borrow shares

collateral Decimal

User's collateral amount

has_supply property

has_supply: bool

Check if user has supply in this market.

has_borrow property

has_borrow: bool

Check if user has borrow in this market.

has_collateral property

has_collateral: bool

Check if user has collateral in this market.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

TransactionResult dataclass

TransactionResult(
    success: bool,
    tx_data: dict[str, Any] | None = None,
    gas_estimate: int = 0,
    description: str = "",
    error: str | None = None,
)

Result of a transaction build operation.

Attributes:

Name Type Description
success bool

Whether operation succeeded

tx_data dict[str, Any] | None

Transaction data (to, value, data)

gas_estimate int

Estimated gas

description str

Human-readable description

error str | None

Error message if failed

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

AccrueInterestEventData dataclass

AccrueInterestEventData(
    market_id: str,
    prev_borrow_rate: Decimal,
    interest: Decimal,
    fee_shares: Decimal,
)

Parsed data from AccrueInterest event.

Attributes:

Name Type Description
market_id str

Unique market identifier

prev_borrow_rate Decimal

Previous borrow rate (per second, 1e18 scale)

interest Decimal

Total interest accrued

fee_shares Decimal

Shares minted as protocol fee

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

BorrowEventData dataclass

BorrowEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    receiver: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Borrow event.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the borrow

on_behalf_of str

Address that received the debt

receiver str

Address that received the borrowed assets

assets Decimal

Amount of assets borrowed

shares Decimal

Amount of borrow shares minted

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

CreateMarketEventData dataclass

CreateMarketEventData(
    market_id: str,
    loan_token: str,
    collateral_token: str,
    oracle: str,
    irm: str,
    lltv: int,
)

Parsed data from CreateMarket event.

Attributes:

Name Type Description
market_id str

Unique market identifier

loan_token str

Address of the loan token

collateral_token str

Address of the collateral token

oracle str

Address of the oracle

irm str

Address of the interest rate model

lltv int

Liquidation LTV (1e18 scale)

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

FlashLoanEventData dataclass

FlashLoanEventData(
    caller: str, token: str, assets: Decimal
)

Parsed data from FlashLoan event.

Attributes:

Name Type Description
caller str

Address that initiated the flash loan

token str

Address of the token borrowed

assets Decimal

Amount borrowed

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

LiquidateEventData dataclass

LiquidateEventData(
    market_id: str,
    caller: str,
    borrower: str,
    repaid_assets: Decimal,
    repaid_shares: Decimal,
    seized_assets: Decimal,
    bad_debt_assets: Decimal = Decimal("0"),
    bad_debt_shares: Decimal = Decimal("0"),
)

Parsed data from Liquidate event.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the liquidation

borrower str

Address of the borrower being liquidated

repaid_assets Decimal

Amount of debt repaid

repaid_shares Decimal

Amount of borrow shares burned

seized_assets Decimal

Amount of collateral seized

bad_debt_assets Decimal

Amount of bad debt (if any)

bad_debt_shares Decimal

Amount of bad debt shares (if any)

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

MorphoBlueEvent dataclass

MorphoBlueEvent(
    event_type: MorphoBlueEventType,
    event_name: str,
    log_index: int,
    transaction_hash: str,
    block_number: int,
    contract_address: str,
    data: dict[str, Any],
    raw_topics: list[str] = list(),
    raw_data: str = "",
    timestamp: datetime = (lambda: datetime.now(tz=None))(),
)

Parsed Morpho Blue event.

Attributes:

Name Type Description
event_type MorphoBlueEventType

Type of event

event_name str

Name of event (e.g., "Supply")

log_index int

Index of log in transaction

transaction_hash str

Transaction hash

block_number int

Block number

contract_address str

Contract that emitted event

data dict[str, Any]

Parsed event data

raw_topics list[str]

Raw event topics

raw_data str

Raw event data

timestamp datetime

Event timestamp

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

from_dict classmethod

from_dict(data: dict[str, Any]) -> MorphoBlueEvent

Create from dictionary.

MorphoBlueEventType

Bases: Enum

Morpho Blue event types.

MorphoBlueReceiptParser

MorphoBlueReceiptParser(**kwargs: Any)

Parser for Morpho Blue transaction receipts.

This parser extracts and decodes events from Morpho Blue transactions, providing structured data for supply, borrow, repay, withdraw, liquidation, and other protocol operations.

Example

parser = MorphoBlueReceiptParser()

Parse a receipt

result = parser.parse_receipt(receipt)

if result.success: for event in result.events: print(f"{event.event_name}: {event.data}")

Initialize the parser.

Parameters:

Name Type Description Default
**kwargs Any

Additional arguments (ignored for compatibility)

{}

parse_receipt

parse_receipt(
    receipt: dict[str, Any],
    timestamp: datetime | None = None,
) -> ParseResult

Parse a transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dictionary with 'logs' field

required
timestamp datetime | None

Optional timestamp for events

None

Returns:

Type Description
ParseResult

ParseResult with parsed events

is_morpho_event

is_morpho_event(topic: str | bytes) -> bool

Check if a topic is a known Morpho Blue event.

Parameters:

Name Type Description Default
topic str | bytes

Event topic (supports bytes, hex string with/without 0x, any case)

required

Returns:

Type Description
bool

True if the topic is a known Morpho Blue event

get_event_type

get_event_type(
    topic_or_name: str | bytes,
) -> MorphoBlueEventType

Get event type from topic hash or event name.

Parameters:

Name Type Description Default
topic_or_name str | bytes

Event topic (supports bytes, hex string with/without 0x, any case) or event name

required

Returns:

Type Description
MorphoBlueEventType

MorphoBlueEventType enum value

extract_supply_amount

extract_supply_amount(
    receipt: dict[str, Any],
) -> int | None

Extract supply amount (assets) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Supply amount in token units if found, None otherwise

extract_withdraw_amount

extract_withdraw_amount(
    receipt: dict[str, Any],
) -> int | None

Extract withdraw amount (assets) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Withdraw amount in token units if found, None otherwise

extract_borrow_amount

extract_borrow_amount(
    receipt: dict[str, Any],
) -> int | None

Extract borrow amount (assets) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Borrow amount in token units if found, None otherwise

extract_repay_amount

extract_repay_amount(receipt: dict[str, Any]) -> int | None

Extract repay amount (assets) from transaction receipt.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Repay amount in token units if found, None otherwise

extract_shares_received

extract_shares_received(
    receipt: dict[str, Any],
) -> int | None

Extract shares received from supply transaction.

In Morpho Blue, supplying assets mints shares representing the deposit.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Shares minted if found, None otherwise

extract_shares_burned

extract_shares_burned(
    receipt: dict[str, Any],
) -> int | None

Extract shares burned from withdraw or repay transaction.

In Morpho Blue, withdrawing/repaying burns shares.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required

Returns:

Type Description
int | None

Shares burned if found, None otherwise

ParseResult dataclass

ParseResult(
    success: bool,
    events: list[MorphoBlueEvent] = list(),
    error: str | None = None,
    transaction_hash: str = "",
    block_number: int = 0,
)

Result of parsing a transaction receipt.

Attributes:

Name Type Description
success bool

Whether parsing succeeded

events list[MorphoBlueEvent]

List of parsed events

error str | None

Error message if parsing failed

transaction_hash str

Hash of the parsed transaction

block_number int

Block number

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

RepayEventData dataclass

RepayEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Repay event.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that made the repayment

on_behalf_of str

Address whose debt was repaid

assets Decimal

Amount of assets repaid

shares Decimal

Amount of borrow shares burned

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SetAuthorizationEventData dataclass

SetAuthorizationEventData(
    caller: str,
    authorizer: str,
    authorized: str,
    is_authorized: bool,
)

Parsed data from SetAuthorization event.

Attributes:

Name Type Description
caller str

Address that set the authorization

authorizer str

Address that granted the authorization

authorized str

Address that received the authorization

is_authorized bool

Whether authorization was granted or revoked

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SupplyCollateralEventData dataclass

SupplyCollateralEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    assets: Decimal,
)

Parsed data from SupplyCollateral event.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the collateral supply

on_behalf_of str

Address that received the collateral credit

assets Decimal

Amount of collateral supplied

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SupplyEventData dataclass

SupplyEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Supply event.

In Morpho Blue, Supply is for lending assets to earn interest.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the supply

on_behalf_of str

Address that received the supply shares

assets Decimal

Amount of assets supplied

shares Decimal

Amount of shares minted

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

TransferEventData dataclass

TransferEventData(
    from_address: str, to_address: str, amount: Decimal
)

Parsed data from ERC20 Transfer event.

Attributes:

Name Type Description
from_address str

Sender address

to_address str

Recipient address

amount Decimal

Amount transferred

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

WithdrawCollateralEventData dataclass

WithdrawCollateralEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    receiver: str,
    assets: Decimal,
)

Parsed data from WithdrawCollateral event.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the withdrawal

on_behalf_of str

Address whose collateral was withdrawn

receiver str

Address that received the collateral

assets Decimal

Amount of collateral withdrawn

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

WithdrawEventData dataclass

WithdrawEventData(
    market_id: str,
    caller: str,
    on_behalf_of: str,
    receiver: str,
    assets: Decimal,
    shares: Decimal,
)

Parsed data from Withdraw event.

In Morpho Blue, Withdraw is for withdrawing supplied (lending) assets.

Attributes:

Name Type Description
market_id str

Unique market identifier

caller str

Address that initiated the withdrawal

on_behalf_of str

Address whose shares were burned

receiver str

Address that received the assets

assets Decimal

Amount of assets withdrawn

shares Decimal

Amount of shares burned

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

MarketNotFoundError

MarketNotFoundError(market_id: str)

Bases: MorphoBlueSDKError

Market does not exist or has not been created.

MorphoBlueSDK

MorphoBlueSDK(
    chain: str = "ethereum", rpc_url: str | None = None
)

Low-level SDK for Morpho Blue protocol interactions.

This SDK handles direct RPC calls to read on-chain state from Morpho Blue. It uses raw calldata encoding for efficiency and minimal dependencies.

Example

sdk = MorphoBlueSDK(chain="ethereum")

Get user position

position = sdk.get_position(market_id, user_address) print(f"Supply shares: {position.supply_shares}") print(f"Borrow shares: {position.borrow_shares}")

Get market state

state = sdk.get_market_state(market_id) print(f"Utilization: {state.utilization_percent}%")

Discover markets

market_ids = sdk.discover_markets()

Initialize the SDK.

Parameters:

Name Type Description Default
chain str

Chain name (ethereum, base)

'ethereum'
rpc_url str | None

Optional RPC URL. If not provided, uses ALCHEMY_API_KEY.

None

Raises:

Type Description
UnsupportedChainError

If chain is not supported

get_position

get_position(market_id: str, user: str) -> SDKPosition

Get user position in a market.

Calls the position(bytes32 id, address user) view function.

Parameters:

Name Type Description Default
market_id str

Market identifier (bytes32 hex string)

required
user str

User address

required

Returns:

Type Description
SDKPosition

SDKPosition with supply_shares, borrow_shares, collateral

Raises:

Type Description
RPCError

If RPC call fails

get_supply_shares

get_supply_shares(market_id: str, user: str) -> int

Get user's supply shares in a market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str

User address

required

Returns:

Type Description
int

Supply shares (1e18 scale)

get_borrow_shares

get_borrow_shares(market_id: str, user: str) -> int

Get user's borrow shares in a market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str

User address

required

Returns:

Type Description
int

Borrow shares (1e18 scale)

get_collateral

get_collateral(market_id: str, user: str) -> int

Get user's collateral in a market.

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str

User address

required

Returns:

Type Description
int

Collateral amount (in token units)

get_market_state

get_market_state(market_id: str) -> SDKMarketState

Get current state of a market.

Calls the market(bytes32 id) view function.

Parameters:

Name Type Description Default
market_id str

Market identifier (bytes32 hex string)

required

Returns:

Type Description
SDKMarketState

SDKMarketState with totals and utilization

Raises:

Type Description
MarketNotFoundError

If market doesn't exist

RPCError

If RPC call fails

get_market_params

get_market_params(market_id: str) -> SDKMarketParams

Get market parameters.

Calls the idToMarketParams(bytes32 id) view function.

Parameters:

Name Type Description Default
market_id str

Market identifier (bytes32 hex string)

required

Returns:

Type Description
SDKMarketParams

SDKMarketParams with token addresses, oracle, IRM, and LLTV

Raises:

Type Description
MarketNotFoundError

If market doesn't exist

RPCError

If RPC call fails

get_market_info

get_market_info(market_id: str) -> SDKMarketInfo

Get complete market information (params + state).

Parameters:

Name Type Description Default
market_id str

Market identifier

required

Returns:

Type Description
SDKMarketInfo

SDKMarketInfo with both params and state

discover_markets

discover_markets(
    from_block: int | None = None,
    to_block: int | str = "latest",
) -> list[str]

Discover all markets by scanning CreateMarket events.

Scans the blockchain for CreateMarket events to find all market IDs.

Parameters:

Name Type Description Default
from_block int | None

Starting block (defaults to Morpho deployment block)

None
to_block int | str

Ending block (defaults to "latest")

'latest'

Returns:

Type Description
list[str]

List of market IDs (bytes32 hex strings)

Raises:

Type Description
RPCError

If event scanning fails

get_market_count

get_market_count() -> int

Get the total number of markets created.

Returns:

Type Description
int

Number of markets discovered

get_block_number

get_block_number() -> int

Get current block number.

Returns:

Type Description
int

Current block number

get_chain_id

get_chain_id() -> int

Get chain ID.

Returns:

Type Description
int

Chain ID

is_connected

is_connected() -> bool

Check if connected to RPC.

Returns:

Type Description
bool

True if connected

shares_to_assets

shares_to_assets(
    shares: int, total_assets: int, total_shares: int
) -> int

Convert shares to assets.

Uses the Morpho formula: assets = shares * totalAssets / totalShares

Parameters:

Name Type Description Default
shares int

Number of shares

required
total_assets int

Total assets in market

required
total_shares int

Total shares in market

required

Returns:

Type Description
int

Asset amount

assets_to_shares

assets_to_shares(
    assets: int, total_assets: int, total_shares: int
) -> int

Convert assets to shares.

Uses the Morpho formula: shares = assets * totalShares / totalAssets

Parameters:

Name Type Description Default
assets int

Asset amount

required
total_assets int

Total assets in market

required
total_shares int

Total shares in market

required

Returns:

Type Description
int

Number of shares

get_supply_assets

get_supply_assets(market_id: str, user: str) -> int

Get user's supply amount in assets (not shares).

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str

User address

required

Returns:

Type Description
int

Supply amount in asset units

get_borrow_assets

get_borrow_assets(market_id: str, user: str) -> int

Get user's borrow amount in assets (not shares).

Parameters:

Name Type Description Default
market_id str

Market identifier

required
user str

User address

required

Returns:

Type Description
int

Borrow amount in asset units

MorphoBlueSDKError

Bases: Exception

Base exception for Morpho Blue SDK errors.

PositionNotFoundError

PositionNotFoundError(market_id: str, user: str)

Bases: MorphoBlueSDKError

Position does not exist for user in market.

RPCError

RPCError(message: str, method: str)

Bases: MorphoBlueSDKError

Error making RPC call.

SDKMarketInfo dataclass

SDKMarketInfo(
    params: SDKMarketParams, state: SDKMarketState
)

Complete market information combining state and params.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SDKMarketParams dataclass

SDKMarketParams(
    market_id: str,
    loan_token: str,
    collateral_token: str,
    oracle: str,
    irm: str,
    lltv: int,
)

Market parameters for a Morpho Blue market (from on-chain read).

These parameters uniquely identify a market. The market_id is derived as: keccak256(abi.encode(loanToken, collateralToken, oracle, irm, lltv))

Attributes:

Name Type Description
market_id str

Market identifier (bytes32 as hex string)

loan_token str

Address of the asset being borrowed

collateral_token str

Address of the collateral asset

oracle str

Address of the price oracle

irm str

Address of the interest rate model

lltv int

Liquidation LTV (1e18 scale, e.g., 0.86e18 = 86%)

lltv_percent property

lltv_percent: Decimal

LLTV as percentage (0-100).

lltv_decimal property

lltv_decimal: Decimal

LLTV as decimal (0-1).

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SDKMarketState dataclass

SDKMarketState(
    market_id: str,
    total_supply_assets: int,
    total_supply_shares: int,
    total_borrow_assets: int,
    total_borrow_shares: int,
    last_update: int,
    fee: int,
)

Current state of a Morpho Blue market (from on-chain read).

Attributes:

Name Type Description
market_id str

Market identifier

total_supply_assets int

Total assets supplied to the market

total_supply_shares int

Total supply shares

total_borrow_assets int

Total assets borrowed

total_borrow_shares int

Total borrow shares

last_update int

Timestamp of last interest accrual

fee int

Protocol fee (1e18 scale, e.g., 0.1e18 = 10%)

utilization property

utilization: Decimal

Calculate market utilization rate (0-1 scale).

utilization_percent property

utilization_percent: Decimal

Utilization as percentage (0-100).

available_liquidity property

available_liquidity: int

Available liquidity for borrowing.

fee_percent property

fee_percent: Decimal

Fee as percentage.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

SDKPosition dataclass

SDKPosition(
    market_id: str,
    user: str,
    supply_shares: int,
    borrow_shares: int,
    collateral: int,
)

User position in a Morpho Blue market (from on-chain read).

Attributes:

Name Type Description
market_id str

Market identifier

user str

User address

supply_shares int

User's supply shares (1e18 scale)

borrow_shares int

User's borrow shares (1e18 scale)

collateral int

User's collateral amount (in token units)

has_supply property

has_supply: bool

Check if user has supply position.

has_borrow property

has_borrow: bool

Check if user has borrow position.

has_collateral property

has_collateral: bool

Check if user has collateral.

is_empty property

is_empty: bool

Check if position is empty.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

UnsupportedChainError

UnsupportedChainError(chain: str)

Bases: MorphoBlueSDKError

Chain is not supported by Morpho Blue.

create_adapter_with_prices

create_adapter_with_prices(
    config: MorphoBlueConfig, prices: dict[str, Decimal]
) -> MorphoBlueAdapter

Create an adapter with a dictionary of real prices.

This is the recommended way to create an adapter for production use. It ensures accurate health factor calculations by providing real prices.

Parameters:

Name Type Description Default
config MorphoBlueConfig

Adapter configuration

required
prices dict[str, Decimal]

Dict mapping token symbols to USD prices

required

Returns:

Type Description
MorphoBlueAdapter

MorphoBlueAdapter configured with real prices

Example

prices = { "USDC": Decimal("1.00"), "USDT": Decimal("1.00"), "wstETH": Decimal("3500.00"), "WETH": Decimal("3100.00"), "WBTC": Decimal("98000.00"), } config = MorphoBlueConfig( chain="ethereum", wallet_address="0x...", ) adapter = create_adapter_with_prices(config, prices)

create_test_adapter

create_test_adapter(
    chain: str = "ethereum",
    wallet_address: str = "0x1234567890123456789012345678901234567890",
) -> MorphoBlueAdapter

Create a test adapter with placeholder prices and SDK disabled.

For unit testing only. DO NOT use in production.

Parameters:

Name Type Description Default
chain str

Chain name (default: ethereum)

'ethereum'
wallet_address str

Wallet address (default: test address)

'0x1234567890123456789012345678901234567890'

Returns:

Type Description
MorphoBlueAdapter

MorphoBlueAdapter configured for testing