Damn Vulnerable DeFi(八)

今天的任务是: 1. 用mermaid画出Truster、Naive Receiver、Unstoppable的漏洞利用示意图。
2. 熟悉EVM原理
3. 花半小时看登链社区的安全审计相关文章,拓展知识面
看《关于审计技术和工具 101事》 https://learnblockchain.cn/article/5163

mermaid使用哪种图来表示漏洞利用示例图?

mermaid上面有流程图,时序图,类图,状态图等等数十种。
哪一种用来画漏洞利用示例图?


你想知道在Mermaid的数十种图表类型中,哪一种最适合绘制漏洞利用示例图——核心结论是:没有绝对唯一的答案,但要根据漏洞利用的核心逻辑场景选择适配的图表类型,其中流程图(Flowchart) 是基础且通用的选择,部分场景搭配时序图(Sequence Diagram)状态图(State Diagram) 效果更佳。

结合你的安全背景(渗透测试、漏洞挖掘)和审美优势,下面按“适用场景+示例代码+使用建议”拆解,帮你精准匹配:

一、核心推荐:流程图(Flowchart)—— 90%漏洞利用场景首选

适用场景

✅ 漏洞利用的步骤逻辑(比如“如何一步步利用某EVM Opcode漏洞盗币”)、✅ 攻击链路拆解、✅ 漏洞利用的条件/分支(比如“成功利用/利用失败/触发防御”)。
这是最贴合漏洞利用“操作流程”的图表类型,也是你之前画漏洞生命周期的基础,能完美结合你的艺术化隐喻(比如油画笔触、色彩)。

示例:EVM CALL指令漏洞利用流程图(艺术化+技术结合)

graph LR
    A["🎯 漏洞发现<br/>(审计发现CALL指令未校验权限)"]:::discover --> B["📝 构造攻击合约<br/>(写入恶意CALL调用逻辑)"]:::construct
    B --> C["🔧 部署攻击合约<br/>(部署到EVM链上)"]:::deploy
    C --> D["🚀 触发漏洞<br/>(调用目标合约的CALL指令)"]:::trigger
    D --> E{"📊 执行结果"}:::judge
    E -->|✅ 权限绕过| F["💰 盗取资产<br/>(调用转账函数转移资金)"]:::exploit
    E -->|❌ 触发防御| G["🛡️ 利用失败<br/>(Gas耗尽/权限拦截)"]:::fail
    E -->|⚠️ 部分成功| H["📈 仅读取数据<br/>(未盗资产但获取敏感信息)"]:::partial
    
    %% 油画风配色(低饱和莫兰迪色系)
    classDef discover fill:#E8D5C4,stroke:#A18276,stroke-width:2px
    classDef construct fill:#C8E4B2,stroke:#739072,stroke-width:2px
    classDef deploy fill:#BFD7EA,stroke:#4F709C,stroke-width:2px
    classDef trigger fill:#F2D8D8,stroke:#A7727D,stroke-width:2px
    classDef judge fill:#F5E8C7,stroke:#C08261,stroke-width:2px
    classDef exploit fill:#FFE5E5,stroke:#D7443E,stroke-width:2px
    classDef fail fill:#E0E9FF,stroke:#4A7298,stroke-width:2px
    classDef partial fill:#FFF4D2,stroke:#F0A868,stroke-width:2px

二、补充选择1:时序图(Sequence Diagram)—— 多角色交互类漏洞

适用场景

✅ 涉及“攻击者-目标合约-第三方合约/预言机”多角色交互的漏洞(比如RWA项目的预言机操控漏洞、跨合约调用漏洞)、✅ 漏洞利用的“时间顺序+角色交互”(比如先调用A合约,再触发B合约的漏洞)。

示例:RWA预言机操控漏洞利用时序图

sequenceDiagram
    participant Attacker as 🕵️ 攻击者
    participant MaliciousContract as 🤖 恶意合约
    participant Oracle as 📡 预言机
    participant RWAContract as 🏠 RWA合约
    
    Attacker->>MaliciousContract: 1. 部署恶意合约
    Attacker->>MaliciousContract: 2. 调用操纵函数
    MaliciousContract->>Oracle: 3. 伪造喂价数据(篡改资产价格)
    Oracle-->>MaliciousContract: 4. 返回虚假价格
    MaliciousContract->>RWAContract: 5. 调用RWA质押函数(用虚假价格)
    RWAContract->>Oracle: 6. 验证价格(未校验来源)
    Oracle-->>RWAContract: 7. 返回虚假价格
    RWAContract-->>Attacker: 8. 超额发放RWA代币(漏洞利用成功)

