# Compound 原理

## 合約架構

1. 主體以 comptroller 為核心，設置所有市場 supportMarket 以及 CollateralFactor、LiquidationIncentive、 CloseFactor、PriceOracle 等等。

&#x20; 2\. cToken 部署方式類似如下是使用 CErc20Delegate 與 CErc20Delegator&#x20;

```javascript
const cBUSDDelegatee = await (await ethers.getContractFactory('CErc20Delegate')).deploy()
const cBUSDDelegator = await (await ethers.getContractFactory('CErc20Delegator')).deploy(
  busd.address, comptroller.address, interestRateModel.address, bigInt(1), 'cToken cBUSD', 'cBUSD', 8, deployer.address, cBUSDDelegatee.address, '0x'
 )
const cbusd = await ethers.getContractAt('CErc20Delegate', cBUSDDelegator.address)
```

&#x20;3\. 設置抵押品的方式為：擁有對應的 cToken underlying asset 後使用 `mint` 來獲得對應的 cToken，之後使用 enterMarket 來把 cToken 設置為抵押物，抵押之後 account 的 liquidity 會增加，即可借貸。

&#x20;4\. 之後使用 cToken 的 borrow 後即可借出對應的 token。（例如 cBTC 執行 borrow 後可借出 BTC）

&#x20;5\. 獲取帳戶的當前狀態：

`comptroller` 合約調用 `getAccountLiquidity()`，回傳三個參數分別為 `(error, liquidity, shortfall)`&#x20;

* 第一個參數 0 表示 success&#x20;
* 第二個參數代表 account liquidity 可用流動性 (還可借款多少金額 = 所有 cToken 加總（ cToken 抵押品價值 \* cToken collateral factor))&#x20;
* 第三個參數 shortfall 如果不為零代表可被清算(需要補足多少金額)，有 shortfall 時 liquidity 一定為 0

## Compound 清算機制

[CEther.sol](https://github.com/compound-finance/compound-protocol/blob/ae4388e780a8d596d97619d9704a931a2752c2bc/contracts/CEther.sol) 或 [CErc20.sol](https://github.com/compound-finance/compound-protocol/blob/20abad28055a2f91df48a90f8bb6009279a4cb35/contracts/CErc20.sol) 會呼叫 [CToken](https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/scenario/src/Contract/CToken.ts) 合約的 liquidateBorrow();

## 相關利息參數

{% embed url="<https://ian.pw/posts/2020-12-20-understanding-compound-protocols-interest-rates>" %}

{% embed url="<https://www.gushiciku.cn/pl/gXE6/zh-tw>" %}

<https://reurl.cc/zZZ4ma>\
<https://reurl.cc/n11A66>

## 部署後可呼叫方法

提款：

cToken -> `_reduceReserves`

利息參數：

<https://observablehq.com/@jflatow/compound-interest-rates>

後續設置:

&#x20;interestRateModel: cToken -> `_setInterestRateModel`

升級 cToken:

&#x20;`cTokenDelegator._setImplementation(address(cTokenDelegate), false, 0x)`

升級 comptrolller:&#x20;

```
unitroller._setPendingImplementation(<new comproller address>); 
unitroller._become();
```

獲取 user 餘額

```javascript
uint balanceOf = cToken.balanceOf(account); // cToken 餘額
uint borrowBalanceCurrent = cToken.borrowBalanceCurrent(account); // borrow 餘額
uint balanceOfUnderlying = cToken.balanceOfUnderlying(account); // supply 餘額
```

## Compound subgraph

<https://thegraph.com/hosted-service/subgraph/graphprotocol/compound-v2>

#### 1. 獲得 user cToken balance 與當前 underlying borrow, supply 餘額

> ```
> cTokenBalance * exchangeRate = underlying token balanc 
> ```

```
{
  account(id: "0x785b9940eaf44be2b832c61816ff873b97a8ad63") {
    hasBorrowed
    tokens {
      symbol
      cTokenBalance
      supplyBalanceUnderlying
      borrowBalanceUnderlying
      market {
        exchangeRate
      }
    }
  }
}
```

## 相關事項

1.新建 cToken 市場幣種之後必須要兩個人以上去 cToken supply 後才能去執行 redeem 或 borrow，不然 utilizationRate function 計算時 reserve 變 0 會產生 Error，整個市場變成不能用。

> 解決方法為轉一些 underlyingAsset 到 cToken address

2.部署新幣時記得要先讓 oracle 設置價格後才能設置 collateral factor ，不然執行 `_setCollateralFactor` 會有 error

![](https://3415061728-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M0u4DA5jITnh37VYXmj%2Fuploads%2FHvw3Oyp3UoZ8CS60WDIL%2F%E6%88%AA%E5%9C%96%202022-04-25%20%E4%B8%8A%E5%8D%8811.17.37.png?alt=media\&token=f10121a2-d785-411d-88da-aaee23754e85)

3.可以使用 cToken.isDeprecated 來判斷某個 cToken 是否已沒在作用，\_setCollateralFactor 與\_setReserveFactor 為 0 以及 \_setBorrowPaused 為 true 即可。

![](https://3415061728-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M0u4DA5jITnh37VYXmj%2Fuploads%2FfqYUYOp5SbiiBqds82W7%2F%E6%88%AA%E5%9C%96%202022-04-25%20%E4%B8%8A%E5%8D%8811.21.55.png?alt=media\&token=b36d1dcb-958b-420e-a744-841ca4646582)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://easonwang.gitbook.io/blockchain/defi-bi-ji/aave-compound/compound-yuan-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
