{"content":{"title":"compound v2 v3 对比","body":"# 新特性简介\r\n\r\n全新的模型，丰富扩展性，更少清算风险，更低清算罚款，省gas\r\n\r\n# 模型变更\r\n\r\n[compound](https:\/\/learnblockchain.cn\/article\/2711) v2 模型 —— 混合资金池子\r\n\r\n各种资产都有自己的 ctoken\r\n\r\n\r\n![compoundv2.png](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/sMh87D07631aa9496ef95.png)\r\n\r\ncompound v3 模型 —— 主资金+抵押品池\r\n\r\n只有base 资产有 ctoken v3\r\n\r\n![compoundv3.png](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/IGXvO0QB631aa953200b1.png)\r\n\r\n\r\n# v2 v3 对比变更\r\n\r\n## 1 模型变更\r\n\r\n- v2 指定的资产 都可以当作抵押品 和 借出品（一种资产一个market，多对多借贷），是一整个的大资金混合池，可交叉借贷 和 贷出来的资产再次抵押借贷（加杠杆）。按ctoken 计算清算\r\n- v3 单个comet主池子（多对一借贷）。一种资产为base asset（基础资产），可存入 可借出，其他指定资产为 collateral asset （抵押资产，最多支持 15种）只能存入 不能借出，按整体 base资产的 ctokenv3 做清算\r\n\r\n## 2 费率变更\r\n\r\n- v2 根据 市场利用率 计算（borrows \/ (cash + borrows - reserves)），supply 计算获得利息 和 borrow 计算归还利息（根据区块），可以通过exchangeRate一起算出，所有supply assets 都可以盈利\r\n\r\n- v3 资金利用率（totalBorrow_\/ totalSupply_）有转折值 kink，利用率低于 kink 利率直线上升（根据时间），支持单独配置提供和借出kink\r\n\r\n## 3 ctoken 变更\r\n\r\n- v2 supply 提供supply asset 对应的ctoken 作为可挖矿存储凭证（每个资产1个ctoken），v3提供 baseasset 的 ctoken v3（所有资产仅提供一种 ctoken，目前为 cUSDC v3 提案升级了一次），\r\n\r\n- v2 可激励 comp 平台币（按区块 supply和borrow），v3 最细开启激励平台币，只对borrow 进行激励\r\n\r\n## 4 清算 变更\r\n\r\n- v2 清算叫 liquidiation，原本的清算机器人是检测所有的质押，然后指定一种 ctoken，针对ctoken 进行清算，（有大量的开源清算机器人，拼算力和速度 ）\r\n\r\n- v3 清算叫 absorb，全新设计了一套清算引擎（撸代码中），分池子检测market，针对 全部资产（基础 资产 + 抵押品）进行清算，ctoken v3 只有 cusdc v3\r\n\r\n- v3 拆分了清算步骤，清算的抵押品 需要先将抵押品的归属权变更为 合约持有，记录gas消耗情况 和 清算数量+次数，然后可选的合约上 按照既定折扣购买抵押品（目前不限制购买人，任何人都能买可出售的抵押品）。\r\n\r\n## 5 治理\r\n\r\n- v2 的治理 是通过dao 对整个 混合大资金池进行参数修改，风险较高\r\n\r\n- v3 治理 通过dao 对单个comet 资金池进行修改，且每个参数都提到了单独的合约 configer 中，操作起来更清晰，一旦出错 只是单个资金池出错\r\n\r\n## 6 规模\r\n\r\n- v2 存款不限量， v3 现处于试运行阶段，对存入的整体池子抵押品总量有限额（2100个wbtc，27000个weth，其余资产见下方）\r\n\r\n\r\n```js\r\n依次为：资产，预言机，代币精度，借贷因子，抵押品清算因子（计算是否能清算），清算折扣（被1减得到discount），可supply上限\r\n\r\n---- comp\r\n0xc00e94Cb662C3520282E6f5717214004A7f26888,0xdbd020CAeF83eFd542f4De03e3cF0C28A4428bd5,18,650000000000000000,700000000000000000,930000000000000000,200000000000000000000000,\r\n ---- wbtc\r\n0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599,0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c,8,700000000000000000,770000000000000000,950000000000000000,210000000000,\r\n --- weth\r\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419,18,825000000000000000,895000000000000000,950000000000000000,27000000000000000000000,\r\n --- uni\r\n0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984,0x553303d460EE0afB37EdFf9bE42922D8FF63220e,18,750000000000000000,810000000000000000,930000000000000000,1250000000000000000000000,\r\n --- link\r\n0x514910771AF9Ca656af840dff83E8264EcF986CA,0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c,18,790000000000000000,850000000000000000,930000000000000000,1250000000000000000000000\r\n```\r\n\r\n\r\n## 7 预言机模式变更\r\n\r\n- v2 获取chainlink 价格后，需要跟 uniswap v2 的池子做一次价格验证，偏差在允许范围内才是有效价格\r\n\r\n- v3 直接读取 chainlink 价格获取，不再依赖 twap，主要是预防 the merge 之后 防止价格操控 （关于twap 的不足说明可见 euler 的 提案），base 和 collateral 都有对usd的chainlink 预言机 \r\n\r\n## 8 代码更友好\r\n\r\n- v2 完整跑起来很费劲（最简化部署可见其他大佬的文档）\r\n\r\n- v3 有各种 官方周边仓库，（快速部署，各类操作，清算）不管干啥 快速上手\r\n\r\n\r\n\r\n# v3 详细介绍\r\n\r\n## 费率\r\n\r\nusdc 池子 kink supply 和 borrow 都为 0.8，资金利用率过高会导致利息剧增（按时间）\r\n\r\nborrow 和 supply 可以配置成不同的，已经解耦，现在配置的完全一样是 80%\r\n\r\n\r\n## 资金利用率计算\r\n都有单独方法获取：\r\nUtilization = TotalBorrows \/ TotalSupply\r\n\r\n### 借款利率\r\n官方文档有误差实际去掉了 reserveRate相关内容，具体公式见下面\r\n> ### 资金利用率  kink <= 0.8时 借款利率\r\n> BorrowRate\r\n>  = InterestRateBase + InterestRateSlopeLow * Utilization\r\n> ### kink > 0.8 借款利率\r\n> BorrowRate\r\n>  = InterestRateBase + InterestRateSlopeLow * Kink + InterestRateSlopeHigh * (Utilization - Kink)\r\n\r\n\r\n### 存款利率 \r\n 官方文档有错误实际这个没用，用的还是借款利率相同算法\r\n> *资金利用率  kink <= 0.8时 存款利率\r\n> SupplyRate = (InterestRateBase + InterestRateSlopeLow * Utilization) * Utilization * (1 - ReserveRate)\r\n>  kink > 0.8 存款利率\r\n> SupplyRate = (InterestRateBase + InterestRateSlopeLow * Kink + InterestRateSlopeHigh * (Utilization - Kink)) * Utilization * (1 - ReserveRate)*\r\n\r\n# 基础池子 详细参数配置\r\n> \"rates\": {\r\n>     \"supplyKink\": 0.8,\r\n>     \"supplySlopeLow\": 0.0325,\r\n>     \"supplySlopeHigh\": 0.4,\r\n>     \"supplyBase\": 0,\r\n>     \"borrowKink\": 0.8,\r\n>     \"borrowSlopeLow\": 0.035,\r\n>     \"borrowSlopeHigh\": 0.25,\r\n>     \"borrowBase\": 0.015\r\n>   },\r\n\r\n备注：\r\n其实代码跟公式对不上，没有 reserverate，而且两者 公式一模一样（借款利率）\r\n\r\n![compoundv3getrate.png](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/x1hN5Wro631aab4e9cb0c.png)\r\n\r\n\r\n## 清算\r\n\r\n查询可以直接查 isLiquidatable（account）\r\n\r\n具体执行需要有2步操作：执行清算 和 购买抵押品，\r\n**第一步将抵押品交给协议**，会记录liquidator 的记录，官方说后续给补偿；\r\n对清算人来说关键抢的是**第二步，按照reserves 的限额值 抢购打折抵押品**（真正获利）\r\n\r\n官方给出了一个使用uniswap V3 的 flason swap 的清算合约和检测，[清算的例子](https:\/\/github.com\/compound-finance\/comet\/tree\/main\/contracts\/liquidator)\r\n\r\n**执行具体步骤**：\r\n1. quoteCollateral 获取报价，collateral 达到清算价位。\r\n2. 使用 flashswap 功能从给定的 Uniswap 池中借用base 资产。\r\n3. 调用absorb 方法 将抵押品归属权交给 合约\r\n4. 确实下是否 reserve < target reserve 否则不能购买抵押品\r\n5. 调用 buycollateral 购买打折的 collateral。\r\n6. 用 Uniswap 池将collateral 交换为base 资产。\r\n7. 偿还闪贷 手续费。\r\n8. 将利润（base token 的折扣）发送给清算人。\r\n\r\n**部分核心代码：**\r\n获取抵押品报价\r\n\r\n```js\r\n \/**\r\n     * @notice Gets the quote for a collateral asset in exchange for an amount of base asset\r\n     * @param asset The collateral asset to get the quote for\r\n     * @param baseAmount The amount of the base asset to get the quote for\r\n     * @return The quote in terms of the collateral asset\r\n     *\/\r\n    function quoteCollateral(address asset, uint baseAmount) override public view returns (uint) {\r\n        AssetInfo memory assetInfo = getAssetInfoByAddress(asset);\r\n        uint256 assetPrice = getPrice(assetInfo.priceFeed);\r\n        \/\/ Store front discount is derived from the collateral asset's liquidationFactor and storeFrontPriceFactor\r\n        \/\/ discount = storeFrontPriceFactor * (1e18 - liquidationFactor)\r\n        uint256 discountFactor = mulFactor(storeFrontPriceFactor, FACTOR_SCALE - assetInfo.liquidationFactor);\r\n        uint256 assetPriceDiscounted = mulFactor(assetPrice, FACTOR_SCALE - discountFactor);\r\n        uint256 basePrice = getPrice(baseTokenPriceFeed);\r\n        \/\/ 主要是这里 可以看到 base 和collateral 都是通过本方法获取，清算的时候一起给回了reserve，但只有 collateral 可以购买\r\n        \/\/ # of collateral assets\r\n        \/\/ = (TotalValueOfBaseAmount \/ DiscountedPriceOfCollateralAsset) * assetScale\r\n        \/\/ = ((basePrice * baseAmount \/ baseScale) \/ assetPriceDiscounted) * assetScale\r\n        return basePrice * baseAmount * assetInfo.scale \/ assetPriceDiscounted \/ baseScale;\r\n    }\r\n```\r\n\r\n清算时合约内部逻辑（将抵押品交给合约）\r\n\r\n```js\r\n\/**\r\n     * @notice Absorb a list of underwater accounts onto the protocol balance sheet  清算入口合约（只会把抵押品给到合约）\r\n     * @param absorber The recipient of the incentive paid to the caller of absorb\r\n     * @param accounts The list of underwater accounts to absorb\r\n     *\/\r\n    function absorb(address absorber, address[] calldata accounts) override external {\r\n        if (isAbsorbPaused()) revert Paused();\r\n        uint startGas = gasleft();\r\n        \/\/ 这里只是把抵押品给回了当前合约\r\n        accrueInternal();\r\n        for (uint i = 0; i < accounts.length; ) {\r\n            absorbInternal(absorber, accounts[i]);\r\n            unchecked { i++; }\r\n        }\r\n        uint gasUsed = startGas - gasleft();\r\n\r\n        \/\/ 这里记录了清算的消耗情况\r\n        \/\/ Note: liquidator points are an imperfect tool for governance,\r\n        \/\/  to be used while evaluating strategies for incentivizing absorption.\r\n        \/\/ Using gas price instead of base fee would more accurately reflect spend,\r\n        \/\/  but is also subject to abuse if refunds were to be given automatically.\r\n        LiquidatorPoints memory points = liquidatorPoints[absorber];\r\n        points.numAbsorbs++;\r\n        points.numAbsorbed += safe64(accounts.length);\r\n        points.approxSpend += safe128(gasUsed * block.basefee);\r\n        liquidatorPoints[absorber] = points;\r\n    }\r\n```\r\n\r\n购买抵押品\r\n\r\n```js\r\n\/**\r\n     * @notice Buy collateral from the protocol using base tokens, increasing protocol reserves\r\n       A minimum collateral amount should be specified to indicate the maximum slippage acceptable for the buyer.\r\n     * @param asset The asset to buy\r\n     * @param minAmount The minimum amount of collateral tokens that should be received by the buyer\r\n     * @param baseAmount The amount of base tokens used to buy the collateral\r\n     * @param recipient The recipient address\r\n     *\/\r\n    function buyCollateral(address asset, uint minAmount, uint baseAmount, address recipient) override external {\r\n        if (isBuyPaused()) revert Paused();\r\n        \/\/ targetreserve 之上，不允许购买抵押品\r\n        int reserves = getReserves();\r\n        if (reserves >= 0 && uint(reserves) >= targetReserves) revert NotForSale();\r\n\r\n        \/\/ Note: Re-entrancy can skip the reserves check above on a second buyCollateral call.\r\n        doTransferIn(baseToken, msg.sender, baseAmount);\r\n\r\n        uint collateralAmount = quoteCollateral(asset, baseAmount);\r\n        if (collateralAmount < minAmount) revert TooMuchSlippage();\r\n\r\n        \/\/ Note: Pre-transfer hook can re-enter buyCollateral with a stale collateral ERC20 balance.\r\n        \/\/       This is a problem if quoteCollateral derives its discount from the collateral ERC20 balance.\r\n        withdrawCollateral(address(this), recipient, asset, safe128(collateralAmount));\r\n\r\n        emit BuyCollateral(msg.sender, asset, baseAmount, collateralAmount);\r\n    }\r\n```\r\n\r\n\r\n\r\n\r\n\r\n## 账户管理\r\n\r\n借助 user nonce 模型，可以允许 其他账户 管理自己账户的 抵押品资产。 意义不明\r\n\r\n## 社区治理\r\n\r\n简化治理，治理系统更改，治理通过单个合约（配置器）进行（之前是统一的管理地址）\r\n\r\n与v2 相同，社区投票，投票通过后执行 timelock，将提案 queue 上去，等待指定周期后 exec 即可。具体执行见v2就行。\r\n\r\n## 预言机模式\r\n\r\n完全依赖 chainklink 价格，每30分钟更新一次价格，通过configor 读取assetinfo 获取到地址（包含 basetoken 和 collateral 各类资产的对 usd价格），\r\n\r\n![compoundtulp.png](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/MVnh7Tzf631aac6d134a2.png)\r\n\r\n不适用 twap 的价格模式应该跟 the merge 有关。具体见 [euler 的提案](https:\/\/snapshot.org\/#\/eulerdao.eth\/proposal\/0xed0cfd4efb6ac3452cbaf626e7ef806a0de5c83a70eaa6d4547d362c01d15fd5)\r\n\r\n\r\n核心合约-- 快速部署\r\n3个代理 1个helper（bulker）\r\n`\"comet\": \"0xc3d688B66703497DAA19211EEdff47f25384cdc3\",\r\n\"configurator\": \"0x316f9708bB98af7dA9c68C1C3b5e79039cD336E3\",\r\n\"rewards\": \"0x1B0e765F6224C21223AeA2af16c1C46E38885a40\",\r\n\"bulker\": \"0x74a81F84268744a40FEBc48f8b812a1f188D80C3\"`\r\n\r\n# 官方给的 uml 图\r\n### 主逻辑调用和交互流程图\r\n\r\n![comentuml.svg](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/VAk5ilIR631aaed4bdd01.svg)\r\n\r\n### 社区治理的调用流程图\r\n\r\n![gover.svg](https:\/\/img.learnblockchain.cn\/attachments\/2022\/09\/j1SbXYna631aaef03df8e.svg)\r\n\r\n\r\n\r\n代码小工具\r\nSPEC 快速同步线上各种参数\r\nspider 将合约同步到其他网络\r\n\r\n\r\n# 个人观点\r\n## 好处：\r\n- 风险低，没有交叉，仅单一资金借出，\r\n- 可扩展性高，后续可以提供\r\n- 可以通过设置变更 挖矿的币种和速率，通过rewardspeed 和 rewardtoken 调控平台币产出 （可变更为 其他币种产出但没必要）\r\n- 代码更清晰\r\n## 不足：\r\n- 不允许交叉借贷，只允许借出 base 资产\r\n- 仅适合 稳定价值的币种，对浮动较大币种 完全不合适\r\n\r\n\r\n# 参考文档\r\n\r\n> compound v2 检测与清算机器人--\r\nHow to Build a Compound Liquidation Bot – bwd (baowebdev.com)\r\ncompound v3 透明公正高利用率--\r\nCompound III is Live. Transparent, fair, autonomous interest… | by Robert Leshner | Compound | Aug, 2022 | Medium\r\n官方文档--\r\nCompound III Documentation\r\nv3 的简单清算--\r\ncomet\/contracts\/liquidator at main · compound-finance\/comet (github.com)\r\ncompound v3 的改动--\r\n今日上线的 Compound III 都有哪些改动？ | DeFi之道 (defidaonews.com)"},"author":{"user":"https:\/\/learnblockchain.cn\/people\/2782","address":null},"history":"QmQvtUXJT3jr7b42RKwwLfsRMFYuWnK3HtYrXAYfokMUhp","timestamp":1663054803,"version":1}