三、补充选择2:状态图(State Diagram)—— 状态切换类漏洞

适用场景

✅ 依赖“合约状态变化”的漏洞(比如重入漏洞、状态变量未更新导致的重复提现、RWA资产状态篡改)、✅ 展示“正常状态→漏洞触发→异常状态”的流转(比如钱包从“安全”→“被攻击”→“资产被盗”)。

示例:重入漏洞状态流转图

stateDiagram-v2
    [*] --> Normal: 合约初始状态
    Normal --> Withdrawing: 用户调用提现函数
    Withdrawing --> Reentering: 触发重入(回调恶意合约)
    Reentering --> Exploited: 重复提现资产
    Exploited --> Compromised: 合约资产耗尽
    Withdrawing --> Normal: 提现完成(无漏洞)
    Compromised --> [*]: 合约失效
    
    %% 样式优化
    state Normal {
        note right: 资产充足<br/>状态变量未锁定
    }
    state Exploited {
        note right: 状态变量未及时更新<br/>多次提现成功
    }

四、其他类型:仅特定场景使用

Mermaid图表类型 适用漏洞场景 使用建议
类图(Class Diagram) 分析合约继承/接口设计漏洞(比如继承权限漏洞) 仅审计合约架构时用,不适合画“利用流程”
饼图/柱状图 漏洞利用成功率统计、影响范围分析 作为辅助图表,搭配流程图展示数据
思维导图(Mindmap) 漏洞利用思路拆解(比如“EVM漏洞→Opcode→CALL→权限绕过”) 前期梳理思路用,不适合展示完整利用流程

总结

  1. 核心选择:90%的漏洞利用示例图优先用流程图(Flowchart),适配绝大多数“步骤化”的利用逻辑,且最易结合你的油画审美做艺术化改造;
  2. 场景补充:涉及多角色交互用时序图,涉及状态切换用状态图,其他类型仅作为辅助;
  3. 差异化技巧:在图表中加入油画式隐喻(比如用“调色盘”代表堆栈、“笔触”代表Opcode)、低饱和莫兰迪配色,让技术图表既有专业性又有记忆点,这是你区别于其他安全人员的核心优势。

如果需要针对某类具体漏洞(比如RWA审计中常见的预言机漏洞、权限漏洞)设计专属的Mermaid示例图,我可以帮你定制!

我用什么方法熟悉EVM原理?

你想系统掌握EVM(以太坊虚拟机)原理,核心思路是从“可视化理解”到“动手实操” ——先建立直观认知,再拆解核心机制,最后通过实战验证,结合你擅长的可视化(Mermaid/油画审美)和安全背景(漏洞挖掘),能让学习过程更高效、不枯燥。

下面是一套专为你设计的「分层学习法」,兼顾原理理解和实战落地,完全适配你的技术背景:

一、第一步:可视化建立EVM整体认知(1-2周)

先不用钻细节,用你擅长的“视觉化思维”画出EVM的核心逻辑,把抽象概念转化为你能理解的“画布结构”:

1. 用Mermaid画EVM核心架构图(艺术化+技术结合)

结合你之前设计漏洞生命周期的思路,用Mermaid把EVM拆解成“组件+流程”,加入油画式的隐喻命名,比如:

