Skip to content

Commit a16f0b7

Browse files
shankars99beer-1
authored andcommitted
feat(hyperliquid-composer): update docs and contract NatSpec (LayerZero-Labs#1929)
Signed-off-by: shankar <shankar@layerzerolabs.org>
1 parent ccc2883 commit a16f0b7

9 files changed

Lines changed: 179 additions & 497 deletions

File tree

.changeset/eight-actors-grow.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@layerzerolabs/hyperliquid-composer": patch
3+
"@layerzerolabs/oft-hyperliquid-example": patch
4+
---
5+
6+
docs update and natspec

examples/oft-hyperliquid/HYPERLIQUID.CHECKLIST.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Block switching is not present in the default oft deploy script.
3434
| Purchase Spot | CoreSpot Deployer | <https://app.hyperliquid.xyz/deploySpot> | HyperCore |
3535
| Blocked by | none | none | Step 2 |
3636

37-
- [ ] Purchase your HyperCore Spot engaging in the [auction](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-16-purchase-the-ticker)
37+
- [ ] Purchase your HyperCore Spot engaging in the [auction](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-0-purchase-the-ticker-prerequisite)
3838

3939
## Step 2 : Deploy the CoreSpot
4040

@@ -54,7 +54,7 @@ Block switching is not present in the default oft deploy script.
5454
| Blocked by | OFT Deployer | Step 0 | Step 3 |
5555
| Blocked by | CoreSpot Deployer | Step 1 | Step 2.2 |
5656

57-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-0-purchase-the-ticker)
57+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-0-purchase-the-ticker-prerequisite)
5858
- [ ] Core spot deployer needs OFT address and deployed transaction hash
5959

6060
### Step 2.2 : Enable freeze privilege (Optional)
@@ -64,7 +64,7 @@ Block switching is not present in the default oft deploy script.
6464
| Enable Freeze Privilege | CoreSpot Deployer | `npx @layerzerolabs/hyperliquid-composer` | HyperCore |
6565
| Blocked by | CoreSpot Deployer | Step 2.1 | Step 2.2 |
6666

67-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-16-enablefreezeprivilege-optional)
67+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-18-enablefreezeprivilege-optional)
6868
- [ ] **MUST be done before genesis** if you want freeze capability
6969
- [ ] Enables post-launch user freeze/unfreeze operations
7070
- [ ] Once set, can only be revoked (irreversible)
@@ -76,7 +76,7 @@ Block switching is not present in the default oft deploy script.
7676
| Set User Genesis | CoreSpot Deployer | `npx @layerzerolabs/hyperliquid-composer` | HyperCore |
7777
| Blocked by | CoreSpot Deployer | Step 2.1 | Step 2.3 |
7878

79-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-26-usergenesis)
79+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-28-usergenesis)
8080
- [ ] HyperCore balances are u64 - the max balance is `2.pow(64) - 1 = 18446744073709551615`
8181
- [ ] Make sure the total balances in the json does not exceed this value.
8282
- [ ] Re-runnable until the next step is executed.
@@ -91,7 +91,7 @@ Block switching is not present in the default oft deploy script.
9191
| Confirm User Genesis | CoreSpot Deployer | `npx @layerzerolabs/hyperliquid-composer` | HyperCore |
9292
| Blocked by | CoreSpot Deployer | Step 2.2 | Step 2.4 |
9393

94-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-36-genesis)
94+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-38-genesis)
9595
- [ ] Locks in the user genesis step and is now immutable.
9696

9797
### Step 2.5 : Create spot deployment
@@ -101,7 +101,7 @@ Block switching is not present in the default oft deploy script.
101101
| Create Spot Deployment | CoreSpot Deployer | `npx @layerzerolabs/hyperliquid-composer` | HyperCore |
102102
| Blocked by | CoreSpot Deployer | Step 2.3 | Step 2.5 |
103103

