Hyperliquid Docs
  • About Hyperliquid
    • Core contributors
  • Onboarding
    • How to start trading
    • How to use the HyperEVM
    • Connect mobile via QR code
    • Export your email wallet
    • Testnet faucet
  • HyperCore
    • Overview
    • Bridge
    • API servers
    • Clearinghouse
    • Oracle
    • Order book
    • Staking
    • Vaults
      • Protocol vaults
      • For vault leaders
      • For vault depositors
    • Multi-sig
  • HyperEVM
    • Tools for HyperEVM builders
  • Hyperliquid Improvement Proposals (HIPs)
    • HIP-1: Native token standard
    • HIP-2: Hyperliquidity
    • HIP-3: Builder-Deployed Perpetuals
    • Frontend checks
  • Trading
    • Perpetual assets
    • Contract specifications
    • Margin tiers
    • Fees
    • Builder codes
    • Order book
    • Order types
    • Take profit and stop loss orders (TP/SL)
    • Margining
    • Liquidations
    • Entry price and pnl
    • Funding
    • Miscellaneous UI
    • Auto-deleveraging
    • Robust price indices
    • Self-trade prevention
    • Portfolio graphs
    • Hyperps
    • Market making
  • Validators
    • Running a validator
    • Delegation program
  • Referrals
    • Staking referral program
  • Points
  • Historical data
  • Risks
  • Bug bounty program
  • Audits
  • Brand kit
  • For developers
    • API
      • Notation
      • Asset IDs
      • Tick and lot size
      • Nonces and API wallets
      • Info endpoint
        • Perpetuals
        • Spot
      • Exchange endpoint
      • Websocket
        • Subscriptions
        • Post requests
        • Timeouts and heartbeats
      • Error responses
      • Signing
      • Rate limits
      • Bridge2
      • Deploying HIP-1 and HIP-2 assets
      • Deploying HIP-3 assets
    • HyperEVM
      • Dual-block architecture
      • Raw HyperEVM block data
      • Interacting with HyperCore
      • HyperCore <> HyperEVM transfers
      • Wrapped HYPE
      • JSON-RPC
    • Nodes
      • L1 Data Schemas
Powered by GitBook
On this page
  • Token Deployment
  • User and Anchor Token Genesis
  • Hyperliquidity
  1. Hyperliquid Improvement Proposals (HIPs)

Frontend checks

There are many ways to reach invalid configurations during the spot deploy process. To avoid this, deployers can try intended deployments on testnet first. For automated deployment integrations, the following is a list of client-side checks that may be helpful.

Token Deployment

    if (szDecimals === undefined || weiDecimals === undefined) {
      displayAlert(
        "Size decimals and Wei decimals must be specified.",
        "error"
      );
      return;
    }
    if (szDecimals > 2 || szDecimals < 0) {
      displayAlert("Size decimals must be between 0 and 2.", "error");
      return;
    }
    if (weiDecimals > 8 || weiDecimals < 0) {
      displayAlert("Wei decimals must be between 0 and 8.", "error");
      return;
    }
    if (szDecimals + 5 > weiDecimals) {
      displayAlert("weiDecimals must be at least szDecimals + 5.", "error");
      return;
    }

User and Anchor Token Genesis

    if (amount.toString().length > 19) {
      displayAlert(`Can only enter up to 19 digits for Amount.`, "error");
      return;
    }

    const hypotheticalTotalSupply =
      BigInt(activeTokenDeployState?.totalGenesisBalanceWei ?? 0) +
      BigInt(amount);

    if (hypotheticalTotalSupply > MAX_UINT_64 / BigInt(2)) {
      displayAlert(
        "Total supply would be too large with this addition",
        "error"
      );
      return;
    }

    const minStartPrice = getMinStartPrice(szDecimals);
    if (
      minStartPrice *
        Number(formatUnits(hypotheticalTotalSupply, weiDecimals)) >
      MAX_MARKET_CAP_MILLIONS_START * 1e6
    ) {
      displayAlert(
        "Total supply would be too large even at smallest possible Hyperliquidity initial price",
        "error"
      );
      return;
    }

    if (
      (!isAddress(user) && existingToken === undefined) ||
      (isAddress(user) && existingToken !== undefined)
    ) {
      displayAlert(
        "Exactly one of user or existing token must be specified.",
        "error"
      );
      return;
    }

    if (user.toLowerCase() === HYPERLIQUIDITY_USER) {
      displayAlert(
        "Cannot assign genesis balance to hyperliquidity user",
        "error"
      );
      return;
    }

    if (!activeTokenDeployState || activeTokenDeployState.token === undefined) {
      displayAlert(
        "Need to handle fetching previously created token.",
        "error"
      );
      return;
    }

    const minWei = getWei(100000, activeTokenDeployState.spec.weiDecimals);
    if (
      existingToken !== undefined &&
      !isAddress(user) &&
      BigInt(amount) < BigInt(minWei)
    ) {
      displayAlert(
        `Using an existing token as anchor token for genesis requires a minimum amount of 100,000 ${activeTokenDeployState.spec.name} (wei=${minWei}).`,
        "error"
      );
      return;
    }

