抽象账户是什么

抽象账户(也有叫合约钱包)是 EIP-4337 提案提出的一个标准。简单来说就是通过智能合约来实现一个“账户(account)”,在合约中自行实现签名验证的逻辑。这样,就使得该合约拥有了“签发交易”的能力。通过抽象账户签发的“交易”我们叫做用户操作(UserOperation,简称Op)。用户对Op进行签名以后,将其发给一个叫Bundler的链下程序,它负责将所有抽象账户所提交的Op打包,然后提交到链上合约EntryPoint中。EntryPoint合约收到Op后,会调用对应的抽象账户来验证其签名,验证通过后会将Op中的calldata取出,对抽象账户进行调用。整个简化版的流程就是这样,省略了诸如paymaster和aggregator之类的角色,想要更全面的了解的话可以阅读以下的文章。

参考文章:

当你阅读完上面的文章后,此时你应该对抽象账户有了一个大概的了解了,这时我们再来简单整理一下整个业务流程吧。

流程如下:

  1. 用户将 Op 进行签名,并发送给 Bundler;
  2. Bundler 调用 Entry Point 中的 handleOps 函数;
  3. EntryPoint 将 UserOperation 作为参数调用 Wallet Contract 中的 validateUserOp,验证所有需要验证的交易。只有在验证成功的情况下才会继续执行后续操作;
  4. 此时 Entry Point 会先确认 UserOperation 中指定的 Paymaster 的状况,例如是否拥有足够的 ETH 来支付这笔交易的手续费;
  5. 接着,Entry Point 调用 Paymaster Contract 中的 validatePaymasterUserOp,确认 Paymaster 愿意支付这笔交易的手续费。如果 Paymaster 愿意支付,那么这笔交易就会继续,否则就会失败;
  6. 然后调用 Wallet Contract 并执行 UserOperation 本身指定的内容;
  7. 接着调用 Paymaster Contract 的 Post-Op,Post-Op 处理直接赞助或划扣用户 ERC20 代币代付等自定义逻辑;
  8. Entry Point 在 Paymaster 质押的 ETH 余额中扣减交易所需支付的 gas fee;
  9. 最后 Entry Point 收集所有交易所需支付的 gas fee 总额 refund 给 Bundler ,交易执行完毕。

同时引用两张Stackup的流程图,帮助大家更直观的了解整个过程:

整个抽象账户项目的架构,各个角色之间的关系:

当用户发起一笔Op的时候,整个业务流程是如何运作的:

在审计过程中需要注意的安全问题

针对抽象账户这个项目的特点,在审计过程中有一些关键点需要特别留意一下。当然,具体的情况根据每个项目的不同而不同,这里只是抛砖引玉,审计工作还是要落实到具体的代码上。

签名问题

抽象账户发送一笔Op,需要进行两次签名检查。

  1. 第一个是在抽象账户中对Op进行签名检查,确保该Op是对应的抽象账户签发的。这个检查是必须要的。
  2. 第二个是用户使用paymaster的时候,需要提供paymaster所签名的信息进行校验。这个检查只有在使用paymaster服务的时候需要进行,不是必须的。

当进行以上这两种的签名与检查时,我们需要注意以下的问题:

  1. 签名是否能够避免重放攻击:具体包括抽象账户的重放攻击,跨链的重放攻击,针对仿盘的重放攻击,硬分叉的重放攻击。在进行审计时要留意签名内容是否包含抽象账户的 nonce 值, chianID,项目合约地址等信息。
  2. 签名的打包方式:在对签名内容进行打包时是否严谨,是否会出现不同的Op进行打包后得到相同字节码的情况。
  3. 抽象账户的签名验证实现:由于Op的签名是需要抽象账户自行实现的,需要针对其具体的实现方法进行分析,确保验证签名的过程严谨准确。

gas计算问题

