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 系统实现端到端的安全与稳定。

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

相关推荐
数据智能老司机15 小时前
Spring AI 实战——提交用于生成的提示词
spring·llm·ai编程
数据智能老司机15 小时前
Spring AI 实战——评估生成结果
spring·llm·ai编程
该用户已不存在16 小时前
免费的 Vibe Coding 助手?你想要的Gemini CLI 都有
人工智能·后端·ai编程
一只柠檬新18 小时前
当AI开始读源码,调Bug这件事彻底变了
android·人工智能·ai编程
用户40993225021220 小时前
Vue 3中watch侦听器的正确使用姿势你掌握了吗?深度监听、与watchEffect的差异及常见报错解析
前端·ai编程·trae
yaocheng的ai分身21 小时前
【转载】我如何用Superpowers MCP强制Claude Code在编码前进行规划
ai编程·claude
重铸码农荣光1 天前
从逐行编码到「氛围编程」:Trae 带你进入 AI 编程新纪元
ai编程·trae·vibecoding
Juchecar1 天前
利用AI辅助"代码考古“操作指引
人工智能·ai编程
Juchecar1 天前
AI时代,如何在人机协作中保持代码的清晰性与一致性
人工智能·ai编程
OpenBuild.xyz1 天前
x402 生态系统:Web3 与 AI 融合的支付新基建
人工智能·web3