预言机接入安全策略--Compond为例

背景

去中心化的报价服务如果突然遭受异常值攻击,抵押物出现了非常高的价格。假如协议此时接受了该报价,从而进行大量借出。攻击者会把所以基于借贷的协议发起攻击,从而盗取里面锁定的全部资产。

策略

所有基于借贷的defi协议都要做好完备的策略来应对这个问题,特别是注意到预言机是不可靠的。不能完全依赖。接下来以Compound的预言机模块为例,介绍如何编写预言机来防范这个问题。核心

  1. 【主要报价】先拿chainlink。
  2. 【备用报价】再拿uniswap。
  3. 如果主要报价和备用报价都失效了,就系统报警。最好禁用所有的功能。

Compound的价格主要从chainlink获取,但是其协议本身是有一个validator合约用于校验获取的价格是否准确。

  1. 校验调用者是否有权限来验证数据准确性
  2. 转换新价格的精度为保留6位小数(价格标准,包括咱们的EXO)
  3. 从univ2获取一个dex的加权价格
  4. 判断是否启用故障倒换,如果有则从univ2获取价格并更新价格
  5. 如果没有,判断chainlink和dex的价格是否相似(5%)并更新价格

二、Uniswap

UniswapV2 使用的价格预言机称为 TWAP(Time-Weighted Average Price) ,即**时间加权平均价格。**Compound就是使用该机制获取Dex的价格,简单来说就是会记录一个累加价格,但是该价格具有延迟性,所以被操控的概率很低,提高了安全性。

加权价格 =(新的时间累加价格 - 上次的时间累加价格)/ 所过区块时间

TWAP 的原理比较简单,首先,在 UniswapV2Pair 合约中,会存储两个变量 price0CumulativeLastprice1CumulativeLast ,在 _update() 函数中会更新这两个变量,其相关代码如下:

price0CumulativeLastprice1CumulativeLast 分别记录了 token0 和 token1 的累计价格。所谓累计价格,其代表的是整个合约历史中每一秒的 Uniswap 价格总和 。且只会在每个区块第一笔交易时执行累加计算,累加的值不是当前区块的第一笔交易的价格,而是在这之前的最后一笔交易的价格,所以至少也是上个区块的价格。取自之前区块的价格,可以大大提高操控价格的成本,所以自然也提高了安全性。 PERIOD 指定为了 24 小时,说明这个示例计算 TWAP 的固定时间窗口为 24 小时,即每隔 24 小时才更新一次价格。该示例也只保存一个交易对的价格,即 token0-token1 的价格。price0Average 和 price1Average 分别就是 token0 和 token1 的 TWAP 价格。比如,token0 为 WETH,token1 为 USDC,那 price0Average 就是 WETH 对 USDC 的价格,而 price1Average 则是 USDC 对 WETH 的价格。 update() 函数就是更新 TWAP 价格的函数,这一般需要链下程序的定时任务来触发,按照这个示例的话,就是链下的定时任务需要每隔 24 小时就定时触发调用 update() 函数。 update() 函数的实现逻辑也和上面所述的公式一致:

  1. 读取出当前最新的累计价格和当前的时间戳;
  2. 计算出当前时间和上一次更新价格时的时间差 timeElapsed,要求该时间差需要达 24 小时;
  3. 根据公式 TWAP = (priceCumulative - priceCumulativeLast) / timeElapsed 计算得到最新的 TWAP,即 priceAverage ;
  4. 更新 priceCumulativeLast 和 blockTimestampLast 为当前最新的累计价格和时间戳。
    不过,有一点需要注意,因为 priceCumulative 本身计算存储时是做了左移 112 位 的操作的,所以计算所得的 priceAverage 也是左移了 112 位的。
    consult() 函数则可查询出用 TWAP 价格计算可兑换的数量。比如,token0 为 WETH,token1 为 USDC,假设 WETH 的价格为 3000 USDC,查询 consult() 时,若传入的参数 token 为 token0 的地址,amountIn 为 2,那输出的 amountOut 则为 3000 * 2 = 6000,可理解为若支付 2 WETH,就可根据价格换算成 6000 USDC。

PriceGuarded

假如,chainlink和uniswap获取的报价都失效了,那么就发出警警报。

总结

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!

Subscribe to shaneson.eth
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.