价格操纵攻击再理解

本文的主要参考是METATRUST的捕鲸船分享,链接如下:

MetaTrust价格操纵攻击分享

价格操纵的来源:

区块链世界中,为保持所有节点的共识一致,区块链阉割了每个节点独立获取链外信息的能力

区块链想获取类似外界的价格信息,只有两种方式:

  • 通过实体类似Chainlink主动喂价,不断地将价格数据发布到链上
  • 直接通过某个智能合约中存储的参数,如uniswap等

举例:这是想获得的WETH价格,即为外部数据

getReserves()请求ETH价格,金融模型计算返回对应的值

这里如果通过闪电贷,如果金融模型错误计算的话,计算出的WETH就很可能出现问题

image-20231216214431185

什么是价格操纵攻击:

价格操纵攻击是指通过操控市场的买卖行为(操控流动性池或地址余额)人为地影响产品或资产价格,以谋取不正当利益

价格操纵的四要素:

  • 市场力量的不对等:通过闪电贷行为拥有大量的资金
  • 买卖行为的操纵:大额的代币兑换,破坏市场机制(市场的流动性)
  • 恶意影响价格:资产价格计算错误(脆弱的询价机制)
  • 谋取不正当利益:出现异常数量的奖励或抵押品

真实价格操纵攻击案例:

image-20231216215338496

正常流程:

  • 用户质押BNB和USDT,获得LP流动性证明;
  • 随后调用getReward()函数兑换掉LP,获得收益
  • 移除流动性过程中,会根据池子中BNB代币,兑换成Bunny代币

攻击流程:

分析可见慢雾pancake攻击分析

  • 第一笔自己交易获得一定的LP流动性证明

  • 用户通过闪电贷兑换了大量的BNB和USDT

  • 第二笔交易闪电贷,向池子中添加大量流动性,同时调用getReward()函数
  • 首先将LP转到WBNB-USDT池子中移除流动性,池子中有大量BNB和USDT
  • 随后大量的BNB和USDT转化为WBNB-BUNNY流动性,WBNB池子中WBNB数量激增
  • 随后根据得到的WBNB-BUNNY的LP数量,valueOfAsset函数计算LP价值
  • 问题就出在valueOfAsset进行LP价值计算的时候,通过WBNB-BUNNY池子中的WBNB实时数量计算,导致单个LP价值显著增加

漏洞函数

image-20231217113643150

getReserve()函数计算得到池中BNByue,后直接用以计算LP相对于BNB的价值

具体金融模型计算:

image-20231216220150156

如何避免价格操纵攻击:

image-20231217113754981

避免使用脆弱的询价机制,主要有三种方式:

  • 通过EOA(Chainlink)这样的实体,不断地喂价
  • 收集多个来源的价格,对不同来源的价格进行加权平均
  • 对过去一段时间内的价格,进行加权平均(uniswap)

一个敏感操作的变量数据,一定不能依赖于用户易于操控的数据,不然容易产生危险。

污点分析的方式进行漏洞检测