Comptroller - Compound 协议风险管理

  • 七哥
  • 更新于 2021-02-13 13:26
  • 阅读 3774

Comptroller协议风险管理

介绍

Comptroller 是 Compound 协议的风险管理层;它决定了用户需要维持多少抵押品,以及是否可以(和多少)清算用户。每次用户与 cToken 交互时,Comptroller 都会被要求批准或拒绝交易。

Comptroller 将用户余额映射到价格(通过价格预言机),再映射到风险权重(称为[抵押系数]() )来进行判断。用户通过调用“[进入市场]()”和“[退出市场]()”,明确列出他们希望在风险评分中包括哪些资产。

架构

Comptroller 作为一个可升级的代理实现。Unitroller 将所有逻辑都代理给 Comptroller 实现,但存储值是在 Unitroller 上设置的。要调用 Comptroller 方法,请使用 Unitroller 地址上的 Comptroller ABI。

进入市场

进入一个市场的清单 -- 重复进入同一个市场,不是错误。要想在一个市场中提供抵押品或借贷,必须先进入市场。

Comptroller

1 function enterMarkets(address[] calldata cTokens) returns (uint[] memory)
  • msg.sender : 应进入特定市场的账户。
  • cTokens : 要进入的 cToken 市场地址。
  • 返回值: 对于每个市场,返回一个错误代码,表示是否已进入市场。成功时为 0,否则返回[错误代码]()。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 CToken[] memory cTokens = new CToken[](2);
3 cTokens[0] = CErc20(0x3FDA...);
4 cTokens[1] = CEther(0x3FDB...);
5 uint[] memory errors = troll.enterMarkets(cTokens);

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const cTokens = [CErc20.at(0x3FDA...), CEther.at(0x3FDB...)];
3 const errors = await troll.methods.enterMarkets(cTokens).send({from: ...});

退出市场

退出一个市场 -- 退出当前没有进入的市场,这不是错误。退出市场将不计入账户流动性计算。

Comptroller

1 function exitMarket(address cToken) returns (uint)
  • msg.sender : 应退出特定市场的账户。
  • cTokens : 要退出的市场 cToken 地址。
  • RETURN : 成功时为 0,否则返回[错误代码]()。

Solidity

1Comptroller troll = Comptroller(0xABCD...);
2uint error = troll.exitMarket(CToken(0x3FDA...));

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const errors = await troll.methods.exitMarket(CEther.at(0x3FDB...)).send({from: ...});

Get Assets In

获取一个账户目前进入的市场列表。要在市场上提供抵押品或借款,必须先进入市场。已进入的市场计入账户流动性计算中。

Comptroller

1 function getAssetsIn(address account) view returns (address[] memory)
  • account : 应查询其进入市场清单的账户;
  • RETURN : 目前进入的每个市场的地址。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 address[] memory markets = troll.getAssetsIn(0xMyAccount);

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const markets = await troll.methods.getAssetsIn(cTokens).call();

抵押系数

一个 cToken 的抵押系数(Collateral factors)可以在 0-90% 之间,代表账户通过铸造 cToken 获得的流动性(借款限额)的比例增加。

一般来说,大额资产或流动性较强的资产抵押系数较高,而小额资产或流动性较差的资产抵押系数较低。如果一项资产的抵押系数为 0%,则不能作为抵押品(或在清算时被扣押),但仍可借入。

随着市场情况的变化,可以通过 Compound 治理,提高(或降低)抵押品系数。

Comptroller

1 function markets(address cTokenAddress) view returns (bool, uint)
  • cTokenAddress : 检查特定的 cToken 是否上市,并获得其抵押系数。
  • RETURN : 值元祖(isListed, collateralFactorMantissa);isListed 代表审计是否承认这个cToken;collateralFactorMantissa 代表(抵押系数),按 1e18 比例乘以一个供给余额来确定可以借入多少资产。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 (bool isListed, uint collateralFactorMantissa) = troll.markets(0x3FDA...);

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const result = await troll.methods.markets(0x3FDA...).call();
3 const {0: isListed, 1: collateralFactorMantissa} = result;

获取账户流动性

在 Compound 协议中,账户流动性被定义为账户抵押品的预估以太值(供应余额乘以协议[抵押系数](),减去账户借款余额的总价值)。这些价值仅使用账户[已进入]()的市场计算。

没有正账户流动性的用户在没有提供更多的资产或者偿还未偿还的借款,使其账户流动性恢复到正值之前,没有能力提取或借入任何资产。

Comptroller

1 function getAccountLiquidity(address account) view returns (uint, uint, uint)
  • account : 应计算其流动性的账户;
  • RETURN : 数组值(error、liquidity、shortfall)。成功时错误为0,否则为[错误代码]()。非零

    liquidity 表示该账户有可用的账户流动性。非零 shortfall 表示该账户目前低于其抵押品要求,需要清算。 liquidity 和 shortfall 最多只有一个不为零。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 (uint error, uint liquidity, uint shortfall) = troll.getAccountLiquidity(msg.caller); 
