翻译:PropertyGPT: LLM-driven Formal Verification of Smart Contracts through Retrieval-Augmented ...

PropertyGPT:通过检索增强属性生成的大型语言模型驱动的智能合约形式化验证

PropertyGPT: LLM-driven Formal Verification of Smart Contracts through Retrieval-Augmented Property Generation

![[Pasted image 20250324104139.png]]

摘要

形式化验证是一种能够证明系统相对于特定规范或属性正确性的技术。它对管理着数十亿美元加密资产的安全敏感型智能合约尤为重要。尽管现有研究已经开发了各种用于智能合约的静态验证工具(或验证器),但一个关键缺失的组成部分是综合性属性的自动生成,这些属性包括不变量、前置/后置条件以及规则。因此,像 Certora 这样的行业领先者不得不依赖其内部专家或众包专家逐一手动编写属性。
随着大型语言模型(LLMs)的最新进展,本文探讨了利用最先进的 LLMs(例如 GPT-4)来转移现有的人编写的属性(例如,来自 Certora 审计报告中的属性)并为未知代码自动生成定制属性的潜力。为此,我们将现有的属性嵌入到向量数据库中,并检索出一个参考属性,以供基于 LLM 的上下文学习生成给定代码的新属性。虽然这一基本流程相对简单,但确保生成的属性具备以下特点仍具挑战性:(i) 可编译,(ii) 适当,以及 (iii) 可验证。为了解决 (i),我们使用编译和静态分析反馈作为外部指导机制,引导 LLM 迭代修订生成的属性。对于 (ii),我们考虑多个相似性维度对属性进行排序,并采用加权算法选出前 K 个属性作为最终结果。对于 (iii),我们设计了一个专用验证器,以正式验证生成属性的正确性。我们将这些策略集成到一个名为 PropertyGPT 的新型基于 LLM 的属性生成工具中。实验表明,PropertyGPT 能够生成全面且高质量的属性,与真实情况相比达到了 80% 的召回率。它成功检测出了 37 个测试案例中的 26 个 CVE 漏洞/攻击事件,还发现了 12 个零日漏洞,获得了 8,256 美元的漏洞赏金奖励。

I. 引言

智能合约是部署并运行在区块链平台上的交易驱动型程序,能够自动执行用户之间的数字协议。大多数智能合约使用图灵完备的编程语言编写,例如 Solidity [47],并在以太坊 [61] 和 BSC [1] 等流行的区块链平台上得到了广泛应用。智能合约广泛应用于去中心化金融(DeFi)[25] 和非同质化代币(NFTs)[5] 等去中心化应用中。然而,它们容易受到各种类型的攻击,包括整数溢出 [51]、重入攻击 [43]、抢先交易 [50] 以及访问控制漏洞 [15], [34]。这些漏洞主要源于因编程错误、实现不当和逻辑缺陷 [66] 而产生的智能合约漏洞。

形式化验证是一种通过不同规范进行全面检查来识别合约漏洞的最先进方法之一。为了进行形式化验证,需为不同的智能合约生成定制的形式化规范。如文献 [54] 所述,智能合约的形式化规范通常包括时序逻辑属性和霍尔逻辑属性。不变量是最常见的合约规范,它指任何合约执行过程中都成立的属性,其次是针对特定功能使用的函数前置/后置条件,以及覆盖跨函数属性的规则。在大多数情况下,时序逻辑属性可以转换为霍尔属性,并嵌入到智能合约代码中 [42]。因此,现有工作通常使用霍尔风格的规范来进行漏洞检测 [56], [58]、不一致性检测 [11] 和正确性验证 [42], [60]。

尽管形式化验证在提高智能合约的安全性和可靠性方面具有巨大潜力,但一个显著的挑战仍然存在:社区仍缺乏自动生成综合性属性的能力,以实现对智能合约的有效形式化验证。虽然有几项研究尝试解决这一问题,但尚未达到为未知合约代码自动生成必要属性(包括不变量、前置/后置条件和规则)的最终目标。例如,InvCon [33], [36] 可以动态推断可能的合约不变量和函数前置/后置条件,但它需要历史交易信息。同样,Cider [32] 和 SmartInv [59] 使用基于机器学习的方法,通过训练-推理范式生成规范,但仅限于不变量属性。因此,像 Certora [10] 这样的行业领先者不得不依赖其内部或众包专家 [9] 逐一手动编写属性,这阻碍了大规模智能合约的有效形式化验证。

本文探讨了大型语言模型(LLMs)的最新进展如何实现智能合约综合属性的自动生成。鉴于 LLMs 在上下文学习中的强大能力(背景见 §II),我们尝试通过对现有人编写的属性进行有效迁移学习,从而为未知代码生成定制属性。更具体地说,我们将现有属性嵌入到向量数据库中,并检索出一个参考属性,以供基于 LLM 的上下文学习生成给定代码的新属性。通过这种方式,只要收集的向量数据库中每种类型都有现有样本,我们就可以生成多种类型的属性。此外,与上述提到的训练-推理范式 [32], [59] 相比,我们的方法不需要容易出错的标注过程(我们可以直接使用现有的原始属性结果,例如来自 Certora 审计报告的内容),也不需要在数据更新时重新训练。

尽管基本的属性生成流程相对简单,但要确保检索增强型属性具备以下特点仍具挑战性:(i) 可编译 compilable,(ii) 适当 appropriate,以及 (iii) 可验证 verifiable。为了解决这些挑战,我们采用了三种新颖的设计,并将其实现于一个名为 PropertyGPT 的基于 LLM 的系统中。首先,我们使用编译和静态分析反馈作为外部指导机制,引导 LLM 迭代修订生成的属性。其次,我们考虑多个相似性维度对属性进行排序,并找到所有维度的平衡指标。由此产生的加权算法选出前 K 个属性作为最终结果。第三,我们设计了一个专用验证器,以正式验证生成的前 K 个属性的正确性。

为了评估 PropertyGPT,我们从 23 个 Certora 项目中收集了 623 条人编写的属性。我们首先将其中 90 条划分为真实情况测试集,其余作为参考属性。我们发现,PropertyGPT 能够覆盖人类专家判定的真实情况中 80% 的等效属性,且精度合理地达到了 64%。需要注意的是,PropertyGPT 生成的额外属性(假阳性)通常也成立,补充了人编写的属性。我们进一步使用所有 623 条属性作为知识库,为 PropertyGPT 提供支持,用于检测现实世界中的 CVE 漏洞和过去的攻击事件。结果显示,PropertyGPT 成功检测出了 13 个 CVE 中的 9 个和 24 个攻击事件中的 17 个。此外,在此过程中,PropertyGPT 展现了对完全不同的数据集进行充分泛化的能力。最后,我们在四个现实世界的悬赏项目上运行 PropertyGPT,以展示其发现零日漏洞的能力。PropertyGPT 成功生成了 22 个漏洞发现,其中 12 个已被确认并修复,为我们赢得了总计 8,256 美元的悬赏奖励。

贡献

