Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BSIP70: Lending for Margin Trading #170

Closed
MichelSantos opened this issue May 19, 2019 · 90 comments
Closed

BSIP70: Lending for Margin Trading #170

MichelSantos opened this issue May 19, 2019 · 90 comments

Comments

@MichelSantos
Copy link
Contributor

MichelSantos commented May 19, 2019

BSIP: 70
Title: Peer-to-Peer Leveraged Trading (Variant B)
Authors: George Harrap, Michel Santos, Peter Conrad
Status: Draft
Type: Protocol
Created: 2019-06-17
Discussion: https://github.com/bitshares/bsips/issues/170

Abstract

This BSIP defines a protocol upgrade in order to support peer-to-peer lending, borrowing and margin trading markets on the BitShares DEX. Lending is defined as any user of the BitShares DEX having the ability to post an offer to lend any BitShares asset they own to a market where a borrower may take that offer (by posting collateral) and pay the lender a lender-defined amount of interest over a time period.

The Borrower may choose to take the offer or post their preferred borrowing interest rate as a Bid and when taken, execute an exchange transaction with that token for another specified by the lender. The borrower will pay the lender interest in the asset type that was borrowed. Should the value of their margin position fall by a specified amount, the borrowers' balance will be margin called and sold on the market to payback the debt to the lender. The borrower risks losing their collateral in the case of a margin call and the lender risks the orderbook depth being insufficient to pay back their loan in the specified market.

Motivation

BitShares is the longest running decentralised cryptocurrency exchange and one of the pioneers of collateralised stablecoins. While the BitShares DEX makes it easy to trade in an environment where users have custody of their own keys, there are opportunities to be made to improve liquidity, onboard new users and affect great trading activity on the BitShares DEX.

The highest volume and most liquid exchanges in the world to date like Bitmex and Bitfinex who rose to dominance due to their usage of leverage in catalysing greater liquidity for their customers.

With this in mind, some of the key inhibitors to growth right now for the BitShares DEX include:

Incentive for Smartcoin creation / holding: The growth in liquidity of Smartcoins like bitUSD, BitCNY, BitEUR and others depends on users locking up BTS collateral to create these assets. For users engaged in creating these assets they must often manage exposure to a highly volatile collateral asset and are not paid for taking on the risk which could reduce potential new issuance.

Smartcoin Liquidity: The most liquid BitShares markets are often the smart coin markets, however the liquidity of Smartcoins in circulation on the orderbook is not yet comparable to larger teir centralised exchanges thereby reducing potential usage of the BitShares DEX.

Counterparty risk of crypto lending: Currently one of the only ways with market traction to earn passive income on cryptocurrency holdings is to trust a centralised counterparty and give up ownership of your money to another entity. This is highly risky with users no longer in control of their funds and at risk of hacking or confiscation.

BTS Price growth: The Bitshares token (BTS) is the underlying collateral required for committee issued assets and therefore a higher Bitshares price incentivises greater Smartcoin creation. Growing demand for BitShares assets promotes higher collateralisation of BTS which requires more BTS being removed from circulation which over time reduces supply and can increase positive price pressure.

The motivation behind this BSIP is to address these concerns and increase user demand, liquidity and passive income opportunities for users of the BitShares DEX.

Rationale

This BSIP seeks to address the inhibitors to growth in the BitShares DEX by introducing P2P Lending, Borrowing and Margin trading markets on the BitShares DEX. This new functionality would address the above concerns as follows:

Passive risk adjusted income: Any user may choose to lend any BitShares asset for a user defined rate of return over a specified time period. This not only provides an added incentive to hold an asset that can return a yield but also ensures existing liquidity of BitShares assets is deployed to the trading orderbook.

On-chain lending and borrowing reduces risk: Users seeking a return would not need to trust third party intermediaries with their funds and can engage in lending and borrowing contracts on the BitShares DEX. This reduces risk compared to competing centralised non-custodial competitors.

Increased DEX liquidity: With the ability for users to lend new or existing liquidity directly to the orderbooks, it provides greater order book depth than exists currently. This reduces risk for margin traders who rely on ample orderbook depth to ensure their positions can be adequately executed at a desired price or in the case of margin calls greater depth reduces collateral losses.

Long / Short any asset on the DEX: A user could borrow or lend any asset on the DEX adding new opportunities to make money from market movements especially in bear markets. This also enables smartcoin issuers to hedge their BTS (or other) exposure which could assist these users maintain adequate MCR ratios thereby reducing global settlement risk.

Added volume and usage of BTS: Every operation on the BitShares DEX requires a fee to be paid which returns BTS to the reserve pool. Greater usage of the BitShares DEX increases fees paid, reduces supply which can result in a positive price pressure on BTS. Additionally new smartcoin issuance for committee assets and some private assets requires BTS as collateral and therefore increased issuance also requires the purchase and lock up of BTS, increasing demand of BTS.

The BitShares DAC is well situated to capture a market opportunity in this space with the core intent of this BSIP to increase the viability of the BitShares DEX as a high volume, non-custodial, transparent and liquid trading exchange.

Specifications

The process flow for margin trading is depicted below. The process consists of seven stages with some stages containing parallel processes.

Process Flow

  1. Stage 1a: Prior to any loan being offered or matched, the asset issuer must authorize the loan asset for lending for margin trading against sets of tradable assets.
  2. Stage 1b: Prior to any loan being offered or matched, it must be possible to look up a valid reference price between the tradable asset and the the loan asset on the internal DEX market.
  3. Stage 2: Lenders and potential Borrowers can place offers on the Lending Order Book. The offers by lenders ("loan offers") and the offers by borrowers ("borrow offers") shall remain on the books until they either expire or are matched by counter-offers.
  4. Stage 3: Compatible offers are matched to create a loan.
  5. Stage 4a: A borrower/ may hold the borrowed asset and/or trade against the agreed-upon tradable asset for the duration of the loan. Stage 4b: The smart contract will transfer interest payments from the borrower's loan portfolio to the lender on a daily basis. Stage 4c The smart contract shall appraise the loan to check whether sufficient collateral backs the loan. Stage 4d: A borrower may update the amount of collateral in their loan.
  6. Stage 5a: A borrower may initiate a loan closure any time prior to the loan expiry. Stage 5b: The smart contract may initiate a margin call when the loan expires. Stage 5c: The smart contract may initiate a loan closure if it is unable to pay the daily interest on behalf of the borrower. Stage 5d: The smart contract may initiate a loan closure by margin call if it appraises the loan's collateral as being too low.
  7. Stage 6: During a margin call process the smart contract attempts to liquidate a loan portfolio to obtain a sufficient balance of the borrowed asset to repay the lender. This might require selling the balance of the tradable asset on the market.
  8. Stage 7a: During a loan closure, the lender is repaid what is owed and any balance of assets that remain in the loan portfolio are transferred to the borrower's regular set of balances. Stage 7b: Alternatively, if a margin call is initiated that does not complete within a certain amount of time, the entire loan portfolio shall be confiscated from the borrower and transferred to the lender as a substitute payment for what is owed.

Stage 1a: Authorized Leveraged Trading Pairs

The asset issuer of the loan asset must authorize the loan asset to be used for lending for margin trading ("leveraged trading") against a set of tradable assets. This set of authorized tradable asset may be updated by the asset issuer at any time. These restrictions shall affect the creation of new loan and borrow offers.

Stage 1b: Reference Price

Knowledge of the exchange rate between the loan asset and the tradable asset is essential for the smart contract to automatically appraise a portfolio during the loan appraissal and to evaluate the need for a possible margin call. This price shall be determined by the smart contract from data on the decentralized exchange and not from any external price feeds. The reference price shall be validated under specific rules, and prohibitions shall be imposed while the reference price is invalid.

Determination of Reference Price

The reference price for the tradable asset that is denominated in terms of the loan asset shall be updated every block that has any activity (new orders, canceled orders, and matched orders) in that market pair's trading book. The reference price of the tradable asset shall be calculated according to the following rules.

Asset Reference Price Validity of Reference Price
Tradable asset is a bitAsset that is not in global settlement The highest offer price for the tradable asset. If there are no offers, the last traded price. Valid if (a) there any offers for the tradable asset, and (b) if there has ever been any trade activity.
Tradable asset is a bitAsset that is in global settlement Global settlement price Always valid
All other assets The highest offer price for the tradable asset. If there are no offers, the last traded price. Valid if (a) there any offers for the tradable asset, and (b) if there has ever been any trade activity.

If the validity conditions are not satisfied for the asset pair, the reference price shall be considered invalid and certain activities shall be prohibited.

Prohibited Activity under Invalid Reference Price

A valid reference price permits the tradable asset components of the portfolio (Tliquid and Torders) to be appraised in terms of the loan asset. This allows the entire loan portfolio to be appraised which further allows a check of the minimum collateral requirements for an existing loan.

Therefore with a valid reference price

