最近发生了一系列用户使用链下签名导致资产被盗的事件,其中的原理是什么?又该如何预防?为何相关链上数据与Uniswap有关系?本文将清楚地说明Permit函数背后的运作模式,以及用户该如何自保的知识。
目录:
链下签名
链下签名是什么
链下签名优点:用户体验好
链下签名缺点:容易被忽视的资安风险
Permit函数
想解决问题:链上授权体验差
Permit函数提升用户体验
Permit函数不适用早期代币
Permit2合约
Uniswap推出Permit2合约
Permit2原理
链下签名窃款的原理
链下签名Permit函数风险增
链下签名难追踪
用户该如何自保
一连串本末倒置的设计
要理解Permit函数的签名如何挪取用户资产,需要先知道链下签名的原理。
链下签署是区块链产业常见的用户互动方式,常用于钱包连接、网站会员登录、确保用户阅读完毕免责声明等,是一种使用Web3钱包独特的互动方式。可以在虚拟世界带入用户的权力。
以OpenSea登录流程举例,其使用了链下签名方式,除了确保用户是钱包持有者之外,也要确认用户同意使用服务条款与隐私权政策。
链下签名有许多的优势:
最明显就是可以减少燃料费消耗
快速完成
整体来说比起链上交易,链下签名的用户体验更好。
链下签名最大问题是可能让用户面临资产遭窃的风险。
虽然链下签名的当下并没有将数据上传区块链,但是某些链上合约的函数可以将用户的签名信息作为参数使用,代表取得特定签名内容的任何人(或是智能合约)都可以因此调用链上的函数(例如Permit函数),并牵动用户的资产。
不同的签名有不同的风险,特别是某些签名内容看不懂的时候,就需要更加特别注意,一律建议当不理解签名内容时,不要随意同意签署以确保安全。
此问题将在文末继续延伸讨论。
可以将用户签名作为参数调用的链上函数,最常见的函数是Permit,提供的功能与approvals相似,不过前者借由链下签名,并不需要用户付出燃料费即可以让用户完成授权。
相信使用过链上服务的用户都熟悉这个画面,当使用代币进行链上合约操作时,需要使用approvals函数进行链上授权,这样才能让合约存取钱包中的代币,以进行服务。
不过由于代币总类繁多,不同的合约也都需要重新授权,更不要说合约也会随时间更新。最终造成用户需要频繁地进行代币授权,除了花费的时间,且每次行动也都需要燃料费用,因此用户体验受到严重影响。
因此出现了EIP-2612,作为延伸ERC-20的代币标准,提出Permit函数,借由将链下签名作为参数输入的方式完成代币授权,让用户不需要为了授权而付出燃料费用。
Permit提供另一种代币授权方法,不过参数是链下签名信息。
而其中的符合Permit函数的签名内容需要包含:
授权者地址
被授权者地址
代币合约地址
授权时间
授权数量
理想情况下,就像是现实生活的签约模式,用户可以依照自身需求调整参数后再进行签署,确保权益。比起approvals也拥有更多的调整空间。
不过由于许多代币早已推出,许多代币合约都是不可更改的,因此Permit函数仅适用在较新的代币上,导致此功能使用场景受到较大的限制。
因此后来Uniswap团队为解决这个问题,打造了一个全新的智能合约—Permit2。
Uniswap团队在推出Universal Router功能时,一并整合了Permit2合约,并同时上线包含Ethereum、Optimism、Arbitrum、Polygon、Celo等网络。让所有代币都可以拥有Permit功能。
Permit2合约:让所有代币都支持Permit函数
既然旧的代币合约内没有Permit函数可以使用,那么就将就继续使用approvals函数。
在Dapp合约与代币合约之间插入Permit2合约,Permit2合约接收Dapp发送过来的链下签名数据验证后,代替Dapp与代币合约互动,每种代币仅需要经过一次approvals函数,借此节省不同Dapp或是不同用户的代币授权次数。
Uniswap借由其影响力,促使其他Dapp整合Permit2,将会使得未来几乎所有代币与服务都仅需要Permit2合约获得授权就可以了。
基于以上的背景知识,终于可以来理解为何使用过Uniswap后的用户就更有遭到签名窃款的风险。
由于链下签名并不需要燃料费用,是用户经常忽略的安全性的环节,若其中遭到恶意网站诱导用户签下符合调用Permit函数的内容,那么用户的代币就会遭到第三方窃取。
上述范例即为符合Permit函数格式的签名,其中授权的代币数量大多数智能合约预设都是无限颗(10^31颗),而授权时间换算下来也有54年,整体来说就是一个长期的无限授权。若此内容来自恶意第三方,用户的资产将面临极大危险。
当然,代币需要拥有Permit函数才可能发生,只不过现在有了Permit2合约就不同了。随着越来越多的协议背后整合Permit2合约,当用户使用过Uniswap或是其他整合Permit2的合约,就让其他代币也同样面临相同的风险。(也才会发生牵扯到Uniswap合约的钓鱼事件)
链下签名不会在链上有纪录,大多是储存在某个私人或是专案的数据库中,体供随时调用。因此比起链上教抑或是链上授权,并不是那么容易追踪与取消,才会说大多Permit授权容易有安全风险。
身为用户,如果对于链下签名的内容不熟悉,也有许多方式可以降低这类代币设计的风险。
第一原则就是不要随意签署不熟悉的内容。
当出现approvals确认画面时,将授权数量调整为本次交易所需数量(虽然这样多次交易会需要重复授权)
虽然签署内容难追踪,仍然可以尝试使用工具尽量查询(revoke.cash)
使用保存小额资产的钱包进行链下签名
不论是Permit函数或是Permit2合约,出发点都是为了改善用户体验,不过最终却让更多的一般用户深陷风险之中,反而要做出更多繁麻的流程(创多钱包、多次approvals)才能确保资产安全,整体的使用体验不但没有提升反而更加糟糕。
不过确实也有许多人注意到此问题,也已经提出潜在的解决方案,相信未来的产业会更加成熟,只是仍需要给时间发展。身为产业早期参与者,注意自身资产安全确实自己是不可忽视的责任。
请务必让身边朋友知悉,由于现今链上环境变化,千万不可忽视链下签名带来的安全风险。
Permit
Permit2
Uniswap
签名
链下签名