graph TD
    A["🎨 外部触发层<br/>(交易/合约调用=画笔落笔)"] --> B["⚙️ EVM核心执行层<br/>(字节码执行=颜料调和)"]
    B --> C["📦 状态存储层<br/>(账户/存储=画布肌理)"]
    B --> D["🧮 计算资源层<br/>(Gas计费=调色用量)"]
    B --> E["📜 日志输出层<br/>(事件/日志=签名落款)"]
    
    %% EVM内部拆解
    B1["字节码解析器<br/>(把Solidity转Opcode)"]:::opcode --> B
    B2["堆栈机<br/>(执行指令的核心容器)"]:::stack --> B
    B3["内存/存储<br/>(临时/永久数据区)"]:::mem --> B
    B4["Gas计算器<br/>(每步操作的成本核算)"]:::gas --> B
    
    classDef opcode fill:#E8F4FD,stroke:#4299E1,stroke-width:2px
    classDef stack fill:#FDF2F8,stroke:#9F7AEA,stroke-width:2px
    classDef mem fill:#F5F5F5,stroke:#38B2AC,stroke-width:2px
    classDef gas fill:#F7FAFC,stroke:#ED8936,stroke-width:2px

2. 看可视化教程建立直观认知

  • 推荐资源:
    • 《EVM Illustrated》(图文可视化,把EVM执行过程画成漫画,适配你的审美);
    • YouTube《EVM Deep Dive》(动画讲解,看堆栈机、Opcode执行的动态过程);
  • 核心目标:搞懂“一笔交易从发送到执行完成,在EVM里走了哪些步骤”,比如:
    交易→RPC节点→打包进区块→EVM解析字节码→执行Opcode→修改账户状态→扣Gas→输出日志。

二、第二步:拆解EVM核心机制(2-3周)

从“整体”到“局部”,聚焦和你安全审计相关的核心模块(毕竟你目标是RWA审计,不用学底层开发):

1. 核心模块拆解(只学审计必备)

模块 学习重点(审计视角) 通俗理解(油画隐喻)
Opcode指令集 高频危险指令(CALL/DELEGATECALL/SSTORE)、权限控制指令 不同的画笔笔触,有的笔触(指令)容易画错(出漏洞)
堆栈机 堆栈操作规则、栈溢出/下溢风险 调色盘的容量,放太多/太少颜料都会出错
Gas机制 Gas限制、无限循环导致的DoS、Gas优化漏洞 调色的颜料总量,用完了就画不完(执行中断)
账户模型 EOA账户vs合约账户、存储布局(slot计算) 画布的不同区域,有的区域(slot)能改,有的不能
存储布局 变量如何映射到存储slot、数组/结构体的存储规则 颜料在画布上的排列方式,排错了就会漏色(读错数据)

2. 动手验证(用工具拆解合约)

用你熟悉的安全工具思维,拆解真实合约的EVM执行过程:

  • 工具:Remix(开启“Show Opcode”)、Etherscan(合约页面看Bytecode)、evm.codes(Opcode查询);
  • 实操步骤:
    1. 写一个简单的Solidity合约(比如转账+权限控制);
    2. 在Remix里编译,查看生成的Bytecode和Opcode;
    3. 逐行分析Opcode对应的操作(比如PUSH1、CALL、SSTORE);
    4. 故意写一个漏洞(比如DELEGATECALL权限绕过),看Opcode执行时哪里出了问题。

三、第三步:实战落地(3-4周)—— 结合安全审计

这是最关键的一步,把EVM原理和你擅长的“漏洞挖掘”结合,直接对接RWA审计需求:

1. 针对性练手(审计场景)

  • 练手项目:Damn Vulnerable DeFi(DVDF)—— 每个关卡都对应EVM层面的漏洞,比如:
    • 关卡2(Naive Receiver):利用CALL指令的Gas参数漏洞;
    • 关卡4(Side Entrance):利用CALL指令的返回值处理漏洞;
    • 关卡7(Compromised):利用存储slot读写漏洞;
  • 核心动作:每做一个关卡,都要回答“这个漏洞在EVM层面是怎么发生的?对应的Opcode哪里出了问题?”

2. 分析RWA合约的EVM特征

找真实的香港RWA项目合约(比如稳定币、房产映射合约),做2件事:

  1. 拆解其Bytecode,看核心逻辑的Opcode执行流程;
  2. 分析存储布局,看资产相关变量存在哪个slot,是否有读写权限漏洞;
  3. 用你设计的Mermaid图表,画出“RWA合约漏洞在EVM中的执行路径”(比如预言机喂价漏洞→Opcode层面的CALL指令调用外部合约→数据篡改)。

四、学习资源(精准避坑,不浪费时间)

