Damn Vulnerable DeFi(四)
上一篇: Damn Vulnerable DeFi(三)
讲过了什么是闪电贷,使用fountry测试不需要部署到测试网,Slither和Mythril的安装。
今天来学习slither的使用
1 | |

slither FlashLoanReceiver.sol 运行后有三种颜色,分别是红色,黄色和绿色的回显。分别代表什么意思
在使用 Slither 分析 FlashLoanReceiver.sol 时出现的红、黄、绿三色回显,是 Slither 对检测结果的严重程度分级,核心用于区分不同风险等级的问题,以下是详细解释:
1. 绿色:安全/无风险(Pass/Informational)
- 含义:绿色输出通常表示无问题,或仅为「信息性提示」(Informational)—— 既不是漏洞,也不是风险,只是 Slither 告知你代码中符合规范、无风险的行为,或纯粹的日志类信息(比如检测完成、某个模块执行正常)。
- 场景示例:
- 检测到某个函数权限控制符合预期;
- 代码中无明显的安全漏洞或代码质量问题;
- Slither 完成某个检测模块的扫描,无异常输出。
2. 黄色:警告/低风险(Warning)
- 含义:黄色代表「警告」,即代码中存在潜在风险、非致命问题,或不符合最佳实践的写法—— 这些问题本身不一定直接导致漏洞,但可能增加后续出错的概率,或违背 Solidity 编码规范,需要开发者关注并确认是否需要修复。
- 核心特点:不影响合约基本功能,但存在「优化空间」或「潜在隐患」,属于「可修复但非紧急」的级别。
- 场景示例:
- 未使用 Solidity 最新的安全特性(如
unchecked不必要的溢出检查); - 函数可见性未显式声明(比如本该用
external却默认public); - 变量命名不规范、冗余代码、未处理的返回值(如
IERC20(token).transfer()未检查返回值,但非核心逻辑); - 闪电贷相关的「非关键逻辑不规范」(比如回调函数注释缺失)。
- 未使用 Solidity 最新的安全特性(如
3. 红色:高危/漏洞(Error/Critical)
- 含义:红色是最高风险级别,表示 Slither 检测到明确的安全漏洞、致命错误,或可被利用的攻击点—— 这些问题会直接导致合约资产损失、功能异常,甚至完全被控制,必须优先修复。
- 核心特点:属于「紧急修复项」,直接威胁合约安全,是 Slither 重点警示的问题。
- 场景示例(针对 FlashLoanReceiver.sol):
- 闪电贷回调函数(如
executeOperation)未校验闪电贷金额/资产,导致恶意调用; - 重入漏洞(Reentrancy):回调函数中未做重入锁,被攻击者利用转移资产;
- 整数溢出/下溢(即使 Solidity 0.8+ 有默认检查,也可能因
unchecked滥用触发); - 权限控制缺失:任何人可调用闪电贷接收函数,窃取资金;
- 闪电贷还款逻辑错误:未足额偿还借贷资产,导致合约资不抵债。
- 闪电贷回调函数(如
补充说明
- Slither 的分级逻辑本质对应其「检测规则的严重程度配置」:
CRITICAL/ERROR→ 红色;WARNING→ 黄色;INFORMATIONAL/PASS→ 绿色。
- 针对闪电贷合约(FlashLoanReceiver),红色高频问题集中在:还款校验缺失、重入、权限绕过、金额计算错误;黄色多为「最佳实践缺失」(如未校验 msg.sender 为闪电贷合约);绿色则是无核心风险。
实操建议
- 红色项:必须逐行排查,修复后重新运行 Slither 确认消除;
- 黄色项:结合业务逻辑评估,若涉及闪电贷核心流程(如回调、还款),建议修复;非核心逻辑可酌情优化;
- 绿色项:无需处理,仅作为「安全确认」的参考。
如果需要更精准的解读,可以贴出 Slither 输出的具体红/黄/绿内容,可进一步分析对应的具体问题和修复方案。
我现在的目标是初级solidity审计工程师
要成为初级Solidity审计工程师,核心是搞定Solidity基础、常见漏洞识别、实操工具运用这三大核心能力,再通过CTF挑战、模仿审计报告积累实战经验,最后搭建作品集投递岗位。以下是分阶段的具体行动方案,适配零基础或转型的情况:
- 打牢核心基础,搭建知识框架
这一步是入门关键,重点掌握区块链底层逻辑和Solidity核心语法,为后续审计打地基。- 吃透区块链与合约基础:优先学以太坊生态,搞懂以太坊虚拟机(EVM)的运行机制、交易生命周期、Gas费用计算等核心知识点,可阅读《Mastering Ethereum》的前6章和13 - 14章;同时熟悉ERC20、ERC721等常用代币标准,以及OpenZeppelin的基础合约库,这些是日常审计中高频接触的内容。
- 精通Solidity核心语法:从变量类型、函数修饰符、继承、事件等基础知识点入手,再深入学习异常处理、外部调用、代理合约等进阶内容。推荐通过Solidity官方文档、CryptoZombies交互式教程入门,搭配Solidity - by - example上的案例巩固,重点练习合约逻辑的可读性和安全性写法。
- 补充辅助技能:至少掌握一门辅助语言,比如Python用于写审计脚本,Go或Rust了解跨链生态合约;另外要具备基础的英文读写能力,因为很多审计工具文档、漏洞库都是英文的,这也是多数初级岗位的基础要求。
- 专攻漏洞与审计工具,培养攻击思维
初级审计核心是能识别常见漏洞,这一步需要熟记漏洞类型,再通过工具提升审计效率。- 牢记常见漏洞与防御方法:重点掌握SWC漏洞注册表中的高频漏洞,比如重入攻击、整数溢出/下溢、权限控制缺陷等,每个漏洞要清楚攻击原理、触发条件和修复方案。例如重入攻击可通过加ReentrancyGuard修饰符防御,整数问题可借助OpenZeppelin的SafeMath库规避。
- 掌握主流审计工具:工具能大幅提升漏洞筛查效率,初级阶段需熟练使用几款核心工具。像Slither用于静态代码分析,可自动检测常见漏洞;Mythril适合扫描以太坊合约的安全问题;还有Tenderly可用于合约调试,观察交易执行过程中的异常。建议搭配Eth Security Toolbox整合这些工具,形成基础审计流程。
- 实战练手,积累可展示的成果
企业招聘初级岗位时,实战经历和作品集比单纯的理论更有说服力,可通过三类方式积累经验。- 刷CTF挑战练手感:从入门级的Ethernaut、Capture the Ether开始,逐步进阶到Damn Vulnerable DeFi、Paradigm CTF。这些挑战模拟真实漏洞场景,能快速培养“攻击者思维”,每解一道题都要记录漏洞分析过程,形成笔记。
- 模仿撰写审计报告:找QuillAudit、OpenZeppelin等机构公开的审计报告当模板,选取开源的小型合约(比如GitHub上的简易DeFi合约项目),模仿报告结构写漏洞描述、风险等级、修复建议。哪怕是分析小项目,也能体现你的审计逻辑。
- 参与漏洞赏金计划:注册Immunefi、Sherlock等平台,从低赏金的小型项目入手,尝试提交漏洞报告。即便没拿到赏金,成功提交的有效报告也能作为求职时的加分项,证明你的实战能力。
- 精准投递,拿下初级岗位
准备好基础技能和作品集后,针对性投递岗位,同时关注岗位偏好提升通过率。- 瞄准适配岗位与渠道:优先投递专业审计公司的初级岗位,比如OpenZeppelin、SlowMist的初级审计助理;也可关注互联网大厂的Web3部门、区块链创业公司的智能合约审计岗。渠道方面,除了BOSS直聘等招聘平台,还能通过Secureum、Spearbit等社区的招聘板块找机会,部分岗位支持远程办公。
- 优化简历与作品集:简历重点写Solidity掌握程度、会用的审计工具、CTF成绩、漏洞报告案例;作品集可整理成GitHub仓库,包含你分析的合约代码、漏洞截图、修复方案和审计报告,方便面试官快速了解你的能力。
- 了解薪资与岗位要求:初级岗位薪资差异较大,国内多数岗位月薪在40 - 70K·14薪,海外初级审计员年薪约5 - 15万美元。岗位通常要求熟悉Solidity,懂Python等辅助语言,有基础审计或安全领域经验更好,部分岗位会优先考虑在审计竞赛中取得好名次的候选人。
有哪些审计竞赛?
适合Solidity审计方向的竞赛大多集中在Web3安全平台,这些竞赛不仅能锻炼漏洞挖掘能力,还能凭借参赛成果丰富求职作品集,部分赛事奖金池丰厚,以下是当前行业内主流且适合不同阶段参与者的审计竞赛:
- Code4rena(C4)竞赛
这是业内认可度极高的智能合约竞争性审计平台,也是Solidity审计从业者的核心参赛选择之一。该平台平均每场竞赛会吸引超100名安全研究人员参与,原本需要半年的代码审查量,在这里一周内就能完成。它常与知名项目合作,比如曾联合Certora举办针对Blend v2的Rust智能合约形式化验证竞赛,还为Marginswap、Maple Finance等项目开设过合计超20万美元奖金池的竞赛。其奖励规则向高危、罕见漏洞倾斜,参与者发现的漏洞越关键、越少见,获得的分成比例越高,平台还有专属排行榜,能提升参与者在行业内的知名度。 - Sherlock竞赛
该平台兼具审计竞赛与安全保障属性,常承办重量级项目的审计赛事,适配Solidity等主流合约语言。2025年9月就承办了由以太坊基金会发起、Gnosis和Lido联合赞助的Fusaka审计竞赛,奖金池丰厚,且首周提交有效漏洞能获2倍奖励积分,第二周有1.5倍加成。平台的奖励机制很灵活,不仅参与者可获漏洞赏金,还会预留约8%的竞赛奖金池作为评委奖励,哪怕只准确评判一个高难度漏洞,也可能拿到大部分评委奖励。此外,平台此前还针对Pectra Bytecode升级等以太坊相关项目举办过审计竞赛,参赛经验的行业认可度很高。 - Cyfrin CodeHawks竞赛
该竞赛以高频次、低门槛著称,特别适合你作为初级Solidity审计工程师入门练手。赛事几乎每周都会上新,参与者只需注册账号并订阅对应赛事,就能获取待审计合约的代码库、审计范围等信息。提交漏洞时需注明漏洞标题、严重等级、漏洞描述及复现步骤即可。竞赛设有完整的流程,包含赛事公告、48小时启动期、审计期、评审期、48小时申诉期和奖励发放环节,奖励以USDC形式通过zkSync链发放。其规则清晰且流程规范,能帮助新手熟悉专业审计的完整流程。 - Paladin审计竞赛
该平台的竞赛聚焦Solidity合约相关的跨链、质押、DeFi等热门赛道,适合想针对性积累细分领域审计经验的参与者。从过往赛事来看,曾开展过LayerZero协议相关的跨链合约审计、DragonSwap的质押与空投合约审计、Ondo Finance的OFT合约审计等多个Solidity方向赛事。竞赛结果会形成正式审计报告对外公开,参与者的漏洞发现成果可直接作为求职时的实战案例,对提升初级从业者的简历含金量很有帮助。 - Cantina竞赛
常与Certora、Paladin等平台合作举办赛事,覆盖Solidity和Rust两类合约审计,其中Solidity相关赛事多聚焦DeFi、桥接类项目。比如2025年曾联合Certora为Aqua Network的Aquarius协议举办审计竞赛,2024年也开展过Curvance项目的Solidity合约审计赛事。其特色是会结合形式化验证工具评估参与者的漏洞发现质量,参与者在参赛过程中还能学习到形式化验证相关的实用技巧,进一步丰富技能储备。
我该如何使用slither正确的对它们进行审计。是slither xx.sol这样全都扫描一遍吗?
要高效且全面地用 Slither 审计这 4 个合约(尤其是包含抽象合约、交互类合约的场景),**不建议简单地逐个执行 slither xx.sol**(会忽略合约间的依赖/交互风险),更推荐按「整体扫描 + 针对性分析 + 细节验证」的步骤操作,以下是具体方法和实操指令:
一、核心前提:先整理合约文件结构
确保 4 个合约文件在同一目录(或清晰的目录结构),比如:
1 | |
如果合约有外部依赖(比如 OpenZeppelin 库),先通过 npm install @openzeppelin/contracts 安装,或在命令中指定依赖路径。
二、第一步:整体批量扫描(优先推荐)
Slither 支持直接扫描整个目录/多个文件,会自动分析合约间的继承、调用关系,能发现跨合约交互风险(比如 FlashLoanReceiver 和 NaiveReceiverPool 的闪贷交互漏洞),指令如下:
1. 扫描整个目录(最便捷)
1 | |
2. 扫描指定多个文件(精准)
1 | |
关键参数补充(提升审计效率):
- 输出报告(方便复盘):
1
2slither audit_dir/ --json audit_report.json # 生成JSON格式报告
slither audit_dir/ --markdown audit_report.md # 生成Markdown报告 - 忽略无关警告(聚焦核心):
1
slither audit_dir/ --exclude low,info # 只显示high/critical级别的漏洞 - 指定编译器版本(避免版本兼容问题):
1
slither audit_dir/ --solc-version 0.8.20 # 替换为合约实际使用的版本
三、第二步:针对不同合约特性做「专项审计」
4 个合约的功能类型不同,需结合 Slither 的内置检测器做针对性验证,避免漏检核心风险:
| 合约文件 | 核心功能/风险点 | Slither 专项指令(补充扫描) |
|---|---|---|
| BasicForwarder.sol | 转发器(权限、签名验证) | slither BasicForwarder.sol --detect unauthorized-access,signature |
| FlashLoanReceiver.sol | 闪贷接收(重入、资金计算错误) | slither FlashLoanReceiver.sol --detect reentrancy,arithmetic |
| Multicall.sol(抽象) | 多调用(接口安全、继承实现) | slither Multicall.sol --detect incorrect-inheritance,interface-issues |
| NaiveReceiverPool.sol | 闪贷池(权限控制、清算逻辑) | slither NaiveReceiverPool.sol --detect access-control,flash-loan |
四、第三步:验证抽象合约的「继承实现风险」
Multicall.sol 是抽象合约,需重点检查:
- 其他合约是否正确继承并实现其抽象方法:
1
slither audit_dir/ --detect incorrect-inheritance # 检测继承错误 - 抽象方法的参数/返回值是否与实现类匹配:
1
slither audit_dir/ --detect interface-issues # 检测接口不兼容问题
五、第四步:手动补充「交互场景」审计(Slither 自动扫描的盲区)
Slither 自动扫描无法完全覆盖「合约间交互逻辑」,需结合业务场景验证:
FlashLoanReceiver和NaiveReceiverPool的闪贷交互:- 检查闪贷还款金额计算是否正确(避免少还/多还);
- 验证闪贷回调函数(
executeOperation)是否有重入漏洞;
BasicForwarder调用Multicall多调用时的权限控制;- 所有合约是否正确处理
Multicall带来的批量调用Gas限制问题。
六、常见问题解决
- 报错「找不到抽象合约依赖」:
确保抽象合约Multicall.sol被其他合约正确 import,且路径无误; - 扫描结果无关键漏洞但业务逻辑可疑:
结合 Slither 的--print指令分析合约结构:1
2slither NaiveReceiverPool.sol --print contract-summary # 打印合约核心信息
slither NaiveReceiverPool.sol --print function-summary # 打印函数调用关系 - 闪贷相关漏洞未被检测:
升级 Slither 到最新版本(pip install slither-analyzer --upgrade),闪贷检测器是新版新增功能。
总结
最优流程:
- 先执行「整体目录扫描」+ 输出报告,掌握全局风险;
- 再针对 4 个合约的特性执行「专项检测器扫描」,聚焦核心风险;
- 最后手动验证抽象合约继承、跨合约交互的业务逻辑漏洞。
这种方式既避免了逐个扫描的碎片化,又能精准覆盖不同合约的风险点,符合 Solidity 审计的最佳实践。
Slither和Mythril的区别是什么?
Slither 和 Mythril 是区块链安全审计领域最常用的两款工具,但核心定位、技术原理、适用场景差异极大——Slither 是「静态分析工具」,主打合约代码逻辑/架构层面的漏洞挖掘;Mythril 是「动态分析(符号执行)工具」,主打运行时路径/状态层面的漏洞验证。以下从核心维度拆解区别,结合你的 4 个合约审计场景说明适配性:
一、核心技术原理(最本质区别)
| 维度 | Slither | Mythril |
|---|---|---|
| 分析类型 | 静态分析(Static Analysis) | 动态分析(符号执行/模糊测试) |
| 核心逻辑 | 不运行合约,直接解析 Solidity 源码/字节码,构建抽象语法树(AST)、控制流图(CFG),分析代码结构、变量、函数调用、继承关系等,识别违反安全规则的模式。 | 模拟合约在 EVM 上的运行,通过「符号执行」遍历所有可能的执行路径(比如不同输入参数、调用顺序),用数学符号代替具体值,验证是否存在触发漏洞的路径;也支持模糊测试(Fuzzing)。 |
| 代码依赖 | 需 Solidity 源码(优先),也支持字节码,但源码分析精度更高。 | 无需源码,直接分析字节码(EVM 层面),适合无源码的合约审计。 |
| 运行效率 | 极快(秒级),批量扫描多个合约无压力。 | 较慢(分钟级甚至小时级),复杂合约(多分支、循环)会因路径爆炸导致耗时剧增。 |
二、核心能力与漏洞覆盖
1. Slither:擅长「代码层面的结构化漏洞」
聚焦合约语法、架构、逻辑设计层面的问题,能覆盖 80% 以上的常见漏洞,尤其适合你的 4 个合约场景:
- 强项漏洞类型:
- 继承错误(比如 Multicall 抽象合约的继承实现问题);
- 权限控制漏洞(BasicForwarder 的签名验证、NaiveReceiverPool 的权限管理);
- 算术错误(FlashLoanReceiver 的闪贷金额计算);
- 接口不兼容、函数可见性错误、重入(基础检测);
- 跨合约调用关系梳理(比如 FlashLoanReceiver 和 NaiveReceiverPool 的交互)。
- 弱项:
无法验证「动态执行路径」的漏洞(比如特定输入参数触发的溢出、隐藏的重入路径);
对依赖运行时状态的漏洞(比如区块高度/时间操纵)检测能力弱。
2. Mythril:擅长「运行时层面的执行路径漏洞」
聚焦 EVM 运行时的状态和路径,能发现 Slither 漏检的「隐蔽性漏洞」:
- 强项漏洞类型:
- 重入漏洞(精准检测 FlashLoanReceiver 回调函数的重入风险);
- 整数溢出/下溢(特定输入触发的金额计算错误);
- 未授权访问(比如特定参数绕过 NaiveReceiverPool 的权限校验);
- 区块属性操纵(比如依赖 block.timestamp 的闪贷清算逻辑);
- 死代码/未触发的恶意逻辑(比如隐藏的转账函数)。
- 弱项:
对架构/继承类漏洞(Multicall 的抽象方法实现)几乎无检测能力;
无法批量扫描多个合约,且对复杂合约易出现「路径爆炸」(扫描不完整)。
三、使用场景与适配性(结合你的 4 个合约)
| 场景需求 | 优先用 Slither | 优先用 Mythril |
|---|---|---|
| 批量扫描 4 个合约,快速掌握全局风险 | ✅ 秒级输出结果,支持目录扫描,能梳理合约间依赖 | ❌ 逐个扫描耗时久,无批量分析能力 |
| 审计 Multicall 抽象合约的继承/接口问题 | ✅ 内置 incorrect-inheritance 检测器,精准覆盖 |
❌ 无法识别抽象合约的语法/架构问题 |
| 验证 FlashLoanReceiver 的闪贷回调重入风险 | ❌ 仅基础检测,易漏检隐蔽路径 | ✅ 符号执行遍历回调函数所有执行路径,精准定位重入 |
| 检查 NaiveReceiverPool 的权限控制逻辑 | ✅ 内置 access-control 检测器,直接指出权限漏洞 |
❌ 需手动构造测试用例,效率低 |
| 无源码审计(仅字节码) | ❌ 源码分析精度远高于字节码 | ✅ 原生支持字节码分析,无需源码 |
| 生成审计报告/批量统计漏洞 | ✅ 支持 JSON/Markdown 报告,可自动化统计 | ❌ 报告能力弱,仅输出简单漏洞列表 |
四、实操层面的关键差异
| 维度 | Slither | Mythril |
|---|---|---|
| 安装/使用难度 | 简单(pip install slither-analyzer),指令简洁,参数易理解 |
稍复杂(需依赖 solc/evm 环境),指令参数多,符号执行需手动配置路径限制 |
| 自定义规则 | 支持(通过 Slither API 编写自定义检测器),适合定制化审计 | 支持(编写 Mythril 插件),但门槛高,需熟悉符号执行逻辑 |
| 与你的合约适配性 | 对 BasicForwarder/Multicall/NaiveReceiverPool 适配度极高 | 对 FlashLoanReceiver 的闪贷运行时漏洞适配度极高 |
五、总结:审计你的 4 个合约,建议「Slither 为主,Mythril 为辅」
- 第一步:用 Slither 批量扫描 4 个合约,覆盖继承、权限、算术、接口等结构化漏洞(比如 Multicall 的抽象方法实现、BasicForwarder 的签名验证);
- 第二步:针对 FlashLoanReceiver 和 NaiveReceiverPool 的闪贷交互逻辑,用 Mythril 做专项扫描,验证运行时的重入、金额计算、路径触发漏洞;
- 第三步:结合两者结果,手动交叉验证(比如 Slither 发现的权限漏洞,用 Mythril 验证是否可实际触发)。
简单来说:
- 想「快速、批量、全面」找代码层面的漏洞 → 用 Slither;
- 想「精准、深入」验证运行时的隐蔽漏洞 → 用 Mythril。
两者搭配是 Solidity 合约审计的黄金组合,尤其适合你的闪贷相关合约(FlashLoanReceiver + NaiveReceiverPool)这类高风险场景。
slither回显解析
1 | |
我会用通俗易懂的方式拆解这些Slither检测结果,先帮你建立核心认知:Slither是智能合约安全扫描工具,这些告警都是合约里的「风险点/不规范写法」,不一定全是致命漏洞,但都可能被利用或导致合约出问题。
先补充背景:你扫的是Damn Vulnerable DeFi里的naive-receiver(天真接收者)合约,核心是一个闪电贷池(NaiveReceiverPool)和一个闪电贷接收者(FlashLoanReceiver),先把两个核心合约的角色说清楚:
- 闪电贷池:提供闪电贷,要求借款人瞬间借、瞬间还(还得加手续费);
- 接收者:向池子借闪电贷的合约。
下面逐个拆解告警:
一、NaiveReceiverPool.flashLoan:arbitrary from in transferFrom(transferFrom用了任意的from地址)
检测原文
weth.transferFrom(address(receiver),address(this),amountWithFee) 用了任意的from
人话解释
- 先懂
transferFrom:ERC20代币的transferFrom(from, to, amount)是「从from地址转amount代币到to地址」,但有个前提:from必须先授权给调用者(这里是池子合约) 才能转。 - 这里的风险:池子合约直接用
receiver作为from地址,没有先检查「receiver是否真的授权给池子」,也没有限制receiver的范围(比如随便填一个地址当receiver)。- 举例子:如果我恶意调用这个
flashLoan,把receiver填成你的钱包地址,池子会尝试从你的地址转钱到自己手里——如果你的地址恰好授权过池子,你的钱就被转走了;就算没授权,也会触发失败,导致合约卡住。
- 举例子:如果我恶意调用这个
- 通俗总结:池子像个「不问授权就硬转别人钱的收银员」,既可能偷钱,也可能自己干活干砸。
二、多处ignores return value / unchecked transfer(忽略转账/授权的返回值)
检测原文
- 池子的flashLoan里:
weth.transfer(...)、weth.transferFrom(...)忽略返回值; - 池子的withdraw里:
weth.transfer(...)忽略返回值; - 接收者的onFlashLoan里:
approve(...)忽略返回值。
人话解释
- 先懂基础:以太坊上的代币转账(
transfer/transferFrom)、授权(approve)函数,执行后会返回bool值(true=成功,false=失败)。 - 这里的问题:合约调用这些函数后,完全没看返回值——相当于你给朋友转钱,转完不看转账成功没,直接默认成功了。
- 举例子:
- 池子给receiver转WETH时,
weth.transfer(receiver, amount)如果失败(比如WETH合约是「非标准ERC20」,转账失败不抛异常只返回false),池子还会继续执行后面的逻辑(比如要求还款),结果就是「钱没转过去,却要人家还」,整个闪电贷逻辑彻底乱了; - 接收者授权池子扣款时,
approve返回false(授权失败),但接收者没管,继续执行,结果池子后面扣钱扣不到,闪电贷还款失败,合约出问题。
- 池子给receiver转WETH时,
- 举例子:
- 通俗总结:合约做事「不验收结果」,转账/授权失败了也不知道,硬着头皮往下走,很容易出各种意外。
三、NaiveReceiverPool.flashLoan:Reentrancy(重入漏洞)
检测原文
flashLoan里有外部调用(transfer、onFlashLoan、transferFrom),之后修改了totalDeposits状态变量,存在跨函数重入风险。
人话解释
- 先懂「重入漏洞」:智能合约调用外部合约(比如转WETH、调用receiver的onFlashLoan)时,外部合约可以「反过来再调用当前合约的其他函数」,如果当前合约没做好防护,会导致状态变量被篡改、钱被偷走。
- 这里的风险点:
- 池子的flashLoan流程是:先给receiver转WETH(外部调用)→ 调用receiver的onFlashLoan(外部调用)→ 从receiver扣钱(外部调用)→ 最后修改
totalDeposits(池子的总存款数); - 问题出在「先做外部调用,后改状态变量」:如果receiver的onFlashLoan是恶意的,在这个过程中「又调用池子的withdraw/ deposit函数」,会导致
totalDeposits的数值计算错误(比如重复加钱、扣钱)。 - 举例子:我写一个恶意的receiver,在
onFlashLoan里反复调用池子的withdraw,因为池子还没更新totalDeposits,会误以为自己还有很多钱,把超额的钱转给我。
- 池子的flashLoan流程是:先给receiver转WETH(外部调用)→ 调用receiver的onFlashLoan(外部调用)→ 从receiver扣钱(外部调用)→ 最后修改
- 通俗总结:池子做事「顺序错了」,先把钱借出去、调用别人的代码,再记账,别人可以趁记账前钻空子,篡改账本。
四、FlashLoanReceiver.onFlashLoan:unused return(忽略approve的返回值)
检测原文
WETH(address(token)).approve(pool,amountToBeRepaid) 忽略了返回值
人话解释
和第二点的「忽略返回值」是同一类问题,但场景是接收者授权:
- 接收者借了闪电贷后,需要授权池子扣自己的WETH(还本金+手续费),但调用
approve后没看是否授权成功; - 风险:如果授权失败(比如接收者的WETH不够授权、授权被限制),池子后面扣钱时扣不到,闪电贷还不上,接收者会被判定违约,甚至池子的钱也收不回来;
- 通俗总结:借钱的人「授权扣款时不看成功没」,可能导致还不上钱,两边都吃亏。
整体总结(小白版)
这些告警可以归为三类问题:
- 做事不检查前提:转别人的钱前不看授权(arbitrary from);
- 做事不验收结果:转账/授权后不看成功没(忽略返回值);
- 做事顺序错了:先调用外部代码,后改账本,容易被钻空子(重入)。
为什么这些问题在naive-receiver里很致命?
这个场景的核心漏洞就是「池子没限制闪电贷的调用者,且接收者没防护」:
- 攻击者可以反复给接收者调用闪电贷,每次调用都扣手续费,就算接收者没借到钱,也会被反复扣手续费,直到把接收者的钱扣光;
- 而Slither扫出来的这些点,都是放大这个漏洞的「助攻」:比如忽略返回值会让扣款逻辑无脑执行,重入会让攻击者有更多操作空间,任意from会让攻击者可以指定别人当接收者扣钱。
修复思路(简单提一下,帮你理解)
- 忽略返回值:调用
transfer/transferFrom/approve后,加检查(比如require(weth.transfer(...), "Transfer failed")); - arbitrary from:限制
receiver必须是合法的、且提前授权的地址,调用transferFrom前检查授权额度; - 重入漏洞:用「检查-效果-交互」(Checks-Effects-Interactions)原则,先改状态变量(比如先更
totalDeposits),再做外部调用(转账、调用onFlashLoan),或加重入锁。
如果还有某个点没懂,比如「闪电贷到底是啥」「授权是啥」,可以具体问,我再拆~