在 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 开始;或回头看 代币授权:你一直在发放的许可,提醒自己这件事为什么重要。

分享本文

相关文章