Guardian's review of Hyperliquid Deployment for USDT0, published March 2025. The report records 11 findings across 2 review rounds, including 1 low and 10 informational.
- Published
- Review window
- February 27 to March 5, 2025
- Rounds
- Main Review, Remediation Review
- Language
- Solidity
- Chains
- Hyperliquid
- Sector
- Stablecoins, Cross-chain
- 0 Critical
- 0 High
- 0 Medium
- 1 Low
- 10 Informational
Scope
Findings 11
Main Review
9 findings · February 27 to March 5, 2025-
L-01 Low System Address Receiver Undefined Behavior Warning Resolved
Description
The
HyperLiquidComposercontract allows the user to transfer their USDT0 to any receiver address on the HyperLiquid L1. Included in this is the HyperLiquid system contract0x2222222222222222222222222222222222222222. It is unclear how the HyperLiquid system will handle a transfer from the composer contract to the system contract followed by another transfer from the system contract to the system contract. Depending on the integration of USDT0 in the spot balances on the HyperLiquid L1 this may cause unexpected issues and has the potential to duplicate tokens depending on the behavior.Recommendation
Consider explicitly disallowing a receiver address of the HyperLiquid system contract
0x2222222222222222222222222222222222222222to avoid any unexpected behavior. -
I-01 Informational Misleading Comment Documentation Acknowledged
Description
The base
TetherTokencontract indicates that theisTrustedvariable is anUnused variable retained to preserve storage slots across upgrades. However in theHyperliquidExtensionthis mapping is used to validatetransferWithHopcallers.Recommendation
Consider removing or updating the comment for the Hyperliquid deployment. Otherwise add a new comment in the
HyperliquidExtensioncontract. -
I-02 Informational Trapped Funds With Malformed ComposeMsg Trapped Funds Acknowledged
Description
The
lzComposefunction in theHyperLiquidComposercontract expects thecomposeMsgto contain an address and only an address in it’s contents. In the event that acomposeMsgis provided which does not adhere to this structure and has less bytes than an address, the decoding reverts and thelzComposecall cannot be executed for the corresponding message. In this case the USDT0 bridged to theHyperLiquidComposercontract is effectively trapped.Recommendation
Be aware of this risk and be sure to include the proper validations in the UI when sending composed messages to the
HyperLiquidComposer. If further mitigation is desired, consider adding a rescue function where a trusted address can withdraw trapped USDT0 from the contract. -
I-03 Informational Lacking Zero Address Checks Validation Resolved
Description
The
HyperLiquidComposercontract does not implement zero address validations in the constructor for the_token,_endpoint, or_oAppaddresses.Recommendation
Consider implementing zero address validations to reduce the risk of an incorrect deployment.
-
I-04 Informational Unnecessary Imports Superfluous Code Resolved
Description
In the
HyperLiquidComposercontract theIOAppCoreandOStableWrapperimports are unnecessary. Additionally, theSafeERC20library usage and import is unnecessary.Recommendation
Remove the
IOAppCore,OStableWrapper, andSafeERC20imports. -
I-05 Informational Lacking Token Validation Validation Resolved
Description
The
lzComposefunction assumes that thetokenandOAppare connected, however there is no explicit validation in the constructor which asserts this at the Smart Contract level. If these addresses are somehow misconfigured it could lead to failed bridges and trapped funds.Recommendation
Consider adding validation in the constructor to ensure that the
OAppandtokenpair are correctly linked via theHyperLiquidExtension.oftContractandOUpgradeable.tokenfunctions. -
I-06 Informational Composed Messages Stuck For Certain Receivers DoS Acknowledged
Description
The
_beforeTokenTransferfunction in theTetherTokenbase contract prevents transfers where the USDT0 contract or the zero address is the recipient. Any composed messages with the recipient as the USDT0 contract or the zero address will therefore be unexecutable. Notice that compose messages with a blacklisted address as the receiver will also be unexecutable, since thetransferWithHopfunction attempts to transfer from thereceiveraddress.Recommendation
Be sure to validate in the UI that the receiver address is not the USDT0 contract on HyperEVM nor the zero address.
-
I-07 Informational Incorrect Documentation Documentation Resolved
Description
The comment for the constructor in the
HyperLiquidComposercontract indicates that the constructorConstructs the StableComposer contract. However instead it should readConstructs the HyperLiquidComposer contract. Additionally, thelzComposefunction documentation indicates that the function is intended to perform atoken swapand that itexpects the encoded compose message to contain the swap amount and recipient address. This misleading documentation about the expected contents of the compose message could be dangerous for users and integrators. If a user were to supply a compose message which follows the documentation the compose message would be unexecutable and the user’s funds would be trapped.Recommendation
Update the documentation to reflect that the
HyperLiquidComposercontract is constructed, what this contracts intent is, and that only a recipient address is expected. -
I-08 Informational Trapped ETH In lzCompose Trapped Funds Acknowledged
Description
The
lzComposefunction ispayablein the LayerZero interface, however the implementation in theHyperLiquidComposercontract does not expect to receive any native funds. As a result any native funds sent by an executor when executing thelzComposefunction would be lost.Recommendation
Consider validating that the
msg.valueprovided to thelzComposefunction is explicitly 0 since thepayablemodifier is necessary to adhere to the LayerZero interface.
Remediation Review
2 findings · February 28 to March 2, 2025-
I-01 Informational Hyperliquid Deployment Concerns Warning Reported
Description
The deployment and bridging of an ERC20 token on HyperEVM, intended to interact with a native spot asset on Hyperliquid L1, involves specific initialization requirements and token supply configurations that raise concerns about correctness and clarity. When a spot token is deployed on Hyperliquid L1, there are multiple settings to take into account, especially, the maximum supply and the user genesis balances. The maximum supply represents the maximum total supply of the token across all chains and it is used mainly for internal accounting, to display market caps etc. The user genesis balances are the accounts that receive the maximum supply when the token is created, or which is the same, the original minted balances. The USDT token current
totalSupplyis equal to 76,918,584,460.692261 on Ethereum mainnet and, therefore, during the deployment into the Hyperliquid L1, it is required to configure the maximum supply to be 76,918,584,460.692261 as well. Moreover, in the user genesis[0x222...222, 76,918,584,460.692261]must be set which basically would say that the total supply should be assigned to the bridge. This, in effect, is just for virtual accounting as the bridge does not have the76918584460692261tokens, however, neither does the L1. Later on, when a transfer from the EVM to the L1 occurs, all Hyperliquid does on the L1 is debit that amount from the0x222...222system address and credit the amount to the account that the amount was transferred from. For example, see the genesis balance of UBTC which is configured to have the entire BTC supply of 21 Million: https://app.hyperliquid.xyz/explorer/token/0x8f254b963e8468305d409b33aa137c67Recommendation
To ensure the successful deployment and bridging of the USDT0 ERC20 token on HyperEVM with Hyperliquid L1, the total balance and user genesis balance for the bridge contract should be assigned to the total supply of USDT on Ethereum Mainnet at the time of listing. It is unclear how to handle tokens which may increase or decrease in totalSupply over time such as USDT, further clarity should be made by the Hyperliquid team before proceeding. Finally, this process should be fully tested earlier on the Hyperliquid testnet following the steps mentioned above.
-
I-02 Informational Unclear ERC20 Transfer Behavior Warning Reported
Description
In this article regarding the functionality of the HyperEVM precompiles it is mentioned that:
Accounts must already exists on the L1 When you first perform an interaction on the L1 from a new smart contract, the action will fail silently on the L1 if the account doesnt not already exists. This must be handled manually such that once the smart contract has been deployed and the address is known, a dust amount of USDC can be sent on the L1 from any account to the address of the smart contract. This forces the account to be created on the L1 and from there everything will work accordingly.It is unclear whether this behavior would only apply to the 0x33333… system precompile address or if it also applies to ERC20 transfers with the 0x222222… system precompile. We are currently confirming this behavior with the HyperLiquid team.
Recommendation
Be aware of this behavior with the 0x333333 system precompile address, and ensure that we are able to confirm the behavior of the 0x222222 ERC20 interactions before moving forward with deployment.
No findings match.
More from USDT0
All 34 reportsPut your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.
