在 SSP 中撤销代币授权

·阅读 7 分钟·作者:SSP Editorial Team
在 SSP 钱包中撤销 ERC-20 代币授权的插图,allowance 被重置为零,SSP Key 联合签名该交易。

在 SSP 中撤销代币授权

每当你在 EVM 链上确认一笔 swap、存款或 NFT 挂单时,你都在授予 dApp 替你转移特定 ERC-20 代币的权限。这些权限——称为授权或 allowance——在交易结算之后仍会留在 on-chain。几个月后,你在三月信任过的合约,到了六月可能仍然有权把那枚代币掏空。解决办法很直接:撤销你不再需要的授权。本指南演示如何从 SSP 完成这件事——SSP 是一个 self-custodial 的 2-of-2 wallet,任何一笔交易(包括撤销)都需要 SSP Key 联合签名。

如果你对这个概念还陌生,先阅读 代币授权:你一直在发放的许可。那里讲清楚了为什么需要授权,以及为什么无限 allowance 是 DeFi 中默认的攻击面。本文是它的清理篇。

简短回顾

当你签名一笔 approve(spender, amount) 调用时,代币合约会记录:spender(通常是路由、vault 或 marketplace 合约)被允许从你的地址转出至多 amount 的该代币。许多 dApp 会请求 2^256 - 1——实际上等同于无限——以便在以后的交互中替你省 gas。这种便利同时也是风险:如果 spender 合约日后被攻陷,或者你不再使用该 dApp 但 allowance 还挂着,攻击者可以在任何时候掏空你的全部余额。

撤销会把这一授权撤回。它并不撤回过去发生的转账,也不会"删除"任何内容,只是把 allowance 重新置零。

撤销的底层机制

一次撤销不过是一笔普通交易。你在原本授予授权的同一条链上、同一份代币合约上调用 approve(spender, 0)。这一次函数调用,会把合约内 allowance[owner][spender] 映射写入一个新的 0,覆盖原来的数字。

几个需要内化的机制要点:

  • 每条链、每个 token-spender 对要撤销一次。 如果你在 Ethereum 上授权过一个 USDC 的 spender,又在 Polygon 上授权过同一个 spender,那就需要两笔撤销交易——每条链各一笔。Allowance 并不会跨链共享。
  • 撤销是一笔独立交易。 它和任何转账一样要消耗 gas。请预先准备:在对应链上准备好原生资产(Ethereum 上是 ETH,Polygon 上是 MATIC,等等)用于支付手续费。
  • 可能比你担心的便宜。 撤销只是一次简单的写入,通常比一次 swap 还便宜。在 Base 这类 Layer 2 上往往只有几分钱。
  • SSP 仍然需要联合签名。 因为 SSP 是 2-of-2 wallet,撤销交易走的还是和任何其他交易一样的流程:由 extension 发起,SSP Key 审核并联签。你的保护机制延伸到清理动作本身——单一设备无法单独撤销,也无法被诱骗去"批准一个伪装成撤销的请求"。

撤销的两条路径

从 SSP 撤销授权有两种同样合法的方式。挑符合当下情况的那一种即可。

路径 1:使用可信的区块浏览器

这是手动且透明的路线。当你确切知道要撤销哪个代币、哪个 spender,或者不想连接第三方工具时,它很合适。

  1. 在合适的浏览器上打开该代币的合约页:
    • Ethereum: etherscan.io
    • Polygon:polygonscan.com
    • Base:basescan.org
    • BNB Smart Chain:bscscan.com
    • Avalanche:snowtrace.io
  2. 进入 Contract 标签,再点 Write Contract(若该代币是 proxy 合约——大多数主流稳定币都是——则点 Write as Proxy)。
  3. 找到 approve 函数。它的两个输入是 spender(你要撤销的地址)与 amount(新的 allowance)。
  4. amount 设为 0。粘贴 spender 地址——从你以前的交易历史里复制,绝不要凭记忆敲。
  5. 连接你的 wallet。大多数浏览器都支持 WalletConnect,这是连接 SSP 的推荐方式。在 extension 里确认连接请求。
  6. 点击 Write。浏览器构造 approve(spender, 0) 交易并把它递交给 SSP。SSP 的 extension 显示调用细节;SSP Key 联签;撤销被广播。

这条路啰嗦,但你签下了什么完全没有任何模糊空间。

路径 2:使用专门的撤销工具