我们总结贡献如下:

  • 我们提出了一种新颖的基于 LLM 的属性生成工具 PropertyGPT,以推动智能合约的全面形式化验证,其核心步骤——检索增强型属性生成——详见 §V。
  • 为了支持 PropertyGPT,我们还设计了一种面向智能合约的属性规范语言(PSL)(§IV)和一个专用的属性验证器(§VI)。
  • 我们进行了广泛的实验和消融研究,以在各种现实场景中评估 PropertyGPT;详见 §VII 和 §VIII。

可用性

属性数据集和原始实验数据可在 https://github.com/Pr0pertyGPT/PropertyGPT 获取,而原型正由我们的行业合作伙伴 MetaTrust Labs 商业化。部分开源版本将在上述 GitHub 链接中更新。

II. 初步知识

大型语言模型(LLMs),例如 GPT-3.5 [40] 和 CodeLLama [44],已在许多自然语言处理任务中得到广泛应用,例如文本生成、翻译和摘要生成。GPT 系列模型在大量文本数据上进行训练,具有生成类人文本的潜力,而 CodeLLama 是 LLama 2 [55] 在开源代码上的微调版本。这些 LLM 在大量文本数据上预训练,然后在特定任务和数据集上进行微调,这些数据集通常包含来自不同编程语言的代码。此外,预训练的 LLM 已展现出革新传统软件任务的潜力,例如代码生成 [8]、修复 [41], [63] 和漏洞检测 [50]。

上下文学习(ICL)

基于预训练的知识,LLM 可以利用各种规范语言编写的现有人类属性。然而,由于预训练数据的限制以及训练所需的努力,LLM 可能无法包含实时信息。为了解决这一问题,提出了上下文学习(ICL)机制,使 LLM 能够从最新的对话或任务上下文中学习 [46], [67]。本质上,上下文学习是一种专门的少量学习 [7],基于少量示例或少量数据来学习新任务。

与微调 [59] 不同,本研究中我们利用最先进的 GPT-4 模型 [4] 的上下文学习能力,用于检索增强型属性生成。

III. PropertyGPT 概述

在本节中,我们介绍了 PropertyGPT 的整体设计,该工具利用 LLMs 的上下文学习(ICL)能力,将现有的人编写的属性迁移并生成用于形式化验证未知代码的定制属性。从高层来看,PropertyGPT 将一段目标智能合约代码作为输入,并最终生成其对应的属性以及验证结果。
![[Pasted image 20250324104707.png]]

如图 1 所示,PropertyGPT 包含八个主要步骤:

  1. PropertyGPT 首先通过嵌入其对应的关键代码创建一个参考属性的向量数据库。需要注意的是,参考属性本身不会被嵌入,因为它们不是搜索关键字。
  2. 给定一段待测试的目标代码(通常是一个函数),PropertyGPT 查询向量数据库以
  3. 检索所有在阈值范围内的相似代码,并将每段代码映射到其原始参考属性。
  4. 所有参考属性随后在一个迭代循环中逐一与目标代码进行测试。
  5. 对于每个参考属性,PropertyGPT 使用生成提示(generation prompt)为目标代码生成候选属性。
  6. 该候选属性随后由编译器检查语法,如果不语法正确,则根据编译器反馈使用修订提示(revising prompt)进一步修正。
  7. 最终,我们获得了一份可编译的属性列表,并根据加权算法对这些属性进行排名,以选出前 K 个合适的属性。
  8. 这些属性最后由我们的专用验证器进行正式验证,旨在发现智能合约漏洞。

为了探索和理解 PropertyGPT 的细节,我们首先在 §IV 中介绍其属性规范语言。接着,在 §V 中描述基于 LLM 的属性生成和优化的主要过程。最后,在 §VI 中,我们将生成的属性与专用的形式化验证器连接起来,以进行属性验证。

IV. 属性规范语言

为了弥合 §V 中的属性生成与 §VI 中的形式化验证之间的差距,我们在本节提出了一种中间语言来指定智能合约的属性。
![[Pasted image 20250324105441.png]]

图 2 展示了我们的属性规范语言(PSL),它扩展了流行的智能合约编程语言 Solidity。在 Solidity 中,智能合约(SC)由一组记录持久程序状态的状态变量和允许用户交互的一系列公共函数组成。符号 ▷◁ 表示一组算术、比较或逻辑运算符,即 {+, −, /, >, <, ==, ! =, >=, <=, &, ||}。布尔表达式 bool expr ⇂(v∗,C∗) 表示涉及状态变量和常量值的布尔表达式。PSL 包括三种不同目的的属性:

  • 不变量 是在合约执行过程中始终成立的属性,定义在状态变量上;
  • 函数前置/后置条件 是可以用霍尔三元组 {p∗}f unc{q∗} 表达的属性,用于检查参数和状态变量的修改是否满足功能需求;
  • 基于场景的属性 定义在受限环境中,可以通过实施不同的假设和定制断言实现为不同的规则。

值得注意的是:
当前的 PSL 原型支持安全性属性,因为相比于活性属性,它们与安全性更为相关。

PSL 相较于现有工作 [10], [60] 在自动化形式化验证方面带来了多项优势。VeriSol [60] 要求基于断言的属性必须插入智能合约代码中。Certora 的验证语言(CVL)由一个闭源的商业验证工具提供支持,这限制了我们使用 CVL 构建 PropertyGPT 自包含管道的能力。此外,CVL 的学习曲线非常陡峭,因为它不仅需要关于智能合约的知识,还需要掌握一些非平凡的技术,例如使用钩子进行数据读取或写入,以处理智能合约的低级执行模型(CVL 的这一局限性示例见附录 B)。相比之下,编写或维护 PSL 规范更容易,因为它们与 Solidity 语言 [47] 具有类似的结构。需要注意的是,PSL 的语义将在 §VI-B 中说明。

V. 属性生成与优化

通过在 §IV 中介绍的目标 PSL,我们的目标是为给定代码自动生成用 PSL 编写的属性。生成的属性是基于 LLM 的迁移学习结果,这些迁移学习来源于现有的人编写的属性,而这些属性可以用任何规范语言编写,不仅限于 PSL,例如 CVL。PropertyGPT 能够实现如此强大的迁移学习,其根本原因在于 LLM 在上下文学习中的能力(见 §II)。然而,我们需要设计一个新颖的流程来促进这一过程。我们的想法是模仿自然语言处理 [29] 或代码 [49] 领域中的 RAG(检索增强生成)过程,利用检索到的参考属性来增强新属性的生成。如前所述,在图 1 中,我们首先详细说明 PropertyGPT 中的检索增强型属性生成过程(见 §V-A)。之后,PropertyGPT 迭代修订 LLM 生成的属性以修复其编译错误(见 §V-B)。此外,我们设计了一种加权算法,帮助 PropertyGPT 对所有可编译的属性进行排名,并仅选出前 K 个合适的属性以供验证器在 §VI 中进行验证。

A. 检索增强型属性生成

在此部分,我们重点讨论从图 1 中步骤 2 到步骤 5 的基本检索增强型属性生成过程。但整个属性生成过程还包括属性 修订排名,分别将在 §V-B 和 §V-C 中介绍。

1. 知识预处理

