《DApp设计与开发》Solidity应用及攻击手段防御模块整理

320 阅读5分钟

常⻅应⽤

◦ Uniswap

参考之前的文章:
UniswapV2 原理与源码解析 - 掘金 (juejin.cn)

Uniswap V1 原理与源码解析 - 掘金 (juejin.cn)

◦ yearn.finance

Yearn.finance在以太坊区块链上提供质押、借贷聚合和收益生成等服务。

常⻅攻击⼿段及防御

◦ 闪电贷

随着 web3 生态的广泛发展,形成了大量具有不同流动性池、价格、利息和费用的 DeFi 协议。套利是在平行市场中赚钱的常用方法。通过使用闪电贷,您可以零风险地从套利中受益,因为您可以借到所有需要的资金,而不需要用自己的钱来玩。

必须在一个交易里借还
例子:

  1. 在 Aave 中借出闪电贷 100 ETH;
  2. 在 DEX1 中全部买入 A(为了解释原理,不考虑滑点的问题),得到 100 A;
  3. 将 100A 在 DEX2 中卖出,得到 110 ETH;
  4. 在 Aave 中偿还闪电贷 100 ETH;
  5. 获利 10 ETH 离场。

预防:
去中心化预言机— —最安全的选择无疑是使用去中心化预言机,利用多个来源找出“真实价格”。一些去中心化的预言机,例如我们自己的 Umbrella Network,更进一步,通过将数据提交到区块链来确保数据的可靠性。

这意味着,如果不法分子试图对从去中心化预言机获取其提要的 dapp 进行快速攻击,价格操纵将失败,交易时间将过去,并且整个交易将逆转——未经处理。

高频定价更新——这是纸面上的一个简单修复,但在实践中可能会更昂贵。在这里,我们只是增加了流动性池向预言机查询新价格的次数的频率。逻辑是,随着更新次数的增加,池中代币的价格会更新得更快,并使价格操纵无效

时间加权平均定价——通常的做法是使用平均值(或最近的中值)来计算流动性池中的价格。但是,TWAP 建议使用跨多个区块的平均价格。

◦ 夹⼦攻击

三明治攻击(sandwich attacks)是DeFi里流行的抢先交易技术的一种,也叫夹子攻击。为了形成一个“三明治”交易,攻击者(或者我们叫他掠夺性交易员)会找到一个待处理的受害者交易,然后试图通过前后的交易夹击该受害者。这种策略来源于买卖资产从而操作资产价格的方法。

区块链的透明度、以及执行订单的延迟(往往在网络拥堵情况下),使抢先交易更加容易,并极大降低了交易的安全性。

一旦掠夺性交易者注意到潜在受害者的待定资产X交易被用于资产Y,他们就会在受害者之前购买资产Y。掠夺性交易者知道受害者的交易将提高资产的价格,从而计划以较低的价格购买Y资产,让受害者以较高的价格购买,最后再以较高的价格出售资产。

主要流程:
(1)攻击者提前洞察了受害者的交易意图,认为有利可图,提前通过利用10个TokenA兑换了100个TokenB,同时抬高了TokenB的价格
(2)受害者在不知情的情况下,通过意外价格滑点,以5个TokenA兑换了40个TokenB,原本5个TokenA可以兑换50个TokenB
(3)攻击者再将100Token B兑换成12.5个TokenA,获利2.5个TokenA

使攻击有效必须满足两个条件: (1)利润需要高于gas费(矿工为处理每笔交易收取的费用):因为利润如果很小,用户需要获得相当多的Token数量才能克服gas费
(2)减少滑点:滑点是指用户在交易中愿意接受的理想价格的最大偏差。由于交易不是立即执行的,在同一Token内操作的其他交易可能会先被执行,从而导致价格的变化。这意味着想要购买Token的用户无法知道他们的交易执行时的确切价格。这就带来了购买可能经历过大幅价格变化的Token问题。

预防:
(1)gas限制
三明治攻击之所以会发生,因为更高的gas费用交易优先于其他交易。通过对该gas费用设置一定的限制,影响将不会那么明显。
(2)避免低流动性池 缺乏良好的流动性对这个问题是不利的。流动性池越小,投资者获得好价格的机会就越小,因为这更容易产生滑点。滑点越高,从三明治攻击中获得的利润就越多。

(3)小额交易
三明治攻击对较大的交易额感兴趣,交易额越大,利润空间越大。避免三明治攻击的一种方法是将我们的交易分成几个较小的交易,因为这些小额交易对于抢跑者来说不太具有吸引力。

◦ 重⼊攻击

重入攻击漏洞的条件有 2 个:

调用了外部的合约且该合约是不安全的
外部合约的函数调用早于状态变量的修改
看这个: 重入攻击 - 掘金 (juejin.cn)

预防:
使用安全的转账函数
使用内置的 transfer或send 函数,因为transfer和send在转账时会传递2300Gas,不足以执行重入调回合约操作,而.call会传递所有可用的Gas(当然也可以设置传递可用的Gas)。

使用官方推荐的检查-生效-交互模式 (checks-effects-interactions) 检查是指条件的真实性。效果是指交互导致的状态修改。最后,交互指的是函数或合约之间的交易。

使用专门针对重入攻击的安全合约 例如OpenZeppelin 官方库中的安全合约ReentrancyGuard.sol