osmosis-labs / isotonic

Smart Contracts for the Lendex Protocol
MIT License
1 stars 0 forks source link

Provide Collateral Info from Market #21

Closed ethanfrey closed 2 years ago

ethanfrey commented 2 years ago

Depends on #19 and #20

For the credit agency to make global calculations, it needs to get info from the Market contracts.

Add to the Market constructor (and the credit agency factory) three more items:

struct InstantiateMsg {
  // ... existing items

  /// denom, eg. uosmo
  common_token: String,
  /// how much we can borrow for one unit of ltoken, 0 <= x < 1
  collateral_ratio: Decimal,
  /// address of contract we can query for price (see #20)
  price_oracle: String,

Common Token comes from the Credit Agency constructor (same for all markets). The collateral ratio and Price Oracle can be set individually for each Market.

Note: if common_token == base_asset, then price is defined as 1.0. No need to query a price oracle for this case (and validation could allow an empty string there? or just store something and ignore it?)

The Market has one more query:

enum QueryMsg {
    CreditLine{ account: String }
}

/// all results normalised with the price oracle to values in common_token
struct CreditLineResponse {
    // total value of L-Tokens in common_token
    pub collateral: Uint128,
    // collateral * collateral_ratio
    pub credit_line: Uint128,
    // total value of B-Tokens in common_token
    pub debt: Uint128,
}

The calculation is basically:

let collateral = query_ltokens(&account)?;
let debt = query_btokens(&account)?;
if collateral.is_zero() && borrowed.is_zero() {
  return Ok(CreditLineResponse::zero());
}
// adjust to common_token
// note: care must be take if this is common/local or local/common... maybe good types?
let price = query_price_oracle()?;
let collateral = collateral * price;
// here I assume it is common/local
let debt = debt * price;
let credit_line = collateral * config.collateral_ratio;
return Ok(CreditLineResponse{ collateral, debt, credit_line });
ueco-jb commented 2 years ago

@ethanfrey regarding

Note: if common_token == base_asset, then price is defined as 1.0. No need to query a price oracle for this case (and validation could allow an empty string there? or just store something and ignore it?)

Can't it be just Option<String>? Unless we want to keep all logic in market, then this field could be just ignored.

ethanfrey commented 2 years ago

Sure, I guess Option<String> is more expressive than "String, but ignore it, if it is some special value"