RAG 系统中的一个关键步骤是首先构建知识库,通常是一个向量数据库 [49]。在 PropertyGPT 的场景中,我们的目标不是从现有的人编写的属性中提取“知识”,而是将它们用作 LLM 上下文学习的参考属性。因此,我们直接使用来自人编写的参考属性的原始信息来构建向量数据库。如图 1 所示,我们将现有属性对应的关键代码嵌入,以构建 RAG 使用的搜索键。需要注意的是,参考属性本身不会被嵌入,因为它们无法通过测试代码进行查询。
![[Pasted image 20250324105524.png]]

2->3 相似示例检索

借助向量数据库,我们可以根据目标代码检索相似的参考属性,从而为后续步骤启用一次性 LLM 学习。为此,在步骤 2 中目标代码也被嵌入,并计算其与数据库中所有向量的点积 [24]。然后检索出点积最高的相似代码,并返回其对应的属性作为步骤 3 的结果。在这里,我们使用一个保守的代码相似性阈值(例如 0.8),以限制检索到的参考属性数量(通常为 10 到 20 条属性),这是可以接受的,因为 PropertyGPT 最终会在 §V-C 中使用加权算法对生成的属性进行排名,并仅选择前 K 个属性作为最终结果。

4->5 上下文学习

所有参考属性随后在一个迭代循环中逐一与目标代码进行测试。对于每个参考属性,PropertyGPT 使用生成提示为目标代码生成候选属性,将参考属性作为一次性示例。
具体来说,有两种类型的生成提示:一种用于生成全局、跨函数规则属性(如图 3 所示),另一种用于生成函数级别的前置/后置条件(如图 4 所示)。
![[Pasted image 20250324105607.png]]

![[Pasted image 20250324105626.png]]

这里我们省略了合约级别不变量的生成提示模板,因为它们通常形式较简单,等同于每个公共合约函数的一次性前置/后置条件。两种提示模板均包含三个部分:第一部分详细说明生成指令,第二部分列出代码和参考属性,第三部分定义输出属性格式。特别是,我们在图 3 中提供了一个规则示例,以帮助 LLM 理解规则属性的语法;而在图 4 中,由于不变量/条件的语法相对简单,我们直接使用自然语言指令指定其语法。此外,由于规则属性是跨函数的,我们在图 3 所示的提示模板中不仅提供了函数代码,还提供了整个合约代码。

为了确定应使用哪种生成提示,PropertyGPT 借助检索到的参考属性类型。如果参考属性是规则,则 PropertyGPT 使用第一种提示模板生成属性;否则,如果参考属性被分类为前置/后置条件,则 PropertyGPT 使用第二种提示模板。

B. 修订属性以修复编译错误

虽然基本的属性生成过程相对简单,但一个特别的挑战是如何确保生成的属性是可编译的。为了解决这一挑战,我们受到 [28], [52] 的启发,并利用编译器和静态检查的反馈迭代修订属性,直到属性可编译或达到最大尝试次数为止,如步骤 6 所示。

利用编译器反馈

我们的 PSL 编译器(详见附录 C 中的编译细节)在属性无法成功编译时提供编译错误信息,包括详细的错误位置和原因。因此,PropertyGPT 利用此反馈指导 LLM 迭代修订属性。
![[Pasted image 20250324105751.png]]

具体来说,我们设计并使用了一个通用提示模板(如图 5 所示)来修订规则属性;请注意,修订函数前置/后置条件的提示与此类似,因此未在此展示。在这个提示中,我们要求 LLM 首先理解生成的属性代码,识别并修复错误,在整个过程中保持风格一致性,并最终确保修订后的规则代码符合特定的格式要求。我们设置了最大尝试次数的阈值,以避免无限循环。在实验中,如 §VIII-D 所示,我们发现 74% 的属性无需修订(63%)或仅需一次尝试即可成功编译,且 84% 的所有属性在五次尝试内成功修订。这使得迭代过程具有可控性。

使用静态检查

然而,我们发现即使编译器未报告任何错误,这并不意味着生成的属性完全正确。一个显著的问题是,LLM 生成的属性可能未能包含目标函数,从而使该属性变得毫无意义。为了解决这一问题,我们对上述步骤中通过的所有可编译属性进行额外的静态检查。如果 PropertyGPT 检测到某个属性缺少目标函数,它会使用一种特殊的提示模板(如图 6 所示,仅列出规则属性的场景,类似于图 5)。
![[Pasted image 20250324105818.png]]

此模板与通用修订提示类似,但明确指出了规则未能测试核心函数执行的问题。通过这种方式,我们不仅确保生成的属性语法正确,而且在功能上也具有意义。

C. 排名前 K 个合适的属性

另一个挑战是如何从所有可编译的属性中选择合适的属性作为最终生成结果。为此,我们提出了一种加权算法对所有生成的属性进行排名,如步骤 7 所示。具体来说,我们基于以下四个嵌入式指标对属性进行排名:

  • X raw ( f , g ) X_{\text{raw}}(f, g) Xraw(f,g):合约代码 f f f g g g 之间的相似性。
  • X summary ( f , g ) X_{\text{summary}}(f, g) Xsummary(f,g):代码 f f f g g g 的高层次功能摘要之间的相似性。
  • Y raw ( ϕ 1 , ϕ 2 ) Y_{\text{raw}}(\phi_1, \phi_2) Yraw(ϕ1,ϕ2):原始属性 ϕ 1 \phi_1 ϕ1 ϕ 2 \phi_2 ϕ2 之间的相似性。
  • Y summary ( ϕ 1 , ϕ 2 ) Y_{\text{summary}}(\phi_1, \phi_2) Ysummary(ϕ1,ϕ2) ϕ 1 \phi_1 ϕ1 ϕ 2 \phi_2 ϕ2 的高层次属性摘要之间的相似性。

需要注意的是,我们引入了 X summary X_{\text{summary}} Xsummary Y summary Y_{\text{summary}} Ysummary 来应对相同功能代码或相同语义属性可能存在多样性的情况,其中高层次的自然语言摘要是通过大型语言模型为给定代码或属性生成的。

对于未知代码 f f f,假设其生成的属性为 ϕ 1 \phi_1 ϕ1,对应参考代码 g g g 的属性为 ϕ 2 \phi_2 ϕ2,我们使用以下加权算法对 ϕ 1 \phi_1 ϕ1 进行评分:

Score ( f , ϕ 1 ) = α ⋅ X raw ( f , g ) + β ⋅ X summary ( f , g ) + γ ⋅ Y raw ( ϕ 1 , ϕ 2 ) + η ⋅ Y summary ( ϕ 1 , ϕ 2 ) \text{Score}(f, \phi_1) = \alpha \cdot X_{\text{raw}}(f, g) + \beta \cdot X_{\text{summary}}(f, g) + \gamma \cdot Y_{\text{raw}}(\phi_1, \phi_2) + \eta \cdot Y_{\text{summary}}(\phi_1, \phi_2) Score(f,ϕ1)=αXraw(f,g)+βXsummary(f,g)+γYraw(ϕ1,ϕ2)+ηYsummary(ϕ1,ϕ2)