Hyperliquidity

    const PX_GAP = 0.003;
    const MAX_N_ORDERS = 4000;
    const MAX_MARKET_CAP_BILLIONS_END = 100;
    const MIN_MARKET_CAP_BILLIONS_END = 1;
    const MAX_MARKET_CAP_MILLIONS_START = 10;
    const MAX_UINT_64 = BigInt("18446744073709551615");

    if (
      startPx === undefined ||
      orderSz === undefined ||
      orderCount === undefined
    ) {
      displayAlert(
        "Start price, order size, and number of orders must be specified.",
        "error"
      );
      return;
    }

    const minStartPx = getMinStartPx(szDecimals);
    if (startPx < minStartPx) {
      displayAlert(
        `First order price must be at least ${roundPx(
          minStartPx,
          szDecimals,
          true
        )}`,
        "error"
      );
      return;
    }

    if (startPx * orderSz < 1) {
      displayAlert("First order size must be at least 1 USDC", "error");
      return;
    }

    if (!activeTokenDeployState || activeTokenDeployState.spots.length === 0) {
      displayAlert(
        "Unexpected error: spot and token should already be registered.",
        "error"
      );
      return;
    }

    const pxRange = Math.ceil(Math.pow(1 + PX_GAP, orderCount));
    const endPx = startPx * pxRange;
    // 1e9 instead of 1e8 because backend checks against u64::MAX / 10
    if (
      pxRange > 1_000_000 ||
      hyperliquidityTotalWei > MAX_UINT_64 ||
      endPx * orderSz * 1e9 > MAX_UINT_64
    ) {
      displayAlert(
        "Total Hyperliquidity token allocation is too large.",
        "error"
      );
      return;
    }

    const minTotalGenesisBalanceSz = 100_000_000;
    if (totalSupply * Math.pow(10, szDecimals) < minTotalGenesisBalanceSz) {
      displayAlert(
        `Total genesis balance must be at least ${minTotalGenesisBalanceSz} lots (minimal tradeable units, i.e. one lot is 0.01 if szDecimals is 2)`,
        "error"
      );
      return;
    }

    const endMarketCap = totalSupply * endPx;
    if (endMarketCap > MAX_MARKET_CAP_BILLIONS_END * 1e9) {
      displayAlert(
        `Market cap must be <${MAX_MARKET_CAP_BILLIONS_END}B USDC at Hyperliquidity end price`,
        "error"
      );
      return;
    }

    if (endMarketCap < MIN_MARKET_CAP_BILLIONS_END * 1e9) {
      displayAlert(
        `Market cap must be >${MIN_MARKET_CAP_BILLIONS_END}B USDC at Hyperliquidity end price`,
        "error"
      );
      return;
    }

    if (totalSupply * startPx > MAX_MARKET_CAP_MILLIONS_START * 1e6) {
      displayAlert(
        `Market cap must be <${MAX_MARKET_CAP_MILLIONS_START}M USDC at Hyperliquidity start price`,
        "error"
      );
      return;
    }

    if (orderCount < 10) {
      displayAlert("Hyperliquidity must have at least 10 orders", "error");
      return;
    }

    if ((orderSz * orderCount) / totalSupply <= 0.01) {
      displayAlert("Hyperliquidity must be >1% of total supply", "error");
      return;
    }
PreviousHIP-3: Builder-Deployed PerpetualsNextTrading

Last updated 12 months ago