Gas计算问题始终贯穿整个项目,Op 中采用了多个变量来规定gas上限,gas priority,gas 价格等。具体可以参考以下样例:

  1. UserOperation 结构体,用于表示用户在智能合约中的操作请求:
  2. - sender:发送此请求的账户地址。
  3. - nonce:请求的唯一标识符,用于防止重复请求攻击。
  4. - initCode:如果设置了此字段,则表示要创建一个新的账户合约,并将其初始化为指定的字节码。
  5. - callData:要在此操作期间执行的方法调用数据。
  6. - callGasLimit:用于限制此调用允许使用的最大 gas 数量。
  7. - verificationGasLimit:用于验证此用户操作是否有效的所需 gas 量。
  8. - preVerificationGas:在 handleOps 方法中计算 gas 费用之前,添加到付款总额中的附加 gas 数量。这是为了覆盖批处理的开销。
  9. - maxFeePerGas maxPriorityFeePerGas:与 EIP-1559 中的 gas 相关参数相同,用于计算最终的 gas 费用。
  10. - paymasterAndData:如果设置了此字段,则表示支付方地址和特定于支付方的数据。支付方将为交易支付费用,而不是发送请求的账户。
  11. - signature:发件人验证的签名,涵盖整个请求、EntryPoint 地址和链 ID

审计过程中要确认每个gas的相关设置是否经过检查,取值是否安全。为了确保gas消耗在limit范围内,所以会在交易执行过程中计算实际gas消耗。在审计过程中需要确认gas消耗的计算是否严谨,是否与对应的limit值进行对比检查。其次是Op中的参数设置过大或过小时是否会造成资损或运行错误等问题。

代币计价问题

代币计价问题通常发生在EntryPoint提供了使用ERC20代币来支付gas费用,或paymaster合约提供了使用ERC20代币来代付gas费用的情况下。首先计算得出执行Op所需要总的gas消耗,然后通过预言机/Defi/签名中的价格来计算等价的ERC20代币,最后从抽象账户获取所需要的ERC20完成gas的代付。

在审计的过程中要注意的问题有:

  1. 用来代付的token是否在白名单的范围内,是否为正规的代币,是否存在使用恶意代币进行支付的隐患。
  2. 从预言机渠道获取代币价格时,需要注意价格的 decimal 和 token 对应的 decimal 在计算过程中是否使用正确。预言机地址是否限制在白名单中。预言机获取的价格是否具有时效性,避免获取到过时的价格。
  3. 从Defi中获取代币价格或兑换代币时,是否对滑点进行了限制,是否存在闪电贷影响代币兑换价格的风险。在swap操作中,tokenIn和tokenOut的计算与使用是否恰当。
  4. 在签名中获取价格时,要注意签名价格是否具有时效性,在价格剧烈波动的场景下这种策略是否会造成用户或者项目方的资产损失。签名的价格是否与代币一一对应。是否存在中心化风险。

钱包逻辑问题

合约钱包/抽象账户至少需要实现下面两个函数,在对钱包部分进行审计时,要重点关注以上两个函数的实现情况,以及验签是否有问题,有没有做好权限管理,在调用的过程中是否存在重入风险等。

  1. 校验 User Operation 签名的函数,以供 EntryPoint 在 validation loop 中调用。其中的签名方法由合约钱包自行实现。
  2. 发起交易的函数,以供EntryPoint 在 execution loop 中调用。

还有一个重点就是对钱包的代理模式进行检查,了解清楚其代理模式。

  1. 明确implement合约(逻辑合约)的替换方式。
  2. EntryPoint是否对钱包合约的implement有限定的要求,是否要求implement合约要在白名单的地址中选取,在与钱包进行交互时是否对implement进行检查,implement是否会在Op执行的过程中进行替换。
  3. 在钱包Proxy合约中的变量,是否能够通过修改implement的方式进行修改。如果能够被修改,是否会对业务流程造成影响,是否会存在安全隐患。

后记

以上就是在抽象账户审计过程中总结归纳的一些经验,不能说是一个全面的审计Check List,但是希望能够给初次接触此类项目的同学一下入手的角度。由于抽象账户这个概念涉及的内容很多,局限于个人的学识,这篇文章还存在很多没能覆盖到的方面,也希望各位师傅能够提出您的看法与建议,大家一起交流学习。

