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, looping, etc).

rust
pub struct ObligationKey {
    pub user: Address,
    pub seed: Option<BytesN<32>>,
}
typescript
export interface ObligationKey {
  seed: Option<Buffer>;
  user: string;
}
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) in your obligation.

rust
fn deposit(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
typescript
deposit: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
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 available liquidity limit.

rust
fn withdraw(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
typescript
withdraw: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
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

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>
typescript
add_collateral: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
ParameterTypeDescription
userObligationKeyObligation to add collateral to
pool_addressAddressPool to lock collateral in
amounti128Amount of collateral to add
referrerOption<Address>Optional referrer for fee sharing

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>
typescript
remove_collateral: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
ParameterTypeDescription
userObligationKeyObligation to remove collateral from
pool_addressAddressPool with locked collateral
amounti128Desired amount to remove. Use i128::MAX to remove all available collateral
referrerOption<Address>Optional referrer for fee sharing

Borrows

borrow

Borrow assets against previously supplied collateral.

rust
fn borrow(
    user: ObligationKey,
    pool_address: Address,
    amount: i128,
    referrer: Option<Address>,
) -> Result<(), MCError>
typescript
borrow: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
ParameterTypeDescription
userObligationKeyObligation borrowing against
pool_addressAddressPool to borrow from
amounti128Amount to borrow. Use i128::MAX to borrow the maximum healthy amount
referrerOption<Address>Optional referrer for fee sharing

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>
typescript
repay: (
  {user, pool_address, amount, referrer}:
    {user: string, pool_address: string, amount: i128, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
ParameterTypeDescription
userObligationKeyObligation borrowing against
pool_addressAddressPool to borrow from
amounti128Amount to repay. Provide a slightly larger amount than your liability to close the debt completely (including continuously accrued rate)
referrerOption<Address>Optional referrer for fee sharing

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>
typescript
liquidate: (
  {liquidator, borrower, borrower_obligation_seed,
   borrow_pool_address, collateral_pool_address,
   repay_amount, min_demanded_collateral_amount}: {
    liquidator: string,
    borrower: string,
    borrower_obligation_seed: Option<Buffer>,
    borrow_pool_address: string,
    collateral_pool_address: string,
    repay_amount: i128,
    min_demanded_collateral_amount: i128,
  },
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
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 caller callback. Follows the ERC-3156 standard.

rust
fn flash_loan(
    contract: Address,
    caller: Address,
    pool_address: Address,
    amount: i128,
) -> Result<(), MCError>
typescript
flash_loan: (
  {contract, caller, pool_address, amount}:
    {contract: string, caller: string, pool_address: string, amount: i128},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>
ParameterTypeDescription
contractAddressContract that leverages the flash loaned amount and adheres to the ERC3156 standard
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>
typescript
issue_cover_bad_debt: (
  {user}: {user: string},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>

claim_cover_bad_debt_results

rust
fn claim_cover_bad_debt_results(user: ObligationKey) -> Result<(), MCError>
typescript
claim_cover_bad_debt_results: (
  {user}: {user: string},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>

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>
typescript
distribute_pool_fees: (
  {pool_address}: {pool_address: string},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>

distribute_all_pools_fees

Distribute fees for every pool in the market. Permissionless.

rust
fn distribute_all_pools_fees() -> Result<(), MCError>
typescript
distribute_all_pools_fees: (
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>

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>
typescript
submit_requests_batch: (
  {user, requests, referrer}:
    {user: string, requests: Array<Request>, referrer: Option<string>},
  options?: MethodOptions
) => Promise<AssembledTransaction<Result<void>>>

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),
}
typescript
// The TS SDK flattens batch requests into a struct + enum:
export interface Request {
  amount: i128;
  pool_address: string;
  request_type: u32;
}

export enum RequestType {
  Deposit = 0,
  Borrow = 1,
  Withdraw = 2,
  Repay = 3,
  AddCollateral = 4,
  RemoveCollateral = 5,
}

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