价格和奖励操纵攻击精华
Price & Reward Manipulation Attacks Distilled
为什么这么重要?
首先, Web3 Defi中使用只能合约来实现各个借贷平台, 市场参与者可以借出代币获得利息, 也可以借入代币在支付利息的同时,进行其他的活动。
借款人必须提供抵押品,该抵押品存储在 DeFi 系统内的智能合约中,如果借款人未能满足还款计划的最后期限或抵押品的价值低于要求的阈值,则可以由贷款人或其他市场参与者清算。
本次深入探讨旨在对审计师和开发商应注意的借贷平台中的漏洞类型进行分类。然而,今天我们只讨论其中两种类型的攻击,所以首先我将分别讨论所有类型的攻击 - 因为它们经常被混淆…
也就是说,我们倾向于相信,没有人会怀疑任何安全实现的基础都是编写代码的特殊方法。因此,本文将仅关注那些对确保代码安全真正有用的方面!
因此,下面您将看到的不是一篇典型的文章,而是一篇知识系统化(SoK,其中我将依靠我自己在这件事上信任的作者,当然还有我们的 pessimistic.io 审核员!
您还会找到用于自学的工具和研究列表,我们强烈建议您单独阅读以更好地理解!顺便说一句,这里有一些空缺职位,因此如果您的项目需要审核 - 请随时写信给我们,请访问我们的[公共报告页面](GitHub - pessimistic-io/audits: Public reports of performed audits)!
当通过操纵自然供需力量人为操纵资产价格时,就会发生市场操纵。这是恶意行为者故意采取的行为,通常旨在以牺牲其他交易者的利益为代价来获利。
市场操纵是一个广义的术语,可以指多种技术。以下是传统金融和 DeFi 中使用的市场操纵技术的一些示例:
- 欺骗——发布交易订单而不打算执行它们。机器人可用于发布大量影响买家和卖家行为的订单,然后在订单完成之前取消这些订单。
- Ramping——人为提高资产市场价格以推动实际买家需求的交易,然后恶意行为者将其出售给实际买家。
- 熊市袭击——试图通过大量抛售或卖空来人为降低资产的市场价格。
- 跨市场操纵——在一个交易环境中进行交易,以操纵另一个环境中的价格,以便进行额外的交易,从价格差异中获利
- 清洗交易——买卖资产以给人留下交易量较高的印象,以吸引合法交易者进入市场。
- 抢先交易——根据市场其他部分无法获得或无法做出回应的内幕信息进行交易。在加密货币领域,抢先交易是 MEV 的一部分。在本文的最后您还可以找到用于自学的工具和研究列表,我们强烈建议您单独阅读以更好地理解!
要执行闪贷攻击,攻击者通常遵循三个步骤:
- 借款:攻击者从 DeFi 平台获取闪电贷,在不提供任何抵押品的情况下借入大笔加密货币。
- 操纵:攻击者利用借来的资金操纵目标加密货币的价格或利用 DeFi 智能合约中的漏洞。
- 偿还:攻击者通常在同一交易块内偿还闪电贷,并将借入的资金返还给借贷平台
实例
问题:价格预言机(keep3r v2)可以采用任意小的 TWAP 间隔来计算抵押品价格,即可以操纵一个区块中的价格并在下一个区块中执行漏洞利用。
解决方案:需要将最小 TWAP 间隔设置为至少几个区块,这样攻击在经济上就没有利润——套利者有时间平衡池中的价格。因此,差距越长,解决方案就越安全,但价格的相关性就越低。
问题:抵押品价格是根据 Curve 池余额计算的,很容易被存款和掉期操纵。 解决方案:使用 TWAP 或像 Chainlink 这样的链下预言机!
[ WDOGE-BNB 配对漏洞] 问题:Wdoge 代币收取转账佣金,并在发送金额之外额外销毁发送者代币 利用:这开启了使用skim()在类似uniswap的池中操纵价格的可能性,因为该函数允许在不进行交换的情况下销毁货币对余额中的代币。 解决方案:仅当您知道自己在做什么时才使用带有转账佣金的代币。
Moonwell 借贷漏洞 有时,即使使用 Chainlink 也可能不足以获得实际的代币价格,而且通常也值得考虑链上预言机的价格反馈。 问题:Moonwell借贷依赖Chainlink来获取Compound c-token价格
但该协议使用桥代币(例如 c.USDC.mad)作为抵押品,并且 Chainlink 没有更新其价格。 Nomad 黑客事件后,桥代币被弃用,在 Moonwell 中,抵押品不足的情况下也可以借款。
5 — RES 代币利用 简介:RES 代币合约中有一个 thisAtoB() 函数,可以通过 PancakeSwap 上的 ALL 将 ALL。
问题:交换后立即在 thisAtoB() 内,烧毁 BSCUSD-ALL 货币对中的 ALL 价格。然后手动换回 Pancake。
解决方案:不要从这对中烧伤!
超空间漏洞利用 简介:合约中有一个函数scaledBalanceOf(),返回用户给出的抵押品数量。 问题:该函数计算为:sharesAmount.mul(_getTotalPooledApeBalance()).div(totalShares) 这里 _getTotalPooledApeBalance 可以通过 APE 代币存款来操纵。 漏洞利用:获得闪贷,兑换为 APE,存入 APE,然后借入。 解决方案:不要依赖/依赖平衡!
BEVO 代币利用 简介:该代币是通缩的。有一个 Deliver() 函数可以减少用于计算余额的 _rate。 问题:与WDOGE-BNB配对漏洞类似,转入矿池后调用pancakeSwapskim()进行攻击,然后高价出售代币。 解决方案:对通货紧缩代币要格外小心!
UPSWING 金融代币利用 简介:如果传输中的接收方是 uniswap 池,则金额将添加到 sellPressure[user] 中。还有releasePressure()函数,它会从uniswap池中销毁sellPressure[user],当向自身转移0个代币时会触发该函数。
问题:非常奇怪的设计流程,但实际上可以从矿池中销毁代币。
漏洞利用:黑客通过交换来提高 sellPressure,然后触发releasePressure(),从而销毁矿池代币,然后以高价出售代币……
解决方案:不要一对烧伤!
520 代币利用 简介:代币有一个 procback 函数,可以从池中销毁代币。 问题:因为你可以销毁,所以你可以操纵池中的价格。 解决办法:不要烧掉一对!
奖励操纵
1 — New Free Dao Exploit 问题:为了获得奖励,需要检查用户的余额(通过balanceOf()),因此黑客可以通过创建合同和提出索赔来获取闪贷并标记几乎所有奖励。
解决方案:不要依赖当前的代币余额,使用余额快照!
2 — 暗池漏洞利用 简介:质押LP代币有奖励。 问题:由于合约逻辑存在问题,导致奖励堆积。 (添加新奖励而不是分配奖励)。 解决方案:检查逻辑,询问如果有人连续多次提出索赔会发生什么。
3 — MooCakeCTX 漏洞利用 简介:您可以存入代币,根据存入的金额获得奖励。 问题:合同中没有注明何时可以领取奖励。可以在与存款相同的区块上获取奖励。开发人员试图通过“Address.isContract”(检查address.codesize)来限制合约,但这可以通过构造函数调用来绕过。
漏洞利用:黑客借了一笔闪贷,存了一笔钱,拿走了奖励 解决办法:逐块检查是否不能立即领取奖励。
4 — SportsDAO 漏洞 简介:有一份合约,你可以质押 LP 代币,并获得奖励…… 问题:奖励取决于质押的 LP 代币总数。问题在于,有一个withdrawTeam()函数可用于将所有LP代币发送到开发人员指定的地址,并且该函数不受角色保护。另外,在transferFrom函数中,如果将代币发送到池中,则会添加金额的7%的奖励。 漏洞利用:黑客获得了闪贷,获得了必要的代币,调用withdrawTeam(),通过transferFrom发送到池中,通过skim()返回,将少量LP代币存入合约中。品牌奖励,获得丰厚收入。 解决方案:withdrawTeam必须是角色保护的。你不能让每个人都获得奖励(transferFrom中的逻辑)。
5 — QTN Token 简介:代币变基,从 LP 池转账时,每个人(池除外)都会根据转账金额增加代币数量。问题:您可以申请闪贷,将代币发送到池中,调用skim(),增加余额并出售代币。 解决方案:请记住,池转移不一定 == 购买,并且用户可以接受闪贷。