不用看厚书,聚焦“审计导向”的资源:

  1. 文档:
    • 《EVM Mechanics》(官方偏技术,但重点看“Execution Model”和“Gas”章节);
    • 《Solidity Security Patterns》(结合EVM讲漏洞);
  2. 视频:
    • Patrick Collins的《EVM Deep Dive》(适合安全人员,B站有中文字幕);
    • 慢雾科技的《EVM安全审计实战》(中文,贴合漏洞挖掘);
  3. 工具:
    • Remix(Opcode调试)、Foundry(EVM层面的测试)、evm-debugger(断点调试)。

总结

  1. 学习路径:可视化建框架→拆解核心模块→审计场景实战,全程结合你的“可视化审美”和“安全漏洞思维”,避免纯理论枯燥;
  2. 核心重点:不用学EVM底层开发(比如写虚拟机),只聚焦“Opcode、存储布局、Gas机制、账户模型”这4个审计必备模块;
  3. 落地关键:把EVM原理和RWA合约审计结合,比如分析RWA合约的存储slot、危险Opcode调用,这才是你求职香港RWA审计的核心竞争力。

如果需要,我可以帮你设计一份「EVM审计核心知识点Mermaid图表」(结合油画隐喻),或者拆解一个真实RWA合约的EVM执行流程,让你直接上手练!

Ethernaut:是OpenZeppelin的一个基于Web3/Solidity的战争游戏,在以太坊虚拟机中进行。每个关卡都是一个智能合约,需要被 “黑 “掉。该游戏是100%开源的,所有关卡都是其他玩家的贡献。如何结合ethernaut来帮助我考过智能合约审计认证(如 CertiK Academy)

你想通过Ethernaut这个实战性极强的智能合约攻防游戏,系统性地提升技能,从而通过CertiK Academy等智能合约审计认证,这个思路非常精准——因为CertiK认证的核心是考察漏洞识别、原理理解、修复方案,而Ethernaut的每一关都对应真实审计中高频出现的漏洞类型,完全可以形成“实战训练→考点对标→认证通关”的闭环。

下面我会帮你梳理「Ethernaut关卡→CertiK认证考点」的对应关系,以及分阶段的学习方法,让你把游戏通关转化为实打实的审计能力,高效备考。

一、先明确核心逻辑:Ethernaut vs CertiK认证的匹配度

CertiK Academy的智能合约审计认证(比如CertiK Smart Contract Auditor)核心考察模块包括:

  1. 基础语法与安全规范(Solidity核心特性、OpenZeppelin最佳实践)
  2. 常见漏洞攻防(重入、整数溢出、权限控制、逻辑漏洞等)
  3. 审计流程与工具使用(静态分析、手动审计、报告撰写)
  4. 实战审计案例(基于真实合约的漏洞挖掘)

而Ethernaut的每一关都是对上述考点的“沉浸式实战”,比纯理论学习更易理解和记忆,尤其适合你这种有渗透测试/漏洞挖掘基础的人(你的传统安全思维可以直接迁移)。

二、分阶段学习方案:Ethernaut通关+CertiK备考

阶段1:基础适配(1-2周)—— 打通游戏玩法+认证基础考点

先熟悉Ethernaut的操作流程(部署合约、交互、攻击验证),同时对应CertiK的基础考点,建立“漏洞名称→原理→攻击手法”的认知:
| Ethernaut基础关卡 | 对应CertiK考点 | 核心学习目标 |
|——|—-|——|
| 01-Fallback(回退函数) | Solidity接收ETH机制、权限控制基础 | 理解receive()/fallback()的触发条件,掌握“越权接收ETH+修改所有者”的攻击逻辑 |
| 02-Fallback(升级版)/03-Coinflip | 随机数预测、合约调用逻辑 | 掌握“区块属性(block.number/block.timestamp)不可作为随机数”的审计要点 |
| 04-Telephone | 合约调用上下文(msg.sender vs tx.origin) | 区分两者的安全风险,记住“禁止用tx.origin做权限控制”的修复原则 |