对大多数用户而言这是更实用的选择。revoke.cash 是这件事广泛使用的开源工具。它会跨所支持的各条链扫描你的地址,列出每一笔仍在生效的 allowance,标记其中风险较高的(无限金额、陌生合约),并允许你通过已连接的 wallet——单笔或批量——撤销它们。

流程:

  1. 在浏览器中直接打开 revoke.cash。把真实域名加入收藏夹,并且只通过这个收藏入口访问。撤销工具的钓鱼仿冒站之所以存在,正是因为用户来到那里时已经做好了签交易的准备。
  2. 通过 WalletConnect 连接,然后用 SSP 扫码或粘贴 URI。
  3. 把链选择器切换到你想审计的那条链。revoke.cash 会拉取你在那条链上的授权。
  4. 浏览列表。每一行显示代币、spender、allowance 数额,以及(通常)一个 dApp 标签。
  5. 对任何你不再使用的项点击 Revoke。每一次撤销都是一笔独立的 approve(spender, 0) 交易,由 SSP 联签。

一份实用的审计流程

每年抽出 20 分钟一两次,按这个清单走一遍:

  1. 通过 WalletConnect 把 SSP 连接到 revoke.cash
  2. 审查你在每条用过的链上的活跃授权。先从 Ethereum 开始——历史上授权关系图最密集的就是它——然后依次走 Polygon、Base、BNB Smart Chain 和 Avalanche。
  3. 优先处理风险最高的项。按无限 allowance 和不认识的 dApp 名字排序或扫一眼。一个你在 2024 年用过一次 swap、之后再没碰过的协议就是首选目标。任何你完全认不出来的合约也是。
  4. 撤销。在 SSP extension 里确认该交易;SSP Key 提示你联签;撤销被广播。
  5. 在 SSP Key 上联签。这是再次核对目标的时机。SSP Key 会显示你正在调用的合约和函数——确认两者都与你的本意一致。
  6. 每条链都重复一次。Allowance 是按链分别存储的。不要假定 Ethereum 上的一次撤销会顺带清理 Polygon。

你不需要把一切都清空。目标是让那些你仍在主动使用的合约保留 allowance,把其余的归零。

注意事项

  • 域名卫生。只使用官方域名 revoke.cash。仿冒钓鱼站恰恰瞄准了这一场景,因为用户此时本来就处在签署交易的状态。先收藏;连接前先核对地址栏。
  • 逐链的事实。在 Ethereum 上撤销 USDC 的授权,并不会影响 Polygon 上的 USDC 授权——尽管在你的投资组合里它们看起来"像同一个代币"。一定要按链逐条走过来。
  • gas 预算。撤销要付 gas。在 Ethereum 上,一批积攒下来的撤销可能加起来不便宜;趁 gas 安静时做。在 Layer 2 上成本几乎可以忽略。
  • 永远要核对 spender。在签下任何"撤销"交易之前,确认调用里的 spender 地址,与你打算撤销的那个合约一致。恶意站点完全可能展示一个假的撤销 UI,实际上却在向攻击者发出一笔新的授权。在 SSP Key 的提示上读出函数名(approve)和金额(0),就是你最后的防线。
  • permit 是另一回事。一些代币(USDC、DAI 的若干变体)支持 permit——一种作为授权使用的 off-chain 签名。revoke.cash 会尽量列出它能识别的 permit 类授权;对于你认不出来的任何项,按你对待 on-chain allowance 的方式来对待它。

清理阶段的 2-of-2 优势

这是经常被忽略的一点:在 SSP 中撤销并不是单一设备上的一次点击。你的 extension 起草了撤销,但它不能独自广播。SSP Key 必须联签,而那一步联签正是你检视"实际要被提交的是什么"的时机。如果你的 extension 哪一天被攻陷,试图提交一笔伪装成"撤销"的恶意交易——其实是一笔新的授权——SSP Key 会在自己的屏幕上显示真正的函数和真正的金额。两台设备,两次发现问题的机会。

定期做一次授权卫生,是大多数用户绕开的、在 DeFi 中杠杆最高的一项习惯。在日历里设一个提醒,做完审计,睡得更安稳。也欢迎继续阅读这个系列——如果你想把链特定的细节稳住,从 SSP 中的 Ethereum 开始;或回头看 代币授权:你一直在发放的许可,提醒自己这件事为什么重要。

分享本文

相关文章