Skip to content

User Operations

ObligationKey

All user-facing functions identify an obligation through an ObligationKey. This key combines the user's address with an optional seed, allowing a single address to hold multiple isolated positions (standard, earn, pair).

rust
pub struct ObligationKey {
    pub user: Address,
    pub seed: Option<BytesN<32>>,
}
Seed valueObligation typeDescription
NoneStandardNormal supply-and-borrow obligation
Some(earn_seed)EarnDeposit-only obligation (no borrowing)
Some(pair_seed)PairComposed obligation for advanced strategies

Authorization is always against the user address inside the key.

Most user operations also accept an optional referrer: Option<Address> parameter. If the referrer is registered in the pool's fee configuration, they receive an immediate share of the origination fee.


Deposits & Withdrawals

deposit

Supply assets to a pool and receive jTokens (supply shares).

rust
fn deposit(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
ParameterTypeDescription
userObligationKeyObligation receiving the deposit
pool_addressAddressTarget pool address
amounti128Amount to deposit
referrerOption<Address>Optional referrer for fee sharing

withdraw

Redeem jTokens for underlying assets. The actual amount withdrawn is capped to maintain the position's LTV at the pool's Open LTV.

rust
fn withdraw(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
ParameterTypeDescription
userObligationKeyObligation to withdraw from
pool_addressAddressPool to withdraw from
amounti128Desired withdrawal amount. Use i128::MAX to withdraw maximum available
referrerOption<Address>Optional referrer for fee sharing

simulate_withdraw

Simulate a withdrawal to preview fees and actual amount. Read-only, no state changes.

rust
fn simulate_withdraw(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<WithdrawResult, MCError>

Returns a WithdrawResult with the simulated withdrawal data.


Collateral Management

add_collateral

Lock assets as collateral. Collateral does not earn interest but is always available for healthy withdrawals.

rust
fn add_collateral(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>

remove_collateral

Unlock and withdraw collateral. The actual amount removed is capped to maintain the position's LTV at the pool's Open LTV.

rust
fn remove_collateral(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
ParameterTypeDescription
amounti128Desired amount to remove. Use i128::MAX to remove all available collateral

Borrows

borrow

Borrow assets against collateral.

rust
fn borrow(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>

repay

Repay borrowed assets. If the provided amount exceeds the total debt, only the outstanding debt is repaid.

rust
fn repay(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
ParameterTypeDescription
amounti128Amount to repay. Use i128::MAX to repay entire debt

Liquidation

liquidate

Liquidate an unhealthy position (health factor < 1.0). The liquidator repays debt and receives collateral at a discount.

rust
fn liquidate(
    liquidator: Address,
    borrower: ObligationKey,
    borrow_pool_address: Address,
    collateral_pool_address: Address,
    repay_amount: i128,
    demanded_collateral_amount: i128,
) -> Result<(), MCError>
ParameterTypeDescription
liquidatorAddressAddress performing the liquidation
borrowerObligationKeyObligation being liquidated (any type via seed)
borrow_pool_addressAddressPool of debt being repaid
collateral_pool_addressAddressPool of collateral being seized
repay_amounti128Amount of debt to repay
demanded_collateral_amounti128Minimum collateral the liquidator finds sufficient

Flash Loans

flash_loan

Borrow without collateral — the loan must be repaid (with fee) within the same transaction. Follows the ERC-3156 standard.

rust
fn flash_loan(
    contract: Address,
    caller: Address,
    pool_address: Address,
    amount: i128,
) -> Result<(), MCError>
ParameterTypeDescription
contractAddressContract implementing FlashLoanReceiver
callerAddressOriginal caller (for auth)
pool_addressAddressPool to borrow from
amounti128Amount to borrow

Bad Debt Coverage

Bad debt coverage is a two-phase, permissionless process:

  1. issue_cover_bad_debt — Sends cover requests to the Insurance Fund for every bad-debt borrow position on the obligation.
  2. claim_cover_bad_debt_results — After off-chain review, claims the results from the Insurance Fund.

issue_cover_bad_debt

rust
fn issue_cover_bad_debt(user: ObligationKey) -> Result<(), MCError>

claim_cover_bad_debt_results

rust
fn claim_cover_bad_debt_results(user: ObligationKey) -> Result<(), MCError>

Fee Distribution

distribute_pool_fees

Distribute a pool's accumulated fees to the configured beneficiaries. Permissionless.

rust
fn distribute_pool_fees(pool_address: Address) -> Result<(), MCError>

distribute_all_pools_fees

Distribute fees for every pool in the market. Permissionless.

rust
fn distribute_all_pools_fees() -> Result<(), MCError>

Batch Operations

submit_requests_batch

Submit multiple operations in a single atomic transaction. Users can combine deposits, borrows, swaps, and liquidations in one batch to build advanced strategies like leveraged positions.

rust
fn submit_requests_batch(
    user: ObligationKey,
    requests: Vec<Request>,
    referrer: Option<Address>,
) -> Result<(), MCError>

The Request enum has 10 variants:

rust
pub enum Request {
    Deposit(StandardRequest),
    Borrow(StandardRequest),
    Withdraw(StandardRequest),
    Repay(StandardRequest),
    AddCollateral(StandardRequest),
    RemoveCollateral(StandardRequest),
    FlashBorrow(StandardRequest),
    SwapExactTokens(SwapExactTokensRequest),
    SwapForExactTokens(SwapForExactTokensRequest),
    Liquidate(LiquidateRequest),
}

See Request & Response Types — Request Types for the full struct definitions.

Example: Leveraged Position via Batch

A leveraged position can be composed by submitting a batch like:

  1. FlashBorrow the borrow asset
  2. SwapExactTokens borrow asset → deposit asset
  3. Deposit the deposit asset
  4. Borrow the borrow asset
  5. Flash loan is auto-repaid at the end of the batch