However an invalid reference price prevents a portfolio appraisal (except for the trivial case where the portfolio only consists of the borrowed asset components (Bliquid and Borders). Without the ability to appraise the tradable asset portion of the portfolio, collateral requirements cannot be evaluated. Therefore,

  • loan offers shall not be matched to prevent the creation of new loans,
  • a borrower shall not be able to sell more of the borrowed asset if the new liquid balance (Bliquidafter) shall become less than the minimum collateral value. This constraint can be expressed as MCV ≤ Bliquidafter.
    • The new limit order (Btradenew) is constrained such that 0 < Btradenew ≤ Bliquidbefore - MCV
  • a borrower shall not be able to sell more of the tradable asset if the new liquid balance (Bliquidafter) shall become less than the minimum collateral value. This constraint can be expressed as MCV ≤ Bliquidafter
    • The new limit order with a minimum to receive of the borrowed asset (Btradereceive) is constrained such that 0 < Btradereceive ≤ Bliquidbefore - MCV
  • a borrower shall not be permitted to withdraw the tradable asset unless the liquid balance of the borrowed asset (Bliquid) is greater than the maintenance collateral value (MCV). This constraint can be expressed as MCV ≤ Bliquid
  • margin calls shall not be initiated because the collateral ratio (CR) of the loan portfolio cannot be calculated.

Stage 2: Offers to Lend and Borrow

Both potential lenders and potential borrowers can place offers on the Loan Order Book. Potential lenders place "loan offers" and potential borrowers place "borrow offers". Loan offers contain the following parameters:

Lending Offer Parameter Description
Asset type to lend
The asset type that the lender is offering to lend
Minimum amount to lend
The minimum amount of the loan asset type that will be lent into a matched loan.
Maximum amount to lend
The maximum amount of the loan asset type that the lender is offering. This amount is deducted from the lender's balances when the offer is created.
Asset type of collateral
The asset type that the borrower must provide as collateral. For this initial version of margin trading, this shall be the same asset type as the asset type to lend.
Maintenance collateral ratio (MCR)
The minimum collateral ratio that the lender is expecting at the beginning of a loan. MCR ≥ MCCR ≥ 1
Margin call collateral ratio (MCCR)
The minimum collateral ratio below which a margin call of the loan is initiated. MCR ≥ MCCR ≥ 1
Maximum duration of margin call
The maximum duration of a margin call, if one is necessary, after which a portfolio confiscation will be triggered.
Asset type to trade against (Tradable asset)
The asset type that the lender permits the borrower to trade against. This restriction protects the lender from exit scam trading.
Minimum duration of loan
The minimum duration of the loan that the lender is willing to accept
Maximum duration of loan
The maximum duration of the loan that the lender is willing to accept
Minimum interest rate
The minimum daily interest rate that the lender is willing to accept
Expiration date Expiration date of the offer

Borrow offers contain the following parameters:

Borrowing Offer Parameter Description
Asset type to borrow
The asset type that the borrower is seeking
Minimum amount to borrow
The minimum amount of the loan asset type that will be borrowed into a matched loan.
Maximum amount to borrow
The maximum amount of the loan asset type that the borrower is willing to borrow.
Asset type as collateral The asset type that the borrower must provide for collateral. For this initial version of margin trading, this shall be the same asset type as the asset type to lend.
Amount of collateral The amount of collateral the borrower has put into the offer. This amount is deducted from the borrower's balances when the offer is created.
Maintenance collateral ratio (MCR)
The maximum collateral ratio that the borrower is willing to offer at the beginning of a loan. MCR ≥ MCCR ≥ 1
Margin call collateral ratio (MCCR)
The maximum collateral ratio below which a margin call of the loan is initiated. MCR ≥ MCCR ≥ 1
Minimum duration of margin call protection
The minimum duration of a margin call, if one is necessary, after which a portfolio confiscation will be triggered.
Asset type to trade against (Tradable asset)
The asset type that the borrower can trade against.
Minimum duration of loan
The minimum duration of the loan that the borrower is willing to accept
Maximum duration of loan
The maximum duration of the loan that the borrower is willing to accept
Maximum interest rate
The maximum daily interest rate that the borrower is willing to accept
Expiration date Expiration date of the offer

After an offer is created, all users shall be able to identify:

  • which unmatched offers are on the Lending Order Book, and
  • which offers are matched.

Users shall have the ability to filter offers either by type (loan offer or borrow offer), asset type to loan, tradable asset type, amounts, interest rate, loan duration, maintenance collateral ratio, and margin call collateral ratio. This capability shall either be done at the Core RPC-API node and/or at the user interface. Offers to lend and offers to borrow shall have unique identifiers which can be referenced for loan matching.

The creation of offers, their partial and complete matches, their expiration, and their closures, shall be recorded as part of the account history of the lender and the borrower.

Offers to lend and borrow shall remain on the Loan Order Book until they either are canceled by the offeror, expire, or are completely matched and filled.

Stage 3: Loan Offer Matching

New offers shall be automatically compared to existing counter-offers on the book. This matchmaking investigation shall:

  1. identify compatible offers
  2. match compatible offers
  3. create a loan from the matched offers

Compatibility Filtering

This matchmaking process shall only match a loan offer (L) with a borrow offer (B) if those offers have the following compatible conditions.

Offer Parameter Compatibility Conditions
Loan amount (P) LPminBPmax and BPminLPmax
Loan duration (D) LDminBDmax and BDminLDmax
Interest rate (I) LIBI
Minimum collateral ratio (MCR) LMCRBMCR
Margin call collateral ratio (MCCR) LMCCRBMCCR
Margin call duration (MCD) BMCDLMCD

Therefore when a new loan offer or borrow offer is received, it shall be checked against the existing offers. This new offer will become the "taker" to the existing "maker" offers. The outcome of this investigation may identify multiple "maker" offers to be compatible with the new "taker" offer.

If no compatible offers are found for the new offer, the new offer shall be added to the offer order book and retained until it is canceled, expires, or is completely matched and filled.

Offer Matching

When multiple loan offers (L) are found to be compatible with multiple borrow offers (B), they shall be prioritized in a deterministic manner to identify which of the compatible offers will be matched to each other.

As the definition of most offer parameters are not exact values (e.g. a lender might offer a loan for exactly 6 months) but are rather bounded values (e.g. a lender might offer a loan for a duration between 3 months and 12 months), and the compatibility conditions permit a range of overlap between a loan offer and a borrow offer, there may mathematically be an infinite number of loan definitions that could be created from even a single loan offer and borrow offer. (Technically the number of loan offers are finite because they will only be characterized by finite-precision integer parameters.) Matches shall be made to favor the existing offers on the loan offer books (the "makers").

If the new offer (the "taker") is a borrow offer, the compatible loan offers shall be sorted in favor of the lenders (the "makers"). These compatible offers shall be sorted in favor of the lender offers as described in the following table.

Loan Parameter Loan Parameter Selection Loan Parameter Value Prioritization Order
Interest rate (I) Highest compatible interest rate BI 1
Loan duration (D) Longest compatible loan duration min(LDmax, BDmax) 2
Loan amount (P) Largest compatible amount min(LPmax, BPmax) 3
Margin call collateral ratio (MCCR) Highest compatible MCCR BMCCR 4
Minimum collateral ratio (MCR) Highest compatible MCR BMCR 5
Margin call duration (MCD) Shortest MCD BMCD 6

If the new offer (the "taker") is a loan offer, the compatible offers shall be sorted in favor of the borrowers (the "makers"). These compatible offers shall be prioritized favor of the borrower offers as described in the following table.

Loan Parameter Loan Parameter Selection Loan Parameter Value Prioritization Order
Interest rate (I) Lowest compatible interest rate LI 1
Loan amount (P) Largest compatible amount min(LPmax, BPmax) 2
Loan duration (D) Longest compatible loan duration min(LDmax, BDmax) 3
Margin call collateral ratio (MCCR) Lowest compatible MCCR LMCCR 4
Minimum collateral ratio (MCR) Lowest compatible MCR LMCR 5
Margin call duration (MCD) Longest MCD LMCD 6

The highest prioritized maker offer shall be paired to the new offer and a new loan shall be created in accordance with the loan parameter values in the corresponding table.

Loan Creation

The matching of a loan offer with a borrow offer shall result in the creation of a loan.

This new loan portfolio shall receive the loan amount (P) from the lending offer and an amount of collateral asset (K) from the borrowing offer equal to

K = (MCR - 1) × P

A loan shall be created from a single lending offer and a single borrowing offer.

This loan portfolio shall then become available for margin trading by the borrower.

Effective Dates of the Loan

The start date of the loan shall be when the loan is matched. The end date of the loan shall be calculated by adding the loan duration to the start date. The loan may be closed:

Filling of Loan Offer

The matching of a loan offer with a borrow offer will result in one or both of the offers being completely consumed. If an offer is not completely filled, the offer shall be "partially filled" by having the loan amount (P) deducted from the offer's "available balance".

Effects of Partial Fills on a Loan Offer

The reduction to a loan offer reduces the amount that has been offered by the prospective lender.

(BPmax)new = (BPmax)old - P

If this remainder exceeds the loan offer's minimum amount (BPmin), the loan offer shall be retained on the offer books. Otherwise the offer shall be cancelled by the smart contract.

Effects of Partial Fills on a Borrow Offer

The reduction to a borrow offer reduces the amount of collateral (K) that is being offered by the prospective borrower.

Knew = Kold - P

This effectively reduces the maximum loan amount of the borrow offer.

(LPmax)new = Knew ÷ (MCR - 1) = (Kold - P) ÷ (MCR - 1)

If this remainder exceeds the borrow offer's minimum amount (LPmin), the loan offer shall be retained on the offer books. Otherwise the offer shall be cancelled by the smart contract.

Re-evaluation of a New Offer

If the partially-filled offer is retained and if the partially filled offer is the new offer, it shall be re-evaluated for loan matching against the remaining counter-offers.

Stage 4a: Margin Trading within Loan Portfolio

Assets that are borrowed shall be placed into the borrower's margin trading "loan portfolio". This portfolio shall only be used for trading on the decentralized exchange in the market pair consisting of the "Asset type to lend/borrow" and the "Asset type to trade against". It shall not be possible to transfer funds to any account, nor use any of the assets as collateral to create another pegged asset on BitShares.

Any assets obtained from trading shall by placed into the loan portfolio and shall also be restricted to trading between the pair of asset types defined in the loan agreement. Conditional withdrawals of the tradable asset by the borrower shall be permitted. Deposit of the lent asset by the borrower shall also be permitted.

Trading Limits

A borrower shall be able to use the borrowed asset type in the loan portfolio to trade against the tradable asset on the order book of the market pair. The amount of the borrowed asset type (B) that may be used for placing new orders shall be limited to ensure that the loan portfolio's balance of the borrowed asset exceeds the minimum collateral (K). Before a trade the liquid balance of the asset type is Bliquidbefore. The liquid balance of the asset type after a new order (Btradenew) can be calculated as

Bliquidafter = Bliquidbefore - Btradenew

The new liquid balance must satisfy the following condition and definition for collateral

Bliquidafter ≥ K = (MCR - 1) × B0

which can be re-arranged as

Btradenew ≤ Bliquidbefore - (MCR - 1) × B0

This expresses a maximum amount for any new limit orders where the borrowed asset is offered to trade. If this amount is negative, no new trades shall be permitted.

Multiple Loan Portfolios

A borrower may have multiple outstanding loans each with their own distinct loan portfolio. Trading of assets from each loan portfolio shall be independent of other loan portfolios that are controlled by the borrower. Trade orders shall only draw from assets within a single loan portfolio.

The distinction of loan portfolios from each other are intended to segregate the risk of each loan which can have separate loan durations, margin collateral ratios, and tradable assets. This segregation should better secure the lenders than a single co-mingled loan portfolio.

User interfaces that facilitate trading for a borrower may optionally aggregate multiple loan portfolios into a single "margin trading wallet" to disguise the fact that multiple loan portfolios are being tracked.

Stage 4b: Daily Interest Payment

The daily interest due (Idaily) on the prinicipal (B0) shall be calculated as

Idaily = B0 × Rdaily

where Rdaily is daily interest rate. This daily interest shall be calculated in terms of the lent asset type.

The daily interest that is due shall be deducted from the borrower's balance of the borrowed asset type in the loan portfolio and deposited into the lender's account. If the borrower's loan portfolio holds insufficient balance of the lent asset type to pay the daily interest then a margin call shall be initiated.

When a loan is closed the interest for that last day shall be paid at that time. If a margin call requires multiple days to complete in accordance with the agreed duration of the margin call's loan, no additional interest shall be owed by the lender beyond payment for the last day of interest.

Stage 4c: Appraisal of Loan Portfolio

Debt Owed

The debt owed by a borrower for a particular loan is the amount lent by the lender. Interest is due on a daily basis.

Portfolio Appraisal

A borrower may have many outstanding loans which are owed to different borrowers. Each loan portfolio will initially consist of the principal that is lent by the lender plus the initial collateral that is provided by the borrower. The borrowed asset and the collateral asset shall initially be the same asset type (B).

After the loan is initiated, the borrower may use that asset type to trade against the tradable asset type (T) that is permitted by the loan, and/or may hold the borrowed asset. Therefore this loan-related portfolio may consist of balances of two asset types: the borrowed asset type, and the tradable asset type.

PA = B + T

Portfolio Components

While a loan is outstanding the balance of the borrowed asset and tradable asset may consist as either liquid balances in the loan portfolio or as open orders on the order book. Therefore the entire loan portfolio may be decomposed into four parts:

  • a balance of borrowed asset that is liquid (Bliquid)
  • a balance of tradable asset that is liquid (Tliquid)
  • a balance of borrowed asset that is in open order (Borders)
  • a balance of tradable asset that is in open order (Torders)

PA = Bliquid + Tliquid + Borders + Tliquid

The valuation of the portfolio shall also be denominated in terms of the borrowed asset type for purposes of appraisal by the smart contract. The valuation of the borrower's loan-related portfolio shall consist of the valuation of the two assets in the portfolio at the time of interest.

  • The valuation of the liquid balance and order balance of the borrowed asset shall simply be their sum.
  • The valuation of the liquid balance and order of the tradable asset shall be denominated in the borrowed asset type by the smart contract with the use of reference price.

Example of Portfolio Appraisal

Bob borrowed 70 bitUSD 203.3 days ago while supplying by supplying 30.03 bitUSD as collateral. Bob has been margin trading with this loan portfolio against bitBTC and currently has a balance of 45 bitUSD and 0.025 bitBTC. The current reference price indicates that bitBTC is priced at 5000 bitUSD per bitBTC. This loan portfolio will be appraised (PA) at:

PA = (45 bitUSD) + (0.025 bitBTC × 5000 bitUSD ÷ bitBTC)

... = (45 bitUSD) + (125 bitUSD)

... = 170 bitUSD


Collateral Ratio

After the calculation of a portfolio appraisal (PA) and the debt owed (B0), the collateral ratio (CR) shall be calculated as

CR = PA ÷ B0

At the beginning of the loan, the collateral ratio will satisfy the following conditions.

CR ≥ MCR ≥ MCCR ≥ 1

Derived Valuations

The maintenance collateral valuation (MCV) of the loan portfolio is denominated in the borrowed asset and equals

MCV = MCR × B0

where B0 is the debt owed.

Similarly, the margin call collateral valuation (MCCV) of the loan portfolio is denominated in the lent asset and equals

MCCV = MCCR × B0

It is desired for the appraised valuation of the portfolio (PA) to be greater than or equal this value

PA ≥ MCV ≥ MCCV ≥ B0

but it is possible for this valuation to fall below the MCV. If

PA < MCCV

a margin call shall be initiated.

Triggering of Appraisal

Portfolio appraisals shall be triggered at multiple times. A portfolio appraisal shall be triggered:

Stage 4d: Loan Portfolio Updates

Status of Loan Portfolio

The "recent" appraisal value, debt owed, collateral ratio, and derived valuations, and of the portfolio shall be able to be queried by the lender and borrower at any time.

Deposits

A borrower shall be able to deposit additional amounts of the borrowed asset into the loan portfolio. A borrower may choose to deposit additional collateral to avoid having the loan be margin called.

Withdrawals

A borrower shall be able to withdraw only the tradable asset as long as the market valuation of the portfolio (PA) after the withdrawal is greater than or equal to the maintenance collateral valuation. The withdrawal limit (Wlimit) is defined as

Wlimit = PA - MCV

where MCV is maintenance collateral valuation and PA is portfolio appraisal.


Example of Withdrawal

Bob borrowed 70 bitUSD 203 days ago at a daily interest rate of 0.0261% while supplying by supplying 30.03 bitUSD as collateral to satisfy the offer's 142.9% maintainance collateral ratio.

The debt owed is still 70 bitUSD. The maintenance collateral valuation (MCV) of the portfolio is

MCV = MCR × B0

... = 1.429 × 73.8276 bitUSD

... = 105.4996 bitUSD

During this time Bob has been margin trading with this loan portfolio against bitBTC and currently has a balance of 45 bitUSD and 0.025 bitBTC. The current reference price indicate that bitBTC is priced at 5000 bitUSD per bitBTC. This loan portfolio will be appraised at:

PA = (45 bitUSD) + (0.025 bitBTC × 5000 bitUSD ÷ bitBTC)

... = (45 bitUSD) + (125 bitUSD)

... = 170 bitUSD

The borrower may withdraw up to the equivalent (Wlimit) of

Wlimit = PA - MCV

... = 170 bitUSD equivalent - 105.4996 bitUSD equivalent

... = 64.5004 bitUSD equivalent

The withdrawal limit denominated in bitBTC is

Wlimit = (64.5004 bitUSD ÷ (5000 bitUSD ÷ bitBTC))

... = 0.01291 bitBTC

Bob may withdraw bitBTC up to this limit because the balance of bitBTC, 0.025, exceeds this amount. If the balance of the tradable asset were, for example, only 0.1 bitBTC then Bob would only be able to withdraw 0.1 bitBTC.


Stage 5a: Initiation of Loan Closure by Borrower

A borrower may close an outstanding loan position by having a sufficient balance of the borrowed asset type in the loan portfolio and then initiating a loan closure with the appropriate parameters.

Initiation of Loan Closure Parameter Description
Lending Offer ID Identifier of an existing and open loan offer

The initiation of a loan closure shall close any and all open trade orders that are related to this loan. If the balance of the borrowed asset type is insufficient to repay what is owed then the initiation of the loan closure shall be rejected. It is the responsibility of the borrower to ensure a sufficient balance in the borrowed asset type to repay the loan.

Stage 5b: Expiration of Loan

The smart contract shall initiate a margin call if an outstanding loan expires.

A future BSIP may consider opening a new loan from any existing offers on the Loan Order Book.

Stage 5c: Initiation of Loan Closure because of Insufficient Funds

A loan portfolio may categorized as consisting of four components of balances of which one is the balance of borrowed asset that is liquid (Bliquid). This balance is drawn from to pay the daily interest. If this balance is insufficient to pay the interest then a loan closure shall be initiated.

Stage 5d: Initiation of Loan Closure by Margin Call

If the collateral ratio ever drops below the margin call collateral ratio,

CR < MCCR

the smart contract shall initiate a margin call.

Stage 6: Margin Call

Restriction of Loan Portfolio

When a margin call is initiated on a specific loan portfolio, no new market orders may be initiated that make use of any balance in the loan portfolio. Any other loan portfolios that the borrower might have shall not be affected by margin calls on other loans.

Any open market orders that are related to that specific loan portfolio shall be cancelled.

After all open orders are cancelled, the portfolio will consist of some amount in the borrowed asset type and some amount in the tradable asset type.

PA = Bliquid + Tliquid

Liquidation Plan

The smart contract shall determine whether the balance of the borrowed asset (Bliquid) is sufficient to pay the necessary balance (Bclosure). The difference between the two is the excess borrowed asset (Bexcess)

Bexcess = Bliquid - Bclosure

If the balance is sufficient (Bexcess > 0), the process shall transition to a conventional loan closure.

If the balance is insufficient (Bexcess < 0), the smart contract shall create a limit order that offers the entire balance of the tradable asset (T) while asking for the difference between what is owed and the liquid balance(-Bexcess). This limit order shall have a limited lifetime defined by the maximum margin call duration that was agreed to in the original loan terms.

If the margin call's limit order is filled, then by definition of the limit order there shall be sufficient balance of the borrowed asset type to transition to a conventional loan closure.

Portfolio Confiscation

If the margin call's limit order expires without being completely filled, a portfolio confiscation shall be automatically initiated to permit the prompt completion of the margin call. The smart contract shall confiscate the entire loan portfolio from the borrower for ultimate transfer to the lender.

Monitoring of Liquidation Plan

It shall be possible to monitor the status of the liquidation plan associated with any margin call. An inquiry into the status of the liquidation plan shall return:

Stage 7a: Conventional Loan Closure

A standard loan closure is possible if and only if the loan portfolio's balance of the borrowed asset type (Bliquid) is sufficient to repay the principal plus interest for the last day of the loan.

Bclosure = B0 + Idaily

If that condition is satisfied, a standard loan closure can be:

Any balances that remain in the loan portfolio after repaying the lender shall be transferred to the borrower's regular set of balances and shall no longer be encumbered by any restrictions.

A future BSIP may consider re-lending a lenders balance by automatically creating a new offer on the Loan Order Book on behalf of the lender.

The loan shall be closed.

Stage 7b: Unconventional Loan Closure

If a margin call's liquidation plan expires without obtaining a sufficient balance of the borrowed asset to repay the lender, the confiscated loan portfolio shall be transferred to the lender as a substitute payment for the debt.

The loan shall be closed.

Definable Loan Constraints

The BitShares Committee shall be able to define parameters that can constrain new loans; changes to these values shall not affect loans that were offered before the change:

Term Description
Maximum loan durations The maximum duration for a new loan offer
Minimum MCR The minimum maintenance collateral ratio (MCR) that may be agreed upon
Minimum MCCR The minimum margin call collateral ratio (MCCR) that may be agreed upon
Maximum interest rates The maximum interest rate that may be agreed upon
Maximum duration of margin call
The duration during which a borrower's loan portfolio shall be protected from confiscation.

Fees

Fees shall be defined for each of the operations:

The standard fee for canceling a trade order shall apply.

Voting Stake

Voting stake shall be calculated per account as before this proposal and with the following additions to account for any core tokens (BTS) that are associated with lending.

  • Any balance of BTS in a lending offer shall be staked to the owner of the offer.
  • Any balance of BTS in a borrowing offer shall be staked to the owner of the offer.
  • If BTS is the tradable asset in a loan portfolio, the liquid balance (Tliquid) and the balance in open orders (Torders) shall be staked to the borrower.
  • If BTS is the borrowed asset in a loan portfolio, the liquid balance (Bliquid) and the balance in open orders (Borders) shall be staked to the lender up to the principal amount that is lent (B0). Any balance in excess of the principal shall be staked to the borrower.
    • The motivation for this segregation of voting stake is to prevent the renting of voting stake through this lending mechanism.

Software Specifications

Note 1: Interest is paid every 24 hours, regardless of local calendar. E. g. Daylight Savings Time is ignored.

Note 2: Percentage-based calculations (interest, CR) are always rounded up to the next possible value (aka "satoshi").

Note 3: MCR and MCCR are expressed in the same way as in the existing price feed logic, i. e. only the part above 100%, and as a scaled percentage value. E. g. a value of 4200 would mean 142%.

Note 4: "Implementation hints" are not to be considered part of the formal specification, but merely as a possible implementation.

Database Objects

lending_offer_object (new)

Fields:

  • lending_offer_id_type id - The object ID
  • account_id_type owner - The lending account ID
  • asset_id_type loan_asset - The asset type that the lender is offering to lend
  • share_type min_amount - The minimum amount of the asset type that the borrower must borrow
  • share_type max_amount - The maximum amount of the asset type that the lender is offering
  • unsigned_int mcr - The minimum collateral ratio that the lender is expecting at the beginning of a loan, as a scaled percentage
  • unsigned_int mccr - The collateral ratio below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int max_call_duration - The maximum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the lender permits the borrower to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the lender is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the lender is willing to accept, in days
  • unsigned_int min_interest_rate - The minimum daily interest rate that the lender is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Implementation hints:

  • Indexed by_owner, by_asset, by_expiration
  • Secondary index for tracking core per account

borrowing_offer_object (new)

Fields:

  • borrowing_offer_id_type id - The object ID
  • account_id_type owner - The borrowing account ID
  • asset_id_type loan_asset - The asset type that the borrower is offering to borrow
  • share_type min_amount - The minimum amount of the asset type that the lender must lend
  • share_type max_amount - The maximum amount of the asset type that the borrower wants to borrow
  • share_type available_collateral - The amount of collateral the borrower has put into the offer
  • unsigned_int mcr - The maximum collateral ratio that the borrower is willing to provide at the beginning of the loan, as a scaled percentage
  • unsigned_int mccr - The maximum collateral ratio the borrower will accept, below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int min_call_duration - The minimum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the borrower wants to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_interest_rate - The maximum daily interest rate that the borrower is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Implementation hints:

  • Indexed by_owner, by_asset, by_expiration
  • Secondary index for tracking core per account

loan_portfolio_object (new)

Fields:

  • account_id_type owner - The borrowing account ID
  • account_id_type lender - The lending account ID
  • asset_id_type principal_asset - The ID of the borrowed asset
  • share_type principal_borrowed - The amount that was originally borrowed
  • share_type minimum_collateral - The minimum amount of collateral that must be maintained
  • share_type principal_balance - The amount of the borrowed asset currently held in the portfolio
  • share_type principal_in_orders - The amount of the borrowed asset currently held in market orders
  • asset_id_type trade_asset - The ID of the asset that can be traded against
  • share_type trade_balance - The amount of the tradable asset currently held in the portfolio
  • share_type trade_in_orders - The amount of the tradable asset currently held in market orders
  • share_type mccv - The portfolio value below which a margin call of the loan is initiated, in terms of principal_asset
  • unsigned_int call_duration - The duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • optional<time_point_sec> confiscation_time - After a margin call has been initiated, this contains the time when the portfolio will be confiscated
  • share_type daily_interest - The daily interest amount to be paid
  • time_point_sec interest_due_at - Date at which the next interest payment is due
  • share_type cumulative_interest - The cumulative interest paid for this loan so far
  • time_point_sec earliest_end - Date after which the portfolio can be closed by the borrower
  • time_point_sec latest_end - Date after which the portfolio will be closed automatically
  • optional<price> call_price - If present, contains the price (in terms of principal/trade) below which the portfolio is margin called

Implementation hints:

  • Indexed by_owner, by_lender, by_interest_due, by_expiration (i. e. latest_end)
  • Secondary index for tracking core per account

Chain parameters

The chain_parameters (configurable by committee) will receive a new extension field margin_lending with these members:

  • unsigned_int max_duration - maximum allowed loan duration in days
  • unsigned_int minimum_mcr - minimum allowed mcr for loans, as a scaled percentage
  • unsigned_int minimum_mccr - minimum allowed mccr for loans, as a scaled percentage
  • unsigned_int max_interest - maximum allowed daily interest rate, as a scaled percentage
  • unsigned_int max_call_duration - maximum allowed call duration in seconds

This extension must not be present in proposals before the hardfork time.

Miscellaneous

  • limit_order_object receives a new field optional<loan_portfolio_id_type> loan

Implementation hints:

  • Secondary index on limit_order_object for tracking by_loan

Operations

All new operations have a simple flat fee.
New operations must not be allowed before the hardfork time, neither in proposals nor directly.
New fees must not be allowed in chain parameter update proposals before the hardfork.

lending_offer_create_operation (new)

Fields:

  • account_id_type lender - The lending account ID
  • asset_id_type asset_to_lend - The asset type that the lender is offering to lend
  • share_type min_to_lend - The minimum amount of the asset type that the borrower must borrow
  • share_type max_to_lend - The maximum amount of the asset type that the lender is offering
  • unsigned_int mcr - The minimum collateral ratio that the lender is expecting at the beginning of a loan, as a scaled percentage
  • unsigned_int mccr - The collateral ratio below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int max_call_duration - The maximum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the lender permits the borrower to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the lender is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the lender is willing to accept, in days
  • unsigned_int min_interest_rate - The minimum daily interest rate that the lender is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Validation checks:

  • lender must be a valid account ID, must exist, must authorize the operation, must pay fee
  • asset_to_lend and tradable_asset must be valid asset IDs, must not be equal, and both assets must exist
  • min_to_lend > 0
  • max_to_lend >= min_to_lend
  • mcr >= mccr
  • max_duration >= min_duration
  • expiration > head_block_time
  • min_duration <= chain_parameters.max_duration
  • mcr >= chain_parameters.min_mcr
  • mccr >= chain_parameters.min_mccr
  • min_interest_rate <= chain_parameters.max_interest_rate
  • max_call_duration <= chain_parameters.max_call_duration
  • lender must have at least max_to_lend of asset_to_lend in his balance
  • asset_to_lend must be authorized for margin lending against tradable_asset
  • asset_to_lend and the tradable_asset must not be transfer restricted
  • lender must be whitelisted or must not be blacklisted for the asset_to_lend and the tradable_asset due to transfer restrictions

Evaluation:

  • Deduct max_to_lend of asset_to_lend from lender balance
  • Create new lending_offer_object and populate object fields from operation fields
  • Operation result is new object id
  • Trigger automatic matching

borrowing_offer_create_operation (new)

Fields:

  • account_id_type borrower - The borrowing account ID
  • asset_id_type asset_to_borrow - The asset type that the borrower is offering to borrow
  • share_type min_to_borrow - The minimum amount of the asset type that the lender must lend
  • share_type max_to_borrow - The maximum amount of the asset type that the borrower wants to borrow
  • unsigned_int mcr - The maximum collateral ratio that the borrower is willing to provide at the beginning of the loan, as a scaled percentage
  • unsigned_int mccr - The maximum collateral ratio the borrower will accept, below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int min_call_duration - The minimum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the borrower wants to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_interest_rate - The maximum daily interest rate that the borrower is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Validation checks:

  • borrower must be a valid account ID, must exist, must authorize the operation, must pay fee
  • asset_to_borrow and tradable_asset must be valid asset IDs, must not be equal, and both assets must exist
  • min_to_borrow > 0
  • max_to_borrow >= min_to_borrow
  • mcr >= mccr
  • max_duration >= min_duration
  • expiration > head_block_time
  • min_duration <= chain_parameters.max_duration
  • mcr >= chain_parameters.min_mcr
  • mccr >= chain_parameters.min_mccr
  • min_interest_rate <= chain_parameters.max_interest_rate
  • min_call_duration <= chain_parameters.max_call_duration
  • borrower must have at least max_to_borrow * mcr of asset_to_borrow in his balance
  • asset_to_borrow must be authorized for margin lending against tradable_asset
  • asset_to_borrow and the tradable_asset must not be transfer restricted
  • borrower must be whitelisted or must not be blacklisted for the asset_to_lend and the tradable_asset due to transfer restrictions

Evaluation:

  • Deduct max_to_borrow * mcr of asset_to_borrow from borrower balance
  • Create new borrowing_offer_object and populate object fields from operation fields
  • Operation result is new object id
  • Trigger automatic matching

lending_cancel_operation (new)

This operation can be used to cancel lending and borrowing offers.

Fields:

  • account_id_type owner - Creator of the operation (fee paying account), must equal owner of the offer
  • offer_id_type offer - Either a lending_offer_id_type or a borrowing_offer_id_type
  • extension_type ext - reserved for future extensions

Validation checks:

  • owner must be a valid account ID, must exist, must authorize the operation, must pay fee
  • offer must be a valid lending offer ID or borrowing offer ID and must exist
  • offer.owner == owner

Evaluation:

  • If offer is a lending offer:
    • Add offer.max_amount of offer.loan_asset to owner balance
  • If offer is a borrowing offer:
    • Add offer.available_collateral of offer.loan_asset to owner balance
  • Delete offer from database
  • Operation result is amount paid back to owner

lending_accepted_operation (new, virtual)

Fields:

  • account_id_type offerer - must equal owner of the offer
  • offer_id_type offer - id of the accepted offer, lending_offer_id_type or a borrowing_offer_id_type
  • loan_portfolio_id_type loan - id of the resulting loan portfolio

loan_interest_operation (new, virtual)

Fields:

  • account_id_type lender - the lender's account id
  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset interest_amount - Amount of interest paid to loan.lender

loan_closed_operation (new, virtual)

Fields:

  • account_id_type lender - the lender's account id
  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset principal_paid_back - Amount of principal paid back to lender
  • asset trade_confiscated - Amount of trade asset paid to lender
  • asset principal_turned_out - Amount of principal paid out to borrower
  • asset trade_turned_out - Amount of trade asset paid out to borrower

loan_close_operation (new)

Fields:

  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust

Validation checks:

  • borrower must be a valid account ID, must exist, must authorize the operation, must pay fee
  • loan must be a valid loan portfolio ID and must exist
  • loan.owner == borrower
  • head_block_time >= loan.earliest_end
  • loan.principal_in_orders == 0 && loan.trade_in_orders == 0
  • loan.principal_balance >= loan.principal_borrowed + loan.daily_interest

Evaluation:

  • Trigger interest payment (see below)
  • Pay loan.principal_borrowed of loan.principal_asset to loan.lender
  • Pay loan.principal_balance - loan.principal_borrowed of loan.principal_asset to loan.borrower
  • Pay loan.trade_balance of loan.trade_asset to loan.borrower
  • Create a virtual loan_closed_operation
  • Delete loan

loan_update_operation (new)

Fields:

  • account_id_type owner - Creator of the operation (fee paying account), must equal owner of the loan portfolio
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset principal_delta - Amount of principal asset to add / withdraw
  • asset trade_delta - Amount of trade asset to add / withdraw
  • extension_type ext - reserved for future extensions

Validation checks:

  • owner must be a valid account ID, must exist, must authorize the operation, must pay fee
  • loan must be a valid loan portfolio ID and must exist
  • loan.owner == owner
  • principal_delta != 0 || trade_delta != 0
  • principal_delta >= 0
  • !confiscation_time.valid || trade_delta >= 0
  • If principal_delta > 0 or trade_delta > 0, owner must have sufficient balance
  • If trade_delta < 0
    • loan.trade_balance >= -trade_delta
    • Let mcv = loan.principal_borrowed + loan.minimum_collateral
    • if is_reference_price_valid
      • If loan.principal_balance + loan.principal_in_orders < mcv
        • Let min_trade = reference_price * (mcv - loan.principal_balance - loan.principal_in_orders)
        • loan.trade_balance + loan.trade_in_orders + trade_delta >= min_trade
    • Otherwise (!is_reference_price_valid)
      • mcv <= loan.principal_balance

Evaluation:

  • If principal_delta > 0:
    • Deduct principal_delta from loan.owner's balance
    • Add principal_delta.amount to loan.principal_balance
  • If trade_delta != 0:
    • Deduct trade_delta from loan.owner's balance
    • Add trade_delta.amount to loan.trade_balance
    • Re-appraise portfolio and throw if margin call is triggered

Loan trading

Note: trading from a loan portfolio happens on the same markets as trading from an account. Trading is therefore not implemented separately, but through modifications to the existing trade mechanisms.

Fields:

The existing limit_order_create_operation and fill_order_operation receive one optional extension field:

  • loan_id_type loan - ID of the loan portfolio from which the trade is executed

The loan field is not allowed before the hardfork time, neither directly nor in proposals.

Validation checks:

If the loan extension is present in a limit_order_create_operation, the following checks replace the existing checks against the seller's account balance:

  • loan is valid and refers to an existing loan_portfolio_object
  • seller == loan.owner
  • !loan.confiscation_time.valid (no trades after margin call)
  • amount_to_sell.asset_id == loan.principal_asset || amount_to_sell.asset_id == loan.trade_asset
  • If amount_to_sell.asset_id == loan.principal_asset:
    • loan.principal_balance - amount_to_sell.amount >= loan.minimum_collateral
    • min_to_receive.asset_id == loan.trade_asset
    • if !is_reference_price_valid
      • 0 < amount_to_sell.amount <= loan.principal_balance - mcv
  • If amount_to_sell.asset_id == loan.trade_asset:
    • loan.trade_balance >= amount_to_sell.amount
    • min_to_receive.asset_id == loan.principal_asset
    • if !is_reference_price_valid
      • 0 < min_to_receive.amount <= loan.principal_balance - mcv

Evaluation:

  • The loan extension will be recorded in the new limit_order_object
  • If loan field is present,
    • amount_to_sell will be deducted from the loan balance and recorded in loan's ..._in_order fields, not the account's
    • fill_order will be modified to pay trade proceeds into loan portfolio and adjust loan's ..._in_order fields
    • fill_order must re-appraise the portfolio
    • cancel_order will be modified to return funds into loan portfolio and adjust loan's ..._in_order fields

Database API Calls

The following methods will be added to the database_api:

  • vector<lending_offer_object> get_lending_offers_by_asset <loan-asset> <trade-asset> <optional limit> <optional start>
  • vector<borrowing_offer_object> get_borrowing_offers_by_asset <loan-asset> <trade-asset> <optional limit> <optional start>
  • vector<lending_offer_object> get_lending_offers_by_account <account> <optional limit> <optional start>
  • vector<borrowing_offer_object> get_borrowing_offers_by_account <account> <optional limit> <optional start>
  • vector<loan_portfolio_object> get_loans_by_lender <account> <optional limit> <optional start>
  • vector<loan_portfolio_object> get_loans_by_borrower <account> <optional limit> <optional start>
  • vector<limit_order_object> get_orders_by_loan <loan-id> <optional limit> <optional start>

All result lists are ordered by ascending object id. Server-side limits are configurable.

Processing Logic Changes

Automatic Matching of Offers

Similar to database::apply_order(). Triggered when a new offer is evaluated.

  • Let taker_offer = new_offer
  • If new_offer is loan offer
  • Otherwise (new offer is borrow offer)
  • while true
    • Let compatible_offers = find_compatible_offers(new_offer, counter_offers, prioritization_policy)
    • if no compatible_offers
      • return false
    • otherwise
      • Let maker_offer = highest-prioritized counter offer
      • [loan_object_id, taker_offer_filled] = create_loan(taker_offer, maker_offer, prioritization_policy)
      • If taker_offer_filled
        • return true

Margin calls

  • Set loan.confiscation_time = head_block_time + loan.call_duration
  • Cancel open market orders of this loan, as usual
  • If loan.principal_balance >= loan.principal_borrowed + loan.daily_interest: close loan as described above
  • Otherwise:
    • Let gap = loan.principal_borrowed + loan.daily_interest - loan.principal_balance
    • Create and execute a virtual limit_order_create for loan with amount_to_sell = loan.trade_balance and min_to_receive = gap
    • If the order has been (partially) filled, restart margin call process (meaning gap is smaller or perhaps closed)

Notes:

  • The new limit order will "walk the book" until the available trade balance has been spent (or there are no more orders in the book with a matching price). It is possible that this process buys up much more principal than required to close the gap, possibly at a price far away from the usual market price. Thus, the borrower should avoid being margin called.
  • Due to rounding, edge cases may exist where the limit order has been partially filled and then cancelled without buying sufficient principal to close the gap. It may then be impossible to create a new order for the remaining gap, because that would be considered "dust". The consequence would be that the loan stays in margin call state until it is confiscated. For practical purposes this shouldn't make much of a difference because rounding issues are a few "satoshis" only.

Interest payments

Similar to database::clear_expired_proposals, in each block

  • Check all loan_portfolio_object.interest_due_at against head_block_time
  • If passed and if !loan_portfolio_object.confiscation_time.valid,
    • If loan.daily_interest > loan.principal_balance: initiate margin_call
    • Otherwise,
      • Deduct loan.daily_interest from loan.principal_balance
      • Add loan.daily_interest of loan.principal_asset to loan.lender's balance
      • Add loan.daily_interest to loan.cumulative_interest
      • Create a virtual loan_interest_operation
      • Add 86400 to loan.interest_due_at
      • Re-appraise portfolio

Expire open offers

Similar to database::clear_expired_orders, in each block

  • Check lending_offer_object.expiration and borrowing_offer_object.expiration against head_block_time
  • If expired, create a virtual lending_cancel_operation and execute as describe above

Expire open loans

Similar to database::clear_expired_orders, in each block

  • Check loan_portfolio_object.latest_end against head_block_time
  • If expired:
    • Cancel open orders of this portfolio with virtual limit_order_cancel operations
    • If loan.principal_balance < loan.principal_borrowed + loan.daily_interest: initiate margin call
    • Otherwise: close loan as described above

Handle margin calls

In each block, for each loan that is in margin call state,

  • If loan.principal_balance >= loan.principal_borrowed + loan.daily_interest
    • Cancel open order, if any
    • Close loan as described above

Confiscate expired margin calls

Similar to database::clear_expired_orders, in each block

  • Check valid loan_portfolio_object.confiscation_time against head_block_time
  • If expired,
    • Cancel open order, if any
    • Add loan.principal_balance of loan.principal_asset to loan.lender's balance
    • Add loan.trade_balance of loan.trade_asset to loan.lender's balance
    • Create appropriate virtual loan_closed_operation
    • Delete loan

Vote tallying

  • vote_tally_helper computes voting_stake per account as before, plus core in
    • lending_offers
    • borrowing_offers
    • If core is the trade_asset in a loan_portfolio
      • Let lender_stake = 0
      • Let borrower_stake = trade_balance
    • If core is the principal_asset in a loan_portfolio
      • Let lender_stake = min(principal_balance, principal_borrowed)
      • Let borrower_stake = principal_balance - lender_stake

Calculate reference price

  • If tradable asset is a bitAsset
    • If tradable asset is in global settlement
      • is_reference_price_valid = true and reference_price = global_settlement_price
  • Otherwise
    • if tradeable asset-borrowed asset market has any offers for the tradable asset
      • is_reference_price_valid = true and reference_price = highest_offer
    • else if tradeable asset-borrowed asset market has ever had any matched exchange
      • is_reference_price_valid = true and reference_price = last_exchange_price
    • otherwise
      • is_reference_price_valid = false

Portfolio appraisal

  • Let principal = loan.principal_balance + loan.principal_in_orders
  • If principal >= loan.mccv, clear loan.call_price
  • Otherwise
    • if (loan.trade_balance + loan.trade_in_orders) > 0
      • set loan.call_price = (loan.mccv - principal) / (loan.trade_balance + loan.trade_in_orders)
      • if reference_price is valid and reference_price < loan.call_price: trigger margin call
    • else
      • Trigger margin call

Changes to cli_wallet

The following commands will be added to cli_wallet:

  • list_lending_offers <account>
  • list_borrowing_offers <account>
  • get_lending_offers <loan-asset> <trade-asset>
  • get_borrowing_offers <loan-asset> <trade-asset>
  • lending_offer_create with operation parameters
  • borrowing_offer_create with operation parameters
  • lending_offer_cancel <id>
  • lending_offer_accept <id> <amount> <duration>
  • loan_update <id> <delta-principal> <delta-trade>
  • get_loan_valuation <id>
  • get_loan_call_price <id>
  • loan_close <id>
  • The sell_asset command will receive an additional optional parameter, the loan portfolio id

Discussion

Risks

Financial: Price of a market pair on the DEX

A stagnant, nascent, or illiquid order book on the DEX for a particular market pair might not reflect the valuation of the collateral according to external market pairs. That will affect the appraisal value of the loan collateral which then affects margin calculations. Margin calculations affect both future loan offers on the books and matched loans.

Potential lenders and borrowers should carefully review any internal market pair and compare it with the external market pair to determine (a) whether internal market reflects a reasonable exchange ratio/price, and (b) whether the internal market could be easily manipulated to either overvalue or undervalue collateral.

Financial: Margin Calls at Market Price

If a margin call is initiated and if a liquidation plan requires selling the tradable asset to repay the lender in lent asset type, borrowers should be aware that it will be sold as an effective market order. The resulting sale on the DEX order book may return much less than if the offer were made on an external market.

Financial: Repayment of a Margin Called Loan

Loans that are margin called might require a liquidation plan that involves placing an limit order to buy enough of the lent asset to repay the loan.

If the market order remains unfilled on the DEX order book in excess of maximum margin call duration, the borrower's entire loan portfolio shall be confiscated thereby leaving the borrower with nothing after the loan closure.

Financial: Avalanche effect of Margin Calls

A margin call on a loan portfolio will immediately try to buy large amounts of the borrowed asset from the market. This can lead to a sudden spike in the trade price. This in turn can affect the reference price, which could lead to additional margin calls in other portfolios.

Powers of Asset Issuers

Asset issuers have extensive control over how their asset is used on BitShares including the ability to whitelist the trading of an asset against other assets), to restrict the transfers of an asset, and to seize any issued asset from an account if the asset is defined with the appropriate flags. These interaction of these powers with lending for margin trading are described.