其中, α , β , γ , η \alpha, \beta, \gamma, \eta α,β,γ,η 是系数,且满足 α + β + γ + η = 1 \alpha + \beta + \gamma + \eta = 1 α+β+γ+η=1

为了调整这些系数,我们训练了一个线性回归模型以近似实际属性得分 Score ^ ( f , ϕ 1 ) \hat{\text{Score}}(f, \phi_1) Score^(f,ϕ1),详情见附录 D。在本研究中,为简单起见,我们假设 Score ^ ( f , ϕ 1 ) = Y summary ( ϕ 1 , ϕ ^ 1 ) \hat{\text{Score}}(f, \phi_1) = Y_{\text{summary}}(\phi_1, \hat{\phi}_1) Score^(f,ϕ1)=Ysummary(ϕ1,ϕ^1),其中 ϕ ^ 1 \hat{\phi}_1 ϕ^1 ϕ 1 \phi_1 ϕ1 对应的真实属性。我们在 PropertyGPT 生成的 3,622 条属性上进行了初步实验,结果表明最优权重为: α : 0.134 \alpha: 0.134 α:0.134, β : 0.556 \beta: 0.556 β:0.556, γ : 0.141 \gamma: 0.141 γ:0.141, η : 0.168 \eta: 0.168 η:0.168

因此,不同得分的属性按降序排列,我们认为排名较高的属性更有可能对验证器的验证过程具有重要意义。

VI. 属性验证

PropertyGPT 生成的属性不仅可编译且适当,而且还可以被验证。
![[Pasted image 20250324105858.png]]

图 7 展示了我们属性验证过程的工作流程。我们的验证器接受用 Solidity 编写的智能合约及其对应的 PSL 规范。我们采用前向符号执行对每个合约语句进行最强后置条件分析。随后,我们进行模块化验证,以确定这些形式规范是否已准确地在智能合约中实现,并在属性成立时生成证明。如果属性被违反,我们使用有界模型检查来验证这些被违反的属性是否确实未在合约执行期间得到满足。在遇到反例时,我们可以确信地得出属性未能成立的结论,这表明智能合约中存在漏洞,需要进一步的手动验证。

A. 智能合约执行建模

