跳到正文

Permit2 签名风险

Permit2 将可重复使用的额度与一次性签名转账分开;安全签名要求精确核验部署、域、支出方、收款方、金额、交易序号、截止时间、见证数据和执行调用数据。

更新于

仅供教育用途,不构成投资建议。投资可能导致损失。

直接答案

Permit2 组合了两套不同的授权系统。AllowanceTransfer 存储可重复使用的所有者-代币-支出方额度,包括金额、到期时间和有序交易序号。SignatureTransfer 使用无序位图交易序号,消耗一次性签名上限,不会建立持久的下游额度。两者仍依赖 ERC-20 代币从所有者到 Permit2 的额度。

无燃料费签名仍可能在支出方或中继者支付执行费用时转移资产。必须核验准确的链、已部署 Permit2 代码、EIP-712 域、模块、代币、支出方、签名上限、收款调用数据、交易序号和时限。合法的 Permit2 合约并不能使恶意的支出方、收款方、路由器或见证数据变得安全。

Permit2 签名风险
0 / 5
0 项已核查; 5 项仍未解决

完成核查不代表资产、交易或系统已经安全。

运作机制

  1. 锁定 chainId、网络、Permit2 verifyingContract、已部署运行时代码、代币地址及小数位、所有者钱包类型和预期应用。应使用官方部署记录;熟悉的地址或标签并不足够。
  2. 读取上游 ERC-20 所有者至 Permit2 的额度和余额。识别有限或无限批准以及代币特有的转账行为;这一账本不会因 Permit2 签名或已存储下游额度到期而消失。
  3. 识别准确路径和已签名的主类型:AllowanceTransfer 的 PermitSinglePermitBatch,或 SignatureTransfer 的 PermitTransferFrom 及其批量和见证数据变体。不得把 transferFrom 当作签名类型。
  4. 解码 EIP-712 域和每条消息。对于 AllowanceTransfer,检查代币、uint160 amountexpiration、有序交易序号、支出方和 sigDeadline。对于 SignatureTransfer,检查获准代币及金额、无序交易序号、截止时间,以及从调用者上下文绑定的支出方。
  5. 单独解码执行调用数据。在基础 SignatureTransfer 中,SignatureTransferDetails.torequestedAmount 是执行参数,而非基础签名许可中的字段;请求金额只需不超过签名上限。核验每个批量索引以及任何准确的见证哈希和类型字符串。
  6. 查询当前有序额度交易序号,或无序位图的字和位,再模拟准确的调用者、调用数据、链和状态。核对收款方、路由器操作、代币特性、余额及两套额度账本;模拟结果可能随状态、排序或重组而改变。
  7. 尽量缩小金额和有效期。发现可疑情况时,保留类型化数据,并通过可信路径提交正确的上游批准撤销、下游额度撤销或交易序号失效操作;应将其视为内存池竞态,等待确认后再核对转账、余额、额度和位图位。

AllowanceTransfer 的 sigDeadline 限制签名许可建立或更新已存储权限的最晚时间;expiration 限制该权限可被使用的期限。SignatureTransfer 的截止时间限制一次性执行。EIP-712 提供类型化哈希和域分隔,而不提供重放保护或意图安全;Permit2 的交易序号和截止时间规则才划定这些边界。

对于合约钱包,ERC-1271 的有效性取决于钱包当前的 isValidSignature 策略、模块、阈值和代码。钱包标签、硬件钱包被截断的屏幕显示和成功的模拟只是证据输入,并非保证。断开前端不会撤销任何批准或签名。

示例

  • 两套额度账本。 代币对 Permit2 的有限额度初始为 1,000 USDC;一个 PermitSingle 为支出方 S 存储 600 USDC。S 转移 225 USDC 后,已存储金额为 600 - 225 = 375 USDC,而标准有限上游代币额度变为 1,000 - 225 = 775 USDC。让 375 到期或将其撤销,并不会自动清除 775;非标准代币可能有所不同。
  • 一次性收款方和金额。 SignatureTransfer 签署的上限为 250 USDC;调用数据请求向商户转移 180 USDC。在余额和上游额度充足时,可以执行 180 的转移。交易序号随后被消耗,因此未使用的 70 USDC 不可重复使用。如果调用数据把攻击者指定为收款方,基础许可本身无法阻止已绑定支出方进行这种重定向。
  • 无序交易序号位图。 对于交易序号 513wordPos = 513 >> 8 = 2bitPos = 513 & 255 = 1,且 mask = 1 << 1 = 2。执行会设置第 2 个字的第 1 位;重放 513 将失败,而位于第 0 位的交易序号 512 保持独立。
  • 撤销竞态。 已存储额度为 400 USDC。所有者广播归零撤销,但一笔 300 USDC 转账先执行,剩余 100 USDC;之后的撤销再将余额设为 0。最终额度为零并不会撤销已经实现的 300 USDC 损失,因此必须核对交易排序和余额。

风险

  • 链 ID、部署或运行时代码错误
  • 假冒或非预期的验证合约
  • 混淆 AllowanceTransfer 与 SignatureTransfer
  • 恶意或错误的支出方和调用者
  • 通过执行调用数据选择收款方
  • 请求金额接近签名上限
  • 代币地址、符号、小数位或原始单位错误
  • 持久或无限的上游 ERC-20 批准
  • 下游金额或到期时间过大
  • 混淆截止时间、签名截止时间与额度到期时间
  • 有序交易序号陈旧或发生竞态
  • 重复使用位图位或失效掩码范围过大
  • 见证哈希或准确类型字符串不匹配
  • 批量条目被隐藏、重复或索引错误
  • 前端显示或调用数据与意图不同
  • 撤销在内存池或 MEV 竞态中失败
  • ERC-1271 模块、签名者、阈值或升级发生变化
  • 收费转账、变基、暂停、冻结或带回调的代币
  • 模拟状态漂移、失败或发生重组
  • 把硬件钱包确认或断开连接误认为安全

常见误区

  • 没有燃料费提示的签名无法转移代币。 其他参与者可以支付执行燃料费。
  • 官方 Permit2 地址能证明支出方和收款方安全。 Permit2 也可能忠实执行恶意权限。
  • SignatureTransfer 和 AllowanceTransfer 建立相同的持久权限。 前者仅使用一次;后者存储可重复使用的额度。
  • 断开连接或撤销一层会取消所有路径和待执行签名。 上游、下游和交易序号状态彼此独立,竞态仍然存在。
  • EIP-712、硬件钱包或成功模拟能证明意图和最终性。 它们改善可见性或测试,却不能取代字段、调用数据和已确认状态的核验。

相关主题

来源

导航

搜索知识库...