104-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-46-createspotdeployment)
104+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-58-createspotdeployment)
105105
- Step MUST be run even though we set `noHyperliquidity=true` in genesis
106106
- This can be run even after deployment and linking
107107

@@ -112,7 +112,7 @@ Block switching is not present in the default oft deploy script.
112112
| Register Spot | CoreSpot Deployer | `npx @layerzerolabs/hyperliquid-composer` | HyperCore |
113113
| Blocked by | CoreSpot Deployer | Step 2.4 | Step 3 |
114114

115-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-56-registerspot)
115+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-48-registerspot)
116116
- [ ] Only USDC is supported on HyperCore at the moment - the sdk defaults to USDC.
117117
- [ ] Make sure the asset bridge address on HyperCore has all the tokens minted in Step 2.3. Partial funding is not supported.
118118
- The final step to be executed after which the token will be listed on the spot order book.
@@ -125,11 +125,11 @@ Block switching is not present in the default oft deploy script.
125125
| Blocked by | OFT Deployer | Step 0 | none |
126126
| Blocked by | CoreSpot Deployer | Step 2.1 | none |
127127

128-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-67-setdeployertradingfeeshare-optional)
128+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-68-setdeployertradingfeeshare-optional)
129129
- [ ] Trading fee share is usually 100% (default value) - this allocates the trading fees to the token deployer instead of burning it.
130130
- [ ] Do not lose or burn your deployer address as it collects tokens.
131131
- [ ] Step can be re-run as long as the new fee% is lower than the current one.
132-
- [ ] **Important**: If you plan to enable quote token capability (Step 2.8), read the [Permissionless Spot Quote Assets](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets) documentation before setting this value as it requires a specific trading fee share.
132+
- [ ] **Important**: If you plan to enable quote token capability (Step 2.8), read the [Permissionless Spot Quote Assets](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets) documentation before setting this value as it requires a specific trading fee share
133133
- Even though the default value is 100%, it is recommended that you set it
134134
- This can be run even after deployment and linking
135135

@@ -142,7 +142,7 @@ Block switching is not present in the default oft deploy script.
142142