智能合约执行的运行时行为依赖于存储在区块链中的持久合约状态、交易环境信息以及待执行的具体合约语句。持久状态由一组合约状态变量维护。交易消息包括当前区块时间戳、调用者、被调用的合约及其被调用的方法。给定一组合约语句 S = [ s ] S = [s] S=[s],每条语句的执行可以建模为一个霍尔三元组 { δ } s { δ ′ } \{\delta\} s \{\delta'\} {δ}s{δ},其中 δ \delta δ δ ′ \delta' δ 分别表示执行 s s s 前后的程序状态。与传统程序不同,智能合约执行不会崩溃。任何意外行为都会导致智能合约交易回滚,使合约状态保持不变。这种回滚行为可能会影响可用性(例如拒绝服务),但通常不会对智能合约的安全性构成威胁,因此我们将其排除在分析之外。

B. 验证技术

我们采用智能合约的小步操作语义来正式验证不变量、函数前置/后置条件和规则。读者可以参考 KSolidity [23] 获取详细的操作语义。

函数前置/后置条件验证

给定一个函数 f f f,令 p p p q q q 分别为其前置条件和后置条件。规范 { p } f { q } \{p\} f \{q\} {p}f{q} 可被证明当且仅当下列谓词成立:
∀ δ ∈ Δ , sp ( f , p ∩ δ )    ⟹    q \forall \delta \in \Delta, \text{sp}(f, p \cap \delta) \implies q δΔ,sp(f,pδ)q
其中, Δ \Delta Δ 包含所有可行的合约状态。

我们省略了合约不变量的验证细节,因为不变量可以被视为一种函数级别规范的变体,对于每个合约函数都成立,具有相同的前置条件和后置条件。

规则验证

给定一个基于规则的属性 rule,其用户提供的假设 δ \delta δassume 语句中声明,断言 q q qassert 语句中声明。该规则成立当且仅当下列谓词成立:
sp ( rule , δ )    ⟹    q \text{sp}(\text{rule}, \delta) \implies q sp(rule,δ)q
需要注意的是, δ \delta δ 不总是可行的合约状态。

我们利用源代码级别的符号执行对 Solidity 智能合约进行最强后置条件分析。与现有研究 [31] 不同,我们的新颖符号执行方法实现了全面的小步语义,能够对现实世界中复杂的智能合约进行自动化分析。虽然 SolSee [31] 在 Solidity 智能合约的符号执行方面取得了进展,但它缺乏对智能合约中常用的一些关键特性的支持,例如复杂表达式的聚合效应以及复杂继承关系中的多态处理。我们通过严格遵循 Solidity 编译器的实践解决了这些限制,确保复杂表达式的精确语义。例如,表达式按照编译器规定的从左到右顺序进行求值。此外,我们的方法在智能合约的编译和执行阶段都能准确解析多态性。为了模拟实际的合约执行,我们的符号执行方法维护了一个全面的函数签名列表,并重新访问合约继承链,以确定模糊调用(如 super().call(),其中 super 指代未知父合约)的确切函数实现。

为应对智能合约的复杂性,我们实现了几种过度近似技术来处理未知或非线性操作语义。
首先,在验证阶段,对链上智能合约的函数调用行为是未知的,因此我们假设所有链上调用成功,但将其返回数据符号化以适应任何可能的结果。这种方法是必要的,因为链上合约可能不是开源的,它们的跨合约交互可能过于复杂,超出了我们当前研究的范围。其次,非线性原生函数(如 sha3,用于计算字符串的哈希值)难以精确建模。为此,我们使用未解释函数 [19] 来捕获其主要特性,例如将 sha3 视为一个单射函数。

我们采用了模块化验证和有界模型检查。在模块化验证期间,我们通过对所有状态变量进行符号化来提升所有状态约束。当规范属性相应成立时,可以安全地确保正确性。否则,我们进行有界模型检查,系统地探索所有可行状态以找到违反被验证属性的反例。任何被违反的属性及其反例都将被手动调查以确认漏洞的存在,类似于 SmartInv [59] 中使用的方法。有界模型检查的深度默认限制为三,我们在未终止执行的情况下最多允许五次循环迭代。

VII. 实现与设置

我们用约 3000 行 Python 代码实现了基于 LLM 的属性生成模块,同时用约 38000 行 C++ 代码实现了对 PSL 属性规范的语法支持和验证功能。此外,为了将符号执行应用于不同版本 Solidity 编写的智能合约,我们开发了一个转换器,将 Solidity 版本 0.6.x 和 0.7.x 中编写的智能合约映射为与最新 Solidity 版本 0.8.x 兼容的抽象语法树(AST),并对它们的语法和语义差异进行了系统性研究。我们使用 Z3 求解器(版本 4.11.2)来处理路径可行性检查和属性可满足性检查中的符号约束。

A. 属性知识收集

为了获得高质量的人类编写属性作为上下文学习的知识库,我们系统性地分析了 Certora 平台上的 61 份审计报告。这些报告由专家编写了用于促进智能合约形式化分析的属性规范,并于 2019 年至 2023 年间发布。通过进一步调查,我们移除了 38 个无法获取合约代码和原始属性的项目,最终收集了 23 个 Certora 项目,包含 623 条人类编写的属性,这些内容将在附录 A 的表 VII 中详细列出。需要注意的是,对于选定的项目,无论其在特定审计项目中是否被违反,所有人类编写的属性都被收集。

为了研究这些属性的特征,我们采用了 sklearn 库中的亲和传播聚类算法 [18],基于属性之间的成对嵌入相似性来识别属性类别。具体来说,我们进行了一些初步实验,发现以下设置 AffinityPropagation(damping=0.5, preference=-75, random_state=5) 能够为属性聚类提供良好的结果。
![[Pasted image 20250324110023.png]]

图 8 展示了六个聚类的分布,每个聚类用不同颜色标记。然而,显然聚类之间存在重叠,尤其是聚类 #3 和 #5。

![[Pasted image 20250324110044.png]]

此外,我们对所有聚类进行了研究,并按照表 I 对人类编写的属性进行了以下分类。属性分为六类:

  • DeFi:涉及对其核心协议组件的管理,包括储备金、抵押品和流动性池;
  • Token:这是整个 DeFi 生态系统的基石,规定了标准行为(如代币余额)和关键操作(如转账和铸造);
  • Arithmetic:专注于数值转换的正确性和资产分割的一致性;
  • Usability:检查包含基于时间戳约束的操作(时间相关使用)和基于合约状态约束的操作(状态依赖使用)的有效性;
  • Governance:在去中心化应用的管理中扮演重要角色,通常通过投票机制实现,涉及投票权转移给委托人和双重投票问题等;
  • Security:检查是否存在常见的漏洞类型,包括抢先交易和溢出。

B. 实验设置

我们通过 OpenAI 提供的 API gpt-4-0125-preview 使用大型语言模型 GPT-4-turbo。关于模型配置,我们遵循默认设置,其中温度参数为 0.8,top-p 为 1,频率惩罚和存在惩罚均为 0,最大响应长度为 2000。此外,我们使用 OpenAI 提供的预训练模型 text-embedding-ada-002 计算所有嵌入相似性。在属性生成过程中,我们将修订尝试次数限制为九次,以控制 LLM 的使用成本。所有实验均在 Docker 环境中进行,运行于 Ubuntu 20.04 操作系统,配备 Intel Core Xeon 2.2 GHz 处理器和 2GB 内存。

VIII. 评估

在本研究中,我们旨在回答以下研究问题(RQs):

  • RQ1(属性生成):PropertyGPT 在为智能合约生成属性时的准确性如何?
  • RQ2(漏洞检测):PropertyGPT 在发现智能合约漏洞方面的有效性如何?它能否达到最先进的结果?
  • RQ3(泛化能力):PropertyGPT 是否具备足够的泛化能力以实现强大的迁移学习?
  • RQ4(影响因素):哪些因素会影响 PropertyGPT 的性能?
  • RQ5(实际影响):PropertyGPT 在现实世界的智能合约项目中发现零日漏洞的表现如何?

方法论

为了回答 RQ1,我们将 Certora 属性划分为测试数据集和“训练”数据集作为知识库。我们指示 PropertyGPT 使用知识库中的智能合约及其属性,为测试数据集中的智能合约生成属性。我们将 PropertyGPT 生成的属性与真实的人类编写的属性进行比较,以研究其有效性。具体来说,我们随机选择了九个(40%)Certora 项目作为测试数据集,并从每个项目中选取了 10 条属性。因此,我们的测试数据集包括来自九个项目的 90 条真实属性。在实验过程中,PropertyGPT 首先提取真实属性所指定的目标函数代码,然后查询知识库以启用上下文学习(ICL)来自动化属性生成。

为了回答 RQ2,我们将 PropertyGPT 与 SmartInv [59] 进行比较,后者是与我们工作同期的研究,于 2024 年 5 月发表。我们联系了作者以获取他们的源代码和基准测试数据集,其中包括 60 个遭受重大损失的攻击事件项目。在审查他们的基准测试后,我们发现了几个问题。在列出的案例中,有 2 个重复,9 个缺乏公开的漏洞交易(例如 sherlockYields),2 个未开源,2 个代码不完整。在剩余的案例中,11 个是可以通过添加广泛使用的 nonReentrancy 修饰符轻松修复的重入攻击。此外,8 个案例涉及价格操纵攻击,这可能难以通过 SmartInv 生成的简单不变量属性识别。例如,Tolmach 等人 [53] 提出了一种半自动的形式化复合分析方法,用于检测 DeFi 协议中的公平性问题,而其他方法则使用运行时监控 [62] 来识别攻击行为或静态分析 [26] 来标记符合预定义模式的易受攻击代码。通过对他们的基准测试的深入分析,我们从 SmartInv 基准测试中挑选了 24 个攻击事件用于我们的评估。此外,我们还将 PropertyGPT 与最先进的工具 [2], [16], [38], [50] 在知名智能合约 CVE 上进行了比较。截至 2024 年 4 月,共有 577 个智能合约 CVE,其中主要是 477 个整数溢出漏洞。为了避免偏差,我们随机选择了 13 个不同类型的 CVE:三个整数溢出案例、三个访问控制漏洞、四个其他逻辑错误等,详细信息见表 IV。
![[Pasted image 20250324110144.png]]

基准测试

![[Pasted image 20250324110158.png]]

如表 II 所示,我们使用 Certora 审计项目评估属性生成过程,并使用 SmartInv 研究的知名 CVE 和攻击事件项目测试 PropertyGPT 在漏洞检测中的适用性。此外,RQ3 和 RQ4 也使用相应的基准测试,细节将在后文详述。


A. RQ1:属性生成

我们在来自九个 Certora 项目的 90 条真实属性上评估了 PropertyGPT,以研究属性生成的有效性。
![[Pasted image 20250324110223.png]]

表 III 显示了 PropertyGPT 使用其余 Certora 属性作为知识库生成属性的结果。需要注意的是,此 RQ 仅衡量生成的属性是否与真实属性匹配,其中 FP 表示未匹配的属性。

前两列显示了项目名称和 Certora 专家编写的属性数量,即 #Property (Certora)。中间五列列出了 PropertyGPT 生成的属性数量,即 #Property (ours),与真实属性等价的真正例(TP)、生成的属性命中真实属性的数量 (#Hit)、遗漏的真实属性数量 (FN) 以及假阳性 (FP)。最后三列是召回率、精确率和 F1 分数指标,其中:
recall = # H i t # H i t + F N , precision = T P T P + F P , F1-score = 2 × recall × precision recall + precision \text{recall} = \frac{\#Hit}{\#Hit + FN}, \quad \text{precision} = \frac{TP}{TP + FP}, \quad \text{F1-score} = \frac{2 \times \text{recall} \times \text{precision}}{\text{recall} + \text{precision}} recall=#Hit+FN#Hit,precision=TP+FPTP,F1-score=recall+precision2×recall×precision

由于 Certora 属性是用专有的 Certora 验证语言(CVL)编写的,支持在 EVM 字节码级别对智能合约进行形式化验证,而 PropertyGPT 使用 PSL 在源代码级别促进属性公式化和验证,目前尚无自动化分析工具可用于这两种不同规范系统之间的等价性检查。因此,两名具有五年研究和审计经验的作者独立检查了 Certora 真实属性与 PropertyGPT 生成属性之间的等价性,第三名作者在出现分歧时进行仲裁。我们欢迎其他研究人员使用我们在 https://github.com/Pr0pertyGPT/PropertyGPT 发布的数据进行复制和验证。

表 III 显示,PropertyGPT 能够生成全面的属性,具有较高的召回率和合理的精确率。大多数生成的属性(26/42)是真正例,大多数真实属性(8/10)能够成功重现,达到了令人满意的召回率(0.80)、合理的精确率(0.64)和良好的 F1 分数(0.71)。深入到具体项目结果,PropertyGPT 能够重现四个项目的全部真实属性,包括 aave_proof_of_reservecelo_governanceousdsushi_benttobox。相比之下,PropertyGPT 仅重现了 openzepplin 的两个真实属性,导致最低的召回率和 F1 分数,尽管其精确率最高。我们调查了结果,发现这主要是因为 OpenZeppelin [3] 是一个基础合约库,几乎被所有现实世界的应用程序直接导入,客户端代码不太可能重新实现类似功能,从而导致可靠的参考属性稀缺。在精确率方面,opyn_gamma_protocol 的表现最差,仅为 0.47。我们调查了所有 16 个假阳性,后来发现其中 11 个假阳性实际上是适用于智能合约但未在 Certora 真实属性中记录的属性。

RQ1 回答:PropertyGPT 能够生成全面且高质量的属性,覆盖了人类专家判定的真实属性中 80% 的等效属性。此外,PropertyGPT 生成的额外属性(FP)通常也成立,补充了人类编写的属性。


B. RQ2:漏洞检测

我们研究了 PropertyGPT 在漏洞检测任务中的适用性,针对知名智能合约 CVE 和 SmartInv 研究的攻击事件项目。注意,为了模拟现实部署情况,我们根据 §VIII-D 的测量结果将 top-K 设置为 top-2,这是从本节开始的最佳配置。

CVE

![[Pasted image 20250324110248.png]]

表 IV 展示了 PropertyGPT 在检测 13 个智能合约 CVE 中的有效性。我们将 PropertyGPT 与 GPTScan [50] 和 Slither [16] 进行了比较。GPTScan 利用 LLM 的变量识别能力实例化高层次的逻辑漏洞检测模式,而 Slither 是一种流行的静态分析工具,用于检测多种常见漏洞类型。特别是,由于原始 GPTScan 仅涵盖十种逻辑漏洞类型,我们通过最新的无监督范式 [49] 对其进行了增强,并将增强版本称为 GPTScan+。此外,Manticore [38] 和 Mythril [2] 是两种字节码级别的符号执行工具,可自动化全面探索程序状态并生成智能合约漏洞利用。在表 IV 中,前两列列出了 CVE 名称及其漏洞类型,其余列显示了每种工具的检测结果。

表 IV 中的检测结果显示,PropertyGPT 的表现优于所有对比工具,检测出了 13 个 CVE 中的 9 个,其次是 GPTScan 检测出 5 个 CVE,Slither 仅检测出 1 个与 delegatecall 相关的 CVE,Mythril 检测出 3 个与溢出相关的 CVE,而 Manticore 未检测出任何 CVE。我们还调查了 PropertyGPT 未能检测出的剩余 4 个 CVE。目前尚不清楚有效的属性如何表达对正确随机性和 delegatecall 使用的期望。CVE-2018-17111 是由访问控制的误用而非缺乏访问控制引起的,这对 PropertyGPT 在属性生成过程中识别这种细微差异提出了相当大的挑战。

通过将新确认的漏洞代码和属性引入我们的知识数据库,可以进一步增强 PropertyGPT 的能力。如表 I 所示,Certora 专家编写的属性似乎缺乏对访问控制的支持,这可能会限制 PropertyGPT 在检测其他广泛存在的访问控制漏洞方面的有效性,尽管我们意识到 PropertyGPT 在上述 CVE 检测结果中已经表现出了一定的泛化能力。

攻击事件

![[Pasted image 20250324110330.png]]

表 V 显示了针对从 SmartInv 基准测试中精选出的 24 个攻击事件项目的评估结果。由于 SmartInv 的作者未分享其插桩后的漏洞合约代码,并且关于其生成的不变量属性的真实情况和原始实验结果也缺失,我们对 SmartInv 进行了定性而非定量的比较,这将在 §IX 中讨论。在表 V 中,前两列列出了项目名称和攻击造成的损失金额,其余列分别显示了检测结果、生成的属性数量、用于属性生成的时间以及形式化验证的时间。

PropertyGPT 成功识别了 24 个真实世界攻击事件中的 17 个漏洞,平均每个项目生成 16 条属性,花费约 12 分钟进行属性生成,仅需 34 秒进行形式化验证。对于 PropertyGPT 未能检测出的剩余 7 个项目,我们研究了其报告漏洞的根本原因。我们认识到,PropertyGPT 不支持智能合约的运行时上下文,而这可能在特定使用场景中对生成属性至关重要。例如,在 BGLD 项目中涉及的通缩代币滥用问题,我们将此留作未来工作。

RQ2 回答:PropertyGPT 能够有效检测简单和复杂智能合约中的漏洞。具体而言,PropertyGPT 在检测 13 个 CVE 中的 9 个方面表现突出,超越了当前最先进的工具。此外,PropertyGPT 在识别 24 个攻击事件中的 17 个逻辑漏洞方面取得了相对良好的结果。

C. RQ3:泛化能力测量

在 §VIII-B 中展示了有效的漏洞检测后,我们仍然对 PropertyGPT 是否具备足够的泛化能力以实现强大的迁移学习感兴趣。鉴于 PropertyGPT 的向量数据库是从 Certora 审计项目构建的,我们使用 RQ2 中的 CVE 和攻击事件数据集来衡量 PropertyGPT 在检索增强型属性生成过程中对完全不同的数据集进行迁移学习的泛化能力。

我们通过测试代码与检索到的参考代码之间的相似性间接衡量 PropertyGPT 在表 IV 和表 V 所示漏洞检测结果中的属性生成泛化能力。也就是说,如果相似性较低,则表明 PropertyGPT 的泛化能力更强。对于相似性指标,为了避免偏差,我们使用了两种流行相似性度量的平均值,即余弦相似性和词移距离(Word Mover’s Distance [64])。结果分别作为独立列呈现在表 IV 和表 V 中。

总体而言,我们发现所有 26 个成功案例(即 PropertyGPT 成功生成了正确的属性)的平均代码相似性为 0.68,范围在 0.64 到 0.73 之间;而对于所有 11 个失败案例(即 PropertyGPT 未能生成适当的属性或验证未成功),其平均相似性为 0.67,范围在 0.63 到 0.69 之间。这一结果有两个含义。首先,绝对相似性值处于合理范围内——既不太高(意味着测试代码与参考代码非常相似),也不太低(意味着向量数据库未能提供有效的参考案例),这表明 PropertyGPT 在分析完全不同的数据集时表现出足够的泛化能力。其次,失败案例的平均相似性仅略低于成功案例(0.67 对比 0.68),这表明失败并非由于 PropertyGPT 缺乏对新代码进行测试的泛化能力。

RQ3 回答:通过我们对测试代码与检索到的参考代码之间相似性的间接测量,PropertyGPT 在分析完全不同的数据集时表现出足够的泛化能力。


D. RQ4:影响因素

在我们的消融研究中,我们首先系统地探索了不同 Top-K 设置对属性选择过程的影响。
![[Pasted image 20250324110429.png]]

在 RQ1 中对相同的 Certora 项目进行了不同试验,在图 9 中,我们绘制了生成属性的召回率、精确率和 F1 分数。显然,所有指标均高于 0.5。更重要的是,当从 top-1 移动到 top-2 时,所有指标都有所增加,尽管精确率从 top-1(0.64)到 top-2(0.65)仅有轻微提升,之后精确率下降并最终在 0.60 左右波动。因此,为了提高效率,我们建议选择生成的 top-2 属性供外部社区专家或其他兼容的程序分析工具使用。

此外,我们深入研究了属性生成过程,重点关注使用编译器反馈信息的属性生成成功率和属性修复次数。
![[Pasted image 20250324110439.png]]

表 VI 显示,未经修订或修复的 GPT-4.0-turbo 的成功率为 63%,相比 PropertyGPT(87%)显著较低。
![[Pasted image 20250324110510.png]]

图 10 可视化了属性修复次数的分布,我们将修复次数限制为九次。可以看出,大多数可编译属性(84%)可以在不超过五次修复尝试的情况下生成。我们还调查了 PropertyGPT 未能修复的剩余 49 条属性,发现主要的编译器错误信息是使用了未声明的变量,这可能通过基于模式的方法 [27] 解决。

RQ4 回答:PropertyGPT 能够有效生成可编译的属性,84% 的所有属性在五次尝试内成功修订,最高成功率达到 87%。其中,top-2 属性在精确率和召回率之间实现了最佳平衡。

E. RQ5:实际影响

为了展示 PropertyGPT 识别零日漏洞的能力,我们在 Secure3 [45] 和 Code4Rena [12] 等流行平台托管的真实悬赏项目上运行了 PropertyGPT。PropertyGPT 成功为 4 个项目生成了 22 个漏洞发现,其中 12 个已被确认并修复。作为回报,我们从厂商处获得了总计 8,256 美元的漏洞赏金。在本节中,为了案例研究,我们列出了两个已修复的零日漏洞以进行负责任的披露,并出于对匿名政策的尊重,未提及这些项目的来源。
![[Pasted image 20250324110524.png]]

图 11 显示,withdrawForwardFee 函数包含一个关键漏洞,允许验证者提取超过其分配份额的转发费用,可能导致不公平的分配和资金损失。该漏洞的产生是因为函数未能根据验证者的比例份额跟踪和限制单个验证者的提取。它通过简单地将请求的提取金额 _amount 加到 totalValidatorForwardFeeWithdrawn 上来计算新的总提取费用(第 10-13 行),而没有考虑请求验证者的应得份额。唯一的检查是针对总收集的转发费用,确保新的总提取金额不超过此金额(第 11 行)。然而,这并不能阻止个别验证者提取超出其份额的金额。
![[Pasted image 20250324110534.png]]

PropertyGPT 通过生成和验证图 12 中列出的函数前置/后置条件检测到了该漏洞。前置条件(第 3-5 行)适用于该合约,因为它们准确捕捉了 onlyModifier 和其他两个 require 语句的约束。后置条件描述了预期功能。然而,其中一个后置条件(第 9 行)totalValidatorForwardFee - totalValidatorForwardFeeWithdrawn == old(totalValidatorForwardFee) - old(totalValidatorForwardFeeWithdrawn) - amount 不成立,从而识别出图 11 中的合约漏洞。
![[Pasted image 20250324110553.png]]

图 13 显示了一个易受攻击的 addEnvelope 函数,该函数未强制执行信封的唯一性(第 7 行),导致现有存储可能被任意覆盖。
![[Pasted image 20250324110632.png]]

图 14 展示了 PropertyGPT 生成的用于检测此类问题的属性。有趣的是,PropertyGPT 能够巧妙地构造多样化的输入数据(第 3-8 行)。当函数调用(第 13 行)成功时,我们检查条件(第 19 行),即相同 ID 的信封之前不存在且信封创建者等于当前调用者。换句话说,此条件不允许使用相同的信封 ID 调用 addEnvelope 函数,并确保 addEnvelope 的效果是将信封创建者设置为函数调用者。由于图 13 中的覆盖漏洞,此断言对该函数不成立。


F. 对有效性的威胁

内部有效性

我们在一个成熟的 Certora 属性数据集上评估了 PropertyGPT 的有效性。然而,Certora 风格的属性与 PropertyGPT 生成的 PSL 风格属性之间缺乏等价性检查工具。为缓解这一问题,三名作者独立审查了这些属性以确定其等价性,并发布了所有生成的属性及其对应的标记结果供公众使用。

外部有效性

我们在漏洞检测中的发现可能不适用于其他类型的智能合约和其他类型的合约漏洞。在本研究中,我们在涵盖多种漏洞的 13 个代表性智能合约 CVE 和 24 个不同应用领域的现实受害项目上评估了 PropertyGPT。此外,我们为高知名度项目生成了 24 个漏洞发现,其中 12 个已被确认并修复,获得了 8,256 美元的赏金奖励。因此,PropertyGPT 提供了一种实用的形式化验证技术,能够检测更广泛的智能合约漏洞。

IX. 相关工作

漏洞检测

许多自动化和半自动化的分析工具被提出用于检测智能合约漏洞。一方面,静态分析工具沿合约的抽象语法树分析代码序列 [16],或使用基于事实的转换和查询系统 [6], [57] 来标记与专家编写模式相匹配的弱点和漏洞。相比之下,模糊测试工具(fuzzers)在测试预言的支持下检查运行时行为,包括操作轨迹 [22], [39] 和执行效果 [35], [58] 以生成漏洞利用,通常比静态分析具有更高的精确率但较低的召回率。另一方面,形式化验证已被广泛应用于确保智能合约正确性的技术中。像 Manticore [38] 和 Mythril [2] 这样的自动化工具使用符号执行探索尽可能多的程序状态,通过一组预定义的检测规则识别易受攻击的行为。半自动化工具则需要用户提供规范属性,包括不变量 [56]、函数前置/后置条件 [60]、时序属性 [42], [48] 和其他定制规则 [10], [21]。

PropertyGPT 的独特之处在于它利用大型语言模型自动化属性生成,并提出了一种基于智能合约源代码级符号执行的强大验证器,支持检测广泛的合约漏洞。

属性生成

静态推理 [51], [60] 和动态推理 [33], [36] 已被应用于智能合约的属性生成,最近机器学习模型也被用于生成不变量属性 [32], [59]。VeriSol [60] 应用 Houdini 算法 [17] 从一组假设候选中推导出正确的不变量属性。SolType [51] 发现 Solidity 智能合约的类型不变量,要求开发者向合约添加细化类型注释。然而,它们的属性仅限于算术运算,以保护智能合约免受整数溢出和下溢的影响。InvCon [33] 及其后续工作 [36] 应用动态不变量检测和静态推理生成合约不变量和函数前置/后置条件,但需要合约具备足够的交易历史。

我们的工作与基于机器学习的方法的努力一致,例如 Cider [32] 和 SmartInv [59]。Cider 使用深度强化学习方法,但仅生成可能的不变量属性,而 PropertyGPT 可以通过验证器验证所有生成的属性。SmartInv 和 PropertyGPT 都由大型语言模型驱动。PropertyGPT 与 SmartInv 的不同之处在于我们使用上下文学习而非微调,且生成的属性超越了函数前置/后置条件。

基于 LLM 的安全系统

通过结合 LLM,各种安全任务得到了更有效的解决。Sun 等人 [50] 提出了 GPTScan,Li 等人 [30] 提出了将 LLM 与静态程序分析相结合的方法,用于漏洞检测,覆盖了比传统工具更多的漏洞类型。除了漏洞检测,LLM 还被用于其他安全任务。Deng 等人 [13] 提出了 TitanFuzz,利用 LLM 引导对 PyTorch 和 TensorFlow 等深度学习库的模糊测试。他们还提出了 FuzzGPT [14],用于合成异常程序以发现漏洞。ChatAFL [37] 利用 LLM 通过解释协议文档来引导协议模糊测试。此外,LLM 已被应用于程序修复任务,如 ACFix [65] 和 ChatRepair [63]。


X. 结论

本文提出了通过利用 LLM 的上下文学习能力实现检索增强型智能合约属性生成的方法。我们将此方法实现为一个名为 PropertyGPT 的工具,并解决了确保生成属性可编译、适当且运行时可验证的挑战。我们的评估结果表明,PropertyGPT 能够检测许多现实世界的合约漏洞,特别是在高知名度项目中,累计获得了厂商提供的 8,256 美元漏洞赏金。在未来的工作中,我们计划在方法中纳入更全面的合约上下文信息(如文档),并从各种来源丰富 PropertyGPT 的属性知识。

附录

A. 补充材料

表 VII 列出了所有 61 个 Certora 项目的原始信息,其中我们收集了 23 个具有可用代码和属性的项目。
![[页面提取自-Liu 等 - 2024 - PropertyGPT LLM-driven Formal Verification of Sma.png]]


B. CVL 示例

根据 §IV 的描述,我们在此提供一个 CVL 示例,以说明其对智能合约低级执行模型而非高级执行模型的依赖性。
![[Pasted image 20250324110745.png]]

图 15 展示了 ERC20Votes4 的部分 CVL 规范。它规定了更新映射 mapping(address => Checkpoint[]) private _checkpoints 中字段 votes 的语义行为。该数据结构用于记录用户投票。本质上,该规范指出,在用户投出新票后,记录的用户投票应相应更新,总票数应重新计算,并且最后一个索引(即用户检查点数组的大小)也应相应更新。

根据我们的经验,编写此类规范对于智能合约开发者来说并非易事,因为图 15 要求为复杂数据结构的每个字段明确定义语义。此外,显式声明低级操作码(如 sstore)并指定相关字段项的变量类型(例如,STORAGE 表示存储变量)会使用户承担智能合约数据的细微且繁琐的细节。相比之下,PSL 扩展了 Solidity,其执行遵循经过深入研究的 Solidity 语义,允许用户编写规范而无需了解验证过程的复杂细节。


C. PSL 规范的编译阶段

PSL 是作为 Solidity 的一种变体开发的,我们通过添加新的语法结构并对 Solidity 编译器施加某些约束来支持用 PSL 编写的规范的编译。具体来说,我们通过修改 Solidity 编译器 v0.8.17 添加了以下关键字:invariant 用于声明不变量规范代码块,rule 用于声明自定义规则代码块,以及 preconditionpostcondition 用于函数前置条件和后置条件。我们还添加了关键字 assume 以用于验证目的(参见图 2)。此外,我们实现了检查机制,仅允许在不变量、前置条件和后置条件规范中使用表达式语句。通过这些措施,我们定制的 PSL 编译器可以接受用 PSL 编写的规范并验证其语法正确性。


D. 通过训练线性回归模型学习最优系数

根据 §V-C 的介绍,本节详细说明了如何训练线性回归模型以学习最优系数,这对于排名前 K 个合适的属性作为最终属性生成结果至关重要。

数据准备

我们使用 PropertyGPT 生成了总计 3,622 条属性生成记录。具体来说,对于每次属性生成,我们从 Certora 数据集中随机选择一个已知的目标代码 f f f,然后 PropertyGPT 为其生成一条规则属性 ϕ 1 \phi_1 ϕ1。我们测量了 X raw ( f , g ) X_{\text{raw}}(f, g) Xraw(f,g) X summary ( f , g ) X_{\text{summary}}(f, g) Xsummary(f,g) Y raw ( ϕ 1 , ϕ 2 ) Y_{\text{raw}}(\phi_1, \phi_2) Yraw(ϕ1,ϕ2) Y summary ( ϕ 1 , ϕ 2 ) Y_{\text{summary}}(\phi_1, \phi_2) Ysummary(ϕ1,ϕ2)。此外,我们计算了实际得分 Score ^ ( f , ϕ 1 ) = Y summary ( ϕ 1 , ϕ ^ 1 ) \hat{\text{Score}}(f, \phi_1) = Y_{\text{summary}}(\phi_1, \hat{\phi}_1) Score^(f,ϕ1)=Ysummary(ϕ1,ϕ^1),其中 ϕ ^ 1 \hat{\phi}_1 ϕ^1 是 Certora 数据集中 f f f 的已知规则属性。我们的训练目标是利用 §V-C 中提到的四个特征生成 Score ( f , ϕ 1 ) \text{Score}(f, \phi_1) Score(f,ϕ1) 以逼近 Score ^ ( f , ϕ 1 ) \hat{\text{Score}}(f, \phi_1) Score^(f,ϕ1)

模型训练

我们使用上述数据训练了一个普通最小二乘法(OLS)线性回归模型,并使用多个指标评估了模型性能:平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、决定系数(R²)、平均绝对百分比误差(MAPE)和平均偏差误差(MDE)。最终,我们获得了以下权重系数和性能结果:

  • 系数 α : 0.134 \alpha: 0.134 α:0.134, β : 0.556 \beta: 0.556 β:0.556, γ : 0.141 \gamma: 0.141 γ:0.141, η : 0.168 \eta: 0.168 η:0.168
  • 性能指标:MAE: 0.0239, MSE: 0.0008, RMSE: 0.0291, R²: 0.1294, MAPE: 2.7810, MDE: -0.0022

这些系数设置达到了相对较好的性能。此外,我们进行了其他初步实验,发现减少预测模型中的特征数量会导致性能指标下降。因此,我们认为所选的四特征组合能够以较高的准确性对生成的属性进行排名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值