3 require(error == 0, "join the Discord"); 
4 require(shortfall == 0, "account underwater"); 
5 require(liquidity > 0, "account has excess collateral");

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const result = await troll.methods.getAccountLiquidity(0xBorrower).call();
3 const {0: error, 1: liquidity, 2: shortfall} = result;

关闭系数

可清偿借款的账户中,可在一次清算交易中偿还的借款的百分比,范围从 0% 到 100%。如果一个用户有多个借款资产,则 closeFactor 适用于任何单一的借款资产,而不是用户未清偿借款的总价值。

Comptroller

1 function closeFactorMantissa() view returns (uint)
  • 返回值 : 关闭系数,按 1e18 比例计算,乘以未偿还的借款余额,确定可以结清多少借款。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 uint closeFactor = troll.closeFactorMantissa();

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const closeFactor = await troll.methods.closeFactoreMantissa().call();

清算奖励

给予清算人的额外抵押品,作为清算水下账户的奖励。例如,如果清算奖励是 1.1 ,那么清算人每关闭一个单位,就能额外获得借款人抵押品的 10%。

Comptroller

1 function liquidationIncentiveMantissa() view returns (uint)
  • 返回值 : 清算奖励,按 1e18 比例计算,再乘以清算人的平仓借款金额,以确定可以扣押多少抵押品。

Solidity

1 Comptroller troll = Comptroller(0xABCD...);
2 uint closeFactor = troll.liquidationIncentiveMantissa();

Web3 1.0

1 const troll = Comptroller.at(0xABCD...);
2 const closeFactor = await troll.methods.liquidationIncentiveMantissa().call();

主要事件

Event Description
MarketEntered(CToken cToken, address account) 成功[进入市场]()时发生
MarketExited(CToken cToken, address account) 成功[退出市场]()时发生

错误代码

Code Name Description
0 NO_ERROR 不算错误
1 UNAUTHORIZED The sender is not authorized to perform this action.
2 COMPTROLLER_MISMATCH Liquidation cannot be performed in markets with different comptrollers.
3 INSUFFICIENT_SHORTFALL The account does not have sufficient shortfall to perform this action.
4 INSUFFICIENT_LIQUIDITY The account does not have sufficient liquidity to perform this action.
5 INVALID_CLOSE_FACTOR The close factor is not valid.
6 INVALID_COLLATERAL_FACTOR The collateral factor is not valid.
7 INVALID_LIQUIDATION_INCENTIVE The liquidation incentive is invalid.
8 MARKET_NOT_ENTERED The market has not been entered by the account.
9 MARKET_NOT_LISTED The market is not currently listed by the comptroller.
10 MARKET_ALREADY_LISTED An admin tried to list the same market more than once.
11 MATH_ERROR A math calculation error occurred.
12 NONZERO_BORROW_BALANCE The action cannot be performed since the account carries a borrow balance.
13 PRICE_ERROR The comptroller could not obtain a required price of an asset.
14 REJECTION The comptroller rejects the action requested by the market.
15 SNAPSHOT_ERROR The comptroller could not get the account borrows and exchange rate from the market.
16 TOO_MANY_ASSETS Attempted to enter more markets than are currently supported.
17 TOO_MUCH_REPAY Attempted to repay more than is allowed by the protocol.

错误信息

Code Name
0 ACCEPT_ADMIN_PENDING_ADMIN_CHECK
1 ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK
2 EXIT_MARKET_BALANCE_OWED
3 EXIT_MARKET_REJECTION
4 SET_CLOSE_FACTOR_OWNER_CHECK
5 SET_CLOSE_FACTOR_VALIDATION
6 SET_COLLATERAL_FACTOR_OWNER_CHECK
7 SET_COLLATERAL_FACTOR_NO_EXISTS
8 SET_COLLATERAL_FACTOR_VALIDATION
9 SET_COLLATERAL_FACTOR_WITHOUT_PRICE
10 SET_IMPLEMENTATION_OWNER_CHECK
11 SET_LIQUIDATION_INCENTIVE_OWNER_CHECK
12 SET_LIQUIDATION_INCENTIVE_VALIDATION
13 SET_MAX_ASSETS_OWNER_CHECK
14 SET_PENDING_ADMIN_OWNER_CHECK
15 SET_PENDING_IMPLEMENTATION_OWNER_CHECK
16 SET_PRICE_ORACLE_OWNER_CHECK
17 SUPPORT_MARKET_EXISTS
18 SUPPORT_MARKET_OWNER_CHECK
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
七哥
七哥
0x7B08...66Fd
区块链项目商业合作请联系微信 triple721