143143
- [ ] **Review requirements first**: Read [Permissionless Spot Quote Assets](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets) for all requirements
144144
- [ ] Requires specific trading fee share value (see Step 2.7 above)
145-
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-657-enablequotetoken-optional)
145+
- [ ] Follow the [guide](https://github.com/LayerZero-Labs/devtools/blob/main/examples/oft-hyperliquid/HYPERLIQUID.README.md#step-78-enablequotetoken-optional)
146146
- [ ] Enables the token to be used as a quote asset for trading pairs (e.g., OTHER_TOKEN/YOUR_TOKEN)
147147
- [ ] Can be executed after trading fee share is set
148148
- [ ] This can be run even after deployment and linking are complete

examples/oft-hyperliquid/HYPERLIQUID.README.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -364,15 +364,17 @@ The current architecture has certain error handling AND checks (because hyperliq
364364

365365
#### Transfer exceeding u64.max
366366

367-
HyperCore's spot send only allows for a maximum of `u64` tokens to be transferred across. This means (in the unlikely event) that the user sends across greater than `u64` the difference would be returned the the `receiver` address on `HyperEVM`.
367+
HyperCore's spot send only allows for a maximum of `u64` tokens to be transferred across. This means (in the unlikely event) that the user sends across greater than `u64` we revert since the bridge can not send that amount.
368368

369-
#### Transfer exceeding HyperCore Bridge Capactiy
369+
#### Transfer exceeding HyperCore Bridge Capacity
370370

371-
HyperCore's core spots support a maximum of `u64` tokens on the core spot, and this is scaled by the decimal difference between the core spot and the evm spot. It is thus possible that the asset bridge on hypercore has been consumed to the point where the entire transfer can't be sent over. In this event we split the `amount` capping it by `amount * 10.pow(ERC20.decimals() - HyperCore.decimals())` which is the maximum possible core spot tokens that can be consumed at the bridge at any given instant and compute the difference between the computed max core amount converted to evm amount (unscaling) and removing that from the incoming evm amount. We now have `dust` which is the difference between the two and return this to the `receiver` address.
371+
HyperCore's Core Spots support a maximum of `u64` tokens on the Core Spot, and this is scaled by the decimal difference between the Core Spot and the EVM Spot. It is thus possible that the asset bridge on HyperCore has been consumed to the point where the entire transfer can't be sent over. In this event the composer reverts with `TransferAmtExceedsAssetBridgeBalance` — this revert is caught by the try/catch in `lzCompose` and the full amount is refunded to the receiver on HyperEVM.
372+
373+
> Note: The composer does NOT refund dust to the receiver on HyperEVM because we do not expect any due to truncation of `sharedDecimals` in OFT transfers. If your implementation produces dust you would need to add dust refund logic to `_transferERC20ToHyperCore` and `_transferNativeToHyperCore`.
372374
373375
#### Malformed `composeMsg` - unable to abi.decode(composeMsg) into address
374376

375-
The above cases only occur in the stae when the compose payload is valid. In the event that developers write their own front end or try to interact with the composer with their own encoding and aren't careful it is possible that the message contains a `composeMsg` that can not be decoded to an `address`, as such we do not have the `receiver` address. In this event we try returning the tokens to the `sender` on HyperEVM where the sender is the `msg.sender` of the layerzero tx on the source chain.
377+
The above cases only occur in the state when the compose payload is valid. In the event that developers write their own front end or try to interact with the composer with their own encoding and aren't careful it is possible that the message contains a `composeMsg` that can not be decoded to an `address`, as such we do not have the `receiver` address. In this event we try returning the tokens to the `sender` on HyperEVM where the sender is the `msg.sender` of the layerzero tx on the source chain.
376378

377379
#### Malformed `composeMsg` - unable to abi.decode(composeMsg) into address and non-evm sender
378380

@@ -402,7 +404,7 @@ Wire the OFTs together with the standard layerzero wire command (or any other wa
402404
npx hardhat lz:oapp:wire --oapp-config <layerzero.config.ts>
403405
```
404406

405-
Test the OFTs qith `quoteSend()` or by sending a test lzTransaction across the networks.
407+
Test the OFTs with `quoteSend()` or by sending a test lzTransaction across the networks.
406408

407409
## Deploy the Core Spot
408410

@@ -428,7 +430,7 @@ You will have to buy a ticker from the Hyperliquid UI - <https://app.hyperliquid
428430

429431
> ⚠️ note: Unless you buy the ticker you will not be able to deploy the Core Spot.
430432
431-
After this we can use the `core-spot create` command to create a new file under `./deployments/hypercore-{testnet | mainnet}` with the name of the Core Spot token index. This is not a Hyperliquid step but rather something to make the deployment process easier. It is crucial to the functioning of the token deployment after which it really is not needed.
433+
After this we can use the `core-spot create` command to create a new file under `./deployments/hypercore-{testnet | mainnet}` with the name of the Core Spot token index. This is not a Hyperliquid step but rather something to make the deployment process easier. This file is important — the subsequent deployment steps read from it.
432434

433435
```bash
434436
npx @layerzerolabs/hyperliquid-composer core-spot \
@@ -438,7 +440,7 @@ npx @layerzerolabs/hyperliquid-composer core-spot \
438440
[--log-level {info | verbose}]
439441
```
440442

441-
### Step 1/7 `enableFreezePrivilege` (Optional)
443+
### Step 1/8 `enableFreezePrivilege` (Optional)
442444

443445
**Must be done before genesis if you want freeze capability.**
444446

@@ -450,7 +452,7 @@ npx @layerzerolabs/hyperliquid-composer enable-freeze-privilege \
450452
[--log-level {info | verbose}]
451453
```
452454

453-
### Step 2/7 `userGenesis`
455+
### Step 2/8 `userGenesis`
454456

455457
This is the part where you set the genesis balances for the deployer and the users. Since `HyperCore` tokens are of uint type `u64` the most tokens possible are `18446744073709551615`.
456458

@@ -491,9 +493,9 @@ npx @layerzerolabs/hyperliquid-composer user-genesis \
491493
[--log-level {info | verbose}]
492494
```
493495

494-
> ⚠️ Note: There is no limit to the number of time you can re-run this command.
496+
> ⚠️ Note: There is no limit to the number of times you can re-run this command.
495497
496-
### Step 3/7 `genesis`
498+
### Step 3/8 `genesis`
497499

498500
This is the step that registers the above genesis balances on `HyperCore`.
499501

@@ -507,7 +509,7 @@ npx @layerzerolabs/hyperliquid-composer set-genesis \
507509
[--log-level {info | verbose}]
508510
```
509511

510-
### Step 4/7 `registerSpot`
512+
### Step 4/8 `registerSpot`
511513

512514
This is the step that registers the Core Spot on `HyperCore` and creates a base-quote pair. You can choose between USDC, USDT0, HYPE, or custom quote tokens.
513515

@@ -540,7 +542,7 @@ NEXT STEP: Finalize the spot pair with:
540542

541543
**Note:** For additional spot pairs (beyond the first), this command participates in the spot pair deployment Dutch auction.
542544

543-
### Step 5/7 `createSpotDeployment`
545+
### Step 5/8 `createSpotDeployment`
544546

545547
This step finalizes a spot deployment by setting hyperliquidity parameters. Required after `register-spot` to make the trading pair live on HyperCore.
546548

@@ -589,15 +591,15 @@ curl -X POST "https://api.hyperliquid.xyz/info" \
589591
-d '{ "type": "tokenDetails", "tokenId": "<YOUR_TOKEN_ID>"}'
590592
```
591593

592-
### Step 6/7: `setDeployerTradingFeeShare` (Optional)
594+
### Step 6/8: `setDeployerTradingFeeShare` (Optional)
593595

594596
This is the step where you set the trading fee share for the deployer. It can be in the range of `[0%,100%]`.
595597

596598
A deployer fee share <https://hyperliquid.gitbook.io/hyperliquid-docs/trading/fees> is claimed per transaction on HyperCore. Half of the base rate (50%) is allocated as the deployer fee share. The deployer can choose to forgo this fee share by setting the share to `0%`. This causes the deployer's fee share part to be burnt. If it were to be set to `100%`, the deployer would receive the full fee share part of the fee.
597599

598600
> ⚠️ Note: The trading fee can be reset as long as the new share is lower than the previous share.
599601
> ⚠️ Note: This step can also be run after the core spot is deployed.
600-
> ⚠️ **Important**: If you plan to enable quote token capability (Step 6.5/7), read the [Permissionless Spot Quote Assets](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets) documentation before setting this value as it requires a specific trading fee share.
602+
> ⚠️ **Important**: If you plan to enable quote token capability (Step 7/8), read the [Permissionless Spot Quote Assets](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets) documentation before setting this value as it requires a specific trading fee share.
601603
602604
```bash
603605
npx @layerzerolabs/hyperliquid-composer trading-fee \
@@ -608,7 +610,7 @@ npx @layerzerolabs/hyperliquid-composer trading-fee \
608610
[--log-level {info | verbose}]
609611
```
610612

611-
### Step 6.5/7 `enableQuoteToken` (Optional)
613+
### Step 7/8 `enableQuoteToken` (Optional)
612614

613615
This step enables the token to be used as a quote asset for trading pairs. This allows other tokens to form trading pairs against your token (e.g., TOKEN/YOUR_TOKEN instead of only YOUR_TOKEN/USDC).
614616

@@ -630,7 +632,7 @@ npx @layerzerolabs/hyperliquid-composer enable-quote-token \
630632

631633
**Prerequisites:**
632634

633-
- Trading fee share must be set (see Step 6/7 above)
635+
- Trading fee share must be set (see Step 6/8 above)
634636
- **Testnet**: 50 HYPE staked + active BUY and SELL limit orders on your token's order book
635637
- **Mainnet**: All requirements per [Hyperliquid's documentation](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/permissionless-spot-quote-assets)
636638

@@ -640,7 +642,7 @@ npx @layerzerolabs/hyperliquid-composer enable-quote-token \
640642
- You must maintain order book requirements for the new `HYPE/ASSET` pair
641643
- Verify quote asset status with the `list-quote-asset` command
642644

643-
### Step 6.7/7 `enableAlignedQuoteToken` (Optional)
645+
### Step 8/8 `enableAlignedQuoteToken` (Optional)
644646

645647
This step enables the token to be used as an aligned quote asset for trading pairs. Aligned quote tokens have special properties and requirements different from regular quote tokens.
646648

@@ -708,13 +710,13 @@ This will output the calldata and a ready-to-use `cast send` command that you ca
708710

709711
## Deploy the Composer
710712

711-
While the composer could have been deployed at any point in time due to its statelessness, it is technically the final step of the deployment process. The following script automatically handles the block switching for you.
713+
While the base composer could have been deployed at any point in time since its constructor only requires immutable values, it is technically the final step of the deployment process. Note that some extensions (e.g. `PreFundedFeeAbstraction`) have mutable state such as `maxUsersPerBlock` and `feeWithdrawalBlockNumber`. The following script automatically handles the block switching for you.
712714

713715
```bash
714716
npx hardhat lz:deploy --tags MyHyperLiquidComposer
715717
```
716718

717-
> ⚠️ Note: You would need to activate the composer's address on hypercore by transferring any amount of tokens from a wallet that has at least $1 in quote tokens. This $1 will be automatically debited from your accoutn to cover an activation fee.
719+
> ⚠️ Note: You would need to activate the composer's address on hypercore by transferring any amount of tokens from a wallet that has at least $1 in quote tokens. This $1 will be automatically debited from your account to cover an activation fee.
718720
719721
## Advanced: Creating Custom Scripts
720722

examples/oft-hyperliquid/contracts/MyHyperLiquidComposer.sol

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ contract MyHyperLiquidComposer is HyperLiquidComposer {
1717
///
1818
/// @param _oft The address of the OFT
1919
/// @param _hlIndexId The HyperLiquid core spot's index value
20-
/// @param _assetDecimalDiff The difference in decimals between the HyperEVM's ERC20 and the HyperLiquid HIP-1 token
21-
/// (i.e. 18 decimals on evm and 6 on HyperLiquid would be 18 - 6 = 12)
20+
/// @param _assetDecimalDiff The decimal difference: ERC20.decimals() - HIP1.weiDecimals() (must be in [-2, 18])
2221
constructor(
2322
address _oft,
2423
uint64 _hlIndexId,

examples/oft-hyperliquid/contracts/extensions/MyHyperLiquidComposer_FeeAbstraction.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { PreFundedFeeAbstraction } from "@layerzerolabs/hyperliquid-composer/con
1515
contract MyHyperLiquidComposer_FeeAbstraction is PreFundedFeeAbstraction {
1616
/// @param _oft The OFT address
1717
/// @param _hlIndexId The HyperLiquid core spot index
18-
/// @param _assetDecimalDiff EVM - HyperLiquid decimal difference
18+
/// @param _assetDecimalDiff The decimal difference: ERC20.decimals() - HIP1.weiDecimals() (must be in [-2, 18])
1919
/// @param _spotId The spot pair ID (e.g., 107 for HYPE/USDC)
2020
/// @param _activationOverheadFee Overhead fee in cents on top of $1 base
2121
/// @param _recoveryAddress Address for fee recovery

0 commit comments

Comments
 (0)