A generalized credit protocol utilizing Mars lending market

Please carefully review the disclaimers at the end of the article.

DeFi lending protocols, such as Aave and Compound, typically require users to first deposit some collateral assets before they can borrow. Once deposited, this collateral is locked inside the lending market smart contracts; the users are not allowed to put them into productive use as they see fit.

In this article, I propose a different approach for Mars protocol, which utilizes a generalized credit account manager built on top of Mars’ Red Bank. This approach will allow borrowers to retain control of their collateral assets, while at the same time providing a return for lenders.

Credit manager and credit accounts

The target audience of the credit manager is risk-seeking investors who wish to undertake leveraged trading or yield farming activities.

To start, a user first needs to access the Mars credit manager contract and request the opening of a credit account. The credit account is analogous to a “sub-account” on centralized trading platforms such as FTX, and is represented by a non-fungible token (NFT).

Users interact with their credit accounts by executing actions. In Rust/CosmWasm code, this can be expressed as (using the cw-asset library):

use cosmwasm_std::Uint128;
use cw_asset::{Asset, AssetList, AssetInfo};
 
enum Action {
    /// deposit the specified asset into the credit account
    Deposit(Asset),
    /// withdraw the specified asset from the credit account
    Withdraw(Asset),
    /// borrow the specified asset from Red Bank
    Borrow(Asset),
    /// repay the specified asset to Red Bank
    Repay(Asset),
    /// swap the asset in the credit account
    Swap {
        offer: Asset,
        ask: AssetInfo,
        minimum_receive: Option<Uint128>,
    },
    /// deposit assets into a vault (e.g. an automated
    /// yield farming strategy)
    EnterVault {
        vault_addr: String,
        deposits: AssetList,
    },
    /// withdraw assets from a vault
    ExitVault {
        vault_addr: String,
        shares: Uint128,
    },
}
 
enum ExecuteMsg {
    /// mint a new credit account NFT
    CreateCreditAccount {
        initial_deposits: AssetList,
    },
    /// update a credit account specified by the token id
    /// by executing an array of actions
    UpdateCreditAccount {
        token_id: String,
        actions: Vec<Action>,
    },
}

The credit manager contract executes the list of actions specified by ExecuteMsg::UpdateCreditAccount { actions } in order. After all actions have been executed, it calculates the overall health factor of the credit account. If the account is unhealthy as a result of the actions, an error is thrown and all actions reverted.

Some readers might have noticed that this design resembles the Fields of Mars contract in Mars V1. Indeed, the credit account can be considered a direct extension of Fields, of which many code components can be reused.

Deposit and borrowing

In the example below, the user funds a freshly-opened credit account with 50 USDC, and borrows 100 USDC from Mars liquidity pool. To do this, provide the following execute message:

{
  "update_credit_account": {
    "token_id": "...",
    "actions": [
      {
        "deposit": {
          "info": {
            "native": "uusdc"
          },
          "amount": "50000000"
        }
      },
      {
        "borrow": {
          "info": {
            "native": "uusdc"
          },
          "amount": "100000000"
        }
      }
    ]
 }
}

The actions results in the following credit account position:

This example highlights a few characteristics of the credit account:

  1. The credit manager does not need to explicitly deposit collateral into Red Bank before borrowing from it. In other words, the loan is extended to the credit manager in the form of uncollateralized debt. (NOTE: Martian Council must have approved an uncollateralized limit)
  2. The user borrows more assets ($100) than their deposit ($50). To our knowledge, this is not possible with other lending protocols. Despite this, the credit account remains over-collateralized ($150 in assets vs $100 in liabilities).
  3. A production-ready credit manager contract will probably need to use a more sophisticated algorithm to assess the health of credit accounts, which takes into consideration various risk factors such as the volatility and market liquidity of each supported asset. In this article, we use LTV for simplicity sake.

Leveraged trading

Credit accounts support trading of assets. Continuing from the previous example, the user may provide the following execute message, which swaps 50 USDC for OSMO (assuming OSMO price is ~$2):

{
  "update_credit_account": {
    "token_id": "...",
    "actions": [
      {
        "swap": {
          "offer": {
            "info": {
              "native": "uusdc"
            },
            "amount": "50000000"
          },
          "ask": {
            "native": "uosmo"
          },
          "minimum_receive": "25000000"
        }
      }
    ]
  }
}

Which results in the following credit account position:

Although the trade takes place on a spot exchange, since it is (partially) funded by borrowed assets from Red Bank, the user here effectively takes a leveraged long position on OSMO.

Vaults

The credit manager may support vaults created by third party protocols, which provide automated trading or yield farming strategies, as long as these vaults are approved by Martian Council (governance), and implement a standard API.

