AI+Web3实战营日志 #7 | 完成Core合约测试

这是我的 AI + Web3 实战营 的第七篇研发日志,前六篇如下:

AI+Web3实战营日志 #1|开营

AI+Web3实战营日志 #2 | 完成底层合约

AI+Web3实战营日志 #3 | Router合约

AI+Web3实战营日志 #4 | Rebalancer合约

AI+Web3实战营日志 #5 | 完成合约开发

AI+Web3实战营日志 #6 | 开始合约测试


另外,关于 AI + Web3 实战营的相关介绍则有如下几篇文章:

我要启动 AI + Web3 实战营了

再谈 AI+Web3 实战营:这到底能带给你什么?

AI+Web3实战营,9月15日正式开营


前言

之前我们一直采用每天晚上 8 点直播的方式推进研发,每次 1.5--2 小时,一周六天。

不过随着参与直播的同学越来越少,加上每天的时间投入有限,整体进度偏慢。于是我提出取消直播,改为我白天集中录制研发过程,大家根据自己的时间去看回放。这样不仅能让我投入更多时间推进项目,也有余力去做功能迭代和完善。征得大家同意后,从当天起,直播正式取消。

过去两天,我录制了 4 个视频,总时长近 5 小时。加上最初的 1.5 小时测试时间,累计约 6.5 小时,终于把 BlockETFCore 合约的所有测试用例全部跑通。

下面就来总结下这次测试成果。

阶段性成果

针对 BlockETFCore 合约,总计设计并完成 337 个测试用例 ,涵盖 9 大模块,具体如下:

模块 测试数量 覆盖率 关键程度 状态
初始化 53 100% 关键
铸造操作 38 100% 关键
精确份额铸造 25 100%
销毁操作 36 100% 关键
计算逻辑 41 100% 关键
费用管理 30 100%
重新平衡 59 100% 关键
访问控制 31 100% 关键
权重调整 24 100%
合计 337 100% -

代码覆盖率详情则如下,涵盖了所有公开函数和内部函数:

scss 复制代码
╔════════════════════════════════════════════════════════════════╗
║ 文件/函数                    │ 语句覆盖 │ 分支覆盖 │ 函数覆盖 ║
╠════════════════════════════════════════════════════════════════╣
║ BlockETFCore.sol             │ 100.00%  │ 100.00%  │ 100.00%  ║
║ ├─ 核心业务功能              │          │          │          ║
║ │  ├─ initialize()           │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ mint()                 │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ mintExactShares()      │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ burn()                 │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ flashRebalance()       │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ executeRebalance()     │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  └─ adjustWeights()        │ 100.00%  │ 100.00%  │ 100.00%  ║
║ ├─ 计算核心函数              │          │          │          ║
║ │  ├─ calculateMintRatio()   │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ calculateBurnAmounts() │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ calculateRequiredAssets() │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  └─ calculateManagementFee() │ 100.00%  │ 100.00%  │ 100.00%  ║
║ ├─ 管理与配置功能            │          │          │          ║
║ │  ├─ collectManagementFee() │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ setManagementFeeRate() │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ setWithdrawFeeRate()   │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ setFeeCollector()      │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ setRebalancer()        │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ setPriceOracle()       │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ pause()                │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  └─ unpause()              │ 100.00%  │ 100.00%  │ 100.00%  ║
║ ├─ 查询与状态函数            │          │          │          ║
║ │  ├─ getRebalanceInfo()     │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ assetInfo()            │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  ├─ isAsset()              │ 100.00%  │ 100.00%  │ 100.00%  ║
║ │  └─ feeInfo()              │ 100.00%  │ 100.00%  │ 100.00%  ║
║ └─ 内部辅助函数              │          │          │          ║
║    ├─ _collectFee()          │ 100.00%  │ 100.00%  │ 100.00%  ║
║    ├─ _updateReserves()      │ 100.00%  │ 100.00%  │ 100.00%  ║
║    ├─ _validateWeights()     │ 100.00%  │ 100.00%  │ 100.00%  ║
║    └─ _transferAssets()      │ 100.00%  │ 100.00%  │ 100.00%  ║
╚════════════════════════════════════════════════════════════════╝

安全测试方面,也覆盖了重入、溢出、访问控制、抢先交易、闪电贷、拒绝服务、预言机操纵、精度损失等常见攻击向量,均未发现漏洞:

漏洞类型 测试数量 发现问题 严重程度 解决方案
重入攻击 12 0 关键 不适用 - 已防护
整数溢出/下溢 15 0 不适用 - Solidity 0.8
访问控制绕过 18 0 关键 不适用 - 安全
抢先交易 8 0 不适用 - 已缓解
闪电贷攻击 6 0 不适用 - 已防护
拒绝服务攻击 10 0 不适用 - 已防护
预言机操纵 5 0 关键 不适用 - 已验证
精度损失 12 0 不适用 - 已控制