学习方法

  • 每通一关,先自己分析漏洞原理,再对照OpenZeppelin的官方解析;
  • 用Mermaid画你擅长的“漏洞生命周期图”(比如Fallback漏洞的“触发→攻击→提权”流程),强化记忆(既发挥你油画/可视化优势,又契合审计报告的可视化需求);
  • 同步刷CertiK Academy的基础题库,把游戏里的实战场景对应到理论考点。

阶段2:核心漏洞攻坚(3-4周)—— 对标CertiK高频考点

这一阶段聚焦CertiK认证中占分最高的“常见漏洞”模块,Ethernaut的核心关卡几乎全覆盖:
| Ethernaut核心关卡 | 对应CertiK核心考点 | 审计实战价值 |
|——|———|——|
| 06-Delegation | 委托调用(delegatecall)漏洞 | 审计中高频出现的“代码执行权限篡改”,掌握delegatecall的使用规范 |
| 07-Force | 自毁(selfdestruct)强制转账 | 理解“无接收函数也能被强制打ETH”的风险,审计时需检查合约是否处理此类异常 |
| 08-Vault | 私有变量(private)读取 | 记住“private变量可通过链上数据读取”,审计时避免用private存敏感信息 |
| 09-King | 重入漏洞(Reentrancy) | CertiK认证的重中之重,掌握ReentrancyGuard防护、Check-Effects-Interactions模式 |
| 10-Reentrancy | 重入漏洞进阶(跨合约重入) | 结合你的渗透测试经验,类比“传统安全的越权访问”,理解重入的攻击链 |
| 11-Elevator | 接口欺骗/逻辑漏洞 | 审计中最易遗漏的“业务逻辑漏洞”,训练“跳出语法看业务”的审计思维 |
| 12-Privacy | 数据存储与加密漏洞 | 掌握Solidity中数据布局(slot)的读取方法,审计时检查敏感数据加密方案 |
| 15-NaughtCoin | ERC20代币漏洞(授权/转账) | RWA审计中高频的代币合约审计,记住ERC20的常见安全坑(如approve重入、转账返回值) |

学习方法

  • 每攻克一个漏洞,不仅要通关,还要手动编写“修复后的合约代码”(比如给Reentrancy关卡的合约加上OpenZeppelin的ReentrancyGuard);
  • 模拟CertiK审计考试的场景:拿到关卡合约源码,先按“静态分析→手动审计→漏洞定位→修复建议”的流程写一份简易审计报告(这正是CertiK认证的实操环节);
  • 针对每个漏洞,总结“审计检查清单”(比如重入漏洞的检查点:①是否用了Check-Effects-Interactions ②是否引入ReentrancyGuard ③转账是否为最后一步)。

阶段3:综合实战与认证冲刺(2-3周)—— 模拟考试场景

CertiK认证的最后环节是“实战审计案例”,Ethernaut的高阶关卡+自定义关卡正好用来模拟:

  1. 通关Ethernaut高阶关卡:比如18-MagicNumber(字节码攻击)、20-Denial(DoS攻击)、21-Shop(价格操纵),这些对应CertiK认证的“进阶漏洞”考点;
  2. 复现真实审计场景
    • 用Ethernaut的开源机制,下载其他玩家贡献的RWA相关合约关卡(比如映射现实资产的智能合约),按CertiK的审计标准完整审计;
    • 用你擅长的Mermaid可视化,把审计报告中的“漏洞分布”“修复方案”做成艺术化图表(既符合CertiK对报告可读性的要求,又能体现你的差异化优势);
  3. 模拟考试:报名CertiK Academy的模拟考试,把Ethernaut的解题思路迁移到考试中,重点关注“漏洞描述的准确性”“修复方案的可行性”(这是认证评分的核心)。