Market Restrictions

The power to whitelist and blacklist trading pairs for an issuer's asset, which has the appropriate flags enabled, shall be unaffected by this proposal. This lending proposal makes use of the existing trading mechanisms therefore all rules shall continue to apply.

For example, if an issuer's asset is blacklisted from trading against any other asset, no trading of the Asset will be possible either from an account's regular set of balances or from their loan portfolio.

Alternatively, an issuer's asset (X) might initially be whitelisted to trade against any other asset, which permits the creation of a loan portfolio to trade against another asset (Y). Trading by the borrower ensues and the borrower obtains some quantity of Asset Y in their portfolio. If the asset issuer then blacklists trading between X and Y, the borrower shall no longer be able to trade the asset from anywhere including their loan portfolio. Another effect will be that margin calls shall no longer be able to be liquidated by means of buying back the borrowed asset on the DEX. Consequently if a margin call is initiated after a blacklisting and the loan portfolio's balance of the borrowed asset was insufficient to repay the lender, the margin call shall eventually result in an unconventional loan closure.

Transfer Restrictions

The existing power to restrict the direct transfer of an issuer's asset, which has the appropriate flags enabled, from one account to another shall be unaffected by this proposal.

Interest payment involves the transfer of the [borrowed asset-type](#borrow-asset] from the borrower to the lender. Therefore the creation of loan and borrow offers, and the matching of offers shall only be permitted if (a) if the borrow asset is not transfer restricted, and (b) if both the lender and the borrower are whitelisted or are not blacklisted for the borrow asset.

An unconventional loan closure transfers all balances of the borrow asset type and the tradable asset type to the lender. Therefore the creation of loan and borrow offers, and the matching of offers shall only be permitted if (a) if the tradable asset is not transfer restricted, and (b) both the lender and the borrower are whitelisted or are not blacklisted for the tradable asset.

Asset Seizure

The power to seize an issuer's asset, which has the appropriate flags enabled, shall remain possible if the asset is held in the account's regular set of balances. This power does not currently extend to assets held in open orders. Similarly, it shall not be possible to seize an asset that is held inside of a loan offer, borrow offer, or loan portfolio. An asset issuer may instead first impose a transfer restriction on the account, and then wait for the loan to be closed with appropriate balances being distributed to the regular balances of the borrower and lender at which time the conventional asset seizure may be invoked.

Summary for Shareholders

This BSIP defines a protocol upgrade to support peer-to-peer lending, borrowing and margin trading markets on the BitShares DEX. The motivation behind this BSIP is to increase the user demand for smartcoins on BitShares by offering on-chain peer-to-peer lending and borrowing to augment the existing trading. The multiple stage process between borrowers and lenders is supported with software specifications and a discussion of risks to lenders, borrowers, and asset holders, and asset issuers.

Copyright

This document is placed in the public domain.

See Also

@ryanRfox
Copy link
Contributor

ryanRfox commented May 19, 2019

Original post by @MichelSantos in the paragraphs below. I inserted the draft BSIP text above so we may continue discussion in the comments section of this Issue before advancing it as a PR.

A working draft of a "Lending for Margin Trading" BSIP is [above]. We are seeking feedback about financial concepts from potential users and software concepts from developers. Certain aspects that still need to be determined are labeled with "TBD" (for "to be determined").

This BSIP variant has selectively restricted the features that are anticipated to be useful for users of the blockchain while still being something that might be deployed within an earlier consensus release. More advanced features are labeled with "future BSIP" and are expected to augment this feature set. Developers who might implement this feature set might make design decisions that are future-compatible with these potential features.

@liondani
Copy link

5plus

@pmconrad
Copy link
Contributor

  1. IMO the restriction on a single trading pair is not sufficient to prevent an exit scam.

For example, someone who has an open call order on CNY with a CR of 1.6 may borrow CNY at a lower CR and sell the borrowed CNY to himself in order to free up his locked collateral. He has then offloaded part of the risk from his call order to the lender. (Arguably on conditions that the lender has accepted, so calling this a scam is debatable.)

Much worse than that is the fact that even the most liquid markets are operating with a spread, and that spread can become significant (i. e. > 1%) for a short period of time. A spread allows the borrower to round-trip trade with himself, transferring value out of the loan portfolio. Many such roundtrips can be squeezed into a single transaction, so even with a tiny spread a significant amount of value can be siphoned off per block.

  1. I think the reference price should be determined not only by looking at past trades, but also depending on the current state of the order book. The order book is what matters when a loan portfolio is margin called. Such a margin call executes only against one side of the order book, and a large loan can have significant effect on the market when margin called, meaning that past trades are not a good measure for the appraisal of the loan portfolio.

  2. The suggested method for margin calls, which is effectively a market order to sell everything, is dangerous. Its effect is comparable to a stop-loss order, which is known to be dangerous if publicly known in advance.

I have more detailed remarks, but I will wait for the PR.

@CryptoKong
Copy link

This is probably one of the best upgrades BitShares could get, really hope we can make this happen.

@ryanRfox
Copy link
Contributor

@pmconrad and other reviewers: My desire is to see sufficient discussion/refactoring of the draft BSIP text in this Issue prior to making the PR from the outcome thereof. @MichelSantos as the author will moderate this discussion and incorporate changes. The Description text should be the most recent and used as the initial PR when deemed complete and ready for posting.

@Mugendian
Copy link

This needs to pass. Agree with kong, all hands on deck to make this happen.

@matle85
Copy link

matle85 commented May 20, 2019

Great stuff - hits so many of our trouble spots!

Quite a few of the CEXs have insurance funds they build up through fees - would we do something similar?

The layman in me wants to know how close would this bring us to a BitMEX 50x 100x etc trading platform type functionality? My understanding is this will mainly get us the bones of the functionality - I'd be keen to see the UI stuff bundled in or a separate worker put forward for a really clean BitMEX type interface for it that everyone coming in will just see and know how to use.

@bitcrab
Copy link
Contributor

bitcrab commented May 21, 2019

haven't gone through all the details, but I believe this is what Bitshares need, let's move it forward.

@matle85
Copy link

matle85 commented May 21, 2019

Just thinking about businesses building atop this - can we make sure we include some facility / approach to them making money?

For example, apart from the margin trading this will also make us a peer to peer decentralised lending platform... There needs to a mechanism in place allowing a business that decides to leverage this to make a profit (i.e. justify investing in the interface, publicity, business costs etc).

This is also a consideration for the trading - how does a company launching and promoting BitDEX make its money?

I guess it needs to be through the fee structure or allowing some third party to take a % mark up on values by facilitating...?

@CryptoKong
Copy link

1. IMO the restriction on a single trading pair is not sufficient to prevent an exit scam.

For example, someone who has an open call order on CNY with a CR of 1.6 may borrow CNY at a lower CR and sell the borrowed CNY to himself in order to free up his locked collateral. He has then offloaded part of the risk from his call order to the lender. (Arguably on conditions that the lender has accepted, so calling this a scam is debatable.)

Would it be possible to create a new order type, so borrowed funds can only be used to open a position that has to be closed, rather than just selling borrowed funds and them being added to users balance where they can do whatever they want with it. Perhaps it could be part of the borrowing function, so when a user borrows funds they also have to input their desired position, eg: long/short, position size, collateral, margin ratio. The borrowed funds would then be put straight into an open position and once closed, whether by choice of forced, borrowed funds are repaid.

@matle85
Copy link

matle85 commented May 21, 2019

I don't see any issue with them doing what they like with it to be honest - what they are doing in that example is reducing their risk of having their smartcoin margin position forcibly closed by agreeing to pay interest on a loan. The person lending should be aware of the risks around loaning and set their rates to suit.

Best to leave it to the market to find the acceptable rates during different market conditions - i.e. during a bear market if loads of people want to borrow to try and protect their position then people with large stacks to lend can get really good returns (noting those really good returns are in part because of the market risk!)

@pmconrad
Copy link
Contributor

My desire is to see sufficient discussion/refactoring of the draft BSIP text in this Issue prior to making the PR from the outcome thereof.

Agree that concept and mechanics should be agreed upon before the PR. PR is better for in-detail discussion of the text, e. g. typos, wording etc. .

@MichelSantos
Copy link
Contributor Author

MichelSantos commented May 21, 2019

Quite a few of the CEXs have insurance funds they build up through fees - would we do something similar?

The the operations for creating and matching loan positions would be new so they would have their own distinct fees. Because of the new computational and memory load that loan positions would impose on block producer nodes, these fees should be enough to at least compensate the block producers.

Whether the loan fees should be even higher to build an insurance fund is interesting. No risk is being taken on by the blockchain with this proposed lending loan because the main risk is being taken on by the lenders. But if the idea is to use fees from loans to pay for insuring some other activity on the blockchain, that could technically be done. However the real-world issue is do you want to have one activity's users insure another activity's users?

If that idea is desirable I think that two things need to be identified:

  • What activity or operation should be insured? Who insures it now? Who takes on the risk now? How much reserve is enough?
  • How much should be the fee be to both compensate the block producers and also add "enough" to the insurance fund?

@MichelSantos
Copy link
Contributor Author

The layman in me wants to know how close would this bring us to a BitMEX 50x 100x etc trading platform type functionality? My understanding is this will mainly get us the bones of the functionality - I'd be keen to see the UI stuff bundled in or a separate worker put forward for a really clean BitMEX type interface for it that everyone coming in will just see and know how to use.

I agree that we should discuss with at least the reference wallet team if for no other reason than this: there will potentially be numerous small loans in their own loan portfolio as this BSIP is currently conceived. This is done to better protect the lenders by uniquely tracking collateral ratios for each loan.

But the consequence is that there will potentially be numerous loans held by borrower, and also by lenders. Each loan portfolio will be traded separately from the others at the discretion of the borrower. This probably needs to be simplified and consolidated for regular users by default. We need to identify useful API calls for client software that will make handling the numerous loan portfolios/margin wallets that are held by a borrower to be fast, efficient, and not cumbersome.

But the next consequence is that it may increase the memory requirements on API nodes.

@MichelSantos
Copy link
Contributor Author

Just thinking about businesses building atop this - can we make sure we include some facility / approach to them making money?

For example, apart from the margin trading this will also make us a peer to peer decentralised lending platform... There needs to a mechanism in place allowing a business that decides to leverage this to make a profit (i.e. justify investing in the interface, publicity, business costs etc).

I think that this largely depends on the imagination of the business. Businesses like individuals can use the platform now. If we had something more concrete we could evaluate what might need to be baked into the blockchain that isn't already there.

@MichelSantos
Copy link
Contributor Author

MichelSantos commented May 21, 2019

Would it be possible to create a new order type, so borrowed funds can only be used to open a position that has to be closed, rather than just selling borrowed funds and them being added to users balance where they can do whatever they want with it. Perhaps it could be part of the borrowing function, so when a user borrows funds they also have to input their desired position, eg: long/short, position size, collateral, margin ratio. The borrowed funds would then be put straight into an open position and once closed, whether by choice of forced, borrowed funds are repaid.

Let's take an example: a Borrower is lent 70 bitUSD (the lent asset) to trade against bitBTC (the tradeable asset). The Borrower is limited in the following ways:

  • the Borrower can hold the bitUSD in the "margin wallet"
  • the Borrower can optionally trade back and forth against bitBTC but all balances are contained within that specific "margin wallet"
  • the Borrower can only withdraw any "excess" bitBTC (excess is that amount of bitBTC that ensures enough collateral to satisfy the minimum collateral ratio that is agreed with the lender) from the "margin wallet" into his/her regular balances

The point is that the Borrower cannot short with any funds that are inside of the "margin wallet". Does this address your main concern? Is this too limiting for the use cases that you had in mind?

The idea of lending that instantly creates a limit order against the tradeable asset is a technical possibility but I wonder if it might be too restrictive.

@christophersanborn
Copy link
Member

Minor: Assuming typo in section 4b, formula for daily interest rate. (Ddaily should not exceed principle P.)

@christophersanborn
Copy link
Member

This seems like a great idea and the mechanism is extremely well articulated.

@froooze
Copy link

froooze commented May 21, 2019

  1. I am against a restriction, what the lender can do with the asset, because he pays interest and potential use cases are too much limited.
  2. The UI needs to show metrics from past borrows, to allow the market a fair risk management.
    If the borrower has no track record, he has to pay higher interest rates.
  3. Interest rates are calculated in percentage of borrowed bitAsset, but should be paid in BTS?

@christophersanborn
Copy link
Member

  • I am against a restriction, what the lender can do with the asset, because he pays interest and potential use cases are too much limited.

A restricted use case though is what makes this whole thing work. Without the restriction, the lender would need the ability to assess the credit-worthiness of individual borrowers, and then this becomes a much more complicated endeavor. As it stands, a "loan ask" can be taken up by any borrower precisely because the usage of the principle is narrowly defined. The lender can set the interest rate based on the risk profile of the activity, NOT the risk profile of the borrower.

@froooze
Copy link

froooze commented May 22, 2019

@christophersanborn: The intention was to have a MCR of under 1?
We should not exclude the case for risk profile of the borrower, because we need only to increase MCR and Interest rate, for this case.

@MichelSantos
Copy link
Contributor Author

@christophersanborn: The intention was to have a MCR of under 1?

@froooze the intention is to have MCR ≥ 1

We should not exclude the case for risk profile of the borrower, because we need only to increase MCR and Interest rate, for this case.

The lender and the borrower can agree to any MCR ≥ 1, and any interest rate

The data about each borrower will be on blockchain. If that is very important then the client interface can show the credit history of the borrower while a lender is reviewing "borrow offers" from lender.

Remember that this proposal matches loans in a three step-process.

  1. A makes an offer to borrow or lend
  2. B reviews offers
  3. If B agrees to offer and can satisfy the initial collateral requirements in that offer, then B can accept the offer and the loan offer is matched

If borrower posts a "borrow offer", potential lenders can review credit history of borrower, and choose whether to accept the offer.
If lender posts a "lend offer", then any borrower who is willing to agree to the lender's terms can select it.

More conservative lenders may prefer to select "borrow offers" instead of posting "lend offers".

@MichelSantos
Copy link
Contributor Author

1. I am against a restriction, what the lender can do with the asset, because he pays interest and potential use cases are too much limited.

This proposal is limited to lending for margin trading purposes. To use borrowed assets for another purpose will require a different BSIP.

2. The UI needs to show metrics from past borrows, to allow the market a fair risk management.
   If the borrower has no track record, he has to pay higher interest rates.

This is possible for the case when borrowers make the initial "borrow offer" because past borrow history is on blockchain. It will be helpful to estimate how much is the demand by lenders to show this data in the UI.

3. Interest rates are calculated in percentage of borrowed bitAsset, but should be paid in BTS?

Payment of principal and interest must be paid in the original asset type that was borrowed.

@CryptoKong
Copy link

Let's take an example: a Borrower is lent 70 bitUSD (the lent asset) to trade against bitBTC (the tradeable asset). The Borrower is limited in the following ways:

* the Borrower can hold the bitUSD in the "margin wallet"

* the Borrower can optionally trade back and forth against bitBTC but all balances are contained within that specific "margin wallet"

* the Borrower can [only withdraw any "excess" bitBTC](https://github.com/bitshares/bsips/issues/170#withdrawals) (excess is that amount of bitBTC that ensures enough collateral to satisfy the minimum collateral ratio that is agreed with the lender) from the "margin wallet" into his/her regular balances

The point is that the Borrower cannot short with any funds that are inside of the "margin wallet". Does this address your main concern? Is this too limiting for the use cases that you had in mind?

The idea of lending that instantly creates a limit order against the tradeable asset is a technical possibility but I wonder if it might be too restrictive.

This adresses my concern and sounds like a much better idea, it offers control and more freedom. I like it.

@froooze
Copy link

froooze commented May 22, 2019

This proposal is limited to lending for margin trading purposes. To use borrowed assets for another purpose will require a different BSIP.

Why do we need a different BSIP? Would be this BSIP not the same, except the market limitation?
If a borrower has less limitations, the market will price in the extra risk.
It makes sense to have some limitations available, but should not forced on everyone.

@pmconrad
Copy link
Contributor

@froooze the use-case in this BSIP is extremely limited because it allows the chain to use the complete loan portfolio, including the borrowed funds as well as any gains from trading, as collateral for the loan. This in turn is what makes margin trading possible at all.

If we allow the user to transfer value out of the loan portfolio, the chain has no means to ensure that the loan will be paid back. Note that a CEX has means of going after the borrower off-chain, and thus has a different risk profile than a smart contract between more or less anonymous participants.

@cloud-8
Copy link

cloud-8 commented May 25, 2019

The borrower must be restricted otherwise they can exploit it fairly easily by taking loans and extracting money or pumping other coins the lender didnt specify in order for them to exit scam. A restriction is how every other implementation of margin trade / lending works too so this is normal. Have seen from great feedback so far.

Has the core team any major concerns on a technical level for this implementation?

@pmconrad
Copy link
Contributor

Has the core team any major concerns on a technical level for this implementation?

The details are not sufficiently spec'd out to answer that at this time.

I believe that in order to prevent exit scams, the load portfolio must be appraised for every operation instead of just once per maintenance interval. This could have a significant impact on performance.

@cloud-8
Copy link

cloud-8 commented May 27, 2019

The details are not sufficiently spec'd out to answer that at this time.

Thanks, what needs more specification ?

I believe that in order to prevent exit scams, the load portfolio must be appraised for every operation instead of just once per maintenance interval. This could have a significant impact on performance.

That seems excessive. It is up to the lender to specify the markets they enable the borrower to margin trade on, they take on the risk. If the Borrower uses the loan for buying illiquid coins and exiting a position they hold outside of this contract then that is a risk the lender must evaluate- doesnt need any intervention outside of that.

@pmconrad
Copy link
Contributor

Added an explicit loan_close_operation to the spec as discussed on telegram, replacing the functionality of loan_update with a negative principal_delta.

How should the following scenario be handled?

With your alternative draft for the reference price we can avoid this scenario entirely if we require a "last price" to exist before margin trading is allowed.

@pmconrad I imagine that what you have in mind is that the loan's call price is improved after the possible matching?

Yes. I think this can easily be determined by checking that the price of the new limit order is better (for the borrower) than the call price.

Another question is how should the call_price be expressed if the value is infinite?

Good point, that's a special case that I missed.
Infinite call price means there is no trade asset available to fill the gap. This is a kind of catastrophic situation - the reasonable thing to do is to pay out the available principal to the lender immediately and close the loan.

@MichelSantos
Copy link
Contributor Author

Good point, that's a special case that I missed.
Infinite call price means there is no trade asset available to fill the gap. This is a kind of catastrophic situation - the reasonable thing to do is to pay out the available principal to the lender immediately and close the loan.

The software specifications has been updated to initiate a margin call in this situation

@MichelSantos
Copy link
Contributor Author

While working on the specification section I have run into the following questions:

1. IMO the "Reference Price" is not just an implementation detail, it is absolutely crucial for the success of this mechanism. I feel I'm lacking the financial background to come up with a reasonable suggestion. Please discuss here.

The reference price section has been updated

2. Please add a section to "Discussion" where asset flags and black/whitelists are considered. E. g. an "override_transfer" cannot be applied to funds inside a loan portfolio.

Please see the section called Powers of Asset Issuers

3. Please add a section to "Discussion" where the consequences for voting of core asset in loan portfolios are discussed. (IMO it is clear the core in lending offers and borrowing offers should vote for the owner of the offer. For core in loans it is not clear, and perhaps should be different of the portfolio is margin called.)

Please see the Voting Stake section. The software specifications have also been synchronized with this description.

@MichelSantos
Copy link
Contributor Author

No, existing mechanisms do not automatically apply here. But application is fairly straightforward:

* An account that is blacklisted for asset A must not be able to create a lending offer for asset A.

* An account that is blacklisted for asset A must not be able to create a borrowing offer for asset A, nor one for trading against asset A.

* If an account that has such lending or borrowing offers open gets blacklisted, the offers should be cancelled automatically.

A variation of this is now described in the Powers of Asset Issuers and the software specifications for your review

@MichelSantos
Copy link
Contributor Author

@pmconrad To accommodate the possible future usage of multiple tradable assets in a loan portfolio, what do you think of changing

asset_id_type tradable_asset

to be

flat_set<asset_id_type> tradable_asset

in lending_offer_create_operation and borrowing_offer_create_operation? With the idea that more substantial changes will occur in a later hard fork that requires a replay.

@MichelSantos
Copy link
Contributor Author

I have also specified that an offer stays if it partially accepted and the remaining part exceeds the min value.

The prose has been synchronized with the software specifications to reflect partial fills

I'm unsure whether it would be easier to replace the explicit accept operation with an offer matching algorithm. Probably yes - leaving it out doesn't save us very much in terms of complexity whereas adding it later will require a new and slightly more complicated BSIP.

The prose and software specs in this variant (Variant A) have been enhanced to describe explicit / discretionary matching by account holders. Another variant will describe automatic matching.

@MichelSantos
Copy link
Contributor Author

MichelSantos commented Jul 17, 2019

I'm unsure whether it would be easier to replace the explicit accept operation with an offer matching algorithm. Probably yes - leaving it out doesn't save us very much in terms of complexity whereas adding it later will require a new and slightly more complicated BSIP.

Variant B of this proposal replaces explicit matching of offers by account holders with automatic matching

@MichelSantos
Copy link
Contributor Author

* Re-appraise portfolio and throw if margin call is triggered

@pmconrad Is the idea that the detection of a potential margin call kills the loan update operation?

@MichelSantos
Copy link
Contributor Author

lending_accept_operation (new)
...
Validation checks:
...
If offer is a borrowing offer:
* collateral_amount is not set
* Let collateral_amount = loan_amount * offer.mcr

This merits a review

@pmconrad
Copy link
Contributor

@pmconrad Is the idea that the detection of a potential margin call kills the loan update operation?

Yes. A similar mechanism exists in call_order_update to prevent a short position from being margin called as a consequence of collateral being reduced.

This merits a review

My original spec wrongly requires offer.mcr >= mcr where mcr is not a field of the operation. What was meant here is a condition that mirrors its counterpart when matching a lending offer, i. e. offer.mcr >= collateral_amount / loan_amount.

To accommodate the possible future usage of multiple tradable assets in a loan portfolio, what do you think of changing asset_id_type tradable_asset to be flat_set<asset_id_type> tradable_asset

How likely do think such a future extension will be? IMO extending this proposal to support multiple trade assets will be quite complex. Therefore I'd leave it at the singular asset_id_type, with the option to add a future extension field if multiple trade asset IDs are required.

@pmconrad
Copy link
Contributor

I think what's still missing is a way for asset issuers to enable/disable and/or limit lending their assets in specifc pairings, as suggested in the forum - https://bitsharestalk.org/index.php?topic=28534.msg331779#msg331779

@MichelSantos
Copy link
Contributor Author

I think what's still missing is a way for asset issuers to enable/disable and/or limit lending their assets in specifc pairings, as suggested in the forum - https://bitsharestalk.org/index.php?topic=28534.msg331779#msg331779

A new stage Stage 1a has been introduced both in this variant and Variant B which prevents new offers from being made if the asset issuer of the loan asset has not authorized leveraged trading with the tradable asset.

But we need software specs that describe how an asset issuer may update these authorization, and where this smart contract will look for it. How about using the asset's asset_options_extensions be used with optional extensions called whitelist_leveraged_trading_markets and blacklist_leveraged_trading_markets?

I have not added quantitative limits to lending.

@MichelSantos
Copy link
Contributor Author

This merits a review

My original spec wrongly requires offer.mcr >= mcr where mcr is not a field of the operation. What was meant here is a condition that mirrors its counterpart when matching a lending offer, i. e. offer.mcr >= collateral_amount / loan_amount.

As I understand your reply, I will leave that software specification alone

To accommodate the possible future usage of multiple tradable assets in a loan portfolio, what do you think of changing asset_id_type tradable_asset to be flat_set<asset_id_type> tradable_asset

How likely do think such a future extension will be? IMO extending this proposal to support multiple trade assets will be quite complex. Therefore I'd leave it at the singular asset_id_type, with the option to add a future extension field if multiple trade asset IDs are required.

My best guess is 40% likely within one year

@MichelSantos
Copy link
Contributor Author

For archival purposes, Variant A of this proposal will be recorded in this comment. This issue's description is being replaced with Variant B.


BSIP: 70
Title: Peer-to-Peer Leveraged Trading (Variant A)
Authors: George Harrap, Michel Santos, Peter Conrad
Status: Draft
Type: Protocol
Created: 2019-04-29
Discussion: https://github.com/bitshares/bsips/issues/170

Abstract

This BSIP defines a protocol upgrade in order to support peer-to-peer lending, borrowing and margin trading markets on the BitShares DEX. Lending is defined as any user of the BitShares DEX having the ability to post an offer to lend any BitShares asset they own to a market where a borrower may take that offer (by posting collateral) and pay the lender a lender-defined amount of interest over a time period.

The Borrower may choose to take the offer or post their preferred borrowing interest rate as a Bid and when taken, execute an exchange transaction with that token for another specified by the lender. The borrower will pay the lender interest in the asset type that was borrowed. Should the value of their margin position fall by a specified amount, the borrowers' balance will be margin called and sold on the market to payback the debt to the lender. The borrower risks losing their collateral in the case of a margin call and the lender risks the orderbook depth being insufficient to pay back their loan in the specified market.

Motivation

BitShares is the longest running decentralised cryptocurrency exchange and one of the pioneers of collateralised stablecoins. While the BitShares DEX makes it easy to trade in an environment where users have custody of their own keys, there are opportunities to be made to improve liquidity, onboard new users and affect great trading activity on the BitShares DEX.

The highest volume and most liquid exchanges in the world to date like Bitmex and Bitfinex who rose to dominance due to their usage of leverage in catalysing greater liquidity for their customers.

With this in mind, some of the key inhibitors to growth right now for the BitShares DEX include:

Incentive for Smartcoin creation / holding: The growth in liquidity of Smartcoins like bitUSD, BitCNY, BitEUR and others depends on users locking up BTS collateral to create these assets. For users engaged in creating these assets they must often manage exposure to a highly volatile collateral asset and are not paid for taking on the risk which could reduce potential new issuance.

Smartcoin Liquidity: The most liquid BitShares markets are often the smart coin markets, however the liquidity of Smartcoins in circulation on the orderbook is not yet comparable to larger teir centralised exchanges thereby reducing potential usage of the BitShares DEX.

Counterparty risk of crypto lending: Currently one of the only ways with market traction to earn passive income on cryptocurrency holdings is to trust a centralised counterparty and give up ownership of your money to another entity. This is highly risky with users no longer in control of their funds and at risk of hacking or confiscation.

BTS Price growth: The Bitshares token (BTS) is the underlying collateral required for committee issued assets and therefore a higher Bitshares price incentivises greater Smartcoin creation. Growing demand for BitShares assets promotes higher collateralisation of BTS which requires more BTS being removed from circulation which over time reduces supply and can increase positive price pressure.

The motivation behind this BSIP is to address these concerns and increase user demand, liquidity and passive income opportunities for users of the BitShares DEX.

Rationale

This BSIP seeks to address the inhibitors to growth in the BitShares DEX by introducing P2P Lending, Borrowing and Margin trading markets on the BitShares DEX. This new functionality would address the above concerns as follows:

Passive risk adjusted income: Any user may choose to lend any BitShares asset for a user defined rate of return over a specified time period. This not only provides an added incentive to hold an asset that can return a yield but also ensures existing liquidity of BitShares assets is deployed to the trading orderbook.

On-chain lending and borrowing reduces risk: Users seeking a return would not need to trust third party intermediaries with their funds and can engage in lending and borrowing contracts on the BitShares DEX. This reduces risk compared to competing centralised non-custodial competitors.

Increased DEX liquidity: With the ability for users to lend new or existing liquidity directly to the orderbooks, it provides greater order book depth than exists currently. This reduces risk for margin traders who rely on ample orderbook depth to ensure their positions can be adequately executed at a desired price or in the case of margin calls greater depth reduces collateral losses.

Long / Short any asset on the DEX: A user could borrow or lend any asset on the DEX adding new opportunities to make money from market movements especially in bear markets. This also enables smartcoin issuers to hedge their BTS (or other) exposure which could assist these users maintain adequate MCR ratios thereby reducing global settlement risk.

Added volume and usage of BTS: Every operation on the BitShares DEX requires a fee to be paid which returns BTS to the reserve pool. Greater usage of the BitShares DEX increases fees paid, reduces supply which can result in a positive price pressure on BTS. Additionally new smartcoin issuance for committee assets and some private assets requires BTS as collateral and therefore increased issuance also requires the purchase and lock up of BTS, increasing demand of BTS.

The BitShares DAC is well situated to capture a market opportunity in this space with the core intent of this BSIP to increase the viability of the BitShares DEX as a high volume, non-custodial, transparent and liquid trading exchange.

Specifications

The process flow for margin trading is depicted below. The process consists of seven stages with some stages containing parallel processes.

Process Flow

  1. Stage 1a: Prior to any loan being offered or matched, the asset issuer must authorize the loan asset for lending for margin trading against sets of tradable assets.
  2. Stage 1b: Prior to any loan being offered or matched, it must be possible to look up a valid reference price between the tradable asset and the the loan asset on the internal DEX market.
  3. Stage 2: Lenders and potential Borrowers can place offers on the Lending Order Book. The offers by lenders ("loan offers") and the offers by borrowers ("borrow offers") shall remain on the books until they either expire or are matched by counter-offers.
  4. Stage 3: A reviewer of the Lending Order Book may agree to any existing offer.
  5. Stage 4a: A borrower/ may hold the borrowed asset and/or trade against the agreed-upon tradable asset for the duration of the loan. Stage 4b: The smart contract will transfer interest payments from the borrower's loan portfolio to the lender on a daily basis. Stage 4c The smart contract shall appraise the loan to check whether sufficient collateral backs the loan. Stage 4d: A borrower may update the amount of collateral in their loan.
  6. Stage 5a: A borrower may initiate a loan closure any time prior to the loan expiry. Stage 5b: The smart contract may initiate a margin call when the loan expires. Stage 5c: The smart contract may initiate a loan closure if it is unable to pay the daily interest on behalf of the borrower. Stage 5d: The smart contract may initiate a loan closure by margin call if it appraises the loan's collateral as being too low.
  7. Stage 6: During a margin call process the smart contract attempts to liquidate a loan portfolio to obtain a sufficient balance of the borrowed asset to repay the lender. This might require selling the balance of the tradable asset on the market.
  8. Stage 7a: During a loan closure, the lender is repaid what is owed and any balance of assets that remain in the loan portfolio are transferred to the borrower's regular set of balances. Stage 7b: Alternatively, if a margin call is initiated that does not complete within a certain amount of time, the entire loan portfolio shall be confiscated from the borrower and transferred to the lender as a substitute payment for what is owed.

Stage 1a: Authorized Leveraged Trading Pairs

The asset issuer of the loan asset must authorize the loan asset to be used for lending for margin trading ("leveraged trading") against a set of tradable assets. This set of authorized tradable asset may be updated by the asset issuer at any time. These restrictions shall affect the creation of new loan and borrow offers.

Stage 1b: Reference Price

Knowledge of the exchange rate between the loan asset and the tradable asset is essential for the smart contract to automatically appraise a portfolio during the loan appraissal and to evaluate the need for a possible margin call. This price shall be determined by the smart contract from data on the decentralized exchange and not from any external price feeds. The reference price shall be validated under specific rules, and prohibitions shall be imposed while the reference price is invalid.

Determination of Reference Price

The reference price for the tradable asset that is denominated in terms of the loan asset shall be updated every block that has any activity (new orders, canceled orders, and matched orders) in that market pair's trading book. The reference price of the tradable asset shall be calculated according to the following rules.

Asset Reference Price Validity of Reference Price
Tradable asset is a bitAsset that is not in global settlement The highest offer price for the tradable asset. If there are no offers, the last traded price. Valid if (a) there any offers for the tradable asset, and (b) if there has ever been any trade activity.
Tradable asset is a bitAsset that is in global settlement Global settlement price Always valid
All other assets The highest offer price for the tradable asset. If there are no offers, the last traded price. Valid if (a) there any offers for the tradable asset, and (b) if there has ever been any trade activity.

If the validity conditions are not satisfied for the asset pair, the reference price shall be considered invalid and certain activities shall be prohibited.

Prohibited Activity under Invalid Reference Price

A valid reference price permits the tradable asset components of the portfolio (Tliquid and Torders) to be appraised in terms of the loan asset. This allows the entire loan portfolio to be appraised which further allows a check of the minimum collateral requirements for an existing loan.

Therefore with a valid reference price

However an invalid reference price prevents a portfolio appraisal (except for the trivial case where the portfolio only consists of the borrowed asset components (Bliquid and Borders). Without the ability to appraise the tradable asset portion of the portfolio, collateral requirements cannot be evaluated. Therefore,

  • loan offers shall not be matched to prevent the creation of new loans,
  • a borrower shall not be able to sell more of the borrowed asset if the new liquid balance (Bliquidafter) shall become less than the minimum collateral value. This constraint can be expressed as MCV ≤ Bliquidafter.
    • The new limit order (Btradenew) is constrained such that 0 < Btradenew ≤ Bliquidbefore - MCV
  • a borrower shall not be able to sell more of the tradable asset if the new liquid balance (Bliquidafter) shall become less than the minimum collateral value. This constraint can be expressed as MCV ≤ Bliquidafter
    • The new limit order with a minimum to receive of the borrowed asset (Btradereceive) is constrained such that 0 < Btradereceive ≤ Bliquidbefore - MCV
  • a borrower shall not be permitted to withdraw the tradable asset unless the liquid balance of the borrowed asset (Bliquid) is greater than the maintenance collateral value (MCV). This constraint can be expressed as MCV ≤ Bliquid
  • margin calls shall not be initiated because the collateral ratio (CR) of the loan portfolio cannot be calculated.

Stage 2: Offers to Lend and Borrow

Both potential lenders and potential borrowers can place offers on the Loan Order Book. Potential lenders place "loan offers" and potential borrowers place "borrow offers". Loan offers contain the following parameters:

Lending Offer Parameter Description
Asset type to lend
The asset type that the lender is offering to lend
Minimum amount to lend
The minimum amount of the loan asset type that will be lent into a matched loan.
Maximum amount to lend
The maximum amount of the loan asset type that the lender is offering. This amount is deducted from the lender's balances when the offer is created.
Asset type of collateral
The asset type that the borrower must provide as collateral. For this initial version of margin trading, this shall be the same asset type as the asset type to lend.
Maintenance collateral ratio (MCR)
The minimum collateral ratio that the lender is expecting at the beginning of a loan. MCR ≥ MCCR ≥ 1
Margin call collateral ratio (MCCR)
The minimum collateral ratio below which a margin call of the loan is initiated. MCR ≥ MCCR ≥ 1
Maximum duration of margin call
The maximum duration of a margin call, if one is necessary, after which a portfolio confiscation will be triggered.
Asset type to trade against (Tradable asset)
The asset type that the lender permits the borrower to trade against. This restriction protects the lender from exit scam trading.
Minimum duration of loan
The minimum duration of the loan that the lender is willing to accept
Maximum duration of loan
The maximum duration of the loan that the lender is willing to accept
Minimum interest rate
The minimum daily interest rate that the lender is willing to accept
Expiration date Expiration date of the offer

Borrow offers contain the following parameters:

Borrowing Offer Parameter Description
Asset type to borrow
The asset type that the borrower is seeking
Minimum amount to borrow
The minimum amount of the loan asset type that will be borrowed into a matched loan.
Maximum amount to borrow
The maximum amount of the loan asset type that the borrower is willing to borrow.
Asset type as collateral The asset type that the borrower must provide for collateral. For this initial version of margin trading, this shall be the same asset type as the asset type to lend.
Amount of collateral The amount of collateral the borrower has put into the offer. This amount is deducted from the borrower's balances when the offer is created.
Maintenance collateral ratio (MCR)
The maximum collateral ratio that the borrower is willing to offer at the beginning of a loan. MCR ≥ MCCR ≥ 1
Margin call collateral ratio (MCCR)
The maximum collateral ratio below which a margin call of the loan is initiated. MCR ≥ MCCR ≥ 1
Minimum duration of margin call protection
The minimum duration of a margin call, if one is necessary, after which a portfolio confiscation will be triggered.
Asset type to trade against (Tradable asset)
The asset type that the borrower can trade against.
Minimum duration of loan
The minimum duration of the loan that the borrower is willing to accept
Maximum duration of loan
The maximum duration of the loan that the borrower is willing to accept
Maximum interest rate
The maximum daily interest rate that the borrower is willing to accept
Expiration date Expiration date of the offer

After an offer is created, all users shall be able to identify:

  • which unmatched offers are on the Lending Order Book, and
  • which offers are matched.

Users shall have the ability to filter offers either by type (loan offer or borrow offer), asset type to loan, tradable asset type, amounts, interest rate, loan duration, maintenance collateral ratio, and margin call collateral ratio. This capability shall either be done at the Core RPC-API node and/or at the user interface. Offers to lend and offers to borrow shall have unique identifiers which can be referenced for loan matching.

The creation of offers, their partial and complete matches, their expiration, and their closures, shall be recorded as part of the account history of the lender and the borrower.

Offers to lend and borrow shall remain on the Loan Order Book until they either are canceled by the offeror, expire, or are completely matched.

Stage 3: Loan Matching

Matching of loans, in this initial version of Lending for Margin Trading, shall be an action taken by account holders who actively agree to specific loan offers by their offer identifier. Automatic matching of offers on the Lending Order Book may be considered in a future BSIP.

When the agreement is matched, the borrower's collateral asset and the corresponding lender's loan asset shall be moved into the borrower's loan-related portfolio.

Acceptance to Borrow

An acceptance to borrow, which is techinically an acceptance of an existing loan offer, shall be made by a borrower who indicates the following in an operation:

Agreement to Lending Offer Parameter Description
Lending Offer ID Identifier of an existing loan offer
Asset type of collateral The asset type that the borrower is providing as collateral. This asset type must be compatible with the offer's acceptable collateral type.
Amount of collateral (K) The amount of collateral that the borrower is providing in the acceptance. This amount must be comptabile with the loan offer's maintenance collateral requirements, minimum amount, and maximum amount.
Duration of the loan
The duration of the loan. This duration must be compatible with the loan offer's minimum duration and maximum duration.

A loan between the offeror and the acceptor shall be created according to the explicit terms of the acceptance. The tradable asset, margin call collateral ratio, and margin call duration are implied to be accepted according to the terms of the loan offer. The interest rate shall be set to the minimum interest rate in the borrow offer. The loan amount (B0) shall be

B0 = K ÷ (MCR - 1)

in accordance with the maintenance collateral requirements.

Acceptance to Lend

An acceptance to lend, which is technically an acceptance of an existing borrow offer, shall be made by a lender who indicates the following in an operation:

Agreement to Borrow Offer Parameter Description
Borrow Offer ID Identifier of an existing offer to borrow
Asset type of loan The asset type that the lender is providing for the loan. This asset type must be compatible with the offer's asset type to borrow.
Amount of loan (B0) The amount of the loan that the lender is providing in the acceptance. This amount must be comptabile with the borrow offer's maintenance collateral requirements, minimum amount, and maximum amount.
Duration of the loan
The duration of the loan. This duration must be compatible with the loan offer's minimum duration and maximum duration.

A loan between the offeror and the acceptor shall be created according to the explicit terms of the acceptance. The tradable asset, margin call collateral ratio, and margin call duration are implied to be accepted according to the terms of the borrow offer. The interest rate shall be set to the maximum interest rate in the borrow offer.

Amount of Collateral

The amount of initial collateral (K) that is provided by the borrower shall be greater than or equal to

K ≥ (MCR - 1) × B0

where MCR is the maintenance collateral ratio (MCR) and B0 is the principal amount that is provided by the lender.


Example of Matching a Loan Offer

A potential lender offers to lend 70 bitUSD with a maintenance collateral ratio of 142.9%. A borrower accepts the terms by offering 30.03 bitUSD as maintenance collateral.

The offer and acceptance will be matched, and the borrower's loan-related portfolio is opened with a total of 100.03 bitUSD.



Example of Matching a Borrow Offer

A potential borrower offers to borrow with 15 bitUSD collateral with an maintenance collateral ratio of 130%. A lender accepts the terms by offering 50 bitUSD as financing.

The offer and acceptance will be matched, and the borrower's loan-related portfolio is opened with a total of 65.00 bitUSD.


Time Period of the Loan

The duration of the accepted loan shall be the duration that was specified in the acceptance.

The start date of the loan shall be when the loan is matched. The end date of the loan is a time period that is compatible with the offer and the acceptance.

Loan Creation Earliest End Date Latest End Date
Loan Created by a Borrower Accepting an Existing Loan Offer Match date + Loan Offer's Minimum Duration Match date + Borrower's Acceptance Duration
Loan Created by a Lender Accepting an Existing Borrow Offer Match date + Lender's Acceptance Duration Match date + Loan Offer's Maximum Duration

The loan may be closed:

Filling of Loan Offers

An acceptance to borrow, which is an acceptance of a loan offer, may consume only a portion of the amount that has been offered by the lender. This "partial fill" of a loan offer can leave a remainder in the offer. If this remainder exceeds the loan offer's minimum amount, the loan offer shall remain on the books for possible future matches although the offer's loan amount shall be reduced to the remainder. Alternatively if the remainder is less than the minimum amount, the offer shall be cancelled by the smart contract.

Similarly, an acceptance to lend, which is an acceptance of a borrow offer, may consume only a portion of the collateral that has been offered by the borrower. This "partial fill" of a borrower offer can leave a remainder in the offer. If this remainder exceeds the borrow offer's minimum amount, the borrow offer shall remain on the books for possible future matches although the offer's collateral amount shall be reduced to the remainder. Alternatively if the remainder is less than the minimum amount, the offer shall be cancelled by the smart contract.

Stage 4a: Margin Trading within Loan Portfolio

Assets that are borrowed shall be placed into the borrower's margin trading "loan portfolio". This portfolio shall only be used for trading on the decentralized exchange in the market pair consisting of the "Asset type to lend/borrow" and the "Asset type to trade against". It shall not be possible to transfer funds to any account, nor use any of the assets as collateral to create another pegged asset on BitShares.

Any assets obtained from trading shall by placed into the loan portfolio and shall also be restricted to trading between the pair of asset types defined in the loan agreement. Conditional withdrawals of the tradable asset by the borrower shall be permitted. Deposit of the lent asset by the borrower shall also be permitted.

Trading Limits

A borrower shall be able to use the borrowed asset type in the loan portfolio to trade against the tradable asset on the order book of the market pair. The amount of the borrowed asset type (B) that may be used for placing new orders shall be limited to ensure that the loan portfolio's balance of the borrowed asset exceeds the minimum collateral (K). Before a trade the liquid balance of the asset type is Bliquidbefore. The liquid balance of the asset type after a new order (Btradenew) can be calculated as

Bliquidafter = Bliquidbefore - Btradenew

The new liquid balance must satisfy the following condition and definition for collateral

Bliquidafter ≥ K = (MCR - 1) × B0

which can be re-arranged as

Btradenew ≤ Bliquidbefore - (MCR - 1) × B0

This expresses a maximum amount for any new limit orders where the borrowed asset is offered to trade. If this amount is negative, no new trades shall be permitted.

Multiple Loan Portfolios

A borrower may have multiple outstanding loans each with their own distinct loan portfolio. Trading of assets from each loan portfolio shall be independent of other loan portfolios that are controlled by the borrower. Trade orders shall only draw from assets within a single loan portfolio.

The distinction of loan portfolios from each other are intended to segregate the risk of each loan which can have separate loan durations, margin collateral ratios, and tradable assets. This segregation should better secure the lenders than a single co-mingled loan portfolio.

User interfaces that facilitate trading for a borrower may optionally aggregate multiple loan portfolios into a single "margin trading wallet" to disguise the fact that multiple loan portfolios are being tracked.

Stage 4b: Daily Interest Payment

The daily interest due (Idaily) on the prinicipal (B0) shall be calculated as

Idaily = B0 × Rdaily

where Rdaily is daily interest rate. This daily interest shall be calculated in terms of the lent asset type.

The daily interest that is due shall be deducted from the borrower's balance of the borrowed asset type in the loan portfolio and deposited into the lender's account. If the borrower's loan portfolio holds insufficient balance of the lent asset type to pay the daily interest then a margin call shall be initiated.

When a loan is closed the interest for that last day shall be paid at that time. If a margin call requires multiple days to complete in accordance with the agreed duration of the margin call's loan, no additional interest shall be owed by the lender beyond payment for the last day of interest.

Stage 4c: Appraisal of Loan Portfolio

Debt Owed

The debt owed by a borrower for a particular loan is the amount lent by the lender. Interest is due on a daily basis.

Portfolio Appraisal

A borrower may have many outstanding loans which are owed to different borrowers. Each loan portfolio will initially consist of the principal that is lent by the lender plus the initial collateral that is provided by the borrower. The borrowed asset and the collateral asset shall initially be the same asset type (B).

After the loan is initiated, the borrower may use that asset type to trade against the tradable asset type (T) that is permitted by the loan, and/or may hold the borrowed asset. Therefore this loan-related portfolio may consist of balances of two asset types: the borrowed asset type, and the tradable asset type.

PA = B + T

Portfolio Components

While a loan is outstanding the balance of the borrowed asset and tradable asset may consist as either liquid balances in the loan portfolio or as open orders on the order book. Therefore the entire loan portfolio may be decomposed into four parts:

  • a balance of borrowed asset that is liquid (Bliquid)
  • a balance of tradable asset that is liquid (Tliquid)
  • a balance of borrowed asset that is in open order (Borders)
  • a balance of tradable asset that is in open order (Torders)

PA = Bliquid + Tliquid + Borders + Tliquid

The valuation of the portfolio shall also be denominated in terms of the borrowed asset type for purposes of appraisal by the smart contract. The valuation of the borrower's loan-related portfolio shall consist of the valuation of the two assets in the portfolio at the time of interest.

  • The valuation of the liquid balance and order balance of the borrowed asset shall simply be their sum.
  • The valuation of the liquid balance and order of the tradable asset shall be denominated in the borrowed asset type by the smart contract with the use of reference price.

Example of Portfolio Appraisal

Bob borrowed 70 bitUSD 203.3 days ago while supplying by supplying 30.03 bitUSD as collateral. Bob has been margin trading with this loan portfolio against bitBTC and currently has a balance of 45 bitUSD and 0.025 bitBTC. The current reference price indicates that bitBTC is priced at 5000 bitUSD per bitBTC. This loan portfolio will be appraised (PA) at:

PA = (45 bitUSD) + (0.025 bitBTC × 5000 bitUSD ÷ bitBTC)

... = (45 bitUSD) + (125 bitUSD)

... = 170 bitUSD


Collateral Ratio

After the calculation of a portfolio appraisal (PA) and the debt owed (B0), the collateral ratio (CR) shall be calculated as

CR = PA ÷ B0

At the beginning of the loan, the collateral ratio will satisfy the following conditions.

CR ≥ MCR ≥ MCCR ≥ 1

Derived Valuations

The maintenance collateral valuation (MCV) of the loan portfolio is denominated in the borrowed asset and equals

MCV = MCR × B0

where B0 is the debt owed.

Similarly, the margin call collateral valuation (MCCV) of the loan portfolio is denominated in the lent asset and equals

MCCV = MCCR × B0

It is desired for the appraised valuation of the portfolio (PA) to be greater than or equal this value

PA ≥ MCV ≥ MCCV ≥ B0

but it is possible for this valuation to fall below the MCV. If

PA < MCCV

a margin call shall be initiated.

Triggering of Appraisal

Portfolio appraisals shall be triggered at multiple times. A portfolio appraisal shall be triggered:

Stage 4d: Loan Portfolio Updates

Status of Loan Portfolio

The "recent" appraisal value, debt owed, collateral ratio, and derived valuations, and of the portfolio shall be able to be queried by the lender and borrower at any time.

Deposits

A borrower shall be able to deposit additional amounts of the borrowed asset into the loan portfolio. A borrower may choose to deposit additional collateral to avoid having the loan be margin called.

Withdrawals

A borrower shall be able to withdraw only the tradable asset as long as the market valuation of the portfolio (PA) after the withdrawal is greater than or equal to the maintenance collateral valuation. The withdrawal limit (Wlimit) is defined as

Wlimit = PA - MCV

where MCV is maintenance collateral valuation and PA is portfolio appraisal.


Example of Withdrawal

Bob borrowed 70 bitUSD 203 days ago at a daily interest rate of 0.0261% while supplying by supplying 30.03 bitUSD as collateral to satisfy the offer's 142.9% maintainance collateral ratio.

The debt owed is still 70 bitUSD. The maintenance collateral valuation (MCV) of the portfolio is

MCV = MCR × B0

... = 1.429 × 73.8276 bitUSD

... = 105.4996 bitUSD

During this time Bob has been margin trading with this loan portfolio against bitBTC and currently has a balance of 45 bitUSD and 0.025 bitBTC. The current reference price indicate that bitBTC is priced at 5000 bitUSD per bitBTC. This loan portfolio will be appraised at:

PA = (45 bitUSD) + (0.025 bitBTC × 5000 bitUSD ÷ bitBTC)

... = (45 bitUSD) + (125 bitUSD)

... = 170 bitUSD

The borrower may withdraw up to the equivalent (Wlimit) of

Wlimit = PA - MCV

... = 170 bitUSD equivalent - 105.4996 bitUSD equivalent

... = 64.5004 bitUSD equivalent

The withdrawal limit denominated in bitBTC is

Wlimit = (64.5004 bitUSD ÷ (5000 bitUSD ÷ bitBTC))

... = 0.01291 bitBTC

Bob may withdraw bitBTC up to this limit because the balance of bitBTC, 0.025, exceeds this amount. If the balance of the tradable asset were, for example, only 0.1 bitBTC then Bob would only be able to withdraw 0.1 bitBTC.


Stage 5a: Initiation of Loan Closure by Borrower

A borrower may close an outstanding loan position by having a sufficient balance of the borrowed asset type in the loan portfolio and then initiating a loan closure with the appropriate parameters.

Initiation of Loan Closure Parameter Description
Lending Offer ID Identifier of an existing and open loan offer

The initiation of a loan closure shall close any and all open trade orders that are related to this loan. If the balance of the borrowed asset type is insufficient to repay what is owed then the initiation of the loan closure shall be rejected. It is the responsibility of the borrower to ensure a sufficient balance in the borrowed asset type to repay the loan.

Stage 5b: Expiration of Loan

The smart contract shall initiate a margin call if an outstanding loan expires.

A future BSIP may consider opening a new loan from any existing offers on the Loan Order Book.

Stage 5c: Initiation of Loan Closure because of Insufficient Funds

A loan portfolio may categorized as consisting of four components of balances of which one is the balance of borrowed asset that is liquid (Bliquid). This balance is drawn from to pay the daily interest. If this balance is insufficient to pay the interest then a loan closure shall be initiated.

Stage 5d: Initiation of Loan Closure by Margin Call

If the collateral ratio ever drops below the margin call collateral ratio,

CR < MCCR

the smart contract shall initiate a margin call.

Stage 6: Margin Call

Restriction of Loan Portfolio

When a margin call is initiated on a specific loan portfolio, no new market orders may be initiated that make use of any balance in the loan portfolio. Any other loan portfolios that the borrower might have shall not be affected by margin calls on other loans.

Any open market orders that are related to that specific loan portfolio shall be cancelled.

After all open orders are cancelled, the portfolio will consist of some amount in the borrowed asset type and some amount in the tradable asset type.

PA = Bliquid + Tliquid

Liquidation Plan

The smart contract shall determine whether the balance of the borrowed asset (Bliquid) is sufficient to pay the necessary balance (Bclosure). The difference between the two is the excess borrowed asset (Bexcess)

Bexcess = Bliquid - Bclosure

If the balance is sufficient (Bexcess > 0), the process shall transition to a conventional loan closure.

If the balance is insufficient (Bexcess < 0), the smart contract shall create a limit order that offers the entire balance of the tradable asset (T) while asking for the difference between what is owed and the liquid balance(-Bexcess). This limit order shall have a limited lifetime defined by the maximum margin call duration that was agreed to in the original loan terms.

If the margin call's limit order is filled, then by definition of the limit order there shall be sufficient balance of the borrowed asset type to transition to a conventional loan closure.

Portfolio Confiscation

If the margin call's limit order expires without being completely filled, a portfolio confiscation shall be automatically initiated to permit the prompt completion of the margin call. The smart contract shall confiscate the entire loan portfolio from the borrower for ultimate transfer to the lender.

Monitoring of Liquidation Plan

It shall be possible to monitor the status of the liquidation plan associated with any margin call. An inquiry into the status of the liquidation plan shall return:

Stage 7a: Conventional Loan Closure

A standard loan closure is possible if and only if the loan portfolio's balance of the borrowed asset type (Bliquid) is sufficient to repay the principal plus interest for the last day of the loan.

Bclosure = B0 + Idaily

If that condition is satisfied, a standard loan closure can be:

Any balances that remain in the loan portfolio after repaying the lender shall be transferred to the borrower's regular set of balances and shall no longer be encumbered by any restrictions.

A future BSIP may consider re-lending a lenders balance by automatically creating a new offer on the Loan Order Book on behalf of the lender.

The loan shall be closed.

Stage 7b: Unconventional Loan Closure

If a margin call's liquidation plan expires without obtaining a sufficient balance of the borrowed asset to repay the lender, the confiscated loan portfolio shall be transferred to the lender as a substitute payment for the debt.

The loan shall be closed.

Definable Loan Constraints

The BitShares Committee shall be able to define parameters that can constrain new loans; changes to these values shall not affect loans that were offered before the change:

Term Description
Maximum loan durations The maximum duration for a new loan offer
Minimum MCR The minimum maintenance collateral ratio (MCR) that may be agreed upon
Minimum MCCR The minimum margin call collateral ratio (MCCR) that may be agreed upon
Maximum interest rates The maximum interest rate that may be agreed upon
Maximum duration of margin call
The duration during which a borrower's loan portfolio shall be protected from confiscation.

Fees

Fees shall be defined for each of the operations:

The standard fee for canceling a trade order shall apply.

Voting Stake

Voting stake shall be calculated per account as before this proposal and with the following additions to account for any core tokens (BTS) that are associated with lending.

  • Any balance of BTS in a lending offer shall be staked to the owner of the offer.
  • Any balance of BTS in a borrowing offer shall be staked to the owner of the offer.
  • If BTS is the tradable asset in a loan portfolio, the liquid balance (Tliquid) and the balance in open orders (Torders) shall be staked to the borrower.
  • If BTS is the borrowed asset in a loan portfolio, the liquid balance (Bliquid) and the balance in open orders (Borders) shall be staked to the lender up to the principal amount that is lent (B0). Any balance in excess of the principal shall be staked to the borrower.
    • The motivation for this segregation of voting stake is to prevent the renting of voting stake through this lending mechanism.

Software Specifications

Note 1: Interest is paid every 24 hours, regardless of local calendar. E. g. Daylight Savings Time is ignored.

Note 2: Percentage-based calculations (interest, CR) are always rounded up to the next possible value (aka "satoshi").

Note 3: MCR and MCCR are expressed in the same way as in the existing price feed logic, i. e. only the part above 100%, and as a scaled percentage value. E. g. a value of 4200 would mean 142%.

Note 4: "Implementation hints" are not to be considered part of the formal specification, but merely as a possible implementation.

Database Objects

lending_offer_object (new)

Fields:

  • lending_offer_id_type id - The object ID
  • account_id_type owner - The lending account ID
  • asset_id_type loan_asset - The asset type that the lender is offering to lend
  • share_type min_amount - The minimum amount of the asset type that the borrower must borrow
  • share_type max_amount - The maximum amount of the asset type that the lender is offering
  • unsigned_int mcr - The minimum collateral ratio that the lender is expecting at the beginning of a loan, as a scaled percentage
  • unsigned_int mccr - The collateral ratio below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int max_call_duration - The maximum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the lender permits the borrower to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the lender is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the lender is willing to accept, in days
  • unsigned_int min_interest_rate - The minimum daily interest rate that the lender is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Implementation hints:

  • Indexed by_owner, by_asset, by_expiration
  • Secondary index for tracking core per account

borrowing_offer_object (new)

Fields:

  • borrowing_offer_id_type id - The object ID
  • account_id_type owner - The borrowing account ID
  • asset_id_type loan_asset - The asset type that the borrower is offering to borrow
  • share_type min_amount - The minimum amount of the asset type that the lender must lend
  • share_type max_amount - The maximum amount of the asset type that the borrower wants to borrow
  • share_type available_collateral - The amount of collateral the borrower has put into the offer
  • unsigned_int mcr - The maximum collateral ratio that the borrower is willing to provide at the beginning of the loan, as a scaled percentage
  • unsigned_int mccr - The maximum collateral ratio the borrower will accept, below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int min_call_duration - The minimum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the borrower wants to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_interest_rate - The maximum daily interest rate that the borrower is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Implementation hints:

  • Indexed by_owner, by_asset, by_expiration
  • Secondary index for tracking core per account

loan_portfolio_object (new)

Fields:

  • account_id_type owner - The borrowing account ID
  • account_id_type lender - The lending account ID
  • asset_id_type principal_asset - The ID of the borrowed asset
  • share_type principal_borrowed - The amount that was originally borrowed
  • share_type minimum_collateral - The minimum amount of collateral that must be maintained
  • share_type principal_balance - The amount of the borrowed asset currently held in the portfolio
  • share_type principal_in_orders - The amount of the borrowed asset currently held in market orders
  • asset_id_type trade_asset - The ID of the asset that can be traded against
  • share_type trade_balance - The amount of the tradable asset currently held in the portfolio
  • share_type trade_in_orders - The amount of the tradable asset currently held in market orders
  • share_type mccv - The portfolio value below which a margin call of the loan is initiated, in terms of principal_asset
  • unsigned_int call_duration - The duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • optional<time_point_sec> confiscation_time - After a margin call has been initiated, this contains the time when the portfolio will be confiscated
  • share_type daily_interest - The daily interest amount to be paid
  • time_point_sec interest_due_at - Date at which the next interest payment is due
  • share_type cumulative_interest - The cumulative interest paid for this loan so far
  • time_point_sec earliest_end - Date after which the portfolio can be closed by the borrower
  • time_point_sec latest_end - Date after which the portfolio will be closed automatically
  • optional<price> call_price - If present, contains the price (in terms of principal/trade) below which the portfolio is margin called

Implementation hints:

  • Indexed by_owner, by_lender, by_interest_due, by_expiration (i. e. latest_end)
  • Secondary index for tracking core per account

Chain parameters

The chain_parameters (configurable by committee) will receive a new extension field margin_lending with these members:

  • unsigned_int max_duration - maximum allowed loan duration in days
  • unsigned_int minimum_mcr - minimum allowed mcr for loans, as a scaled percentage
  • unsigned_int minimum_mccr - minimum allowed mccr for loans, as a scaled percentage
  • unsigned_int max_interest - maximum allowed daily interest rate, as a scaled percentage
  • unsigned_int max_call_duration - maximum allowed call duration in seconds

This extension must not be present in proposals before the hardfork time.

Miscellaneous

  • limit_order_object receives a new field optional<loan_portfolio_id_type> loan

Implementation hints:

  • Secondary index on limit_order_object for tracking by_loan

Operations

All new operations have a simple flat fee.
New operations must not be allowed before the hardfork time, neither in proposals nor directly.
New fees must not be allowed in chain parameter update proposals before the hardfork.

lending_offer_create_operation (new)

Fields:

  • account_id_type lender - The lending account ID
  • asset_id_type asset_to_lend - The asset type that the lender is offering to lend
  • share_type min_to_lend - The minimum amount of the asset type that the borrower must borrow
  • share_type max_to_lend - The maximum amount of the asset type that the lender is offering
  • unsigned_int mcr - The minimum collateral ratio that the lender is expecting at the beginning of a loan, as a scaled percentage
  • unsigned_int mccr - The collateral ratio below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int max_call_duration - The maximum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the lender permits the borrower to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the lender is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the lender is willing to accept, in days
  • unsigned_int min_interest_rate - The minimum daily interest rate that the lender is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Validation checks:

  • lender must be a valid account ID, must exist, must authorize the operation, must pay fee
  • asset_to_lend and tradable_asset must be valid asset IDs, must not be equal, and both assets must exist
  • min_to_lend > 0
  • max_to_lend >= min_to_lend
  • mcr >= mccr
  • max_duration >= min_duration
  • expiration > head_block_time
  • min_duration <= chain_parameters.max_duration
  • mcr >= chain_parameters.min_mcr
  • mccr >= chain_parameters.min_mccr
  • min_interest_rate <= chain_parameters.max_interest_rate
  • max_call_duration <= chain_parameters.max_call_duration
  • lender must have at least max_to_lend of asset_to_lend in his balance
  • asset_to_lend must be authorized for margin lending against tradable_asset
  • asset_to_lend and the tradable_asset must not be transfer restricted
  • lender must be whitelisted or must not be blacklisted for the asset_to_lend and the tradable_asset due to transfer restrictions

Evaluation:

  • Deduct max_to_lend of asset_to_lend from lender balance
  • Create new lending_offer_object and populate object fields from operation fields
  • Operation result is new object id

borrowing_offer_create_operation (new)

Fields:

  • account_id_type borrower - The borrowing account ID
  • asset_id_type asset_to_borrow - The asset type that the borrower is offering to borrow
  • share_type min_to_borrow - The minimum amount of the asset type that the lender must lend
  • share_type max_to_borrow - The maximum amount of the asset type that the borrower wants to borrow
  • unsigned_int mcr - The maximum collateral ratio that the borrower is willing to provide at the beginning of the loan, as a scaled percentage
  • unsigned_int mccr - The maximum collateral ratio the borrower will accept, below which a margin call of the loan is initiated, as a scaled percentage
  • unsigned_int min_call_duration - The minimum duration of a margin call in seconds, if one is necessary, after which a portfolio confiscation will be triggered
  • asset_id_type tradable_asset - The asset type that the borrower wants to trade against
  • unsigned_int min_duration - The minimum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_duration - The maximum duration of the loan that the borrower is willing to accept, in days
  • unsigned_int max_interest_rate - The maximum daily interest rate that the borrower is willing to accept, as a scaled percentage
  • time_point_sec expiration - Expiration date of the offer
  • extension_type ext - reserved for future extensions

Validation checks:

  • borrower must be a valid account ID, must exist, must authorize the operation, must pay fee
  • asset_to_borrow and tradable_asset must be valid asset IDs, must not be equal, and both assets must exist
  • min_to_borrow > 0
  • max_to_borrow >= min_to_borrow
  • mcr >= mccr
  • max_duration >= min_duration
  • expiration > head_block_time
  • min_duration <= chain_parameters.max_duration
  • mcr >= chain_parameters.min_mcr
  • mccr >= chain_parameters.min_mccr
  • min_interest_rate <= chain_parameters.max_interest_rate
  • min_call_duration <= chain_parameters.max_call_duration
  • borrower must have at least max_to_borrow * mcr of asset_to_borrow in his balance
  • asset_to_borrow must be authorized for margin lending against tradable_asset
  • asset_to_borrow and the tradable_asset must not be transfer restricted
  • borrower must be whitelisted or must not be blacklisted for the asset_to_lend and the tradable_asset due to transfer restrictions

Evaluation:

  • Deduct max_to_borrow * mcr of asset_to_borrow from borrower balance
  • Create new borrowing_offer_object and populate object fields from operation fields
  • Operation result is new object id

lending_cancel_operation (new)

This operation can be used to cancel lending and borrowing offers.

Fields:

  • account_id_type owner - Creator of the operation (fee paying account), must equal owner of the offer
  • offer_id_type offer - Either a lending_offer_id_type or a borrowing_offer_id_type
  • extension_type ext - reserved for future extensions

Validation checks:

  • owner must be a valid account ID, must exist, must authorize the operation, must pay fee
  • offer must be a valid lending offer ID or borrowing offer ID and must exist
  • offer.owner == owner

Evaluation:

  • If offer is a lending offer:
    • Add offer.max_amount of offer.loan_asset to owner balance
  • If offer is a borrowing offer:
    • Add offer.available_collateral of offer.loan_asset to owner balance
  • Delete offer from database
  • Operation result is amount paid back to owner

lending_accepted_operation (new, virtual)

Fields:

  • account_id_type offerer - must equal owner of the offer
  • offer_id_type offer - id of the accepted offer, lending_offer_id_type or a borrowing_offer_id_type
  • loan_portfolio_id_type loan - id of the resulting loan portfolio

lending_accept_operation (new)

This operation can be used to accept lending and borrowing offers.

Fields:

  • account_id_type acceptor - Creator of the operation (fee paying account), must not equal owner of the offer
  • offer_id_type offer - Either a lending_offer_id_type or a borrowing_offer_id_type
  • asset_id_type loan_asset - The asset type of the loan amount
  • share_type loan_amount - The loan amount requested / offered
  • share_type collateral_amount - The collateral amount requested / offered
  • unsigned_int duration - The duration after which the loan will be closed automatically, in days
  • extension_type ext - reserved for future extensions

Validation checks:

  • acceptor must be a valid account ID, must exist, must authorize the operation, must pay fee
  • offer must be a valid lending offer ID or borrowing offer ID and must exist
  • offer.owner != acceptor
  • offer.loan_asset == loan_asset
  • offer.min_duration <= duration <= offer.max_duration
  • offer.min_amount <= loan_amount <= offer.max_amount
  • duration <= chain_parameters.max_duration
  • If offer is a lending offer:
    • offer.mcr <= collateral_amount / loan_amount
    • acceptor must have at least collateral_amount of loan_asset in his balance
  • If offer is a borrowing offer:
    • collateral_amount is not set
      • Let collateral_amount = loan_amount * offer.mcr
    • acceptor must have at least loan_amount of loan_asset in his balance
  • is_reference_price_valid
  • loan_asset, collateral_amount, and the offer.tradable_asset must not be transfer restricted
  • acceptor and offer.owner must be whitelisted or must not be blacklisted for the loan_asset, collateral_amount, and the offer.tradable_asset due to transfer restrictions

Evaluation:

  • Create loan_portfolio_object and populate fields from operation and offer
  • If offer is a lending offer:
    • Deduct collateral_amount of loan_asset from acceptor's balance
    • Deduct loan_amount from offer.max_amount
    • If offer.max_amount < offer.min_amount: create and execute virtual cancel operation for offer
  • If offer is a borrowing offer:
    • Deduct loan_amount of loan_asset from acceptor's balance
    • Deduct collateral_amount from offer.available_collateral
    • If offer.available_collateral / offer.mcr < offer.min_amount: create and execute virtual cancel operation for offer
  • Set in loan_portfolio_object:
    • principal_borrowed = loan_amount
    • minimum_collateral = collateral_amount
    • principal_balance = loan_amount + collateral_amount
    • daily_interest = loan_amount * offer.interest_rate
    • interest_due_at = head_block_time + 86400
    • mccv = loan_amount * (1 + offer.mccr)
    • If offer is a lending offer:
      • earliest_end = head_block_time + 86400 * offer.min_duration
      • latest_end = head_block_time + 86400 * duration
    • Otherwise (offer is a borrowing offer)
      • earliest_end = head_block_time + 86400 * duration
      • latest_end = head_block_time + 86400 * offer.max_duration
  • Create virtual lending_accepted_operation to notify owner of offer
  • Operation result is new object id

loan_interest_operation (new, virtual)

Fields:

  • account_id_type lender - the lender's account id
  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset interest_amount - Amount of interest paid to loan.lender

loan_closed_operation (new, virtual)

Fields:

  • account_id_type lender - the lender's account id
  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset principal_paid_back - Amount of principal paid back to lender
  • asset trade_confiscated - Amount of trade asset paid to lender
  • asset principal_turned_out - Amount of principal paid out to borrower
  • asset trade_turned_out - Amount of trade asset paid out to borrower

loan_close_operation (new)

Fields:

  • account_id_type borrower - the borrower's account id
  • loan_id_type loan - ID of the loan portfolio to adjust

Validation checks:

  • borrower must be a valid account ID, must exist, must authorize the operation, must pay fee
  • loan must be a valid loan portfolio ID and must exist
  • loan.owner == borrower
  • head_block_time >= loan.earliest_end
  • loan.principal_in_orders == 0 && loan.trade_in_orders == 0
  • loan.principal_balance >= loan.principal_borrowed + loan.daily_interest

Evaluation:

  • Trigger interest payment (see below)
  • Pay loan.principal_borrowed of loan.principal_asset to loan.lender
  • Pay loan.principal_balance - loan.principal_borrowed of loan.principal_asset to loan.borrower
  • Pay loan.trade_balance of loan.trade_asset to loan.borrower
  • Create a virtual loan_closed_operation
  • Delete loan

loan_update_operation (new)

Fields:

  • account_id_type owner - Creator of the operation (fee paying account), must equal owner of the loan portfolio
  • loan_id_type loan - ID of the loan portfolio to adjust
  • asset principal_delta - Amount of principal asset to add / withdraw
  • asset trade_delta - Amount of trade asset to add / withdraw
  • extension_type ext - reserved for future extensions

Validation checks:

  • owner must be a valid account ID, must exist, must authorize the operation, must pay fee
  • loan must be a valid loan portfolio ID and must exist
  • loan.owner == owner
  • principal_delta != 0 || trade_delta != 0
  • principal_delta >= 0
  • !confiscation_time.valid || trade_delta >= 0
  • If principal_delta > 0 or trade_delta > 0, owner must have sufficient balance
  • If trade_delta < 0
    • loan.trade_balance >= -trade_delta
    • Let mcv = loan.principal_borrowed + loan.minimum_collateral
    • if is_reference_price_valid
      • If loan.principal_balance + loan.principal_in_orders < mcv
        • Let min_trade = reference_price * (mcv - loan.principal_balance - loan.principal_in_orders)
        • loan.trade_balance + loan.trade_in_orders + trade_delta >= min_trade
    • Otherwise (!is_reference_price_valid)
      • mcv <= loan.principal_balance

Evaluation:

  • If principal_delta > 0:
    • Deduct principal_delta from loan.owner's balance
    • Add principal_delta.amount to loan.principal_balance
  • If trade_delta != 0:
    • Deduct trade_delta from loan.owner's balance
    • Add trade_delta.amount to loan.trade_balance
    • Re-appraise portfolio and throw if margin call is triggered

Loan trading

Note: trading from a loan portfolio happens on the same markets as trading from an account. Trading is therefore not implemented separately, but through modifications to the existing trade mechanisms.

Fields:

The existing limit_order_create_operation and fill_order_operation receive one optional extension field:

  • loan_id_type loan - ID of the loan portfolio from which the trade is executed

The loan field is not allowed before the hardfork time, neither directly nor in proposals.

Validation checks:

If the loan extension is present in a limit_order_create_operation, the following checks replace the existing checks against the seller's account balance:

  • loan is valid and refers to an existing loan_portfolio_object
  • seller == loan.owner
  • !loan.confiscation_time.valid (no trades after margin call)
  • amount_to_sell.asset_id == loan.principal_asset || amount_to_sell.asset_id == loan.trade_asset
  • If amount_to_sell.asset_id == loan.principal_asset:
    • loan.principal_balance - amount_to_sell.amount >= loan.minimum_collateral
    • min_to_receive.asset_id == loan.trade_asset
    • if !is_reference_price_valid
      • 0 < amount_to_sell.amount <= loan.principal_balance - mcv
  • If amount_to_sell.asset_id == loan.trade_asset:
    • loan.trade_balance >= amount_to_sell.amount
    • min_to_receive.asset_id == loan.principal_asset
    • if !is_reference_price_valid
      • 0 < min_to_receive.amount <= loan.principal_balance - mcv

Evaluation:

  • The loan extension will be recorded in the new limit_order_object
  • If loan field is present,
    • amount_to_sell will be deducted from the loan balance and recorded in loan's ..._in_order fields, not the account's
    • fill_order will be modified to pay trade proceeds into loan portfolio and adjust loan's ..._in_order fields
    • fill_order must re-appraise the portfolio
    • cancel_order will be modified to return funds into loan portfolio and adjust loan's ..._in_order fields

Database API Calls

The following methods will be added to the database_api:

  • vector<lending_offer_object> get_lending_offers_by_asset <loan-asset> <trade-asset> <optional limit> <optional start>
  • vector<borrowing_offer_object> get_borrowing_offers_by_asset <loan-asset> <trade-asset> <optional limit> <optional start>
  • vector<lending_offer_object> get_lending_offers_by_account <account> <optional limit> <optional start>
  • vector<borrowing_offer_object> get_borrowing_offers_by_account <account> <optional limit> <optional start>
  • vector<loan_portfolio_object> get_loans_by_lender <account> <optional limit> <optional start>
  • vector<loan_portfolio_object> get_loans_by_borrower <account> <optional limit> <optional start>
  • vector<limit_order_object> get_orders_by_loan <loan-id> <optional limit> <optional start>

All result lists are ordered by ascending object id. Server-side limits are configurable.

Processing Logic Changes

Margin calls

  • Set loan.confiscation_time = head_block_time + loan.call_duration
  • Cancel open market orders of this loan, as usual
  • If loan.principal_balance >= loan.principal_borrowed + loan.daily_interest: close loan as described above
  • Otherwise:
    • Let gap = loan.principal_borrowed + loan.daily_interest - loan.principal_balance
    • Create and execute a virtual limit_order_create for loan with amount_to_sell = loan.trade_balance and min_to_receive = gap
    • If the order has been (partially) filled, restart margin call process (meaning gap is smaller or perhaps closed)

Notes:

  • The new limit order will "walk the book" until the available trade balance has been spent (or there are no more orders in the book with a matching price). It is possible that this process buys up much more principal than required to close the gap, possibly at a price far away from the usual market price. Thus, the borrower should avoid being margin called.
  • Due to rounding, edge cases may exist where the limit order has been partially filled and then cancelled without buying sufficient principal to close the gap. It may then be impossible to create a new order for the remaining gap, because that would be considered "dust". The consequence would be that the loan stays in margin call state until it is confiscated. For practical purposes this shouldn't make much of a difference because rounding issues are a few "satoshis" only.

Interest payments

Similar to database::clear_expired_proposals, in each block

  • Check all loan_portfolio_object.interest_due_at against head_block_time
  • If passed and if !loan_portfolio_object.confiscation_time.valid,
    • If loan.daily_interest > loan.principal_balance: initiate margin_call
    • Otherwise,
      • Deduct loan.daily_interest from loan.principal_balance
      • Add loan.daily_interest of loan.principal_asset to loan.lender's balance
      • Add loan.daily_interest to loan.cumulative_interest
      • Create a virtual loan_interest_operation
      • Add 86400 to loan.interest_due_at
      • Re-appraise portfolio

Expire open offers

Similar to database::clear_expired_orders, in each block

  • Check lending_offer_object.expiration and borrowing_offer_object.expiration against head_block_time
  • If expired, create a virtual lending_cancel_operation and execute as describe above

Expire open loans

Similar to database::clear_expired_orders, in each block

  • Check loan_portfolio_object.latest_end against head_block_time
  • If expired:
    • Cancel open orders of this portfolio with virtual limit_order_cancel operations
    • If loan.principal_balance < loan.principal_borrowed + loan.daily_interest: initiate margin call
    • Otherwise: close loan as described above

Handle margin calls

In each block, for each loan that is in margin call state,

  • If loan.principal_balance >= loan.principal_borrowed + loan.daily_interest
    • Cancel open order, if any
    • Close loan as described above

Confiscate expired margin calls

Similar to database::clear_expired_orders, in each block

  • Check valid loan_portfolio_object.confiscation_time against head_block_time
  • If expired,
    • Cancel open order, if any
    • Add loan.principal_balance of loan.principal_asset to loan.lender's balance
    • Add loan.trade_balance of loan.trade_asset to loan.lender's balance
    • Create appropriate virtual loan_closed_operation
    • Delete loan

Vote tallying

  • vote_tally_helper computes voting_stake per account as before, plus core in
    • lending_offers
    • borrowing_offers
    • If core is the trade_asset in a loan_portfolio
      • Let lender_stake = 0
      • Let borrower_stake = trade_balance
    • If core is the principal_asset in a loan_portfolio
      • Let lender_stake = min(principal_balance, principal_borrowed)
      • Let borrower_stake = principal_balance - lender_stake

Calculate reference price

  • If tradable asset is a bitAsset
    • If tradable asset is in global settlement
      • is_reference_price_valid = true and reference_price = global_settlement_price
  • Otherwise
    • if tradeable asset-borrowed asset market has any offers for the tradable asset
      • is_reference_price_valid = true and reference_price = highest_offer
    • else if tradeable asset-borrowed asset market has ever had any matched exchange
      • is_reference_price_valid = true and reference_price = last_exchange_price
    • otherwise
      • is_reference_price_valid = false

Portfolio appraisal

  • Let principal = loan.principal_balance + loan.principal_in_orders
  • If principal >= loan.mccv, clear loan.call_price
  • Otherwise
    • if (loan.trade_balance + loan.trade_in_orders) > 0
      • set loan.call_price = (loan.mccv - principal) / (loan.trade_balance + loan.trade_in_orders)
      • if reference_price is valid and reference_price < loan.call_price: trigger margin call
    • else
      • Trigger margin call

Changes to cli_wallet

The following commands will be added to cli_wallet:

  • list_lending_offers <account>
  • list_borrowing_offers <account>
  • get_lending_offers <loan-asset> <trade-asset>
  • get_borrowing_offers <loan-asset> <trade-asset>
  • lending_offer_create with operation parameters
  • borrowing_offer_create with operation parameters
  • lending_offer_cancel <id>
  • lending_offer_accept <id> <amount> <duration>
  • loan_update <id> <delta-principal> <delta-trade>
  • get_loan_valuation <id>
  • get_loan_call_price <id>
  • loan_close <id>
  • The sell_asset command will receive an additional optional parameter, the loan portfolio id

Discussion

Risks

Financial: Price of a market pair on the DEX

A stagnant, nascent, or illiquid order book on the DEX for a particular market pair might not reflect the valuation of the collateral according to external market pairs. That will affect the appraisal value of the loan collateral which then affects margin calculations. Margin calculations affect both future loan offers on the books and matched loans.

Potential lenders and borrowers should carefully review any internal market pair and compare it with the external market pair to determine (a) whether internal market reflects a reasonable exchange ratio/price, and (b) whether the internal market could be easily manipulated to either overvalue or undervalue collateral.

Financial: Margin Calls at Market Price

If a margin call is initiated and if a liquidation plan requires selling the tradable asset to repay the lender in lent asset type, borrowers should be aware that it will be sold as an effective market order. The resulting sale on the DEX order book may return much less than if the offer were made on an external market.

Financial: Repayment of a Margin Called Loan

Loans that are margin called might require a liquidation plan that involves placing an limit order to buy enough of the lent asset to repay the loan.

If the market order remains unfilled on the DEX order book in excess of maximum margin call duration, the borrower's entire loan portfolio shall be confiscated thereby leaving the borrower with nothing after the loan closure.

Financial: Avalanche effect of Margin Calls

A margin call on a loan portfolio will immediately try to buy large amounts of the borrowed asset from the market. This can lead to a sudden spike in the trade price. This in turn can affect the reference price, which could lead to additional margin calls in other portfolios.

Powers of Asset Issuers

Asset issuers have extensive control over how their asset is used on BitShares including the ability to whitelist the trading of an asset against other assets), to restrict the transfers of an asset, and to seize any issued asset from an account if the asset is defined with the appropriate flags. These interaction of these powers with lending for margin trading are described.

Market Restrictions

The power to whitelist and blacklist trading pairs for an issuer's asset, which has the appropriate flags enabled, shall be unaffected by this proposal. This lending proposal makes use of the existing trading mechanisms therefore all rules shall continue to apply.

For example, if an issuer's asset is blacklisted from trading against any other asset, no trading of the Asset will be possible either from an account's regular set of balances or from their loan portfolio.

Alternatively, an issuer's asset (X) might initially be whitelisted to trade against any other asset, which permits the creation of a loan portfolio to trade against another asset (Y). Trading by the borrower ensues and the borrower obtains some quantity of Asset Y in their portfolio. If the asset issuer then blacklists trading between X and Y, the borrower shall no longer be able to trade the asset from anywhere including their loan portfolio. Another effect will be that margin calls shall no longer be able to be liquidated by means of buying back the borrowed asset on the DEX. Consequently if a margin call is initiated after a blacklisting and the loan portfolio's balance of the borrowed asset was insufficient to repay the lender, the margin call shall eventually result in an unconventional loan closure.

Transfer Restrictions

The existing power to restrict the direct transfer of an issuer's asset, which has the appropriate flags enabled, from one account to another shall be unaffected by this proposal.

Interest payment involves the transfer of the [borrowed asset-type](#borrow-asset] from the borrower to the lender. Therefore the creation of loan and borrow offers, and the matching of offers shall only be permitted if (a) if the borrow asset is not transfer restricted, and (b) if both the lender and the borrower are whitelisted or are not blacklisted for the borrow asset.

An unconventional loan closure transfers all balances of the borrow asset type and the tradable asset type to the lender. Therefore the creation of loan and borrow offers, and the matching of offers shall only be permitted if (a) if the tradable asset is not transfer restricted, and (b) both the lender and the borrower are whitelisted or are not blacklisted for the tradable asset.

Asset Seizure

The power to seize an issuer's asset, which has the appropriate flags enabled, shall remain possible if the asset is held in the account's regular set of balances. This power does not currently extend to assets held in open orders. Similarly, it shall not be possible to seize an asset that is held inside of a loan offer, borrow offer, or loan portfolio. An asset issuer may instead first impose a transfer restriction on the account, and then wait for the loan to be closed with appropriate balances being distributed to the regular balances of the borrower and lender at which time the conventional asset seizure may be invoked.

Summary for Shareholders

This BSIP defines a protocol upgrade to support peer-to-peer lending, borrowing and margin trading markets on the BitShares DEX. The motivation behind this BSIP is to increase the user demand for smartcoins on BitShares by offering on-chain peer-to-peer lending and borrowing to augment the existing trading. The multiple stage process between borrowers and lenders is supported with software specifications and a discussion of risks to lenders, borrowers, and asset holders, and asset issuers.

Copyright

This document is placed in the public domain.

See Also

@pmconrad
Copy link
Contributor

Moved into PR #189

@sschiessl-bcp
Copy link
Collaborator

@MichelSantos

When we talked at DevCon I suggest to allow multiple Assets type to trade against (Tradable asset). Is there a specific reason this was rejected? I only see more flexibility while implementation costs are little. There will be a separate portfolio with separate balances anyways.

I had some more points I don't remember that we talked about at DevCon, I unfortunately did not write them down. Did you, were you able to revisit them / was there any value?

Cheers,
Stefan

@pmconrad
Copy link
Contributor

We briefly discussed multiple trade assets and decided to leave that out for now because it increases the complexity substantially. Specifically, such a loan would have many interdependent call prices.

@MichelSantos
Copy link
Contributor Author

I had some more points I don't remember that we talked about at DevCon, I unfortunately did not write them down. Did you, were you able to revisit them / was there any value?

Hello @sschiessl-bcp. We also discussed when the interest paid from the borrower's loan portfolio would be deposited into the lender's account: would it be a manual withdrawal, or automatic; if automatic at what frequency.

Daily automatic deposits to the lender was simpler and is what is described in this BSIP.

@sschiessl-bcp
Copy link
Collaborator

I had some more points I don't remember that we talked about at DevCon, I unfortunately did not write them down. Did you, were you able to revisit them / was there any value?

Hello @sschiessl-bcp. We also discussed when the interest paid from the borrower's loan portfolio would be deposited into the lender's account: would it be a manual withdrawal, or automatic; if automatic at what frequency.

Daily automatic deposits to the lender was simpler and is what is described in this BSIP.

  1. Doesn't this go against the flow of other passive "income" streams on BitShares (transaction and market fees)?

  2. My motivation for this point was that the direct way may create liabilities as taxable events depending on your jurisdiction. For example, I remember @xeroc saying that referral rewards are not immediately a taxable event since you need to manually claim it (claiming is then taxable). Maybe @pmconrad has insight?

@sschiessl-bcp
Copy link
Collaborator

sschiessl-bcp commented Sep 18, 2019

We briefly discussed multiple trade assets and decided to leave that out for now because it increases the complexity substantially. Specifically, such a loan would have many interdependent call prices.

A use case is funding market making operations with it, or simply funding a professional trader to play with your funds.

From a complexity standpoint I trust your judgment. You have logic specified for one item, against a list based approach right from the start (the list based approach could be restricted via committee parameter to allow only length 1 initially). Extending logic written for one item to a list based approach is quite annoying at a later stage.

For me personally I often found that list based approaches in coding lead to a better concept, as I am not prone to do any implicit but not obvious shortcuts.

@sschiessl-bcp
Copy link
Collaborator

We briefly discussed multiple trade assets and decided to leave that out for now because it increases the complexity substantially. Specifically, such a loan would have many interdependent call prices.

A use case is funding market making operations with it, or simply funding a professional trader to play with your funds.

From a complexity standpoint I trust your judgment. You have logic specified for one item, against a list based approach right from the start (the list based approach could be restricted via committee parameter to allow only length 1 initially). Extending logic written for one item to a list based approach is quite annoying at a later stage.

For me personally I often found that list based approaches in coding lead to a better concept, as I am not prone to do any implicit but not obvious shortcuts.

No reaction means you promote keep as is?

@pmconrad
Copy link
Contributor

pmconrad commented Oct 1, 2019

Yes.

@abitmore
Copy link
Member

Draft merged in #189. Closing the issue. BTW there are new discussions about this BSIP in #254.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests