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
NoneStandardGeneral-purpose supply-and-borrow obligation
Some(...)EarnDeposit-only obligation (no borrowing). The contract computes the seed internally.
Some(...)MultiplyIsolated obligation for leveraged (looping) positions. The seed is derived from the deposit/borrow token pair.

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