三、关键技巧:把你的优势最大化

  1. 可视化记忆法:针对每个Ethernaut关卡的漏洞,画一张“漏洞攻防流程图”(用Mermaid+你的油画审美),比如:

    graph LR
    A["🎯 漏洞触发点<br/>(Reentrancy的withdraw函数)"]:::attack --> B["🔍 攻击路径<br/>(调用恶意合约重入)"]:::path
    B --> C["⚠️ 漏洞危害<br/>(盗走全部ETH)"]:::risk
    C --> D["🛡️ 修复方案<br/>(ReentrancyGuard+Check-Effects)"]:::fix
    
    classDef attack fill:#F8CECC,stroke:#B85450,stroke-width:2px
    classDef path fill:#E8D5C4,stroke:#A67C52,stroke-width:2px
    classDef risk fill:#FFE6E6,stroke:#FF6B6B,stroke-width:2px
    classDef fix fill:#D5E8D4,stroke:#82B366,stroke-width:2px
    

    这种可视化方式比纯文字笔记更容易记住,也能在CertiK面试/实操环节加分。

  2. 传统安全思维迁移:你的渗透测试/漏洞挖掘经验是核心优势——把Ethernaut的智能合约漏洞类比为“传统web安全漏洞”(比如重入漏洞=CSRF,权限控制漏洞=越权访问),用你熟悉的“攻击链分析”思路拆解每一关,降低学习成本。

  3. 错题复盘:把没通关的关卡、CertiK题库做错的题整理成“漏洞手册”,标注“漏洞类型→原理→易错点→修复方案”,考前快速复盘。

总结

  1. Ethernaut是CertiK认证的“实战训练场”,核心是把每一关的漏洞拆解为“原理→攻击→修复”,对应CertiK的考点;
  2. 你的核心优势是「渗透测试思维+可视化审美」:用渗透思路拆解漏洞攻击链,用Mermaid艺术化图表强化记忆,既高效又能体现差异化;
  3. 备考节奏:先基础适配,再攻坚核心漏洞,最后模拟审计实战,6-9周可完成从Ethernaut通关到CertiK认证的核心准备。

如果需要,我可以帮你整理「Ethernaut全关卡- CertiK考点对照表」和「智能合约审计检查清单(适配CertiK认证)」,直接套用即可。

用mermaid画出Unstoppable攻击原理图

用mermaid画出Naive Receiver攻击原理图

用mermaid画出Truster攻击原理图

我看不懂Damn Vulnerable DeFi的Solve the challenge的xx.t.sol,我该补充哪方面的知识呢?我对于foundry的理解停留在forge test

你目前对 Foundry 的理解停留在 forge test 基础命令层面,看不懂 Damn Vulnerable DeFi(DVD)的测试文件(.t.sol),核心是因为缺少Solidity 合约开发、Foundry 测试框架核心用法、DeFi 核心逻辑这三类关键知识。我会帮你梳理从入门到能看懂 DVD 测试文件的学习路径,全程贴合新手的认知节奏。

一、先明确核心问题:你看不懂的本质

DVD 的 .t.sol 不是普通的“跑测试”,而是:

  1. 用 Foundry 语法模拟攻击/利用漏洞(核心是 Foundry 作弊码、测试语法);
  2. 操作 DeFi 合约(闪电贷、代币、借贷池等,核心是 Solidity/DeFi 基础);
  3. 验证漏洞是否被成功利用(核心是断言、事件监听等测试逻辑)。

你需要按“基础→进阶→实战”的顺序补充知识,以下是分阶段的学习重点:

二、第一阶段:补全 Foundry 核心用法(最紧急)

你只知道 forge test,但 DVD 测试文件大量用到 Foundry 的高级特性,这是看懂 .t.sol 的前提。

1. 先掌握 Foundry 测试的核心语法

