Euler Finance遭闪电贷攻击,损失1.97亿美金!漏洞分析附PoC
字数 1335 2025-08-11 08:36:00

Euler Finance 闪电贷攻击漏洞分析教学文档

1. 事件概述

  • 时间: 2023年3月13日 UTC时间08:56:35
  • 损失金额: 1.97亿美元
  • 涉及代币: 6种不同代币
  • 攻击类型: 闪电贷攻击
  • 漏洞位置: donateToReserves函数缺少流动性检查

2. 攻击流程详解

2.1 攻击准备阶段

  1. 闪电贷借款:

    • 从Aave协议借入3000万DAI
    • 部署两个合约: 借贷合约和清算合约
  2. 初始存款:

    • 将2000万DAI存入Euler Protocol
    • 获得1950万eDAI(抵押代币)

2.2 杠杆操作阶段

  1. 首次借款:

    • 利用mint函数借出10倍杠杆:
      • 借出1.956亿eDAI
      • 借出2亿dDAI(债务代币)
  2. 部分还款:

    • 使用剩余的1000万DAI偿还部分债务
    • 销毁1000万dDAI
    • 再次借出1.956亿eDAI和2亿dDAI

2.3 漏洞利用阶段

  1. 捐赠攻击:

    • 调用donateToReserves函数捐赠10倍偿还资金(1亿eDAI)
    • 此操作使账户处于可清算状态
  2. 清算操作:

    • 调用liquidate函数进行清算
    • 获得清算奖励:
      • 3.1亿dDAI
      • 2.5亿eDAI

2.4 获利退出阶段

  1. 资金提取:
    • 通过withdraw函数提取3890万DAI
    • 归还Aave闪电贷3000万DAI
    • 最终获利: 887万DAI

3. 漏洞技术分析

3.1 关键函数对比

正常函数(mint):

function mint(...) {
    // ...
    checkLiquidity(account);  // 关键流动性检查
    // ...
}

漏洞函数(donateToReserves):

function donateToReserves(...) {
    // 缺少checkLiquidity检查
    // ...
}

3.2 漏洞原理

  1. 流动性检查缺失:

    • donateToReserves函数未调用checkLiquidity
    • 允许用户故意使自己处于可清算状态
  2. 清算机制滥用:

    • 攻击者通过捐赠大量资金人为制造可清算状态
    • 然后自己清算自己获取奖励
  3. 杠杆循环利用:

    • 通过多次借款/还款放大资金规模
    • 利用协议的高杠杆特性(10倍)

4. 漏洞修复建议

  1. 添加流动性检查:

    • donateToReserves函数中添加checkLiquidity调用
  2. 清算保护机制:

    • 禁止用户清算自己的账户
    • 设置清算最小时间间隔
  3. 杠杆限制:

    • 设置单次操作的最大杠杆倍数
    • 实施逐步增加的借款利率
  4. 捐赠限制:

    • 设置捐赠金额上限
    • 添加捐赠冷却时间

5. 安全开发实践

  1. 关键操作检查清单:

    • 所有资金操作函数必须包含流动性检查
    • 实现完整的权限控制和状态验证
  2. 借贷协议特殊注意事项:

    • 资金偿还流程验证
    • 实时流动性检测机制
    • 债务清算安全边界
  3. 审计要点:

    • 完整的状态机验证
    • 所有外部调用函数的重入保护
    • 全面的边界条件测试

6. 攻击复现(PoC)

参考Numen Cyber提供的PoC代码:
GitHub PoC链接

复现步骤:

  1. 设置测试环境(Fork主网状态)
  2. 部署攻击合约
  3. 执行闪电贷借款
  4. 按攻击流程执行各步骤
  5. 验证最终获利金额

7. 总结与启示

  1. 审计重要性:

    • 合约上线前必须经过专业安全审计
    • 特别关注状态转换和边界条件
  2. 协议设计原则:

    • 最小权限原则
    • 完备性检查原则
    • 失败安全原则
  3. 监控与响应:

    • 实时异常交易监控
    • 紧急暂停机制
    • 漏洞响应预案
  4. 行业建议:

    • 建立安全开发标准
    • 实施多层防御策略
    • 定期安全培训更新
Euler Finance 闪电贷攻击漏洞分析教学文档 1. 事件概述 时间 : 2023年3月13日 UTC时间08:56:35 损失金额 : 1.97亿美元 涉及代币 : 6种不同代币 攻击类型 : 闪电贷攻击 漏洞位置 : donateToReserves 函数缺少流动性检查 2. 攻击流程详解 2.1 攻击准备阶段 闪电贷借款 : 从Aave协议借入3000万DAI 部署两个合约: 借贷合约和清算合约 初始存款 : 将2000万DAI存入Euler Protocol 获得1950万eDAI(抵押代币) 2.2 杠杆操作阶段 首次借款 : 利用mint函数借出10倍杠杆: 借出1.956亿eDAI 借出2亿dDAI(债务代币) 部分还款 : 使用剩余的1000万DAI偿还部分债务 销毁1000万dDAI 再次借出1.956亿eDAI和2亿dDAI 2.3 漏洞利用阶段 捐赠攻击 : 调用 donateToReserves 函数捐赠10倍偿还资金(1亿eDAI) 此操作使账户处于可清算状态 清算操作 : 调用liquidate函数进行清算 获得清算奖励: 3.1亿dDAI 2.5亿eDAI 2.4 获利退出阶段 资金提取 : 通过withdraw函数提取3890万DAI 归还Aave闪电贷3000万DAI 最终获利 : 887万DAI 3. 漏洞技术分析 3.1 关键函数对比 正常函数(mint) : 漏洞函数(donateToReserves) : 3.2 漏洞原理 流动性检查缺失 : donateToReserves 函数未调用 checkLiquidity 允许用户故意使自己处于可清算状态 清算机制滥用 : 攻击者通过捐赠大量资金人为制造可清算状态 然后自己清算自己获取奖励 杠杆循环利用 : 通过多次借款/还款放大资金规模 利用协议的高杠杆特性(10倍) 4. 漏洞修复建议 添加流动性检查 : 在 donateToReserves 函数中添加 checkLiquidity 调用 清算保护机制 : 禁止用户清算自己的账户 设置清算最小时间间隔 杠杆限制 : 设置单次操作的最大杠杆倍数 实施逐步增加的借款利率 捐赠限制 : 设置捐赠金额上限 添加捐赠冷却时间 5. 安全开发实践 关键操作检查清单 : 所有资金操作函数必须包含流动性检查 实现完整的权限控制和状态验证 借贷协议特殊注意事项 : 资金偿还流程验证 实时流动性检测机制 债务清算安全边界 审计要点 : 完整的状态机验证 所有外部调用函数的重入保护 全面的边界条件测试 6. 攻击复现(PoC) 参考Numen Cyber提供的PoC代码: GitHub PoC链接 复现步骤: 设置测试环境(Fork主网状态) 部署攻击合约 执行闪电贷借款 按攻击流程执行各步骤 验证最终获利金额 7. 总结与启示 审计重要性 : 合约上线前必须经过专业安全审计 特别关注状态转换和边界条件 协议设计原则 : 最小权限原则 完备性检查原则 失败安全原则 监控与响应 : 实时异常交易监控 紧急暂停机制 漏洞响应预案 行业建议 : 建立安全开发标准 实施多层防御策略 定期安全培训更新