ERC-4626 通货膨胀攻击概述

  • mixbytes
  • 发布于 2023-08-25 12:27
  • 阅读 17

本文详细分析了针对 ERC-4626 标准的通货膨胀攻击,包括其定义、攻击示例以及预防措施。作者通过多个代码示例展示了黑客如何利用漏洞进行攻击,以及推荐的修复方法,强调了安全审计和开发者在早期保护 DeFi 金库和池的重要性。

作者: Konstantin Nekrasov - MixBytes 的安全研究员

简介

通货膨胀攻击是一个广泛存在的问题,针对 ERC-4626 代币化保险库标准,并且直到最近才得到关注。这种攻击允许恶意行为者盗取脆弱池中的首次存款,可能导致毫无防备的投资者遭受重大损失。这个漏洞在 OpenZeppelin ERC4626 审计 中得到了强调。

许多项目使用 ERC-4626 标准,如 erc4626.info,而且 在实际操作中有价值数百万美元的交易 可能被利用(但幸运的是没有)。因此,我们决定撰写一篇文章,描述这种攻击以及如何防范它。

定义

在早期阶段,任何利用“铸造股份”功能以交换基础资产的交易池都可能受到通货膨胀攻击,导致投资者将部分或全部资金损失给池或黑客。

该漏洞源于“铸造股份”功能中的舍入问题,如以下公式所示:

sharesAmount = totalShares * assetAmount / asset.balanceOf(address(this))

黑客可以操纵分母,使受害者获得零或一股保险库。

示例

让我们来看三个示例。

示例 1. 将股份舍入为零

该示例基于 OpenZeppelin ERC4626 实现:

abstract contract ERC4626 is ERC20 {
    IERC20 asset;

    constructor(IERC20 asset_) {
        asset = asset_;
    }

    function totalAssets() public view returns (uint256) {
        return asset.balanceOf(address(this));
    }

    function convertToShares(uint256 assets) public view returns (uint256) {
        if (totalAssets() == 0) {
            return assets;
        }
        return totalSupply() * assets / totalAssets();
    }

    function convertToAssets(uint256 shares) public view returns (uint256) {
        return totalAssets() * shares / totalSupply();
    }

    function deposit(uint256 assets) public {
        asset.transferFrom(msg.sender, address(this), assets);
        _mint(msg.sender, convertToShares(assets));
    }

    function burn(uint256 shares) public {
        _burn(msg.sender, shares);
        asset.transfer(msg.sender, convertToAssets(shares));
    }
}

攻击场景:

  1. 黑客后运行一个 ERC4626 池的创建交易。
  2. 黑客为自己铸造了一股:deposit(1)。因此,totalAsset()==1,totalSupply()==1。
  3. 黑客前运行受害者想要存入 20,000 USDT(20,000.000000)的存款。
  4. 黑客在受害者面前膨胀分母:asset.transfer(20_000e6)。现在 totalAsset()==20_000e6 + 1,totalSupply()==1。
  5. 接下来,受害者的交易被处理。受害者获得 1 * 20_000e6 / (20_000e6 + 1) == 0 股份。受害者获得零股份。
  6. 黑客销毁自己的股份并拿走所有的资金。

如何修复?一个选项是限制铸造零股份,但这单独并没有完全解决漏洞,正如第二个示例所示。

示例 2. 舍入为一股

假设我们在上述示例的 deposit() 函数中添加了以下条件:

require(convertToShares(assets) != 0);

然后攻击变得更加复杂:

  1. 黑客后运行一个 ERC4626 池的创建交易。
  2. 黑客为自己铸造了一股:deposit(1)。因此,totalAsset()==1,totalSupply()==1。
  3. 黑客前运行受害者想要存入 20,000 USDT(20,000.000000)的存款。
  4. 黑客在受害者面前膨胀分母:asset.transfer(10_000e6)。现在 totalAsset()==10_000e6 + 1,totalSupply()==1。
  5. 接下来,受害者的交易被处理。受害者获得 1 * 20_000e6 / (10_000e6 + 1) == 1 股份。受害者仅获得一股,与黑客持有的股份相同。
  6. 黑客销毁自己的股份并获得池中的一半,大约是 30_000e6 / 2 == 15_000e6,因此他们的利润为 +5,000(占受害者存款的 25%)。

如何修复?有 不同的方法。例如,你可以在首次存款时铸造“死亡股份”。

示例 3. 纠缠和死亡股份

假设我们采取额外步骤,实施“死亡股份”技术,该技术 由 UniswapV2 使用 以保护池的 deposit() 函数:

uint constant NUMBER_OF_DEAD_SHARES = 1000;

function deposit(uint256 assets) public {
    asset.transferFrom(msg.sender, address(this), assets);
    uint shares = convertToShares(assets);

    if (totalShares() == 0) {
        _mint(address(0), NUMBER_OF_DEAD_SHARES);
        shares -= NUMBER_OF_DEAD_SHARES;
    }

    _mint(msg.sender, shares);
}

攻击的复杂性增加了三倍,尽管黑客不再能窃取资金,但仍然可以利用纠缠机会:

  1. 黑客后运行一个 ERC4626 池的创建交易。
  2. 黑客铸造了 1,000 股:deposit(1000)。因此,totalAsset()==1000,totalSupply()==1000。注意在此示例中 balanceOf(hacker) == 0 和 balanceOf(address(0)) == 1000。
  3. 黑客前运行受害者想要存入 20,000 USDT(20,000.000000)的存款。
  4. 黑客在受害者面前膨胀分母:asset.transfer(20_000_000e6)。现在 totalAsset() == 20_000_000e6 + 1000,totalSupply() == 1000。
  5. 接下来,受害者的交易被处理。受害者获得 1000 * 20_000e6 / (20_000_000e6 + 1000) == 0 股份。受害者获得零股份,将其存款损失给池。
  6. 因此,黑客燃烧任何受害者的存款,但花费千倍的资金才能做到这一点。

结论

在本文中,我们分析了几种可能导致 ERC-4626 保险库受到通货膨胀攻击的漏洞代码示例。我们讨论了几种如何防范攻击的方法及其缺陷。有关不同方法的详细列表,以及它们的优缺点,可以在 OpenZeppelin GitHub 问题 中找到。审计员和开发人员了解这种攻击的工作原理以确保 DeFi 保险库和池的早期阶段安全至关重要。

相关链接

  1. «为 ERC4626 通货膨胀攻击实施或推荐减缓措施» - OpenZeppelin GitHub 问题
  2. OpenZeppelin ERC4626 实现
  3. UniswapV2 死亡股份铸造代码
  4. OpenZeppelin ERC4626 安全报告
  5. «十亿-plus 美元代码中的潜在错误»易受攻击的百万美元交易示例
  6. Riley Holterhus 关于 «通货膨胀攻击」 的说明
  • MixBytes 是谁?

MixBytes 是一支专业区块链审计员和安全研究员团队,专注于为 EVM 兼容和 Substrate 基础项目提供全面的智能合约审计和技术咨询服务。请在 X 上关注我们,随时了解最新的行业趋势和见解。

  • 原文链接: mixbytes.io/blog/overvie...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
mixbytes
mixbytes
Empowering Web3 businesses to build hack-resistant projects.