去中心化的报价服务如果突然遭受异常值攻击,抵押物出现了非常高的价格。假如协议此时接受了该报价,从而进行大量借出。攻击者会把所以基于借贷的协议发起攻击,从而盗取里面锁定的全部资产。
所有基于借贷的defi协议都要做好完备的策略来应对这个问题,特别是注意到预言机是不可靠的。不能完全依赖。接下来以Compound的预言机模块为例,介绍如何编写预言机来防范这个问题。核心
Compound的价格主要从chainlink获取,但是其协议本身是有一个validator合约用于校验获取的价格是否准确。
UniswapV2 使用的价格预言机称为 TWAP(Time-Weighted Average Price) ,即**时间加权平均价格。**Compound就是使用该机制获取Dex的价格,简单来说就是会记录一个累加价格,但是该价格具有延迟性,所以被操控的概率很低,提高了安全性。
加权价格 =(新的时间累加价格 - 上次的时间累加价格)/ 所过区块时间
TWAP 的原理比较简单,首先,在 UniswapV2Pair 合约中,会存储两个变量 price0CumulativeLast 和 price1CumulativeLast ,在 _update() 函数中会更新这两个变量,其相关代码如下:
price0CumulativeLast 和 price1CumulativeLast 分别记录了 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() 函数的实现逻辑也和上面所述的公式一致:
假如,chainlink和uniswap获取的报价都失效了,那么就发出警警报。
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!
不要不要不要完全信任任何一个第三方报价,一定要做完备性检查!!