炒作退潮,从技术角度解读Hyperliquid的桥合约、HyperEVM及其潜在问题
作者:Shew,仙壤GodRealmX
近期广受市场关注的Hyperliquid是最有影响力的链上订单薄交易所之一,其TVL已超过20亿美元,在被Messari评价为“链上Binance”的同时,甚至还把本已淡出大众视角的Layer3、应用链叙事重新拉回聚光灯下。凭借着Token上线一个月内FDV拉至300亿美元的辉煌成绩,Hyperliquid获得了从普通用户到从业人员的广泛关注,与此同时市面上也涌现出了大量关于Hyperliquid的研报,但这些文章基本聚焦于其在订单簿产品功能和交易机制上的特点,没有深入探究其背后的技术构造以及安全隐患。
本文作者旨在补足这一空缺,单纯从技术构造与安全的角度来考察Hyperliquid,帮助更多人理解这一明星项目的结构与原理。我们将从Hyperliquid跨链桥合约的构造与隐患、HyperEVM与HyperL1双链构造两大角度展开阐述,帮助大家深入理解其背后的技术架构与实现方式。
(目前Hyperliquid占用了Arbitrum上的USDC总供应量的67%)
HyperLiquid跨链桥解析
由于HyperLiquid并没有开源核心组件,但是开源了相关的桥合约,所以我们对桥合约方面的风险更为了解。Hyperliquid在Arbitrum上部署了一个桥合约,用来存储用户存入的USDC资产,我们可以在Bridge组件内看到Hyperliquid节点的部分行为。
验证者集合
从节点身份划分的角度来看,Hyperliquid有4组验证者,分别为hotValidatorSet、coldValidatorSet以及finalizers和lockers,对应着不同的职能。其中hotValidatorSet用于响应用户的提款操作等高频行为,一般使用热钱包以随时响应Hyperliquid用户的提款请求。
而coldValidatorSet主要用于修改系统配置,如改写hotValidatorSet或lockers等验证者集合的名单,或是处理桥合约的锁定状态,而且 coldValidatorSet 有权直接将某些提款请求无效化。
而lockers是一组有特殊权限的验证者,类似于Layer2惯用的“安全委员会”,会在一些突发情况下用投票决定是否让跨链桥暂停运转。目前Hyperliquid桥的lockers集合内包含5个地址,只需要2个locker投票即可暂停桥合约的运行。
至于finalizers其实也是一组特殊的验证者,主要用于确认跨链桥的状态变化,从合约层面来看主要确认的就是用户存款和提款。Hyperliquid的跨链桥使用“提交-确认”机制,比如用户发起提款后并不会被立即执行,需要等待一段时间(这段时间被称为争议期)。等待争议期结束后,finalizers内的成员执行提款交易,提款才可以被正常执行。
而一旦跨链桥出现问题,比如某笔提款声明要提走的资产大于该用户实际拥有的资产余额,Hyperliquid节点就可以在争议期内使用lockers投票暂停跨链桥合约运行,或者由 coldValidatorSet直接将有问题的提款请求无效化。
目前Hyperliquid的只有4个验证者节点,所以hotValidatorSet和coldValidatorSet只对应4个链上地址。Hyperliquid在初始化时,自动将hotValidatorSet内的地址注册为 lockers和finalizers的成员,而coldValidatorSet为Hyperliquid官方自己控制,使用冷钱包来存储密钥。
存款
Hyperliquid的桥合约基于EIP-2612的Permit方法来处理用户的存款操作,且桥合约内只允许用户存入USDC一种资产。Permit相比于传统的Approve—Transfer模式更为简洁,也便于支持批量操作。
Hyperliquid的桥合约使用了batchedDepositWithPermit函数来批量处理多笔存款,这里的存款动作较为简单,不存在资金安全风险,在处理流程上很简洁,只是使用了Permit方法来节优化UX。
提款
相比于存款,提款是一个高度危险的操作,所以提款逻辑会比存款复杂很多。当用户发起提款请求后,Hyperliquid节点会调用桥合约的batchedRequestWithdrawals函数。此时桥合约会要求每笔提款请求必须凑齐hotValidatorSet的2/3签名权重,注意很多文档在此处都描述为“集齐2/3的签名”,但实际上桥合约检查的是“2/3的签名权重”。目前HyperLiquid只有4个权重相同的节点,所以检查签名权重和检查签名数量暂时一致,但在未来,HyperLiquid可能引入高权重的节点。
当发起提款请求后,跨链桥不会立即将合约控制的USDC转移出去,而是有一个“争议期”,类似于欺诈证明协议中的“挑战期”。目前Hyperliquid桥合约的争议期为200秒,在争议期内可能出现两种情况:
1.lockers认为目前的提款请求存在严重问题,此时可以直接投票把合约暂停/冻结;
2.节点认为部分提款行为存在问题,此时coldValidatorSet 成员可以调用 invalidateWithdrawals函数,令该笔提款无效化。
如果争议期内没有出现问题,待争议期结束后,finalizers内的成员可以调用桥合约中的batchedFinalizeWithdrawals函数来敲定最终的状态,该函数触发后USDC才会被打到用户在Arbitrum的钱包地址里。
所以从安全模型的角度来看,假如有恶意攻击者想在Hyperliquid的提款流程中做手脚,就需要突破三道防线:
1.掌握hotValidatorSet内的2/3签名权重,换言之需要获取一定数量的私钥或是串谋;目前HyperLiquid只有4个验证者,被攻击者控制或串谋的可能性不低;
2.在争议期内,攻击者应避免自己的恶意交易被发现,一旦被发现很有可能使lockers出手锁住合约。我们会在下文专门讨论这部分。
3.获取至少一个finalizers 成员的私钥,让自己的提款行为被最终确认。目前 finalizers成员和hotValidatorSet成员基本一致,所以只要攻击者满足了上述条件1,就自动满足了条件3。
桥合约的锁定
前面我们多次提到了Hyperliquid设置了一个锁定跨链桥合约的功能。具体来说,锁定跨链桥需要lockers成员调用跨链桥合约中的voteEmergencyLock函数进行投票,目前当2名 lockers调用该函数给出投票后,跨链桥合约就会被锁定并暂停运转。
但需要注意,HyperLiquid的跨链桥也提供了unvoteEmergencyLock函数,允许lockers成员撤回投票。而一旦跨链桥合约被成功锁定,就只能通过名为emergencyUnlock的函数来解除锁定,需要收集coldValidatorSet成员2/3以上的签名权重。
emergencyUnlock 功能在解除锁定的同时,也会输入新的hotValidatorSet和 coldValidatorSet验证者地址集合,并且会立即更新。
验证者集合更新
相比于费尽心思尝试突破提款流程中的已有防线,一种更好的攻击手段是直接使用 updateValidatorSet函数更新hotValidatorSet和coldValidatorSet验证者集合。这要求调用者必须给出所有hotValidatorSet成员的签名,且该操作有200秒的争议期。
当争议期结束后,需要finalizers成员调用finalizeValidatorSetUpdate函数,完成最终的状态更新。
至此,我们已经介绍了Hyperliquid跨链桥的大部分细节。本文没有介绍lockers和 finalizers的更新逻辑,这两者的更新都需要hotValidatorSet签名,而将某一个成员移除则需要coldValidatorSet签名。
总结下来,Hyperliquid的桥合约包含以下风险:
1.黑客控制了coldValidatorSet后可以无视任何阻拦来盗取用户资产。因为coldValidatorSet拥有emergencyUnlock函数的操作权限,可以让lockers对桥合约的锁定动作无效化,并且可以即时更新节点名单。目前Hyperliquid 只存在4个验证者节点,被盗取私钥的可能性并不低;
2.finalizers拒绝对用户的提款交易进行最终确认,展开审查攻击;种情况下用户资产不会被盗,但可能无法从桥合约中提款;
3.lockers恶意定跨链桥,此时所有的提款交易都无法执行,只能等coldValidatorSet解锁;
HyperEVM与双链交互架构
为了让订单簿交易变的可编程化,比如引入隐私交易等需要智能合约来实现的场景,Hyperliquid推出了名为HyperEVM的方案。它相比于传统的EVM有两个特殊优势:一是HyperEVM可以读取HyperLiquid的订单簿状态,二是HyperEVM内的智能合约可以与Hyperliquid订单簿系统交互,这大大扩展了Hyperliquid的应用场景。
举一个简单例子,如果用户需要保证挂单操作的隐私性,此时可以在HyperEVM上通过类似Tornado Cash的智能合约套一层隐私,然后通过特定接口在HyperLiquid的订单簿系统中触发挂单动作。
在介绍HyperEVM前,我们需要介绍Hyperliquid为HyperEVM准备的特殊架构。由于Hyperliquid有定制化的超高性能订单薄系统,而EVM环境下的交易处理速度要慢很多。为了避免订单簿系统工作速度变慢,Hyperliquid使用了“双链方案”,实质是让Hyperliquid节点设备在软件层面同时运行两条区块链,每个节点都在本地存放两条链的数据,对两条链的交易分别进行处理。
Hyperliquid为其定制化的订单薄系统专门设置了一条链,同时增加了一条EVM兼容的链(HyperEVM)。这两条链的数据在节点群体间通过相同的共识协议来传播,作为一个统一的状态来存在,但在不同的执行环境中分别运行。我们称订单薄专用链为Hyperliquid L1 (L1),这条链是存在许可制的;而用于HyperEVM 的链为HyperEVM(EVM),这条链是无许可的,任何人都可以部署合约,这些合约可以通过预编译代码来访问L1内的信息。
需要注意的是Hyperliquid L1的出块速度大于HyperEVM链,但这些区块仍会按顺序执行。EVM 链上的合约可以读取过往L1区块内的数据,并向未来的L1区块写入数据。如下图:
为了让HyperL1和HyperEVM之间实现交互,Hyperliquid利用了Precompiles和Events两种技术手段。
Precompiles
所谓的预编译(Precompiles),说白了就是将一些在智能合约中不易实现、复杂度较高的操作直接挪到底层中实现,把对Solidity不友好、较为麻烦的计算流程挪到常规的智能合约外部去处理,这类预编译代码可以用C、C++等比Solidity更贴近设备底层的语言来实现。
预编译的方式可以让EVM支持更高级更复杂的功能,便于支持智能合约开发者的需求。在表现形式上,预编译实质就是一组特殊的智能合约,其他智能合约可以直接调用这些特殊合约,传入参数并获得预编译执行的返回结果。目前原生EVM内就通过预编译的方式实现了ecRecover指令,可以在EVM内部检查secp256k1签名是否正确,而该指令就位于0x01地址内。
使用预编译增加一些特殊功能是目前的主流做法,比如 Base 就增加了P256预编译代码来方便用户进行WebAuth身份鉴权操作。
(此图来自 Rollup Codes 网站)
与这种目前的主流方案一致,HyperEVM 也增加了一系列的预编译代码来实现EVM对 Hyperliquid订单薄系统状态的读取。目前已知的一个Hyperliquid的预编译代码地址是0x0000000000000000000000000000000000000800,该预编译地址可以读取最近一个L1区块内的用户的永续合约的仓位情况。
Events
我们在上文提到HyperEVM可以向HyperL1区块内写入数据,写入行为就是依赖于Events实现的。Events是EVM内的原生概念,它允许智能合约在执行过程中向外部(如前端应用或监听器)发送日志信息,便于外界监听智能合约的运行情况。
比如在用户使用ERC-20合约的代币转账功能时,合约会抛出Transfer相对应的Event,以便于区块浏览器等前端应用获知代币转账情况。这些Events信息会被包含在区块内,而监听和检索Events日志都存在大量的成熟方案。
现在很多和跨链相关的场景都会使用Events来传递跨链参数,比如Arbitrum部署在以太坊主网上的桥合约内,用户就可以调用相关函数抛出事件在Arbitrum上触发交易。
已知的信息表明,HyperLiquid节点会监听
0x3333333333333333333333333333333333333333(事件地址)抛出的Events,根据Events包含的信息获知用户意图,并据此将意图转化为交易动作,写入未来的Hyperliquid L1区块中。
比如,上述事件地址会提供一个函数,当用户调用此函数时,事件地址会抛出名为IocOrder的Event。在Hyper L1区块产生时,HyperLiquid节点会先查询最近HyperEVM内事件地址抛出的Events,当检索到新的IocOrder事件时,就会将其转化为在Hyper L1内的挂单操作。
HyperBFT
在共识协议层面,Hyperliquid采用了名为HyperBFT的协议,这是一种基于HotStuff的衍生方法。目前HutStuff-2已经是最新的复杂度最低的几种共识协议之一。
根据资料显示,在最初HyperLiquid使用了Tendermint共识算法,是Cosmos系统内默认使用的共识算法,但该算法效率较低,每个阶段都需要All-to-All的消息交换,每个节点都要向所有其他节点发送消息,通信复杂度为O(n²),其中n是节点的数量。
如果采用Tendermint,Hyperliquid每秒最多能处理20,000笔订单。为了达到中心化交易所的速度,HyperLiquid团队基于HotStuff开发了HyperBFT算法,并将其用Rust 实现,理论上每秒最多可处理200万笔订单。
下图展示了在非并行情况下的HyperBFT共识的消息传递方式,可以看到,所有的消息被Leader汇总并统一广播,免去了节点之间自行交换消息的步骤,大幅降低了复杂度。
简单来说,HyperBFT 就是当前的leader出块,全体节点参与投票并将投票结果统一发送给Leader,再让下一个leader轮换的共识协议。实际上Hotstuff和Tendermint涉及的具体细节要复杂的多,本文受限于篇幅和侧重点不在此赘述。
对开发者而言需要注意的要点
上述基于Precompiles的数据读取机制是比较完美的,Solidity开发者读取Hyper L1状态时不需要专门编写相应的代码,但是需要注意msg.sender的问题。与大部分以太坊二层类似,HyperLiquid 也允许用户直接与Hyper L1内的系统合约交互,间接触发在HyperEVM链上的交易动作,此时如果智能合约在该交易内读取msg.sender字段,会发现msg.sender对应的是HyperL1系统合约的地址,而不是最开始在HyperL1上发起交易的用户地址。
而对于EVM与L1的交互,开发者需要注意一系列问题。第一个问题是交互的非原子性问题,假如用户在HyperEVM上通过前述事件地址,间接在L1内挂单,但L1内并没有充分的资产,那么该交易肯定会失败,但用户调用事件地址的函数时不会有错误返回提示。交互的非原子性问题可能导致用户的资产受损。此时对于开发者而言,需要在EVM智能合约端手动处理挂单失败的情况。而且EVM内的智能合约应该有用于最终资金收回的函数,避免用户资产在L1内永远无法提取出来。
其次,EVM对应的合约地址在L1内必须存在映射账户,当用户在EVM内部署完成智能合约后,需要在L1内向映射地址转入少量USDC,迫使L1为合约地址创建账户。该部分操作可能与 HyperLiquid的底层共识相关,在Hyperliquid的文档中有明确要求。
最后,开发者需要注意一些特殊情况,特别是代币的余额情况。Hyper L1存在一个特殊地址用于资产转移,但用户将资产发送到该特殊地址时,资产就会从L1跨到HyperEVM链内。由于 HyperLiquid节点实际上同时执行EVM链和L1链,可能在用户转移资产后HyperEVM仍许久未出块,此时用户在EVM链上无法读到自己的余额。
简单来说,此时的用户资产卡在的跨链桥内,无论是在L1还是EVM链内都无法查询,开发者构建的协议应当处理上述特殊情况,避免用户产生恐慌情绪。
总结来看,HyperEVM类似于基于Hyperliquid L1的二层,HyperEVM依赖于预编译代码读取L1 状态,也依赖于Events来与Hyper L1产生交互。L1也存在一些系统合约帮助用户在HyperEVM内触发交易,或是进行资产跨链。但与一般的Layer1——Layer2架构不同,Hyperliquid为HyperEVM提供了更高的互操作性。
参考资料
Hyperliquid: The Hyperoptimized Order Book L1
hyperliquid-dex/contracts
The Not-So-Definitive guide to Hyperliquid Precompiles.
What is the difference between PBFT, Tendermint, HotStuff, and HotStuff-2?
Bitcoin Consolidates as Realized Profits Stay Low – No Signs Of Major Sell-Off Yet
Bitcoin is navigating a highly volatile environment, as escalating Middle East conflicts and intensi...
Here Is the Main Reason Why Ethereum Price Remains Choppy Amid High Spot ETF Demand
The post Here Is the Main Reason Why Ethereum Price Remains Choppy Amid High Spot ETF Demand appeare...
XRP Addresses Holding 1M Coins Reach 12-Year High As Experts Predict Move Above $4
The XRP Ledger (XRPL) is witnessing increased network activity, which is bullish for its native toke...