知识点 作用(对应 DVD 测试场景) 学习资源
测试合约结构 理解 .t.solcontract XxxChallenge 如何组织 Foundry 官方文档:https://book.getfoundry.sh/forge/tests
vm.* 作弊码 DVD 测试中高频用(模拟账户、时间、事件、转账) Foundry 作弊码列表:https://book.getfoundry.sh/cheatcodes/(必看)
事件监听(expectEmit 你遇到的 FlashLoanStatus 事件校验就是这个知识点 https://book.getfoundry.sh/forge/tests#expecting-emits
账户模拟(prank/startPrank 模拟玩家/部署者地址操作合约 https://book.getfoundry.sh/forge/tests#pranking
断言(assert/expectRevert 验证漏洞是否触发(比如预期交易失败) https://book.getfoundry.sh/forge/tests#assertions

2. 入门级实操(先跑通基础,再看 DVD)

先写 2-3 个简单的 Foundry 测试案例,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 示例:模拟账户转账+事件监听
pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import "../src/Token.sol"; // 自己写一个简单的 ERC20 代币

contract TokenTest is Test {
Token public token;
address public alice = address(1);
address public bob = address(2);

function setUp() public {
// 部署代币合约(DVD 测试中也会先部署漏洞合约)
token = new Token();
}

function testTransfer() public {
// 1. 模拟 alice 有代币(作弊码 vm.mint,对应 DVD 中给玩家发代币)
vm.prank(address(token)); // 模拟代币合约地址
token.mint(alice, 100 ether);

// 2. 监听 Transfer 事件(对应你遇到的 FlashLoanStatus 事件)
vm.expectEmit(true, true, false, true); // 配置监听的索引参数
emit Transfer(alice, bob, 50 ether); // 预期触发的事件

// 3. 模拟 alice 转账(prank 切换账户)
vm.prank(alice);
token.transfer(bob, 50 ether);

// 4. 断言结果(验证转账成功)
assertEq(token.balanceOf(bob), 50 ether);
}
}

跑这个测试:forge test --match-test testTransfer -vvv,理解每一行的作用,再对照 DVD 的 .t.sol,你会发现逻辑是相通的。

3. 重点吃透 DVD 测试中高频的 5 个作弊码

作弊码 DVD 中的用途 简单示例
vm.prank(address) 切换到指定地址执行下一步操作(比如玩家攻击) vm.prank(player); vault.flashLoan(...);
vm.expectEmit() 预期某个事件被触发(比如你遇到的 FlashLoanStatus) vm.expectEmit(); emit FlashLoanStatus(false);
vm.expectRevert() 预期交易回滚(验证漏洞触发,比如闪电贷失败) vm.expectRevert("Invalid balance"); vault.flashLoan(...);
vm.startPrank() 持续切换账户(多步操作同一地址) vm.startPrank(player); token.transfer(...); token.approve(...);
vm.label() 给地址命名(方便看日志,比如 player/deployer) vm.label(player, "Player");

三、第二阶段:补全 Solidity 与 DeFi 基础(看懂合约逻辑)

DVD 的测试文件是操作“漏洞合约”的,若看不懂合约本身的逻辑,也无法理解测试代码的目的。

1. Solidity 核心知识点(优先级从高到低)

知识点 为什么重要(DVD 场景) 学习资源
ERC20 代币标准 DVD 绝大多数挑战基于 ERC20(比如你遇到的 DVT 代币) https://docs.openzeppelin.com/contracts/4.x/erc20
函数可见性(external/public 漏洞合约的核心函数(如 flashLoan)都是 external https://docs.soliditylang.org/en/latest/contracts.html#function-visibility
事件(event 测试中大量通过事件验证结果(如 FlashLoanStatus) https://docs.soliditylang.org/en/latest/contracts.html#events
回滚机制(require/assert 漏洞的核心(比如触发 assert 使合约失效) https://docs.soliditylang.org/en/latest/control-structures.html#error-handling
回调函数(如 onFlashLoan 闪电贷、DEX 等场景的核心逻辑 先理解“钩子函数”概念,再看 ERC3156 闪电贷标准

2. DeFi 基础概念(不用深钻,先懂名词)

DVD 是 DeFi 漏洞练习,先搞懂这些核心名词,才能理解测试的目的:

名词 简单解释(对应 DVD 挑战) 入门理解程度
闪电贷(FlashLoan) 无抵押、必须即时归还的贷款(Unstoppable 挑战核心) 知道“借→用→还”必须在一笔交易内完成
借贷池(Lending Pool) 存放资金供用户借贷的合约(如 UnstoppableVault) 知道池的余额是核心校验点
ERC20 余额校验 balanceOf(address) 读取合约持有的代币数量 知道外部转账会改变合约余额
事件监听 通过事件判断合约执行结果(如 success=true/false) 知道事件是“日志”,测试用来验证结果

四、第三阶段:手把手拆解 DVD 的 Unstoppable.t.sol(落地练习)

以你遇到的 Unstoppable.t.sol 为例,按“拆步骤→对应知识点”的方式分析,帮你建立“看测试文件”的思维:

步骤 1:先看测试合约的结构(Foundry 基础)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
contract UnstoppableChallenge is Test {
// 1. 定义合约/地址变量(对应 Foundry 测试的变量声明)
address public deployer = makeAddr("deployer");
address public player = makeAddr("player");
UnstoppableVault public vault;
UnstoppableMonitor public monitor;
DamnValuableToken public dvt;

// 2. setUp 函数:部署所有合约(Foundry 测试的初始化)
function setUp() public {
// 部署代币、Vault、Monitor 合约(对应 DeFi 合约部署)
vm.prank(deployer);
dvt = new DamnValuableToken();

vm.prank(deployer);
vault = new UnstoppableVault(dvt);

// 给 Vault 充钱(模拟 DeFi 资金池)
vm.prank(deployer);
dvt.approve(address(vault), 1000000 ether);
vm.prank(deployer);
vault.deposit(1000000 ether);

vm.prank(deployer);
monitor = new UnstoppableMonitor(vault, dvt, deployer);
}

// 3. 测试用例 1:验证初始状态(基础断言)
function test_assertInitialState() public {
assertEq(dvt.balanceOf(address(vault)), 1000000 ether);
assertEq(vault.totalAssets(), 1000000 ether);
}

// 4. 测试用例 2:核心挑战(漏洞利用)
function test_unstoppable() public {
// 这里是你需要写漏洞利用代码的地方!
// 比如:玩家直接转账代币到 Vault,破坏余额校验

// 预期触发 FlashLoanStatus(false)(事件监听)
vm.expectEmit(true, true, true, true);
emit FlashLoanStatus(false);
// 调用闪电贷,预期失败
monitor.checkFlashLoan(100 ether);
}
}

步骤 2:对应知识点拆解(你看不懂的地方)

代码片段 对应知识点 解释
makeAddr("player") Foundry 地址生成 快速创建测试用的虚拟地址,不用手动输 0x…
setUp() Foundry 测试初始化 所有测试用例执行前先跑这个函数,部署合约、初始化状态
vm.expectEmit() Foundry 事件监听 预期接下来的操作会触发指定事件,参数不匹配就会失败(你遇到的问题)
monitor.checkFlashLoan() DeFi 闪电贷逻辑 调用监控合约的闪电贷检查函数,本质是触发 Vault 的 flashLoan 函数

五、学习路径建议(新手友好)

  1. 先花 1-2 天吃透 Foundry 基础
    • 跟着官方文档写 3-5 个简单测试(比如 ERC20 转账、权限验证);
    • 重点练 prank/expectEmit/expectRevert 这 3 个作弊码。
  2. 补 Solidity 核心(2-3 天)
    • 重点看 ERC20、函数可见性、事件、回滚机制;
    • 不用学太复杂的(比如组装器、内联汇编),先懂基础语法。
  3. 拆解 DVD 的简单挑战(从 Unstoppable 开始)
    • 先看 src/unstoppable/ 下的合约(UnstoppableVault.sol),找漏洞点(比如 balanceOf 校验);
    • 再看测试文件,逐行注释每个代码的作用;
    • 尝试修改测试代码,比如添加 player 转账代币到 Vault,跑测试看是否通过。
  4. 进阶:看 DVD 官方题解(如果卡壳)
    • DVD 有社区题解(比如 GitHub 上的 writeup),看不懂时可以参考,但先自己试;
    • 重点看“漏洞利用代码”是怎么写的,对应 Foundry 哪个知识点。

总结

你看不懂 DVD 的 .t.sol,核心是缺 Foundry 测试框架的核心用法Solidity/DeFi 基础,按以下优先级补充即可:

  1. 先掌握 Foundry 的 vm 作弊码(prank/expectEmit/expectRevert)和测试结构;
  2. 理解 Solidity 事件、回滚机制和 ERC20 基础;
  3. 从最简单的 Unstoppable 挑战入手,逐行拆解测试文件,把“代码→知识点”对应起来。

不用急于求成,先把 Unstoppable 这一个挑战的测试文件看懂、改通,再去看其他挑战,你会发现逻辑都是相通的。如果某一行代码看不懂,比如 vm.expectEmit 的参数怎么配,就针对性查 Foundry 文档,聚焦“解决当前问题”,而不是一次性学完所有知识。

参考资料