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

By [Keegan小钢](https://paragraph.com/@keeganlee) · 2025-09-27

---

这是我的 [**AI + Web3 实战营**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495279&idx=1&sn=4369256be0f5ad49989242a35eab3a04&scene=21#wechat_redirect) 的第七篇研发日志，前六篇如下：

[**AI+Web3实战营日志 #1｜开营**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495285&idx=1&sn=49acd14afddf10e8bd0e0813f07f90a0&scene=21#wechat_redirect)

[**AI+Web3实战营日志 #2 | 完成底层合约**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495299&idx=1&sn=bf08bcdf92558408615ca17c097f46ba&scene=21#wechat_redirect)

[**AI+Web3实战营日志 #3 | Router合约**](https://mp.weixin.qq.com/s/P2M7DE1enBZYD3zw1Z4jhA)

[**AI+Web3实战营日志 #4 | Rebalancer合约**](https://mp.weixin.qq.com/s/GntcgQPP35XSJOWqbw9Oqw)

[**AI+Web3实战营日志 #5 | 完成合约开发**](https://mp.weixin.qq.com/s/j_faRPDhEfjRUCh4zMHYMw)

[**AI+Web3实战营日志 #6 | 开始合约测试**](https://mp.weixin.qq.com/s/GFxKu2ugnAX5wspR3qezvw)

* * *

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

[**我要启动 AI + Web3 实战营了**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495268&idx=1&sn=c226a51bc06d180858a41fa9becbf752&scene=21#wechat_redirect)

[**再谈 AI+Web3 实战营：这到底能带给你什么？**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495273&idx=1&sn=628a703d76cc808a0484f576234f2c7a&scene=21#wechat_redirect)

[**AI+Web3实战营，9月15日正式开营**](https://mp.weixin.qq.com/s?__biz=MzA5OTI1NDE0Mw==&mid=2652495279&idx=1&sn=4369256be0f5ad49989242a35eab3a04&scene=21#wechat_redirect)

* * *

**前言**
------

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

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

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

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

**阶段性成果**
---------

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

![](https://storage.googleapis.com/papyrus_images/489cf7899afda9cfee423e2ccce7c97a1c1f35933b735bf63c86223d0a8cb9f7.png)

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

    ╔════════════════════════════════════════════════════════════════╗
    ║ 文件/函数                    │ 语句覆盖 │ 分支覆盖 │ 函数覆盖 ║
    ╠════════════════════════════════════════════════════════════════╣
    ║ 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%  ║
    ╚════════════════════════════════════════════════════════════════╝
    

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

![](https://storage.googleapis.com/papyrus_images/6f900741b9f652d555a53e3d60b6f26891cb1da247ddde029f6b30cd6f8e98ae.png)

**推动合约优化**
----------

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

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

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

---

*Originally published on [Keegan小钢](https://paragraph.com/@keeganlee/ai-web3-7-core)*
