Author: Shew, Xianrang GodRealmX
The Hyperliquid, which has recently attracted widespread market attention, is one of the most influential on-chain order book trading platforms, with a TVL exceeding $2 billion. It has been evaluated by Messari as the "on-chain Binance", and has even brought the narratives of Layer3 and application chains, which had faded from the public eye, back into the spotlight. With the brilliant achievement of reaching a FDV of $30 billion within one month of its Token launch, Hyperliquid has gained widespread attention from ordinary users to industry practitioners. Meanwhile, a large number of research reports on Hyperliquid have emerged in the market, but these articles have mainly focused on the characteristics of its order book product functions and trading mechanisms, without delving into the technical structure and security risks behind it.
The author of this article aims to fill this gap, and will examine Hyperliquid from the perspective of technical structure and security, helping more people understand the structure and principles of this star project. We will elaborate on the construction and vulnerabilities of the Hyperliquid cross-chain bridge contract, as well as the dual-chain structure of HyperEVM and HyperL1, to help everyone gain a deeper understanding of its underlying technical architecture and implementation.
(Hyperliquid currently occupies 67% of the total USDC supply on Arbitrum)
Analysis of the HyperLiquid Cross-chain Bridge
Since HyperLiquid has not open-sourced its core components, but has open-sourced the related bridge contracts, we have a better understanding of the risks on the bridge contract side. Hyperliquid has deployed a bridge contract on Arbitrum to store the USDC assets deposited by users, and we can see some of the behaviors of the Hyperliquid nodes in the Bridge component.
Validator Set
From the perspective of node identity division, Hyperliquid has 4 groups of validators, namely hotValidatorSet
, coldValidatorSet
, finalizers
and lockers
, corresponding to different functions. The hotValidatorSet
is used to respond to high-frequency actions such as user withdrawals, generally using hot wallets to respond to Hyperliquid users' withdrawal requests at any time.
The coldValidatorSet
is mainly used to modify system configurations, such as rewriting the roster of hotValidatorSet
or lockers
validators, or handling the locked state of the bridge contract, and the coldValidatorSet
has the power to directly invalidate certain withdrawal requests.
The lockers
are a group of validators with special privileges, similar to the "security committee" commonly used in Layer2, and will vote to decide whether to temporarily suspend the operation of the cross-chain bridge in some emergency situations. Currently, the lockers
set of the Hyperliquid bridge contains 5 addresses, and only 2 lockers need to vote to temporarily suspend the operation of the bridge contract.
As for the finalizers
, they are also a group of special validators, mainly used to confirm the state changes of the cross-chain bridge, and from the contract level, they mainly confirm the user's deposits and withdrawals. Hyperliquid's cross-chain bridge uses a "submit-confirm" mechanism, where users' withdrawal requests will not be executed immediately after initiation, but need to wait for a period of time (this period is called the dispute period). After the dispute period ends, the members of the finalizers
execute the withdrawal transaction, and the withdrawal can then be executed normally.
If the cross-chain bridge encounters problems, such as a withdrawal declaration requesting more assets than the user actually has, the Hyperliquid nodes can vote to temporarily suspend the operation of the cross-chain bridge contract using the lockers
, or the coldValidatorSet
can directly invalidate the problematic withdrawal request.
Currently, Hyperliquid only has 4 validator nodes, so the hotValidatorSet
and coldValidatorSet
only correspond to 4 on-chain addresses. When Hyperliquid is initialized, it automatically registers the addresses in the hotValidatorSet
as members of the lockers
and finalizers
, while the coldValidatorSet
is controlled by the Hyperliquid team itself, using cold wallets to store the keys.
Deposits
Hyperliquid's bridge contract uses the Permit method based on EIP-2612 to handle user deposit operations, and the bridge contract only allows users to deposit the USDC asset. Permit is more concise than the traditional Approve-Transfer mode, and also facilitates batch operations.
Hyperliquid's bridge contract uses the batchedDepositWithPermit
function to batch process multiple deposits, and this deposit action is relatively simple and does not involve financial security risks, and the processing flow is very concise, using only the Permit method to optimize the UX.
Withdrawals
Compared to deposits, withdrawals are a highly dangerous operation, so the withdrawal logic will be much more complex. When a user initiates a withdrawal request, the Hyperliquid node will call the batchedRequestWithdrawals
function of the bridge contract. At this point, the bridge contract will require that each withdrawal request must have the signature weight of 2/3 of the hotValidatorSet
, note that many documents describe this as "gathering 2/3 of the signatures", but in fact the bridge contract checks the "2/3 of the signature weight". Currently, HyperLiquid only has 4 nodes with the same weight, so checking the signature weight and checking the number of signatures are temporarily the same, but in the future, HyperLiquid may introduce high-weight nodes.
After a withdrawal request is initiated, the cross-chain bridge will not immediately transfer the USDC controlled by the contract out, but will have a "dispute period", similar to the "challenge period" in the fraud proof protocol. Currently, the dispute period of the Hyperliquid bridge contract is 200 seconds, and two situations may occur during the dispute period:
1. The lockers
believe that the current withdrawal request has serious problems, in which case they can directly vote to pause/freeze the contract;
2. The nodes believe that some withdrawal behaviors are problematic, in which case the coldValidatorSet
members can call the invalidateWithdrawals
function to invalidate the withdrawal.
If no problems arise during the dispute period, after the dispute period ends, the members of the finalizers
can call the batchedFinalizeWithdrawals
function in the bridge contract to finalize the final state, and this function will trigger the USDC to be sent to the user's wallet address on Arbitrum.
So from the perspective of the security model, if a malicious attacker wants to tamper with the withdrawal process of Hyperliquid, they need to break through three lines of defense:
1. Mastering 2/3 of the signature weight of the hotValidatorSet
, in other words, they need to obtain a certain number of private keys or collude; currently HyperLiquid only has 4 validators, so the possibility of the attacker controlling or colluding is not low;
2. During the dispute period, the attacker should avoid their malicious transactions being discovered, otherwise the lockers
may step in and lock the contract. We will discuss this part in more detail below.
3. Obtain the private key of at least one finalizers
member to ensure that their withdrawal behavior is finally confirmed. Currently, the finalizers
members and the hotValidatorSet
members are basically the same, so as long as the attacker meets the above condition 1, they automatically meet condition 3.
Locking of the Bridge Contract
We have mentioned several times that Hyperliquid has set up a function to lock the cross-chain bridge contract. Specifically, to lock the cross-chain bridge, the lockers
members need to call the voteEmergencyLock
function in the cross-chain bridge contract to vote, and currently when 2 lockers
call this function to cast their votes, the cross-chain bridge contract will be locked and suspended.
However, it is worth noting that the HyperLiquid cross-chain bridge also provides the unvoteEmergencyLock
function, which allows lockers
members to withdraw their votes. Once the cross-chain bridge contract is successfully locked, it can only be unlocked through a function called emergencyUnlock
, which requires the collection of signatures from more than 2/3 of the coldValidatorSet
members.
The emergencyUnlock
function, while unlocking the lock, will also input new hotValidatorSet
and coldValidatorSet
validator address sets, and will be immediately updated.
Validator Set Update
Rather than trying hard to break through the existing defenses in the withdrawal process, a better attack method is to directly use the updateValidatorSet
function to update the hotValidatorSet
and coldValidatorSet
validator sets. This requires the caller to provide the signatures of all hotValidatorSet
members, and this operation has a 200-second dispute period.
After the dispute period ends, finalizers
members need to call the finalizeValidatorSetUpdate
function to complete the final state update.
So far, we have introduced most of the details of the HyperLiquid cross-chain bridge. This article does not introduce the update logic of lockers
and finalizers
, both of which require hotValidatorSet
signatures, and removing a member requires coldValidatorSet
signatures.
In summary, the HyperLiquid bridge contract contains the following risks:
1. If a hacker controls the coldValidatorSet
, they can steal user assets without any obstruction. Because the coldValidatorSet
has the operation authority of the emergencyUnlock
function, they can invalidate the locking action of the lockers
on the bridge contract, and can immediately update the node list. Currently, HyperLiquid only has 4 validator nodes, and the possibility of stealing private keys is not low;
2. Finalizers refuse to finalize user withdrawal transactions, launching a review attack; in this case, user assets will not be stolen, but they may not be able to withdraw from the bridge contract;
3. Lockers maliciously lock the cross-chain bridge, in which case all withdrawal transactions cannot be executed, and can only wait for the
coldValidatorSet
to unlock;
HyperEVM and Dual-Chain Interaction Architecture
In order to make order book trading more programmable, such as introducing privacy transactions that require smart contracts to implement, Hyperliquid has launched a solution called HyperEVM. Compared to the traditional EVM, HyperEVM has two special advantages: one is that HyperEVM can read the order book state of HyperLiquid, and the other is that the smart contracts in HyperEVM can interact with the HyperLiquid order book system, which greatly expands the application scenarios of HyperLiquid.
For example, if a user needs to ensure the privacy of the order placement operation, they can add a layer of privacy through a smart contract similar to Tornado Cash on HyperEVM, and then trigger the order placement action in the HyperLiquid order book system through a specific interface.
Before introducing HyperEVM, we need to introduce the special architecture that Hyperliquid has prepared for HyperEVM. Since Hyperliquid has a customized ultra-high-performance order book system, the transaction processing speed in the EVM environment is much slower. To avoid slowing down the order book system, Hyperliquid uses a "dual-chain solution", which essentially means that Hyperliquid nodes run two blockchains at the software level, and each node stores the data of the two chains and processes the transactions of the two chains separately.
Hyperliquid has set up a chain specifically for its customized order book system, and has also added an EVM-compatible chain (HyperEVM). The data of these two chains is propagated among the node group through the same consensus protocol, and exists as a unified state, but runs separately in different execution environments. We call the chain dedicated to the order book as Hyperliquid L1 (L1), and this chain is permissioned; while the chain for HyperEVM is HyperEVM (EVM), and this chain is permissionless, where anyone can deploy contracts, and these contracts can access information in L1 through precompiled code.
It is worth noting that the block generation speed of Hyperliquid L1 is greater than that of the HyperEVM chain, but these blocks will still be executed in sequence. Contracts on the EVM chain can read the data in past L1 blocks and write data to future L1 blocks. As shown in the following figure:
To enable interaction between HyperL1 and HyperEVM, Hyperliquid uses two technical means: Precompiles and Events.
Precompiles
Precompiles, in simple terms, means moving some operations that are difficult to implement in smart contracts and have high complexity to the underlying layer, moving the computational process that is not friendly to Solidity and relatively troublesome to the outside of the regular smart contract, and this precompiled code can be implemented in languages closer to the device bottom layer such as C and C++.
The precompile method can allow the EVM to support more advanced and complex functions, and facilitate the needs of smart contract developers. In terms of appearance, precompiles are essentially a group of special smart contracts, and other smart contracts can directly call these special contracts, pass in parameters, and obtain the return results of the precompile execution. Currently, the native EVM has implemented the ecRecover
instruction through precompiles, which can check the correctness of the secp256k1
signature within the EVM, and this instruction is located at address 0x01
.
Adding some special functions through precompiles is the current mainstream approach, such as Base adding P256
precompiled code to facilitate user WebAuth identity authentication operations.
(This image is from the Rollup Codes website)
Consistent with this current mainstream approach, HyperEVM has also added a series of precompiled codes to implement the EVM's reading of the Hyperliquid order book system state. Currently, a known Hyperliquid precompiled code address is 0x0000000000000000000000000000000000000800
, which can read the user's perpetual contract position information in the most recent L1 block.
Events
As mentioned earlier, HyperEVM can write data into HyperL1 blocks, and this writing behavior is dependent on Events. Events is a native concept in EVM, which allows smart contracts to send log information to the outside world (such as front-end applications or listeners) during the execution process, so that the outside world can monitor the running status of the smart contract.
For example, when a user uses the token transfer function of an ERC-20 contract, the contract will throw the corresponding Transfer
Event, so that the block browser and other front-end applications can know the token transfer situation. These Events information will be included in the block, and there are many mature solutions for listening and retrieving Events logs.
Now many cross-chain-related scenarios will use Events to transmit cross-chain parameters, such as the bridge contract deployed on the Ethereum mainnet by Arbitrum, where users can call related functions to throw events on Arbitrum to trigger transactions.
The available information shows that HyperLiquid nodes will listen to the Events thrown by the address 0x3333333333333333333333333333333333333333
(event address), and based on the information contained in the Events, they will convert the user's intentions into transaction actions and write them into the future Hyperliquid L1 blocks.
For example, the above event address will provide a function, and when the user calls this function, the event address will throw an Event named IocOrder
. When the Hyper L1 block is generated, the HyperLiquid node will first query the Events thrown by the event address in the recent HyperEVM, and when a new IocOrder
event is found, it will convert it into an order placement operation in the Hyper L1.
HyperBFT
At the consensus protocol level, Hyperliquid adopts a protocol called HyperBFT, which is a derivative method based on HotStuff. Currently, HutStuff-2 is one of the latest consensus protocols with the lowest complexity.
According to the information, Hyperliquid initially used the Tendermint consensus algorithm, which is the default consensus algorithm used in the Cosmos system, but this algorithm is less efficient, and each stage requires an All-to-All message exchange, where each node needs to send messages to all other nodes, with a communication complexity of O(n²), where n is the number of nodes.
If Tendermint is used, Hyperliquid can process up to 20,000 orders per second. To achieve the speed of a centralized exchange, the HyperLiquid team developed the HyperBFT algorithm based on HotStuff and implemented it in Rust, which can theoretically process up to 2 million orders per second.
The following diagram shows the message passing mode of the HyperBFT consensus in a non-parallel scenario, where all messages are summarized and uniformly broadcast by the Leader, eliminating the step of nodes exchanging messages with each other, greatly reducing the complexity.
In simple terms, HyperBFT is a consensus protocol where the current leader produces blocks, all nodes participate in voting, and the voting results are uniformly sent to the Leader, and then the next leader takes over. In fact, the specific details involved in Hotstuff and Tendermint are much more complex, and this article does not go into details due to the limited scope and focus.
Key points for developers to note
The above-mentioned data reading mechanism based on Precompiles is relatively perfect, Solidity developers do not need to write specific code to read the Hyper L1 state, but they need to pay attention to the issue of msg.sender
. Similar to most Ethereum Layer 2s, HyperLiquid also allows users to directly interact with the system contracts in Hyper L1, indirectly triggering transactions on the HyperEVM chain. In this case, if the smart contract reads the msg.sender
field in the transaction, it will find that msg.sender
corresponds to the address of the HyperL1 system contract, rather than the user address that initially initiated the transaction on HyperL1.
For the interaction between EVM and L1, developers need to pay attention to a series of issues. The first problem is the non-atomicity of the interaction, if the user indirectly places an order on L1 through the aforementioned event address on HyperEVM, but there are insufficient assets on L1, then the transaction will definitely fail, but the user will not receive an error return when calling the event address function. The non-atomicity of the interaction may lead to the user's assets being damaged. In this case, developers need to manually handle the failure of order placement in the EVM smart contract. Moreover, the smart contract in the EVM should have a function to ultimately retrieve the funds, to avoid the user's assets being permanently unrecoverable on L1.
Secondly, the contract address corresponding to the EVM must have a mapped account on L1, when the user deploys the smart contract in the EVM, they need to transfer a small amount of USDC to the mapped address on L1 to force L1 to create an account for the contract address. This operation may be related to the underlying consensus of HyperLiquid, and there are specific requirements in the HyperLiquid documentation.
Finally, developers need to pay attention to some special situations, especially the balance of tokens. Hyper L1 has a special address for asset transfer, but when users send assets to this special address, the assets will be transferred from L1 to the HyperEVM chain. Since the HyperLiquid nodes actually execute both the EVM chain and the L1 chain, the user's balance on the EVM chain may not be readable for a long time after the user transfers the assets, as the HyperEVM has not yet produced a block.
In simple terms, the user's assets are stuck in the cross-chain bridge at this time, and they cannot be queried on either L1 or the EVM chain. The protocol developed by the developer should handle the above special situations to avoid causing panic among users.
In summary, HyperEVM is similar to a Layer 2 based on the Hyperliquid L1, HyperEVM relies on Precompiled code to read the L1 state, and also relies on Events to interact with Hyper L1. L1 also has some system contracts to help users trigger transactions on HyperEVM or perform asset cross-chain. But unlike the general Layer1-Layer2 architecture, Hyperliquid provides higher interoperability for HyperEVM.
References
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?