【项目学习】ERC-4337 抽象账户项目审计过程中需要注意的安全问题的更多相关文章

  1. Halo 开源项目学习(一):项目启动

    项目简介 Halo 是一个优秀的开源博客发布应用,在 GitHub 上广受好评,正好最近在练习写博客,借此记录一下学习 Halo 的过程. 项目下载 从 GitHub 上拉取项目源码,Halo 从 1 ...

  2. 值得学习的C语言开源项目

    值得学习的C语言开源项目   - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工 ...

  3. 【C/C++开发】值得学习的C语言开源项目

    值得学习的C语言开源项目 - 1. Webbench Webbench是一个在Linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...

  4. 值得学习的C/C++开源项目 持续更新

    值得学习的C语言开源项目 持续更新 文章目录 值得学习的C语言开源项目 持续更新 - 1. Webbench - 2. Tinyhttpd - 3. cJSON - 4. CMockery - 5. ...

  5. Python学习路径及练手项目合集

    Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159

  6. ReactNative新手学习之路01-创建项目开始

    新手学习之路01-创建项目开始 小菜鸟准备学习RN开发,决定写下自己的学习历程,方便其他也想要学习RN的人,后期会持续更新写下自己所有学习经历,一步步从菜鸟成长成业内高手.开发环境准备,本文默认环境已 ...

  7. 转:从开源项目学习 C 语言基本的编码规则

    从开源项目学习 C 语言基本的编码规则 每个项目都有自己的风格指南:一组有关怎样为那个项目编码约定.一些经理选择基本的编码规则,另一些经理则更偏好非常高级的规则,对许多项目而言则没有特定的编码规则,项 ...

  8. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  9. SpringMVC项目学习1_web.xml

    最近接触的所有项目都是SpringMVC+ajax的项目,因此以一个项目为例学习下. --------------------------------------------------------- ...

  10. 跟着刚哥学习Spring框架--创建HelloWorld项目(一)

    1.Spring框架简介 Spring是一个开源框架,Spring是在2003年兴起的一个轻量级的开源框架,由Rod johnson创建.主要对JavaBean的生命周期进行管理的轻量级框架,Spri ...

随机推荐

  1. day68:Vue:类值操作/style样式操作&v-for&filer/computed/watch&生命周期钩子函数&axios

    目录 1.类值操作 :class 2.style操作样式 :style 3:示例:选项卡 @click+:class 4.v-for示例:循环商品显示 5.过滤器:filter 6.计算属性:comp ...

  2. 微服务 - Redis缓存 · 数据结构 · 持久化 · 分布式 · 高并发

    本篇内容基于 Redis v7.0 的阐述:官网:https://redis.io/ 本篇计划用 Docker 容器辅助部署,所以需要了解点 Docker 知识:官网:https://www.dock ...

  3. SpringBoot自定义权限过滤注解详解

    一.需求 我们在做项目的时候,通常会根据不同的账号登录进去,展示的菜单和列表不同,这是因为我们在后端根据定义的角色权限,来筛选不同的数据.我们来看看我们Before和After是如何做的. 二.Bef ...

  4. Windows安装系统

    0x01下载PE 微PE 0x02安装PE 0x021方式一:安装到系统 此方法开机有选择系统的选项,强迫症使用方法二 0x022方式二:安装到U盘 此方法需要一个U盘 确认无误后点击 立即安装到U盘 ...

  5. Linux 根据名称自动kill掉当前相关进程

    ps aux | grep app | grep -v "grep" | awk '{print $2}' | xargs -r kill

  6. 快速上手Linux核心命令(七):Linux系统信息相关命令

    目录 前言 uname 显示系统信息 hostname 显示或设置系统主机名 du 统计磁盘空间使用情况 echo 显示一行文本 watch 监视命令执行情况 stat whereis 显示命令及其相 ...

  7. [人脸活体检测] 论文:Face De-Spoofing: Anti-Spoofing via Noise Modeling

    Face De-Spoofing: Anti-Spoofing via Noise Modeling 论文简介 将非活体人脸图看成是加了噪声后失真的x,用残差的思路检测该噪声从而完成分类. 文章引用量 ...

  8. 【必知必会的MySQL知识】③DML语言

    目录 前言 准备 插入数据 语法格式 插入完整行数据 插入多行数据 将检索出来的数据插入表 更新数据 准备两张表 语法 实践操作 删除数据 语法 实践操作 小结 前言 前面的两篇文章中,我们已经对My ...

  9. 【必知必会的MySQL知识】④DCL语言

    目录 一.概述 二 .授权 2.1 语法格式 2.2 语法说明 2.3 权限类型 2.4 权限级别 三. 回收权限 3.1 语法格式 3.2 语法说明 3.3 注意事项 四 .实践操作 一.概述 数据 ...

  10. 2020-09-14:KVM和XEN虚拟化的区别?

    福哥答案2020-09-14:#福大大架构师每日一题#[答案来自此链接](https://bbs.csdn.net/topics/397671000)KVM:1.虚拟化支持:全虚拟化.2.支持架构:虚 ...