推动合约优化

在完整测试过程中,我们也发现并完成了多项优化:

  1. Oracle 初始化流程 :原本需要先部署合约,再单独调用 setPriceOracle,过程有点繁琐,也存在中间步骤失败的风险。于是我们把 Oracle 地址直接放进构造函数里,部署时一步完成,既减少操作步骤,也更直观。
  2. 防止重入攻击 :初始化函数涉及到多次外部调用。为避免潜在的重入风险,我们给 initialize 函数加上了 nonReentrant 修饰符,让逻辑执行更安全。
  3. 代币转账的安全性 :原本用的是直接 transferFrom,这种方式在失败时可能静默不报错。现在统一改为 SafeERC20,确保转账失败会直接 revert,避免出现账面和实际不一致的问题。
  4. 减少 for 循环initialize 函数最初有 4 个独立 for 循环 ,最终优化到只有 1 个 for 循环,大大节省了 gas。
  5. 铸造时返还多余资产:之前的铸造函数逻辑,调用者如果转入了多余的资产,会直接留在合约里;之后优化为把多余资产返还给用户,对用户更加友好了。
  6. 移除最小铸造份额限制:原来的版本,铸造时会有最小份额的限制,但考虑到随着 ETF 份额净值不断增长,就算是最小份额也可能会变成挺高的一个门槛,最终决定移除了这个最小份额限制,提高了灵活性。
  7. 完善预估函数的计算:铸造和销毁的三个预估计算函数,之前缺少了对管理费的计算,测试时发现预估值与实际值存在差异,于是在预估计算时,把管理费的计算也添加到了计算中,保证了预估计算和实际铸造销毁时的数额的一致性。
  8. 再平衡内部调用权限问题 :合约里有两个再平衡函数,flashRebalanceexecuteRebalance,两个函数都有 onlyRebalancer 的条件限制, executeRebalance 会调用 flashRebalance。之前,是通过 this 的方式去调用 flashRebalance 的。测试时发现,出现了权限错误。因为使用了 this 方式调用,对于 flashRebalance 来说,现在的 msg.sender 其实是当前合约,而不是 rebalancer,而因为有 onlyRebalancer 的限制,所以就报出权限错误了。最终,将 flashRebalance 的可见性改为了 public,调用时去掉了 this,改为直接调用,问题就解决了。

正是因为有了非常完善全面的测试,我们才能发现这些优化的地方。

小结

这一次,我们在 BlockETFCore 合约测试 上累计投入了 6 个半小时,时间甚至超过了合约本身的开发。但这种投入非常值得:

  • 保障了核心模块的稳定性与安全性:337 个测试用例 + 100% 覆盖率,让整个合约基础更加牢固。
  • 推动了架构和细节的优化:从 Oracle 初始化到再平衡权限,很多潜在问题在测试中被提前解决。
  • 为后续测试奠定了模板:这套完整的流程和经验,将直接应用到 Router、Rebalancer 等其他合约测试中,加快整体进度。

如果放在传统的测试流程中,这样规模的测试通常需要一个 2--3 人的测试团队,至少耗时 2--3 周 才能完成。而我们仅凭个人+AI 协作,就在不到 7 个小时里完成了同等甚至更高质量的测试。这种效率差距,本身就是一次 研发范式的变革

从这一步开始,我们真正建立起了"开发 + 测试 + 优化"的完整闭环。下一步,我们将继续推进 Router、Rebalancer、Oracle 等合约的全面测试,直到整个 BlockETF 系统实现端到端的安全与稳定。

这个实战营,每一天都在进步。 🚀

相关推荐
和平hepingfly3 小时前
再见Playwright!谷歌官方Chrome DevTools MCP正式发布,AI编程效率再翻倍
ai编程
Jagger_3 小时前
Spec-Kit 使用指南:让AI开发更规范、更高效
aigc·ai编程·cursor
央链知播3 小时前
链改2.0总架构师何超秘书长重构“可信资产lPO与数链金融RWA”
金融·重构·web3·区块链·业界资讯
用户4099322502123 小时前
PostgreSQL数据类型怎么选才高效不踩坑?
后端·ai编程·trae
黄啊码5 小时前
【黄啊码】AI Coding正在让你平庸地付费上班
人工智能·ai编程
学历真的很重要5 小时前
Claude Code 万字斜杠命令指南
后端·语言模型·面试·职场和发展·golang·ai编程
飞哥数智坊16 小时前
打造我的 AI 开发团队(二):bmad,开箱即用的敏捷开发智能体
人工智能·ai编程
RainbowSea18 小时前
4. ChatClient 的初始,快速使用上手
java·spring·ai编程
RainbowSea18 小时前
3. Ollama 安装,流式输出,多模态,思考模型
java·spring·ai编程