本文通过实验展示了AI(Claude)在审计Solidity智能合约时的表现:能有效识别重入、访问控制、算术溢出等常见漏洞,但完全无法检测经济攻击,如预言机操纵。

我们进行了一次实验。涉及 43 个生产环境的 DeFi 合约,总计约 5 万行 Solidity 代码,涵盖借贷、永续合约、金库和跨链桥。我们将所有代码交给 Claude,并给出明确指令:找出所有漏洞,按严重性排序,提出修复建议。
六小时后,输出结果令人印象深刻。三个借贷池中被标记出重入模式。一个金库初始化函数缺少零地址检查。一笔不安全的 ERC20 转账忽略了返回值。一个升级函数存在访问控制漏洞。费用计算中存在微妙的整数舍入问题。这些都是真实的发现,都值得交给开发团队处理。
然而,有一类漏洞模型完全忽略了。正是这类漏洞导致 Mango Markets 损失 1.17 亿美元、Lodestar Finance 损失 580 万美元,并在 2022 年至 2024 年间导致数十个小规模协议被洗劫一空。
本文旨在探讨:Claude 看到了什么,它没看到什么,以及为什么这个差距比现在正在融资的创始人意识到的要严重得多。
LLM 是出色的模式匹配器。它们已经消化了每一篇公开的 Solidity 漏洞事后分析报告、GitHub 上的每一份审计报告以及过去五年的每一篇安全博客。当它们看到一个函数时,实际上是在问:我见过的数千个有漏洞的函数中,这个最像哪一个?
对于大部分智能合约漏洞来说,这已经足够了。Claude 能够可靠地发现:
onlyOwner、缺少 initializer 修饰符、应设为 internal 的 public 函数。delegatecall。这些都是已经被写过上万次的漏洞。模式识别可以很好地处理它们。独立研究也证实了这一点。2024 年一项针对五个前沿 LLM 的智能合约漏洞评估研究发现,对常见漏洞类别的召回率很高,但同时也存在持续的误报问题,并且在任何新颖或依赖上下文的漏洞上存在难以突破的上限。
那么,为什么仅靠 AI 还不够呢?
它错过了所有的经济攻击。
不是因为代码看起来干净(它确实看起来干净),而是因为漏洞不在代码中。漏洞在于代码所依赖的假设。
以下是从我们测试的一个合约中提取的函数。Claude 审查了它,没有发现任何问题,然后继续往下看:
function getCollateralValue(address user) external view returns (uint256) {
uint256 tokenAmount = userDeposits[user];
uint256 price = priceOracle.getPrice(collateralToken);
return tokenAmount * price / 1e18;
}
function borrow(uint256 amount) external {
uint256 collateralValue = getCollateralValue(msg.sender);
require(
collateralValue >= amount * collateralRatio / 100,
"insufficient collateral"
);
userBorrows[msg.sender] += amount;
IERC20(borrowToken).transfer(msg.sender, amount);
}
从代码角度来看,这没问题。有价格预言机,有抵押品检查,没有重入、溢出或缺失修饰符。任何模式匹配工具(无论是 AI 还是其他工具)都会给它一个绿色勾号。
现在,再以攻击者的视角读一遍。
抵押代币的流动性很差,日交易量很小。预言机读取自两个深度较浅的中心化交易所。一个拥有 1000 万美元资金的攻击者可以在十分钟内将该代币的价格推高 20 倍。一旦价格上涨,getCollateralValue 会返回一个夸大的数字,require 检查通过,攻击者就可以提取整个 borrowToken 储备。
记住我以便更快登录
这正是 2022 年 10 月 Mango Markets 发生的情况。事后声明直言不讳:预言机报告如预期工作。 代码完全按照编写的方式执行。问题在于,协议建立在这样一个假设之上:MNGO/USD 的价格会像真实市场价格一样表现。但事实并非如此,因为 400 万美元的资金可以在三个交易所同时将流动性差的代币价格推高 2300%。
Claude 无法发现这一点,因为“你的抵押代币流动性太差,不能用作抵押品”并没有语法上的特征。漏洞存在于代码、市场结构和经济激励之间的交互中。这不是一种模式,而是一种对世界的建模。
在 2026 年,重入和整数溢出基本上已是解决过的问题。标准库处理了大部分情况。如今导致协议被盗的漏洞越来越多是经济层面的:
每一种都需要推理攻击者会用一百万美元和对你协议的充分理解做什么,而不仅仅是你的 transfer 调用是否返回布尔值。AI 工具可以在抽象层面描述这些类别,但很难针对具体代码库实例化它们,因为这样做需要同时将整个经济模型和代码铭记在心。
这不是增加训练数据就能解决的问题。这是要求一个模式匹配器在对抗性条件下进行建设性推理的固有局限。
模式识别问的是“这段代码看起来危险吗?”而不变性测试问的是“是否存在任何合法调用的序列,会破坏协议必须始终保留的性质?”后一个问题正是针对经济漏洞的正确问题。
针对上述借贷合约的 Foundry 不变性测试可能是这样的:
function invariant_protocolStaysSolvent() public view {
uint256 totalCollateralUSD = collateralOracle.getPrice(collateralToken)
* totalCollateralDeposited / 1e18;
uint256 totalDebtUSD = totalBorrowed;
assertGe(totalCollateralUSD, totalDebtUSD, "INSOLVENT");
}
function invariant_noAtomicProfit() public {
uint256 attackerStart = attacker.balanceUSD();
handler.runRandomAttackSequence();
uint256 attackerEnd = attacker.balanceUSD();
assertLe(attackerEnd, attackerStart, "atomic profit possible");
}
模糊测试器会针对系统运行数千次随机化的调用序列,同时改变价格、存款和借款。一旦任何序列破坏了不变性,测试就会失败并给出可重现的用例。这就是像 Trail of Bits 这样的团队如何捕获审计遗漏的经济漏洞的方法。这也是在给定正确建模的价格压力处理器的情况下,Mango 类漏洞在主网上线前就会暴露出来。
经济攻击建模则更上一层楼。它问的是:破坏每个不变性所需的最小资本是多少?如果答案是“800 万美元可以操纵我们的预言机并窃取 1 亿美元”,那么无论代码做了什么,这都是一个发现。
我们使用 AI 工具。它加快了审计中无聊的 60% 工作。但我们为每个项目都交付了两项 AI 无法单独完成的东西。
不变性测试框架。 用 Foundry 或 Medusa 编写,与协议的具体经济逻辑相关联。包括偿付能力不变性、无原子利润不变性、金库的份额价格单调性不变性、借贷的清算可行性不变性。我们返回的失败测试用例通常是最有价值的审计成果。
经济攻击建模。 对每个预言机、每个抵押资产、每条费用路径的书面分析,并估算每条路径的攻击者所需资本。如果你的协议可以被任何拥有不到 500 万美元的人利用,你会从我们这里得知,而不是在资金被抽走时从 Twitter 上看到。
对于正在融资的创始人来说,这两项成果都可以作为尽职调查材料。成熟的投资者越来越要求在资料室里看到不变性测试覆盖率和经济压力测试。一套通过的测试套件所体现出的运营成熟度,是任何审计标志都无法比拟的。
如果你已经部署到测试网,并且正在决定你的安全预算应该真正花在什么地方,那就是我们可以开始对话的地方。
与 Ancilar 预约预审计审查: www.ancilar.com/services/smart-contract-audit
- 原文链接: medium.com/@ancilartech/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码