作者: Ameen Soleimani
翻译&校对: Aisling & 阿剑
来源:以太坊爱好者
你可能听说过区块链初创企业Compound。他们基于以太坊创造了compound.finance,个人可以在该市场中出借所持有的ETH,DAI,USDC及一些其他 ERC20 数字资产并以此赚取利息。
Today, the interest rate offered to DAI lenders is 10%, which is high enough to turn EthHeads’ heads (see cover photo).
如今,DAI出借方的利率是10%,足以让ETH持有者侧目(如封面图片所示)。
作为SpankChain的CEO,管理包括近50万DAI的公司储备是我的职责。如果不把我们的 DAI 放到 Compound 平台上,按照 10% 的年利率,那么我们将每个月损失近4000美元。这是相当大的一笔机会成本。但是投资需要牢记的是:天下没有免费的午餐。所有的投资都有风险,在Compound平台上放贷也不例外。
上个月,我花了一些时间对通过 Compound 平台放贷存在的几类风险进行了评估:
智能合约安全风险
中心化单点故障
银行挤兑风险
我将调查研究分成了以下几类,但是在此之前首先需了解的最重要的事情是:
智能合约安全近乎完全没问题。
Compound 是一个托管系统,如果借贷池管理员的私钥泄漏,则所有借贷池中的资产将都可能被盗走。
在 Compound 上放贷不保证能随时提取资产。如果您尝试提取您的资产,但是当时所有资产都锁定在未偿还的贷款中,那么您的提款交易将失败。
-我希望这些投资者人能够了解这些风险… 图源:https://defipulse.com/compound –
合约安全
已有多家知名的智能合约安全公司对 Compound 进行了审计。
OpenZeppelin 审计报告
Trail of Bits 审计报告
Certora 审计报告
此外,Compound 还为严重漏洞专门提供了上限为 25 万美元的悬赏(赏金为被盗资金的 1% 或者是冻结资金的10%),据我所知,目前还没有独立安全研究人员获得这笔赏金。
该合约保存的资产至少有六个月超过 2000万美元,至少有两个月超过 5000万美元,当前该合约里保存的资产超过 1亿美元。对我个人而言,合约安全最重要的指标是 合约持有总资产×合约保存资产时间,到目前为止,Compound 的安全性已经得到了大量公共资产的证明。
基于以上因素,我目前认为 Compound 智能合约是安全的。
中心化单点故障
由于我自己并不是一名智能合约安全专家,因此我向 samczsun 寻求帮助——samczsun 以发现了 0x 合约中一个关键 bug 而出名(当时 0x 合约已经接受过顶级公司的多次审核) ,他也因此获得了 10万美元的报酬。关于 Compound 的中心化单点故障(我关注的重点),他提供的报告如下:
Compound v2 有四种不同的管理职能,由三个地址分别承担:
每种 cToken 都有一个管理员。目前,所有 cToken 的管理员都被设置为 0x8B8592E9570E96166336603a1b4bd1E8Db20fa20
每种 cToken 都有一个监察员(comptroller),目前都被设置为 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B。Unitroller 也有一个管理员,目前被设置为 0x8B8592E9570E96166336603a1b4bd1E8Db20fa20
当前的价格预言机都有一个锚点管理员和一个 poster,分别为设置为0xF06e41aDD8A7E7A8aD81a07C0ACA291E4573ca50 和 0x3c6809319201b978D821190Ba03fA19A3523BD96。
只要能获得一种 cToken 的管理员资格,攻击者就可以替换监察员实现,然后执行以下一项或者多项操作:
通过 transferAllowed 函数返回 false 防止转移现有 cTokens
通过 transferAllowed 函数返回 true 转移作为抵押品的 cTokens
通过 mintAllowed 函数返回 false 防止生成新的 cTokens
通过 redeemAllowed 函数返回 false 防止赎回已有 cTokens
通过 repayBorrowAllowed 函数返回 false 防止偿还现有贷款
通过 liquidateBorrowAllowed 函数返回 false 防止清算贷款
通过 seizeAllowed 函数返回 true 窃取用户 cTokens
通过 borrowAllowed 函数返回 false 防止借入底层资产
通过 borrowAllowed 函数返回 true 来吸干所有底层资产
通过 cToken 的管理员资格,攻击者还可以替换利率模型,从而实现:
将借贷成本(即:块利率)提升至 0.0005% /区块
若能获得 Unitroller 代理的管理员资格,攻击者可以:
对于所有使用 Unitroller 的 cTokens (当前是 100% 占比),通过替换 Unitroller 实现与替换 cToken 监察员一样的攻击
通过更改清算激励机制,在清算时获得更多的代币
通过更改价格预言机,以低于实际的价格进行 cTokens 借贷(例如:ETH、WBTC 等)
通过更改某种 cToken 的质押信息,结合新增 cToken 以及更改价格预言机的能力,攻击者可以通过他们创造的代币进行抵押借款,实现窃取系统全部资产。
若能获得价格预言机的锚点管理员资格,攻击者可以:
使得某一资产的价格偏离其真实价格的 10%
若能获得价格预言机的 poster 资格,攻击者可以:
每个小时都让资产价格偏离其存储价值的 10%
若能同时取得对价格预言机的管理员资格和 poster 资格,攻击者就可以:
将资产价格设为任意值
总结一下 samczsun 的报告:Compound 合约被设计为可以通过中央管理员进行适当的升级。最重要的合约是代理合约,其指向包含了逻辑实现的逻辑合约地址,管理员拥有随意修改地址指针的权利。由于所有的 cTokens 使用相同的管理员 ,如果管理员私钥泄露了,那么所有质押在 Compound 中的资产都可以被轻松窃取。
sam 的报告中也提到了一些更为狡猾的攻击,如果攻击者有这样的机会——比起实施更为复杂的攻击,这样可以更快的卷走所有钱。OpenZeppelin 在他们的 Compound 审计概要中进行了有效总结。
然而,恶意管理员或者被窃取私钥的管理员手中拥有冻结市场、审查交易甚至从系统中窃取全部资产的能力。类似地,控制资产价格预言机即便不能窃取系统的全部资产,也可以窃取大部分。当前,所有实时市场的管理员都是同一个外部账户。
但是有趣的是, Trail of Bits团队没有在任何相关材料中提及这一点。此外,Compound 的 FAQ 还低估了管理员特权,并没有提供任何关于管理员有可能窃取所有资产的警告:
协议的开发者 Compound Lab,Inc,目前控制着以太坊地址:0x8b8592e9570e96166336603a1b4bd1e8db20fa20 ,即管理员地址。管理员地址拥有新增资产、更新价格预言机、更新利率模型以及更新协议风险模型的权利。
另一件需要注意的事情是, Compound 当前的托管设置本身并不会导致系统的不安全。他们会极力维护管理员密钥安全,并且很有可能(希望如此)他们正在与 820 万美元种子轮融资可以买到的最好的托管供应商合作。不过毫无疑问,在决定存入 50 万 DAI 时,我会将这一点放在心上。
银行挤兑风险
Dharma 首席运营官之前的的这条关于竞争性贷款平台的推特,带我打开了新世界的大门,让我明白了 Compound 这类平台的银行挤兑风险。
上述推特中显示的利用率高达 98.62%,这意味着在当时,出借方存储的 98.62% 的 DAI 都已经借出。只有 1.38% 的 DAI 还可取出,所以,在当时,只有相当小一部分出借方可以随自己心愿收回其存入的 DAI。
如果有足够多的 DAI 债权方(cDAI 持有者)在同一时刻想要收回他们存入的 DAI,他们的提款操作将耗尽所有可用 DAI,并使得 DAI 利用率提升至 100%,从而阻止进一步的提款操作。试图提款的出借方将只能看到交易失败,并且不得不等到更多的借款方归还贷款后才能进行提款。
由于存在 cDAI 提款卡壳的可能性,人们将会对此有所顾虑,并且他们的担忧可能会自我实现。就是说,当一部分 cDAI 持有者试图一次取出其存入的全部 DAI 时,银行挤兑将有可能发生,因为有很多 cDAI 持有者都担心这种情况的发生。
陷入 cDAI 银行挤兑的出借方可以选择等之后再取出其 DAI,也可以通过出售 cDAI 以获得 DAI,但是这样会产生手续费,而且,如果有许多其他出借方也在出售 cDAI ,那么价格可能会更差。 如果出借方选择等待危机结束并继续持有 cDAI,在此期间他们仍可以享受到出借资金所得的利息。
Compound 是如何解决这个问题的?
Compound 团队对这种流动风险的处理都很直接,他们在白皮书中进行了相关介绍:
该协议不保证流动性;相反,它依靠利率模型进行激励。在资产需求极度旺盛的的时期,协议的流动性(可用于提款或出借的代币)将减少;在这种情况下,利率会上升,从而刺激供应并抑制借贷。
Compound 基于 cToken 特定的 “利率合约” 为每种 cToken 确定借款人的利率。该合约目前实现了 cDAI 的利率模型。公式为:借款人年利率 = 基本利率 +(乘数 * 利用率)
对于 cDAI 而言,基本利率 = 5%, 乘数 = 15%(这些值都被硬编码到了合约中)。利用率 为 100% 时,借款人支付的利息为20%。这意味着当 DAI 利用率最大时,借款人的资金成本也只是 20%——因此,如果他们相信 ETH(贷款抵押品)这一年的涨幅会超过 20% 的话,他们就没有动力偿还贷款。 这可能会导致很多 cDAI 持有者在很长一段时间内还将继续持有 cDA。
Compound 唯一能处理这一问题的工具就是使用中心化管理员升级利率模型,这就是 6 周前,利用率升到 99% 时他们所采用的方案(与上面引用的推文属同一时期)。
综上所述,利用率达到最大时存在流动性危机以及迫在眉睫的银行挤兑风险,而出借方唯一能做的事就是希望 Compound 使用管理员特权更新并且增加利率,从而激励借款方偿还贷款进一步提高想要退出的出借方所需的流动性。
<结论
像 Compound 这样的协议在中心化和去中心化中保持着微妙的平衡,它需要权衡快速升级的能力和由此必然引入的中心化单点故障。
我不觉得 Compound 选择中心化的方式引导其产品是错的(因为这种方式显然是有效的,要不然我也不会写这篇文章),但是我确实希望智能合约中包含 1000 万~1 亿美元的项目能够按照最高标准进行,尤其是在向用户传达风险和提供警告方面。
基本上,我们应该支持、鼓励项目做与 Robert Leshner(Compound 的首席执行官)相反的事情:
中心化在技术上可能是正确的,但是我们都知道攻陷管理员的办法有很多…
现在我依旧没有想好是否要将我管理的 DAI 存储到 Compound 中。可能我会先用 10 万个 DAI 试试水?会出什么问题呢…In Compound We Trust!
感谢 Eva Beylin 的反馈以及编辑!(完)
原文链接:
https://medium.com/@ameensol/what-you-should-know-before-putting-half-a-million-dai-in-compound-fafdb2645f77
作者: Ameen Soleimani
翻译&校对: Aisling & 阿剑