The API includes execute functions for entering or exiting, and query functions for assessing the asset value locked in the vault. The execute functions also must emit events in a specific format (out of scope for this article) so that they can be parsed by the credit manager.

/// each vault contract must implement this
enum VaultExecuteMsg {
    Enter {
        deposits: AssetList,
    },
    Exit {
        shares: Uint128,
    },
}
 
/// each vault contract must implement this
enum VaultQueryMsg {
    /// the amount of assets under management of the vault that 
    /// belongs to a specific user; response type: `cw_asset::AssetList`
    Deposit {
        user: String,
    },
}

For example, assume a vault that takes OSMO and USDC deposits, provides them to an Osmosis DEX pool, stakes the LP share tokens, and auto-compounds staking rewards. To enter this vault, the user executes:

{
  "update_credit_account": {
    "token_id": "...",
    "actions": [
      {
        "enter_vault": {
          "vault_addr": "...",
          "deposits": [
            {
              "info": {
                "native": "uosmo"
              },
              "amount": "25000000"
            },
            {
              "info": {
                "native": "uusdc"
              },
              "amount": "50000000"
            }
          ]
        }
      }
    ]
  }
}

Which results in:

NOTE: It is possible to execute the two previous steps (swap and enter vault) in one transaction, improving user experience.

Liquidations

To ensure solvency (i.e. that the protocol always has more assets than liabilities), the credit manager must monitor the health factor of each credit account, and execute liquidations when necessary.

A credit account’s health factor may drop due to:

  • the value of assets going down (e.g. prices dropping)
  • the value of liabilities going up (e.g. borrow interest accrues, or prices of the debt assets going up)

Once the health factor drops below a preset threshold (liquidation threshold, a governance-decided parameter), any person can trigger a liquidation of the credit account. The liquidator must pay back some amounts of debts on behalf of the credit account; they will in return be rewarded some of the account’s assets as the liquidation bonus:

The liquidator may then sell the vault shares in the secondary market.

In this example, the user account’s net value falls from $20 ($120 in assets minus $100 in liabilities) to $15 (losing $5), while the liquidator’s account net value increases by $5. The transfer of this $5 is the liquidation bonus, rewarded to the liquidator for deploying capital to ensure the protocol’s solvency. The maximum allowed amount of bonus for each liquidation event, the bonus rate, can either be set by governance (i.e. the approach used by Aave) or by free market mechanisms (Euler).

Closing thoughts

A generalized credit protocol would enable leveraged trading or yield farming capabilities that are largely available only on centralized exchanges today. End users would be able to borrow more than they’ve deposited into the lending protocol while still ensuring all credit accounts are fully collateralized. Mars Hub’s decentralized architecture would also give third parties the ability to propose and write new trading and yield farming strategies that could tap Red Bank deposits on any supported blockchain. The proposed protocol would increase utility for traders. This new source of demand may generate higher yields for depositors and more fees for Mars Hub and MARS stakers.

Disclaimers

Please be advised: This article sets forth speculation regarding a possible design of a potential generalized credit account protocol built utilizing ‘Mars protocol’. There is no guarantee or promise being made, or duty or obligation being assumed, or right being created or conferred hereby, and no contract or agreement is implied. There is no guarantee or assurance that new Mars software will be created or deployed, or that any Mars software which is created or deployed will adhere to the design or have all of the features described herein.

If Mars software is created or deployed, this article does not constitute a representation, warranty or guarantee as to how that software will function or the outcomes to be produced by that software. This article is not an offer or solicitation to purchase or otherwise acquire MARS tokens, and does not constitute investment or other advice.

Mars protocol is open-source software, and the Mars branding is licensed under creative commons. Accordingly, no single person or group controls what forks or derivations of Mars protocol may be created in the future. There is no specific entity or entities that have promised or committed to develop the software described herein, and you should not have any expectation of continued software development or governance on the part of any specific person or persons.

Do not make any financial decisions based on this article.

This article is further qualified by, and subject to, the Mars Disclaimers.

I went down the account rabbit hole after reading Jose’s tweet. The only additional functionality I think could add huge utility if possible, would be granting the Account priority in liquidation mechanisms wherein if it is holding the assets and they are liquid, it gets the chance to repay the debt instead of getting liquidated.

This can be done through the list of Events made by the Account contract. All the dApp would need to add is a check, a query in this case, to see if the Account has the debt asset liquid. If it says it doesn’t or it does and there is an error w/ the query, parse the reply and/or liquidate as normal.

Users would enjoy the added safety to liquid actions and the markets would benefit from the added liquidity and softened downturns.