# Hfun Labs Docs ## Hfun Sentry Gated access to the Alphaticks validator sentry via [aHYPESeat](/hfun-ahype/ahypeseat/introduction). ### Overview Hfun Sentry provides direct connection to the Alphaticks validator sentry node running in `ap-northeast-1` (Tokyo). This enables low-latency access to Hyperliquid L1 data for node operators. Access is managed through the aHYPESeat contract - users purchase a seat and whitelist their node's IP address. ### Benefits * **Low latency**: Direct connection to validator sentry in AWS Tokyo * **Reliable**: Enterprise-grade infrastructure * **Permissionless**: Purchase access via aHYPESeat contract ### Requirements * aHYPE collateral for seat purchase * A running [Hyperliquid node](https://github.com/hyperliquid-dex/node) * Static IP address for your node ## Setup ### 1. Purchase a Seat 1. Go to [alphaticks.io/alpha-hype-sentry](https://alphaticks.io/alpha-hype-sentry) 2. Connect your wallet 3. Purchase a seat by locking aHYPE collateral ### 2. Whitelist Your IP After purchasing a seat, configure your node's IP address: 1. Enter the static IP of your Hyperliquid node 2. Submit the whitelist transaction 3. Wait for confirmation ### 3. Configure Your Node Update your Hyperliquid node `gossip_config.json` to connect to the Alphaticks sentry: ```json { "root_node_ips": [ { "Ip": "3.114.22.239" } ], "try_new_peers": false, "chain": "Mainnet" } ``` See the [Hyperliquid node documentation](https://github.com/hyperliquid-dex/node) for full setup instructions. ### 4. Verify Connection Once configured, your node should sync from the Alphaticks sentry. Check your node logs to confirm the connection is established. ### Managing Your Seat * **Add collateral**: Top up aHYPE to maintain healthy collateral ratio * **Update IP**: Change your whitelisted IP if your node moves * **Monitor health**: Ensure your seat doesn't become liquidatable See [aHYPESeat documentation](/hfun-ahype/ahypeseat/introduction) for contract details and automation. ## Client Messages All messages sent from the client to the server. ### Subscribe ```json {"method": "subscribe", "subscription": {...}} ``` See [Subscriptions](./subscriptions) for available subscription types. ### Unsubscribe ```json {"method": "unsubscribe", "subscription": {...}} ``` ### Ping ```json {"method": "ping"} ``` The server responds with `{"channel": "pong"}`. ### Post (Query) ```json {"method": "post", "id": 123, "request": {...}} ``` See [Post Requests](./post-requests) for available query types. ### Example: wscat ```bash wscat -c "wss://api.example.com/ws?jwt=" ``` Once connected: ``` > {"method": "subscribe", "subscription": {"type": "l2Book", "coin": "BTC"}} > {"method": "ping"} > {"method": "unsubscribe", "subscription": {"type": "l2Book", "coin": "BTC"}} ``` ## HTTP Endpoints ### POST /info HTTP endpoint for querying order book data. Your IP address must be whitelisted - authentication is automatic. *** ### All Mids Request mid prices for all trading pairs. **Request:** ```json { "type": "allMids" } ``` **Response:** ```json { "BTC": "97000.5", "ETH": "3500.25", ... } ``` Returns a map of coin symbols to their mid prices as strings. *** ### Impact Price Calculate impact prices for a given coin and notional size. **Request:** ```json { "type": "impactPrice", "coin": "BTC", "notional": "10000" } ``` | Field | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------- | | `type` | string | yes | Must be `"impactPrice"` | | `coin` | string | yes | Trading pair (e.g., `"BTC"`, `"ETH"`) | | `notional` | string | yes | Notional size in USD | **Response:** ```json { "buyImpactPx": "97100.5", "sellImpactPx": "96900.3", "time": 1703271234000 } ``` | Field | Type | Description | | -------------- | -------------- | --------------------------------------------- | | `buyImpactPx` | string \| null | Price to buy the notional amount (walk asks) | | `sellImpactPx` | string \| null | Price to sell the notional amount (walk bids) | | `time` | number | Timestamp in milliseconds | **Error Responses:** * `400 Bad Request` - Invalid notional value * `500 Internal Server Error` - Failed to process request *** ### Example: cURL #### All Mids ```bash curl -X POST https://api.example.com/info \ -H "Content-Type: application/json" \ -d '{"type": "allMids"}' ``` #### Impact Price ```bash curl -X POST https://api.example.com/info \ -H "Content-Type: application/json" \ -d '{"type": "impactPrice", "coin": "BTC", "notional": "100000"}' ``` *** ### IP Whitelist Management Endpoints for managing IP whitelists. Requires signature authentication. **Authentication Header:** ``` Authorization: Signature ts=,sig= ``` | Parameter | Type | Description | | --------- | ------ | ------------------------------------------------------------- | | `ts` | number | Unix timestamp in seconds (must be within 60s of server time) | | `sig` | string | Ethereum signature (hex with 0x prefix) | Sign the message `hfun-feed:` with your Ethereum wallet. The signature must be from an address with an active AlphaHype seat. **Example (JavaScript/ethers.js):** ```javascript const timestamp = Math.floor(Date.now() / 1000); const message = `hfun-feed:${timestamp}`; const signature = await wallet.signMessage(message); const headers = { 'Authorization': `Signature ts=${timestamp},sig=${signature}`, 'Content-Type': 'application/json' }; ``` *** #### POST /ip/add Add an IP address to the whitelist for the authenticated address. **Request:** ```json { "ip": "203.0.113.42" } ``` | Field | Type | Required | Description | | ----- | ------ | -------- | --------------------------- | | `ip` | string | yes | IPv4 or IPv6 address to add | **Response (200 OK):** ```json { "status": "ok", "ip": "203.0.113.42" } ``` **Errors:** * `400 Bad Request` - Invalid IP address format or IP already whitelisted * `401 Unauthorized` - Invalid or missing signature * `403 Forbidden` - Signer does not have an active seat, or max IPs per seat exceeded * `503 Service Unavailable` - IP whitelist feature not enabled *** #### POST /ip/remove Remove an IP address from the whitelist for the authenticated address. **Request:** ```json { "ip": "203.0.113.42" } ``` | Field | Type | Required | Description | | ----- | ------ | -------- | ------------------------------ | | `ip` | string | yes | IPv4 or IPv6 address to remove | **Response (200 OK):** ```json { "status": "ok", "ip": "203.0.113.42" } ``` **Errors:** * `400 Bad Request` - Invalid IP address format * `401 Unauthorized` - Invalid or missing signature * `403 Forbidden` - Signer does not have an active seat * `503 Service Unavailable` - IP whitelist feature not enabled *** #### POST /ip/list List all whitelisted IP addresses for the authenticated address. **Request:** Empty body or `{}`. **Response (200 OK):** ```json { "ips": [ "203.0.113.42", "198.51.100.10" ] } ``` **Errors:** * `401 Unauthorized` - Invalid or missing signature * `403 Forbidden` - Signer does not have an active seat * `503 Service Unavailable` - IP whitelist feature not enabled *** ### Example: IP Management with cURL #### Add IP ```bash curl -X POST https://api.example.com/ip/add \ -H "Content-Type: application/json" \ -H "Authorization: Signature ts=1234567890,sig=0x..." \ -d '{"ip": "203.0.113.42"}' ``` #### Remove IP ```bash curl -X POST https://api.example.com/ip/remove \ -H "Content-Type: application/json" \ -H "Authorization: Signature ts=1234567890,sig=0x..." \ -d '{"ip": "203.0.113.42"}' ``` #### List IPs ```bash curl -X POST https://api.example.com/ip/list \ -H "Content-Type: application/json" \ -H "Authorization: Signature ts=1234567890,sig=0x..." \ -d '{}' ``` ## HFun Feed WebSocket API Real-time order book data from Hyperliquid node infrastructure. ### Overview This server provides real-time order book data from Hyperliquid node infrastructure. It implements endpoints compatible with [Hyperliquid's official API](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions), with extensions. ### AlphaHype Seats Access to the API requires an AlphaHype seat. The seat system is an on-chain smart contract on the Hyper EVM with a limited number of seats available (currently 10). #### How It Works 1. **Purchase a seat** by depositing aHYPE tokens as collateral 2. **Whitelist your IP** via the [`/ip/add`](./http-endpoints)#post-ipadd) endpoint 3. **Connect** - authentication is automatic once your IP is whitelisted #### Pricing Model Seat fees are based on utilization - the more seats occupied, the higher the fee rate: * Fee rate scales linearly from a minimum to maximum rate * Fees accrue per second while you hold a seat * Higher utilization = higher fees for all seat holders #### Collateral & Health * Your collateral must always cover your accrued fees (debt) * If your debt exceeds your collateral, your position becomes unhealthy * Unhealthy seats are automatically disconnected from the API * Unhealthy positions can be liquidated ("kicked"), forfeiting the collateral * Add collateral or repay fees to maintain a healthy position #### Management Seats can be purchased and managed on [alphaticks](https://alphaticks.io/alpha-hype-api). ### Available Subscriptions | Type | Description | | ----------------------------------------------- | ---------------------------------------------------- | | [`l1Book`](./subscriptions/l1-book) | Top of book (best bid/ask) | | [`l2Book`](./subscriptions/l2-book) | Aggregated price levels (periodic snapshots) | | [`l3Book`](./subscriptions/l3-book) | Order-level data, lightweight fields | | [`l4Book`](./subscriptions/l4-book) | Order-level data, full details (triggers, TIF, etc.) | | [`trades`](./subscriptions/trades) | Real-time trade stream | | [`candle`](./subscriptions/candles) | Real-time candlestick data | | [`allMids`](./subscriptions/all-mids) | Mid prices for all trading pairs | | [`impactPrice`](./subscriptions/impact-price) | Impact price calculations | | [`orderUpdates`](./subscriptions/order-updates) | Real-time order status updates | | [`userFills`](./subscriptions/user-fills) | Real-time fill notifications | ### Available Queries | Type | Description | | ----------------------------- | ------------------------------ | | [`l3Orders`](./post-requests) | Query L3 orders by price range | | [`l4Orders`](./post-requests) | Query L4 orders by price range | ## Post Requests (Queries) Query orders by price range without subscribing to full book. ### Request Format ```json { "method": "post", "id": 123, "request": { "type": "info", "payload": { "type": "l4Orders", "coin": "BTC", "pxMin": "35000", "pxMax": "37000" } } } ``` ### Payload Types | Type | Description | | ---------- | ------------------------------ | | `l4Orders` | Query L4 orders in price range | | `l3Orders` | Query L3 orders in price range | ### Payload Fields | Field | Type | Description | | ------- | ---------------------------- | ------------------------- | | `type` | `"l4Orders"` \| `"l3Orders"` | Query type | | `coin` | string | Trading pair | | `pxMin` | string | Minimum price (inclusive) | | `pxMax` | string | Maximum price (inclusive) | ### Response ```json { "channel": "post", "data": { "id": 123, "response": { "type": "info", "payload": { "type": "l4Orders", "data": { "coin": "BTC", "time": 1699900000000, "orders": [ [/* bids */], [/* asks */] ] } } } } } ``` ### Response Fields | Field | Type | Description | | ------------------------------ | ------ | -------------------------------- | | `id` | number | Request ID (echoed from request) | | `response.type` | string | Response type (`"info"`) | | `response.payload.type` | string | Query type | | `response.payload.data.coin` | string | Trading pair | | `response.payload.data.time` | number | Timestamp | | `response.payload.data.orders` | array | `[bids, asks]` arrays | ### Example: Query L3 Orders **Request:** ```json { "method": "post", "id": 1, "request": { "type": "info", "payload": { "type": "l3Orders", "coin": "ETH", "pxMin": "3400", "pxMax": "3600" } } } ``` **Response:** ```json { "channel": "post", "data": { "id": 1, "response": { "type": "info", "payload": { "type": "l3Orders", "data": { "coin": "ETH", "time": 1699900000000, "orders": [ [ {"user": "0x...", "coin": "ETH", "side": "B", "limitPx": "3500.0", "sz": "1.0", "oid": 123, "timestamp": 1699899000000} ], [ {"user": "0x...", "coin": "ETH", "side": "A", "limitPx": "3550.0", "sz": "2.0", "oid": 456, "timestamp": 1699899500000} ] ] } } } } } ``` ## Rate Limits Rate limits are enforced per authenticated identity (Ethereum address or Telegram user ID). All limits are shared across your WebSocket connections - if you open multiple connections, they draw from the same pool. ### Connections Each identity can maintain a limited number of concurrent WebSocket connections. AlphaHype users can open up to **10 connections**, while Telegram users can open up to **20 connections**. This allows you to run multiple clients or services under the same identity without interference. If you try to open a new connection after reaching the limit, it will be rejected with HTTP 429. ### Subscriptions You can have up to **100 active subscriptions** across all your connections. When you hit the limit, new `subscribe` requests will fail, but your existing subscriptions keep working. Unsubscribe from channels you no longer need to free up slots. ### Unique Users For user-specific subscriptions (`orderUpdates` and `userFills`), there's a limit of **10 unique user addresses** you can track across all connections. This prevents any single client from monitoring too many accounts. Subscribing to both `orderUpdates` and `userFills` for the same address counts as just one unique user. When you close a connection, the user slots it was using become available again. ### Messages Inbound WebSocket messages are limited to **1,000 per minute** with a small burst allowance for temporary spikes. This includes all message types: `subscribe`, `unsubscribe`, `ping`, and `post` requests. Under normal usage you won't hit this limit - it's primarily there to protect against runaway clients or bugs that might flood the server. ### Inflight Posts The `post` method for queries allows up to **100 concurrent requests** awaiting response. This is a high limit that accommodates heavy query workloads while preventing any single client from monopolizing server resources. If you hit this limit, wait for some of your pending requests to complete before sending more. ### HTTP Requests The HTTP `/info` endpoint is limited to **30 requests per minute**. For real-time data, prefer WebSocket subscriptions which don't count against this limit. ### Errors When any rate limit is exceeded, the server responds with: ```json { "channel": "error", "data": { "error": "rate limit exceeded" } } ``` For connection limits, the WebSocket handshake is rejected with HTTP 403. ## Server Messages All server messages have this structure: ```json { "channel": "", "data": { ... } } ``` ### Channels | Channel | Description | | ---------------------- | ------------------------------------ | | `subscriptionResponse` | Confirms subscription/unsubscription | | `l1Book` | Top of book data | | `l2Book` | Aggregated book levels | | `l3Book` | Order-level book (lightweight) | | `l4Book` | Order-level book (full detail) | | `allMids` | All mid prices | | `trades` | Trade stream | | `candle` | Candlestick data | | `impactPrice` | Impact price calculations | | `orderUpdates` | Order status updates | | `userFills` | User fill notifications | | `post` | Query response | | `pong` | Ping response | | `error` | Error message | ### Subscription Response Confirms subscription or unsubscription. ```json { "channel": "subscriptionResponse", "data": { "method": "subscribe", "subscription": { "type": "l2Book", "coin": "BTC", ... } } } ``` ### Pong Response to ping. ```json { "channel": "pong" } ``` ### Error ```json { "channel": "error", "data": { "error": "Invalid subscription based on universe: ..." } } ``` #### Error Types * `Invalid websocket request` * `Invalid spot subscription` * `Invalid subscription based on universe` * `Already subscribed` * `Already unsubscribed` * `Failed to get order book universe` * `Failed to get order book snapshot` ## Subscriptions ### Authentication Your IP address must be whitelisted to connect. Once whitelisted via the [`/ip/add`](./http-endpoints)#post-ipadd) endpoint, authentication is automatic - no headers or query parameters needed. The server checks the client IP against the whitelist. If found, the connection is authenticated under the associated AlphaHype seat holder's address. IP whitelisting can be managed on [alphaticks](https://alphaticks.io/alpha-hype-api). *** ### Subscription Types The `subscription` field in subscribe/unsubscribe messages is a discriminated union based on the `type` property. | Type | Description | Updates | | ----------------------------------------------- | ------------------------ | ---------------------- | | [`l1Book`](./subscriptions/l1-book) | Top of book | Periodic snapshots | | [`l2Book`](./subscriptions/l2-book) | Aggregated price levels | Periodic snapshots | | [`l3Book`](./subscriptions/l3-book) | Order-level, lightweight | Snapshot + incremental | | [`l4Book`](./subscriptions/l4-book) | Order-level, full detail | Snapshot + incremental | | [`trades`](./subscriptions/trades) | Trade stream | Real-time | | [`candle`](./subscriptions/candles) | Candlestick data | Real-time | | [`allMids`](./subscriptions/all-mids) | All mid prices | Periodic (1s) | | [`impactPrice`](./subscriptions/impact-price) | Impact prices | Periodic | | [`orderUpdates`](./subscriptions/order-updates) | Order status | Real-time | | [`userFills`](./subscriptions/user-fills) | User fills | Real-time | ### Coin Parameter Most subscriptions require a `coin` parameter: * Perpetual contracts: `"BTC"`, `"ETH"`, `"SOL"`, etc. * Spot markets: Use the `@` prefix, e.g., `"@1"` for spot asset ID 1 ### Rate Limits See [Rate Limits](./rate-limits) for subscription and message limits. ## TypeScript Types Complete TypeScript type definitions for the WebSocket API. ### Subscription Types ```typescript type Subscription = | { type: 'l2Book'; coin: string; nSigFigs?: number; nLevels?: number; mantissa?: number; interval?: string } | { type: 'l3Book'; coin: string; snapshot?: boolean } | { type: 'l4Book'; coin: string; snapshot?: boolean } | { type: 'trades'; coin: string; withSideInfo?: boolean } | { type: 'candle'; coin: string; interval: string } | { type: 'l1Book'; coin: string; interval?: string } | { type: 'allMids' } | { type: 'impactPrice'; coin: string; notional: string; interval?: string } | { type: 'orderUpdates'; user: string } | { type: 'userFills'; user: string; aggregateByTime?: boolean }; ``` ### Client Messages ```typescript type ClientMessage = | { method: 'subscribe'; subscription: Subscription } | { method: 'unsubscribe'; subscription: Subscription } | { method: 'ping' } | { method: 'post'; id: number; request: PostRequest }; ``` ### Server Messages ```typescript type ServerMessage = | { channel: 'subscriptionResponse'; data: ClientMessage } | { channel: 'l1Book'; data: L1BookData } | { channel: 'l2Book'; data: L2BookData } | { channel: 'l3Book'; data: L3BookSnapshot | L3BookUpdates } | { channel: 'l4Book'; data: L4BookSnapshot | L4BookUpdates } | { channel: 'allMids'; data: AllMidsData } | { channel: 'trades'; data: Trade[] } | { channel: 'candle'; data: Candle } | { channel: 'impactPrice'; data: ImpactPriceData } | { channel: 'orderUpdates'; data: OrderUpdate[] } | { channel: 'userFills'; data: Fill[] } | { channel: 'post'; data: PostResponse } | { channel: 'pong' } | { channel: 'error'; data: { error: string } }; ``` ### HTTP Types ```typescript type InfoRequest = | { type: 'allMids' } | { type: 'impactPrice'; coin: string; notional: string }; interface ImpactPriceHttpResponse { buyImpactPx: string | null; sellImpactPx: string | null; time: number; } ``` ### Common Types ```typescript type Side = 'A' | 'B'; ``` ### L1 Book Data ```typescript interface L1BookData { coin: string; time: number; bid: Level | null; ask: Level | null; } interface Level { px: string; sz: string; n: number; } ``` ### L2 Book Data ```typescript interface L2Level { px: string; sz: string; n: number; } interface L2BookData { coin: string; time: number; levels: [L2Level[], L2Level[]]; // [bids, asks] } ``` ### L3 Book Data ```typescript interface L3Order { user: string; coin: string; side: Side; limitPx: string; sz: string; oid: number; timestamp: number; } interface L3BookSnapshot { coin: string; time: number; height: number; sequence: number; levels: [L3Order[], L3Order[]]; } interface L3BookUpdates { time: number; height: number; diffs: SequencedOrderDiff[]; } ``` ### L4 Book Data ```typescript interface L4Order extends L3Order { triggerCondition: string; isTrigger: boolean; triggerPx: string; isPositionTpsl: boolean; reduceOnly: boolean; orderType: 'Market' | 'Limit' | 'Stop Market' | 'Stop Limit' | 'Take Profit Limit' | 'Take Profit Market' | 'Vault Close'; tif?: string; cloid?: string; } interface L4BookSnapshot { coin: string; time: number; height: number; sequence: number; levels: [L4Order[], L4Order[]]; } interface L4BookUpdates { time: number; height: number; orders: OrderStatus[]; diffs: SequencedOrderDiff[]; } interface OrderStatus { time: string; user: string; status: 'open' | 'filled' | 'canceled' | 'triggered' | 'rejected'; order: L4Order; } ``` ### Order Diffs ```typescript type RawBookDiff = | { New: { sz: string } } | { Update: { origSz: string; newSz: string } } | 'Remove'; interface OrderDiff { user: string; oid: number; px: string; coin: string; side: Side; rawBookDiff: RawBookDiff; } interface SequencedOrderDiff extends OrderDiff { sequence: number; } ``` ### Order Updates ```typescript interface OrderUpdate { order: OrderUpdateInner; status: string; statusTimestamp: number; } interface OrderUpdateInner { coin: string; side: Side; limitPx: string; sz: string; oid: number; timestamp: number; origSz: string; cloid?: string; } ``` ### All Mids Data ```typescript interface AllMidsData { mids: Record; // coin -> mid price } ``` ### Impact Price Data ```typescript interface ImpactPriceData { coin: string; notional: string; buyImpactPx: string | null; sellImpactPx: string | null; time: number; } ``` ### Trades ```typescript interface Trade { coin: string; side: Side; px: string; sz: string; hash: string; time: number; tid: number; users: [string, string]; sideInfo?: SideInfo[]; } interface SideInfo { user: string; startPos: string; oid: number; twapId?: number; cloid?: string; } ``` ### Candles ```typescript interface Candle { t: number; // open time (ms) T: number; // close time (ms) s: string; // symbol/coin i: string; // interval o: string; // open price c: string; // close price h: string; // high price l: string; // low price v: string; // volume n: number; // trade count } ``` ### Fills ```typescript interface Fill { coin: string; px: string; sz: string; side: Side; time: number; startPosition: string; dir: string; closedPnl: string; hash: string; oid: number; crossed: boolean; fee: string; builderFee?: string; tid: number; cloid?: string; feeToken: string; twapId?: number; liquidation?: Liquidation; } interface Liquidation { liquidatedUser: string; markPx: string; method: string; } ``` ## All Mids Mid prices for all trading pairs, updated every second. ```json {"method": "subscribe", "subscription": {"type": "allMids"}} ``` Data format: `AllMidsData` ```json {"channel": "allMids", "data": {"mids": {"BTC": "65000.5", "ETH": "3500.25", "SOL": "125.50"}}} ``` ## Candles Real-time candlestick data. ```json {"method": "subscribe", "subscription": {"type": "candle", "coin": "BTC", "interval": "1m"}} ``` Supported intervals: `"1m"`, `"3m"`, `"5m"`, `"15m"`, `"30m"`, `"1h"` Data format: `Candle` ```json {"channel": "candle", "data": {"t": 1699900000000, "T": 1699900060000, "s": "BTC", "i": "1m", "o": "65000.0", "c": "65100.0", "h": "65150.0", "l": "64950.0", "v": "125.5", "n": 342}} ``` ## Impact Price Impact price calculations for a given notional size, sent as periodic snapshots. ```json {"method": "subscribe", "subscription": {"type": "impactPrice", "coin": "BTC", "notional": "10000"}} ``` The `interval` field is optional (default `"1s"`). Valid values: `"500ms"`, `"1s"`. Maximum notional is $100,000,000. Data format: `ImpactPriceData` ```json {"channel": "impactPrice", "data": {"coin": "BTC", "notional": "10000", "buyImpactPx": "65100.5", "sellImpactPx": "64900.3", "time": 1699900000000}} ``` Impact prices are calculated by simulating a market order of the specified notional size. If the book doesn't have enough liquidity, the corresponding price will be `null`. ## L1 Book Best bid and ask (top of book), sent as periodic snapshots. ```json {"method": "subscribe", "subscription": {"type": "l1Book", "coin": "BTC"}} ``` The `interval` field is optional (default `"500ms"`). Valid values: `"200ms"`, `"500ms"`, `"1s"`. Data format: `L1BookData` ```json {"channel": "l1Book", "data": {"coin": "BTC", "time": 1699900000000, "bid": {"px": "65000.0", "sz": "1.5", "n": 3}, "ask": {"px": "65001.0", "sz": "1.0", "n": 2}}} ``` ## L2 Book Aggregated price levels, sent as periodic snapshots. ```json {"method": "subscribe", "subscription": {"type": "l2Book", "coin": "BTC"}} ``` Optional fields: * `nSigFigs`: Significant figures for price aggregation (2-5) * `nLevels`: Number of price levels per side (default 20, max 100) * `mantissa`: Price rounding mantissa (2 or 5, only when nSigFigs=5) * `interval`: Update interval (default `"500ms"`). Valid values: `"100ms"`, `"200ms"`, `"500ms"` Data format: `L2BookData` ```json {"channel": "l2Book", "data": {"coin": "BTC", "time": 1699900000000, "levels": [[{"px": "65000.0", "sz": "1.5", "n": 3}], [{"px": "65001.0", "sz": "1.0", "n": 2}]]}} ``` The `levels` array contains `[bids, asks]`. ## L3 Book Order-level data with basic fields. Sends an initial snapshot followed by incremental diffs. ```json {"method": "subscribe", "subscription": {"type": "l3Book", "coin": "BTC"}} ``` Set `"snapshot": false` to skip the initial snapshot. Data format: `L3BookSnapshot | L3BookUpdates` ### Applying Diffs Diffs may arrive before the snapshot. Use `sequence` and `height` to apply them correctly: 1. Cache incoming diffs while waiting for the snapshot 2. When the snapshot arrives, note its `height` and `sequence` 3. Apply a diff only if: `diff.height >= snapshot.height && diff.sequence > snapshot.sequence` 4. Discard diffs that don't meet this condition ### Diff Types ```typescript type RawBookDiff = | { New: { sz: string } } | { Update: { origSz: string; newSz: string } } | 'Remove'; ``` ## L4 Book Order-level data with full details (triggers, TIF, order type, etc.). Sends an initial snapshot followed by incremental diffs and order status updates. ```json {"method": "subscribe", "subscription": {"type": "l4Book", "coin": "BTC"}} ``` Set `"snapshot": false` to skip the initial snapshot. Data format: `L4BookSnapshot | L4BookUpdates` ### Applying Diffs Same as L3 Book - use `sequence` and `height` to apply diffs correctly: ``` diff.height >= snapshot.height && diff.sequence > snapshot.sequence ``` ### Order Status Values * `open` - Order is active on the book * `filled` - Order completely filled * `canceled` - Order was canceled * `triggered` - Trigger order activated * `rejected` - Order was rejected ### Limitations L4 subscriptions do not support spot order books. ## Order Updates Real-time order status updates for a user address. ```json {"method": "subscribe", "subscription": {"type": "orderUpdates", "user": "0x1234567890abcdef1234567890abcdef12345678"}} ``` Data format: `OrderUpdate[]` ```json {"channel": "orderUpdates", "data": [{"order": {"coin": "BTC", "side": "B", "limitPx": "65000.0", "sz": "1.0", "oid": 12345, "timestamp": 1699900000000, "origSz": "1.0"}, "status": "open", "statusTimestamp": 1699900000000}]} ``` ### Status Values * `open` - Order is active * `filled` - Order completely filled * `canceled` - Order canceled * `triggered` - Trigger activated * `rejected` - Order rejected ## Trades Real-time trade stream. ```json {"method": "subscribe", "subscription": {"type": "trades", "coin": "BTC"}} ``` Set `"withSideInfo": true` to include detailed side info (user addresses, positions, order IDs). Data format: `Trade[]` ```json {"channel": "trades", "data": [{"coin": "BTC", "side": "B", "px": "65000.5", "sz": "0.1", "hash": "0x...", "time": 1699900000000, "tid": 12345, "users": ["0x...", "0x..."]}]} ``` The `users` array contains `[maker, taker]` addresses. ## User Fills Real-time fill notifications for a user address. ```json {"method": "subscribe", "subscription": {"type": "userFills", "user": "0x1234567890abcdef1234567890abcdef12345678"}} ``` Set `"aggregateByTime": true` to combine fills for the same order at the same timestamp (sizes summed, prices weighted-averaged, fees summed). Data format: `Fill[]` ```json {"channel": "userFills", "data": [{"coin": "BTC", "px": "65000.5", "sz": "0.1", "side": "B", "time": 1699900000000, "startPosition": "0.5", "dir": "Open Long", "closedPnl": "0", "hash": "0x...", "oid": 12345, "crossed": false, "fee": "6.50", "tid": 111, "feeToken": "USDC"}]} ``` ### Direction Values * `Open Long` / `Close Long` * `Open Short` / `Close Short` ## HpumpCore The **Hpump Market** operates on a **bonding curve model**, allowing tokens to build liquidity and establish a fair price before being launched on HyperCore or HyperEVM. *** ### Bonding Curve Overview The bonding curve model is inspired by **Uniswap V2’s Constant Product Market Maker (CPMM)** and uses the formula: **X ⋅ Y = K** ##### Key Components: * **X (USDC)**: Represents the amount of USDC inflow during token purchases. * **Y (Tokens)**: The number of tokens available for sale. * **K**: A constant value ensuring the bonding curve remains balanced. ##### **Threshold Formula for Bonding** For a launch token to bond and be listed on HyperCore, the following condition must be met: **X⋅0.65 ≥ Auction Price** This ensures that sufficient USDC has been accumulated in the bonding curve to pay for the gas cost and seed initial liquidity in the buy-side order book. *** #### **How It Works** 1. **Market Dynamics:** * As buyers purchase tokens, **X (USDC)** increases while **Y (tokens)** decreases. * **For example:** * Initial Parameters: X0=500; Y0=1,000,000; starting price = $0.0005. * After $99,500 net inflow: X=100,000, price = $0.10. 2. **Bonding Trigger:** * Once X⋅0.65 reaches the auction threshold (e.g., $65,000), the token is **automatically created**. * However, the **token creator** **must** **manually deploy the trading pair**, giving them the flexibility to launch their token on Hyperliquid at their preferred timing. 3. **USDC Allocation:** * **65% (Auction Price):** Pays the gas cost for deploying the token. * **35% (Remaining USDC):** Automatically added to the HIP-2 liquidity pool, creating a reliable buy-side market. 4. **Airdrop to Buyers:** * Once bonded, early buyers receive a **proportional airdrop** of the actual token. * This is sent directly to their **Hypurr Fun bot wallet**. ## HpumpEVM **The HpumpEVM Market** operates on a **bonding curve model**, allowing tokens to build liquidity before transitioning to **HyperSwap** through liquidity pool creation. **Bonding Curve Overview** The bonding curve model uses a mathematical formula to determine token pricing as trading volume increases. **Key Components:** * **Trading Phase**: Users can buy and sell tokens immediately after creation * **Bonding Curve**: Price increases as more tokens are purchased from the curve * **Liquidity Pool Creation**: When bonding requirements are met, tokens transition to HyperSwap **How It Works** 1. **Token Creation:** • Tokens are created and immediately available for trading • Trading occurs on the bonding curve with dynamic pricing 2. **Trading Phase:** • Users trade tokens while they remain on the bonding curve • Price increases as supply decreases through purchases 3. **Transition to HyperSwap:** • When bonding requirements are met, tokens migrate to **HyperSwap** • Liquidity pools are created for continued trading • Seamless transition from bonding curve to AMM trading **Detailed Mechanics** *Coming soon - full documentation on bonding thresholds, liquidity allocation, and migration process.* ## Account #### Creating an Account 1. **Get Started with Telegram**\ Hypurr Fun is a Telegram bot, so you’ll need a [Telegram](https://telegram.org/) account to use it. If you don’t already have one, create an account on Telegram first. 2. **Access the Bot**\ Search for **@HypurrFunBot** on Telegram or use this [direct link](https://t.me/HypurrFunBot). Press **“Start”** or type **/start** to begin. 3. **Set Up Your Wallet**\ After starting the bot, you’ll receive a welcome message along with your personal wallet address. 4. **Secure Your Wallet** It is strongly recommended to **export your private key** to avoid losing access to your wallet. * Go to **Settings** and select **Export private key**. * Save the key in a secure location and **NEVER** share it with anyone (including Hypurr Fun team members). 5. **Deposit USDC**\ To use **Hypurr Fun**, you’ll need to send **at least 10 USDC** from either the **Arbitrum chain** or **Hyperliquid**. For full details, we highly recommend reading the [Deposit](account/wallet-actions/deposit) section of this documentation. 6. **Transfer USDC to Spot Wallet** After depositing funds, ensure you transfer your USDC to the **Spot Wallet** using the **Perp to Spot** option in the **/spotwallet** command. All operations in the Hypurr Fun bot, including trading and plugins, require assets to be in the Spot Wallet. You’re now ready to start trading with Hypurr Fun! *** #### **View and Manage Your Wallets** Hypurr Fun provides several commands to view and manage different parts of your wallet and access essential features: * **Spot Wallet Operations**: * Use the **`/spotwallet`** command to view your **Spot Wallet** on Hyperliquid and perform operations such as **withdrawals** or other fund management tasks. * For a detailed **PnL report** of your spot trading activity, use the **`/spotpnl`** command. * **Perp Wallet Operations**: * Use the `/perpwallet` command to view your **Perp Wallet** on Hyperliquid and see your positions. * **Hpump Wallet**: * Use the **`/launchwallet`** command to view your HpumpCore and HpumpEVM assets. * For a detailed **PnL report** of your Hpump trading activity, use the **`/launchpnl`** command. * **Wallet Configuration**: * Use `/wallets` to manage and select your default wallet. * Use `/settings` to configure and manage your wallet preferences, set up the trade widget, and extract information. *** #### Advanced Wallet Management While a default wallet is created for you, Hypurr Fun offers advanced options to customize and expand your wallet setup: * [Multi Wallets](account/multi-wallets) * **Link** or **import** multiple wallets into the bot. * Your number of available wallet slots depends on your **HFUN balance** (3 by default, with one extra slot per HFUN held, up to 10 slots). * [Wallet Actions](account/wallet-actions) * Set a **Default Wallet** for trading, deposits, and plugins like the Sniper or Dumper. * **Learn how to deposit and withdraw funds** from Hypurr. * [Wallet Settings](account/wallet-settings) * Manage your wallet preferences, enhance security with **2FA**, configure trade options, adjust display settings, and export data via the **/settings** widget. ## Getting Started You can trade on Hypurr Fun through two platforms: * **Telegram**: Start by [creating your account](account) - Full trading experience with advanced features * **Website**: Use your own EOA wallet (MetaMask, Rabby) at [hpump.trade](https://hpump.trade/) **Next Steps**: Check out our guides for[ Hpump (trade & launch tokens)](hpump), [HyperCore spot & perp trading](hypercore), and [HyperEVM trading](hyperevm) *Platform Architecture & User Flow* *** #### Links * **Website**: [hypurr.fun](https://hypurr.fun/) * **Hypurr Fun Bot**: [Launch Bot](https://t.me/HypurrFunBot) * **Pre-Market (Hpump)** * **Hypurr Pump Chat**: [Join the Chat](https://t.me/+GRIwAPnAUBk4ODE0) * **Dashboard for launches**: [https://hpump.trade/](https://hpump.trade/) * **Live Market (Hfun)** * **Hypurr Fun Chat**: [Join the Group](https://t.me/+SJRiO42rufBmODBk) * **Explorer**: [Hypurrscan](https://hypurrscan.io/dashboard) * **Portfolio Manager:** [app.hypurr.fun](https://app.hypurr.fun/) #### Bot Commands ##### **Hypurr Fun Bot** * **Wallet Commands** * **`/wallets`** - Manage and select your default wallet * **`/settings`** - Configure wallet preferences, trade widget, and extract information * **`/label`** - Add a label to a wallet address * **`/labels`** - Show your wallet labels * **`/spotwallet`** - View and manage your HyperCore spot wallet * **`/perpwallet`** - View and manage your HyperCore perp wallet * **`/evmwallet`** - View and manage your HyperEVM wallet * **`/launchwallet`** - View and manage your HpumpCore and HpumpEVM wallet * **Metrics** * **`/launchpnl`** - Detailed PnL report for Hpump * **`/spotpnl`** - Detailed PnL report for HyperCore spot trading * **`/perppnl`** - soon * **`/twaps`** - Shows all your active TWAP orders (HyperCore spot) * **`/referrals`** - Display referral information * **`/whalechats`** - Show eligibility for whale chats * **Research** * **`/search HYPE`** - Find HyperCore spot tokens by name * **`/tokens`** - Display trending HyperCore spot tokens * **`/launches`** - View and sort biggest launches by volume * **`/instruments`** - Display trending perp instruments * **Trade** * **Hpump** * **`/launches`** - HpumpCore launches, click on the name to see the trading widget * **HpumpEVM** - Coming soon. Use [hpump.trade](https://hpump.trade) website * **HyperCore** * **`/sniper`** - Automatically buy HyperCore spot tokens when listed * **`/dumper`** - Automatically sell HyperCore spot airdropped tokens * **`/tokens`** - HyperCore spot tokens, click on the name to see the trading widget * **`/instruments`** - HyperCore perp instruments, click on the name to see the trading widget * **HyperEVM** * Coming soon on TG * **Launch** * **HpumpCore** * **`/launch`** - Launch directly from bot * Use [hpump.trade](https://hpump.trade) website * **HpumpEVM** * Coming soon on TG * Use [hpump.trade](https://hpump.trade) website ##### Hpump & Hfun Chat - Channel Commands * **`/info`** - Holders, token supply, allocation and deployer information * **`/price` -** Check price, TVL, market cap, and bonding progress. * **`/twaps`** - View active TWAP orders for the asset * **Charts** - Access detailed charts at [hpump.trade](https://hpump.trade) ## Hpump The **Hpump Market** on Hypurr Fun **simplifies memecoin trading** by removing the Hyperliquid auction constraint **and initial liquidity barriers**. *** #### Tools Available **Telegram** * **General & Support Channel**: [Hpump Chat](https://t.me/+GRIwAPnAUBk4ODE0) for FAQs and discussions about Hpump. * **Launch Alerts**: Get notified about new token launches, allowing you to stay updated and catch all sniping opportunities (note: expect a mix of high-potential and lower-quality tokens). * **Token-Specific Chats**: Each token in the Hpump phase has its own Telegram chat for community interactions. **Website** * Access the [Hpump Dashboard](https://hpump.trade/) to explore key insights for launch tokens. * **Trust Factor Indicators**: 👑 (High Trust), 🟢 (Normal Trust), 🟡 (Moderate Trust), 🔴 (Low Trust) for evaluating token reliability. * **Creator Information**: View the deployer’s Telegram handle and check their reputation in the community. * **Bonding Progress**: Monitor Total Value Locked (TVL) and thresholds to determine when tokens are ready to transition to Hyperliquid. *** #### What Can You Do in the Hpump Market? 1. **Trade Launch Tokens** Buy and sell tokens during their Hpump phase, before they are listed on Hyperliquid. 2. **Token Transition to Hyperliquid**: Platform helps gather necessary funds and liquidity for successful bond on HyperCore or HyperEVM. *** #### Useful Commands **Commands to Execute in the Hypurr Fun Bot** * **`/launches`**: View and sort the biggest launches by volume. * **`/launchwallet`**: Check your assets in the Hpump Market. * **`/launchpnl`**: Track your performance in the Hpump Market. **Commands to Execute in the Token’s Hpump Chat** * **`/info`**: Access details like top holders, token supply, and deployer information. * Charts - On [hpump.trade](https://hpump.trade) ## HyperCore The **HyperCore Market** on Hypurr Fun is where you can trade perp and spot tokens that have already launched on Hyperliquid. This includes advanced features like spot/perp trading, sniping newly listed tokens, and managing airdrops efficiently. *** #### Tools Available **Telegram** * **General & Support Channel**: [Hfun Chat](https://t.me/+SJRiO42rufBmODBk) for FAQs and community discussions. * **Listing Alerts**: Get notified instantly when new tokens are created and when new pairs are launched on HL, allowing you to act quickly by sniping or dumping tokens. * **Token-Specific Chats**: Each spot token has its own dedicated Telegram chat for discussions and updates. **Hypurr Explorer** * Access [Hypurrscan](https://hypurrscan.io/) to explore token data, auctions, trending tokens, TWAP, and general stats. *** #### What Can You Do in the Spot Market? 1. **Trade Spot Tokens** Buy and sell tokens like **HFUN/USDC,** and more. Execute spot trades or set up advanced strategies like **TWAP (Time-Weighted Average Price)** to optimize your entries and exits. 2. **Snipe New Tokens** Configure your sniper to act on newly listed tokens instantly, ensuring you don’t miss out on opportunities. The more **$HFUN** you hold in your wallet, the higher your priority over others is. 3. **Manage Your Airdrops** Automatically sell tokens that have been airdropped to your wallet using the **dumper** feature. This saves time and ensures you can capitalize on market opportunities. 4. **Trade Perp Instruments** Access perpetual contracts for leveraged trading on various assets. *** #### Useful Commands **Commands to Execute in the Hfun Bot** * **`/tokens`**: View a list of tokens ordered by 24-hour trading volume (Trending Tokens). * **`/sniper`**: Set up and configure the sniper to automatically purchase tokens as soon as they are listed. * **`/dumper`**: Automate the selling of airdropped tokens directly from your wallet. * **`/spotwallet`**: View and manage your assets in the Spot Market. * `/perpwallet`: View and manage your positions. * **`/spotpnl`**: Track your current positions and view your profit and loss (PnL) for spot trades. * **`/twaps`**: View your active TWAP (Time-Weighted Average Price) orders. * **`/search [SYMBOL]`** **`/buy [SYMBOL]`**: Open the trade widget for a specific token. **Commands to Execute in the Token’s Hfun Chat** * **`/price`**: Check the price, market cap, and 24-hour price change of a token. * **`/info`**: View token details, number of holders, liquidity, and allocation. * **`/twaps`**: View currently running TWAP orders for the token. ## HyperEVM The **HyperEVM Market** on Hypurr Fun is where you can trade erc20 tokens that already have liquidity pool accross HyperSwap. *** #### What Can You Do in the Spot Market? 1. **Trade ERC-20 Tokens** Buy and sell **ERC-20 tokens** deployed on HyperEVM. *** #### Useful Commands **Commands to Execute in the Hfun Bot** * `/evmwallet`: View and manage your erc20 tokens. **Commands to Execute in the Token’s Hfun Chat** * **`/price`**: Check the price, market cap, and 24-hour price change of a token. * **`/info`**: View token details, number of holders, liquidity, and allocation. * **`/twaps`**: View currently running TWAP orders for the token. ## Introduction **Hfun** is the fastest **Telegram trading bot & launchpad** for Hyperliquid, designed to streamline token launching, trading, and portfolio management across multiple markets. We provide efficient execution tools with an intuitive interface for both experienced traders and newcomers. Hypurr provides seamless access to **both live markets and pre-market opportunities**: | Market Type | Platform | Description | | ---------------------------------------------- | -------------- | -------------------------------------------------- | | [Live Markets](https://t.me/+SJRiO42rufBmODBk) | HyperCore Spot | Real-time spot trading on Hyperliquid | | | HyperCore Perp | Perpetual futures trading on Hyperliquid | | | HyperEVM | ERC20 token trading on HyperEVM | | [Pre-Market](https://t.me/+GRIwAPnAUBk4ODE0) | HpumpCore | Launchpad for tokens before HyperCore spot listing | | | HpumpEVM | Launchpad for tokens before HyperEVM liquidity | *** *How Hypurr Fun Works* #### Key Features * **🔧 Efficient Execution**: Trade and manage positions with reliable performance * **🚀 Launchpad Access**: Create tokens and build community support to reach listing thresholds * **🎯 Alert Notifications**: Get alerted on latest listings, trending coins and more. Never miss a memecoin launch again. * **📊 Portfolio Tools**: TWAP orders, position sizing, and automated selling * **💰 Revenue Sharing**: 100% of fees reinvested into **$HFUN buybacks** * **🤝 Referral Program**: Earn **10% of trading fees** from referred users * **🔒 Secure Infrastructure**: Professional-grade wallet protection ## Perp **Steps to Trade Perp Instruments:** 1. **Find Instruments** Use the `/instruments` command to see a list of available perpetual instruments, ordered by their 24-hour trading volume.
2. **Select an Instrument** Once you've identified the instrument you want to trade, click its symbol at the bottom of the message. This will open the **Trading Widget**.
3. **Use the Trading Widget** * Use the buttons on the widget to trade: * **Long Options**: Choose pre-set amounts (**$20**, **$100**) or enter a custom amount using **"Long $X"** * **Short Options**: Choose pre-set amounts (**$20**, **$100**) or enter a custom amount using **"Short $X"** * **Management**: Use **"PnL Card"** to view your position details, **"Refresh"** to update prices, or **"Close"** to exit your position ## Spot **Steps to Trade Spot Tokens:** 1. **Find Tokens** * Use the **`/tokens`** command to see a list of available tokens, ordered by their 24-hour trading volume. * Alternatively, use **`/search [SYMBOL]`** to directly search for a specific token. Commands like **`/buy`** or **`/sell`** also work to initiate trading for a specific token. 2. **Select a Token** * Once you've identified the token you want to trade, click its symbol at the end of the message. * This will open the **Trade Widget**. 3. **Use the Trade Widget** * Use the buttons on the widget to trade: * **Buy Options**: Choose pre-set USDC amounts or enter a custom amount using the **"Buy $X"** button. * **Sell Options**: Sell pre-set percentages of your token balance or enter a custom percentage using the **"Sell X%"** button. * Note: If you don’t see the "Buy" or "Sell" buttons, it might be because your wallet doesn’t have enough USDC. *** #### Creating a TWAP To address the potential **illiquidity of Hyperliquid spot tokens**, Hypurr Fun provides the **TWAP (Time-Weighted Average Price)** tool. This feature allows you to buy or sell large amounts of tokens over a set period of time, minimizing market impact. **How to Set Up a TWAP** 1. **Access the TWAP Widget** * On the **Trade Widget** of your selected token, press the **"TWAP"** button. * This will open the **TWAP Widget**, where you can view running TWAPs or create a new one. 2. **Create a New TWAP Order** * Press the **"New"** button to open the **TWAP Creation Widget**. * By default, the TWAP is set to **"Buy"**. If you want to sell, press the **"Buy"** button to switch it to **"Sell"**. 3. **Configure Your TWAP** * **Target Notional**: Set the total notional value in USDC to buy or sell for the target token. * **TWAP Duration**: Specify the time period over which the TWAP will spread the purchase or sale. 4. **Start the TWAP** * Once your settings are configured, press the **"Start TWAP"** button to begin. **Monitor Your TWAP** * Use the **`/twaps`** command to view all your running TWAPs and monitor their progress. ## Dumper With Hypurr Fun, you can use the dumper feature to automatically sell tokens airdropped to your wallet. These are tokens that you purchased in the **Hpump market** and have successfully bonded on **HyperCore**. *** #### From the dumper menu, you can: * Create new configurations. * Activate or deactivate existing configurations. * Customize your settings to match your trading strategy. *** #### Creating a New Dumper Configuration 1. **Access the Dumper Widget** * Use the **`/dumper`** command to open the Dumper widget. * Press the **“New”** button to create a new configuration. 2. **Name Your Configuration** * Enter a **config name** to identify your setup. * The name is NOT the ticker of the token—it’s simply a label for differentiating between multiple configs. 3. **Set Your Parameters**\ Configure the following settings for your Dumper: * **Target Token**:\ Specify the ticker of the token you want to dump, or use **“ALL”** to sell every airdrop received. * **Target Percentage**:\ Define the percentage of your airdropped tokens that you want to sell. * **Market Cap Threshold**:\ Set the market cap (FDV) at which the Dumper will execute sell orders immediately after token deployment. 4. **Activate the Configuration** * Once all parameters are set, press the **“Disabled”** button to enable the configuration. * The Dumper will now automatically execute as airdrops are received. *** ##### Why Use the Dumper? The **dumper** feature is essential for automating the sale of airdropped tokens, saving you time and ensuring you can act quickly in dynamic markets. It’s especially useful for managing multiple tokens or maximizing gains from unexpected airdrops. ## Sniper The **`/sniper`** command allows you to access and configure the **sniping widget**. This tool is designed to help you automatically buy tokens the moment they are listed, based on your personalized configurations. *** #### From the sniping menu, you can: * Create new configurations. * Activate or deactivate existing configurations. * Customize your settings to match your trading strategy. *** #### Creating a New Sniper Configuration 1. **Start with the “New” Button** * Click **“New”** to create a new sniper configuration. * Enter a **config name** (It must be different from the token name!). 2. **Configure Sniping Parameters**\ After naming your config, a detailed menu will appear with the following options: * **Config Name**: A label for your configuration (does not affect the sniping process). * **Target Token**: Enter the ticker symbol of the token you want to snipe. * **Max Notional**: Set the maximum amount in USDC to spend on the token. * **Max Market Cap**: Specify the maximum market capitalization (in USDC) for the token. The sniper will not buy if the token exceeds this value. * **Max Team Allocation**: The sniper will only execute if the token’s team allocation is below this threshold. * **Max Liquidity Allocation**: Ensure the liquidity allocation is within your acceptable range. * **Max Airdrop Allocation**: Limit sniping to tokens with airdrop allocations below this value. 3. **Activate Your Configuration** * To activate a config, click on the **“Disabled”** button to change it to **“Enabled”**. *** ##### Additional Features * **Anti-Rug Function**: * Enable this option to avoid sniping tokens flagged by the Hypurr Fun team as high-risk or potential rugpulls. * **Trigger Manually**: * Use this to instantly snipe a token when the launch time is known in advance. * **Delete Configurations**: * Remove unused or outdated configs using the **“Delete”** button. * **Navigate Back**: * Use the **“Home”** button to return to the config selection menu. *** ##### Why Use the Sniping Tool? The **sniping tool** is essential for traders who want to **capitalize on newly launched tokens** quickly and efficiently, while maintaining full control over their **risk exposure**. With customizable parameters and safety features like **Anti-Rug**, it’s a powerful addition to your trading arsenal. ## Launch First, you need to choose if you want to deploy your token on **HyperCore** or **HyperEVM**. #### HpumpCore ##### Launch Via Hfun Bot 1. Use the **/launch** command in the **Hypurr Fun bot** to start the process. 2. Provide key details such as: * **Token Information**: Define the unique **symbol** for your token and provide a description: * A **short description** (max **50 characters**) that will appear on the Hyperliquid frontend. * A **full description** with full details about your token, including its purpose, features, and links to socials or external resources. * Optionally, upload a **picture** (logo or image) to visually represent your token. * **Initial Notional**: Allows the creator to secure tokens before snipers. The purchased supply is locked for a duration (min **1h**, up to **1w**) to ensure a fair launch. Minimum notional is **$500**. 3. Your token will then be listed in the **Hpump ecosystem**, making it available for trading and enabling others to support your project. ##### Launch Via Hpump Dashboard Click on the Launch Button and provide the same key information *** #### HpumpEVM ##### Launch Via Hfun Bot * Coming Soon ##### Launch Via Hpump Dashboard - Same as HpumpCore *** #### **Launch Protection** **HpumpCore Features** * **Initial Notional Lock**: Creator's initial purchase locked for chosen duration (**1h, 12h, 1d, 3d, or 1w**) * **Order Capping**: Orders limited to **$1,500** during first **60 seconds** * **Trading Start Delay**: Trading begins **1 minute after launch** * **Preconfigured Buy**: Creators can secure tokens during launch to compete with snipers **HpumpEVM Features** * **Native HYPE Trading**: Launches traded with native **HYPE** (not WHYPE) * **Launch Cooldown**: **60 seconds** between launches, plus **10 extra seconds** for 0 score users * **Trading Options**: Use Hfun wallet or external wallet (external wallets default to 0 score) * **HFUN Score**: Requires **HFUN in HyperCore wallet** to increase score (HyperEVM HFUN not counted) * **No Minimum Buy**: No minimum purchase amount for first buy * **Dev Lock**: Currently no dev lock logic (coming in future version) ## Trade The trading process is the same for **HpumpCore** and **HpumpEVM**. #### **Step 1: Discover & Analyze Tokens** 1. **Stay Updated via Telegram** * **Launch Alerts**: Watch for new launch announcements in the Hpump Chat. * **One-Click Trading**: In the alert message, click **“Trade”** to open the Trade Widget. 2. **Explore the Hpump Dashboard** * **Trust Factor Indicators**: It's for informational purposes only and are determined based on predefined criteria. * **Creator Information**: Verify the deployer’s reputation to gauge token reliability. * **Bonding Progress**: Keep an eye on the TVL (Total Value Locked) and thresholds to know when a token is transitioning to Hyperliquid. 3. **Engage in Token-Specific Chats** * Each token has a dedicated Telegram channel for direct community discussions. * **Use Key Commands**: * **/info**: View deployer details, top holders, and token supply. * **chart/price** - Hpump Dashboard * After reviewing these details, simply click **“Trade”** in the Telegram chat to jump back into the Trade Widget. *** #### **Step 2: Trade** ##### **A. Hfun Bot** 1. **Open the Launches List** * Use the **/launches** command to view tokens ranked by trading volume. * **Sorting Options**: Filter by price change or market cap. * **Scroll Navigation**: Quickly browse tokens to find your target. * Once you select a token (e.g., **WIZ**), you’ll see specific trading options: 2. **Execute Your Trades** * **Buy Tokens**: * Click **“Buy $X”** and specify the USDC amount (or use pre-set amounts). * **Sell Tokens**: * Click **“Sell X%”** to quickly choose a percentage of your holdings. * **Other Controls**: * **Refresh**: Updates token details (price, TVL, market cap). * **Close**: Returns you to the main token list. ##### **B. Hpump Dashboard** 1. **Select a token** 2. **Execute Your Trades** *** ### Fees A **1% fee** is applied to all trades conducted through the **Hpump Market**. These fees are redirected to the [HFUN Fees Receiver](https://hypurrscan.io/address/0x501a76325a353a4249740ada1d4bce46dbdd67d6) wallet. The collected fees are **exclusively used** to **purchase** the **HFUN** token, supporting its ecosystem and value appreciation. ## Multi Wallets Hypurr Fun creates a wallet for you by default, but you can also import or link existing wallets into the bot. The number of wallet slots you have depends on your **$HFUN balance**. *** #### **How to Link Wallets** There are three ways to link a wallet into the bot: 1. **Private Key**: * Full functionality, including transfers, bridging out on Arbitrum, spot/perp trading, and pre-market trading. * Recommended for active trading. 2. **API Key**: * Allows spot/perp trading without exposing your private key. * Provides an additional layer of security. 3. **Read-Only**: * View-only mode to check your balance and track PnL. * Ideal if you don’t plan to trade with this wallet. *** #### **Why Import Additional Wallets?** * **HFUN Privileges**: Access benefits tied to your $HFUN balance, such as priority in sniping or other exclusive features. * **Whale Chats**: Gain entry to exclusive community spaces for high-value traders. *** #### **Security Recommendation** If you do not plan to actively trade with a wallet, it’s best to import it in **Read-Only mode** for enhanced security. ## Wallet Actions The Wallet Actions section explains how to manage the Default Wallet, as well as deposits, withdrawals, and fund recovery in Hypurr Fun. #### **Set a Default Wallet** Designate a **Default Wallet** using the **/wallets** command. This wallet will be used for all your key actions, including **transfers, withdrawals, spot trading, and PnL reports**. Additionally, you can set **different default wallets** for specific plugins: * [Sniper Plugin](../hypercore/spot/sniper): For executing sniping actions. * [Dumper Plugin](../hypercore/spot/dumper): For managing efficient token sales. ## Wallet Settings Access all wallet settings via the **`/settings`** widget.\ This widget allows you to navigate and configure different wallet options easily. *** #### **Display Settings** * **Log Trades**: Toggle the option to display a log message whenever a trade is executed. * **Hide Small Balances**: Hide small balances in your wallet overview to reduce clutter. Actions: * **Disable Log Trades** * **Hide Small Balances** *** #### **Trade Settings** This section allows you to preconfigure the buttons in the **Trade Widget** for faster trading. * **Buy Buttons Config**: Set the notional amount for the left and right buy buttons. * **Sell Buttons Config**: Set the percentage for the left and right sell buttons. * **Max Slippage Config**: Adjust the maximum slippage allowed for trades. Actions: * Adjust individual buy, sell, or slippage values as needed. *** #### **General Settings** * **Tip Amount Config**: Set the default tip amount you can send using the recipient’s Telegram handle in the **Hypurr Fun Chat** by typing **/tip @username**. * **Auto-Bridge**: Enable or disable the automatic bridging of balances from Arbitrum to Hyperliquid. Actions: * **Disable Tipping**: Turn off tipping functionality. * **Disable Auto-Bridge**: Prevent automatic bridging if you prefer manual control. *** #### **Data Settings** Export historical data from the default wallet: * This allows you to download a CSV file containing your trade history for record-keeping or analysis. * Note: The data corresponds to the wallet currently set as the default. *** #### **Two-Factor Authentication (2FA)** To enable Two-Factor Authentication (2FA) for transfers and withdrawals: 1. Press the **"2FA"** button, then select **"Setup 2FA"**. 2. The bot will provide a QR code. 2. Scan the QR code using your preferred 2FA app (e.g., Google Authenticator, Authy). 3. After scanning, reply in the chat with the current code from your 2FA app. 4. If the code is correct, 2FA will be enabled. **Note:** Keep the QR code secure, as you’ll need your 2FA app to verify future withdrawals or transfers. ## Deposit You can deposit funds into your wallet via either the **Arbitrum network** or the **Hyperliquid network**. #### **Arbitrum Deposits** 1. Open the Wallet widget using **/spotwallet**. 2. Copy your wallet address and send **Native USDC** (**⚠️ USDC.e is not supported**) to the wallet. 3. Ensure you send **at least 10 USDC**—amounts below this will not appear in the wallet. 4. Once the funds are sent, you’ll receive a notification. If not, press the **"Refresh"** button in the Wallet widget. 5. **⚠️ If you mistakenly send unsupported funds**, refer to the [Fund Recovery ](fund-recovery)section for instructions on recovering them. #### **Hyperliquid Deposits** 1. Open the Wallet widget using **/spotwallet**. 2. Copy your wallet address and send **Hyperliquid USDC** to the wallet. * Use the **Transfer** button on the Hyperliquid platform to send funds. * **⚠️ Do not use the Withdraw button**, as it is designed for withdrawing funds to the Arbitrum network. * Ensure you send **at least 10 USDC**—amounts below this will not appear in the wallet. * Once your wallet is initialized with this minimum amount, you can then send **any Hyperliquid spot asset** to your wallet. 3. After sending, press the **"Refresh"** button in the Wallet widget. ## Fund Recovery If you send the wrong token to the wallet, you can recover your funds by exporting your private key and importing it into any EVM-compatible wallet like **Metamask**, **Rainbow**, or **Rabby**. 1. Use the **/settings** command to open the Settings widget. 2. Press the "**Export Private Key**" button to retrieve your private key. ⚠️ Handle your private key securely to prevent unauthorized access to your wallet. ## Withdraw Withdraw funds from your wallet via the **Arbitrum network** or transfer tokens within the **Hyperliquid network**. #### **Arbitrum Withdrawals** 1. Open the Wallet widget using **`/spotwallet`** and press the **"Withdraw"** button. 2. Enter the Arbitrum wallet address (⚠️ Recommended to use a wallet you control, not an exchange wallet). 3. Enter the USDC amount you wish to withdraw. Note: The Hyperliquid bridge takes a **1 USDC fee** per transaction. 4. Confirm the withdrawal by sending a **"YES"** message or your **2FA code** (if enabled). #### **Hyperliquid Transfers** 1. Open the Wallet widget using **`/spotwallet`** and press the **"Transfer"** button. 2. Select the token (all SPOT tokens are supported). 3. Enter the wallet address to transfer to (⚠️ **DO NOT transfer to an exchange wallet; Hyperliquid isn’t supported on any CEX**). 4. Enter the token amount you wish to transfer. 5. Confirm the transfer by sending a **"YES"** message or your **2FA code**. Note: Transfers to a non-existing Hyperliquid wallet incur a **1 USDC account creation fee**. > **Note** > Additionally: * Tokens in the **Launch Wallet** (`/launchwallet`) cannot be withdrawn to your personal wallet. To recover the value, you will need to **sell the tokens first**. * All operations (withdrawals, transfers) are performed on the **Spot wallet**. If your funds are on **Perpetual**, you must transfer them to **Spot** using the corresponding button in the wallet widget. ## Import Private Key #### **How to Import a Private Key into Hypurr Fun** Follow these steps to securely import your private key into the Hypurr Fun Bot: 1. Use the **/wallets** command to open the Wallets menu. 2. Press **"Add Wallet"**. 3. Select **"Import Wallet"**. 4. Name your wallet (this name is for identification purposes and is different from your wallet's address). 5. Enter your wallet's private key (ensure it starts with **"0x"**). *** 🎉 Your wallet has been successfully imported and is now ready for use! ## Link API Key #### **How to Link a Wallet Using API Key in Hypurr Fun** Follow these steps to link your wallet using an API key in the Hypurr Fun Bot: 1. Use the **/wallets** command to open the Wallets menu. 2. Press **"Add Wallet"**. 3. Select **"Link Wallet"**. 4. Name your wallet (this name is for identification purposes and is different from your wallet's address). 5. Enter your wallet's address (ensure it starts with **"0x"**). 6. The bot will ask you to allow API access. Go to [Hyperliquid API Settings](https://app.hyperliquid.xyz/API) and add an entry for the given address. 7. Once API access has been granted, press the **"Link"** button in the bot. *** 🎉 Your wallet has been successfully linked and is ready for use! ## Link Read-Only Wallet #### **How to Link a Wallet in Read-Only Mode in Hypurr Fun** Follow these steps to link your wallet in **Read-Only mode**: 1. Use the **/wallets** command to open the Wallets menu. 2. Press **"Add Wallet"**. 3. Select **"Link Wallet (Read-Only)"**. 4. Name your wallet (this name is for identification purposes and is different from your wallet's address). 5. Enter your wallet's address (ensure it starts with **"0x"**). 6. The bot will ask you to transfer a specific amount of **USDC**. Go to [Hyperliquid](https://app.hyperliquid.xyz) and transfer the **exact amount** of USDC to the given wallet, from your **SPOT account only**. 7. Once the USDC transfer is complete, press the **"Link"** button in the bot. *** #### **Whale Chats** **Whale Chats** are exclusive Telegram groups reserved for token holders who meet specific thresholds. ##### Exclusive Whale Chats
**Whale Chats List** These chats are designed for holders of specific tokens who meet strict ownership thresholds: * **Hyperliquid Fat Cats**: 1,000,000 $PURR (0.1%) — [@Hyperintern](https://x.com/Hyperintern) * **JEFF Whale Chat**: 2,478 $JEFF (0.25%) — [@JHyperliquid](https://x.com/JHyperliquid) * **HFUN Whale Chat**: 1,994 $HFUN (0.2%) — [@Hypurrfun](https://x.com/Hypurrfun) * **Catbal Council**: 5,000 $CATBAL (0.5%) — [@CatCabal\_hl](https://x.com/CatCabal_hl) * **Pip Whales**: 5,000 $PIP (0.5%) — [@PipOnHL](https://x.com/PipOnHL) * **Schizo**: 4,991 (0.5%) — [@schizo\_on\_hl](https://x.com/schizo_on_hl) * **Atehun**: 4,539 $ATEHUN (0.4%) — [@crypto\_adair](https://x.com/crypto_adair) **HYPE Whale Chats** For $HYPE token holders, multiple tiers of Whale Chats exist: * **Hype Whale Chat**: 100,163 $HYPE * **Beluga Whale Chat**: 500,818 $HYPE * **Fabled Chat**: 2,500,000 $HYPE ## API ## EVM ## HpumpV1 | Name | Smart Contract | Description | | ------------------------ | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | | HpumpV1Factory | 0x4475887aF77b696D1675dE24Cb1023c679618c94 | The factory is responsible for launching new launches, tracking launches, routing trades and graduating launches. | | HpumpV1BaseLaunchFactory | 0xbEfd1746f2f7cb2123BfD456c52949c21f7ea1E7 | A launch factory that is used to instantiate new launches. | ##### ABIs The ABIs for HpumpV1Factory and HpumpV1BaseLaunchFactory are [here](https://gitlab.com/hypurr/hypurr-grpc/-/tree/master/abis?ref_type=heads). ## EOA EOA endpoint api spec - coming soon ## Static Static endpoint api spec - coming soon ## Telegram Telegram endpoint api spec - coming soon ## aHYPESeat Events Reference Complete event reference for the SeatMarket contract. ### Fee Accrual Events #### Accrued Emitted when fees are accrued to the cumulative index. ```solidity event Accrued( uint256 dt, uint256 feePerSecond, uint256 totalFeeAccrued, uint256 newCumulativeFee ); ``` | Parameter | Type | Indexed | Description | | ------------------ | --------- | ------- | ----------------------------------------- | | `dt` | `uint256` | No | Time elapsed since last accrual (seconds) | | `feePerSecond` | `uint256` | No | Fee rate during this period (WAD) | | `totalFeeAccrued` | `uint256` | No | Total fees accrued this period | | `newCumulativeFee` | `uint256` | No | New cumulative fee index | *** ### Seat Lifecycle Events #### SeatPurchased Emitted when a user purchases a seat. ```solidity event SeatPurchased(address indexed user, uint256 deposit); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ------------------------------- | | `user` | `address` | Yes | Address that purchased the seat | | `deposit` | `uint256` | No | Amount of aHYPE deposited | *** #### SeatKicked Emitted when an unhealthy position is liquidated. ```solidity event SeatKicked( address indexed user, address indexed kicker, uint256 collateralSeized, uint256 debtValue ); ``` | Parameter | Type | Indexed | Description | | ------------------ | --------- | ------- | ---------------------------------- | | `user` | `address` | Yes | Address that was liquidated | | `kicker` | `address` | Yes | Address that performed liquidation | | `collateralSeized` | `uint256` | No | Amount of collateral seized | | `debtValue` | `uint256` | No | Debt value at liquidation | *** ### Collateral Events #### CollateralAdded Emitted when a user adds collateral to their position. ```solidity event CollateralAdded(address indexed user, uint256 amount); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ------------------------- | | `user` | `address` | Yes | Address adding collateral | | `amount` | `uint256` | No | Amount of aHYPE added | *** #### CollateralWithdrawn Emitted when a user withdraws excess collateral. ```solidity event CollateralWithdrawn(address indexed user, uint256 amount); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ------------------------------ | | `user` | `address` | Yes | Address withdrawing collateral | | `amount` | `uint256` | No | Amount of aHYPE withdrawn | *** ### Fee Events #### FeesRepaid Emitted when a user repays accrued fees. ```solidity event FeesRepaid(address indexed user, uint256 amount); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | --------------------- | | `user` | `address` | Yes | Address repaying fees | | `amount` | `uint256` | No | Amount of fees repaid | *** #### FeeDistributed Emitted when fees are distributed (to recipient and burn). ```solidity event FeeDistributed(uint256 toRecipient, uint256 burned); ``` | Parameter | Type | Indexed | Description | | ------------- | --------- | ------- | ---------------------------- | | `toRecipient` | `uint256` | No | Amount sent to fee recipient | | `burned` | `uint256` | No | Amount burned | *** ### Admin Events #### ParamsUpdated Emitted when market parameters are updated. ```solidity event ParamsUpdated( uint256 maxSeats, uint256 minFeePerSecond, uint256 maxFeePerSecond, address feeRecipient, uint256 burnBps ); ``` | Parameter | Type | Indexed | Description | | ----------------- | --------- | ------- | ----------------------------- | | `maxSeats` | `uint256` | No | New maximum seats | | `minFeePerSecond` | `uint256` | No | New minimum fee rate | | `maxFeePerSecond` | `uint256` | No | New maximum fee rate | | `feeRecipient` | `address` | No | New fee recipient address | | `burnBps` | `uint256` | No | New burn rate in basis points | *** ### Event Flow Examples #### Complete Seat Purchase Flow ``` 1. User calls purchaseSeat(1000e8) └── SeatPurchased(user, 1000e8) 2. Time passes, fees accrue └── Accrued(86400, feeRate, totalFee, newIndex) // on next interaction ``` #### Fee Repayment Flow ``` 1. User checks debt └── debtValueOf(user) returns 50e8 2. User calls repayFees(50e8) └── FeesRepaid(user, 50e8) └── FeeDistributed(45e8, 5e8) // assuming 10% burn ``` #### Liquidation Flow ``` 1. Position becomes unhealthy (debt > collateral) 2. Liquidator calls kick(user) └── SeatKicked(user, liquidator, collateral, debt) └── FeeDistributed(collateral * 0.9, collateral * 0.1) ``` #### Voluntary Exit Flow ``` 1. User calls exit() └── FeeDistributed(debt * 0.9, debt * 0.1) └── User receives (collateral - debt) aHYPE ``` *** ### Monitoring Recommendations #### Key Events for Integrators | Use Case | Events to Monitor | | ------------------ | ---------------------------------------------- | | Track seat changes | `SeatPurchased`, `SeatKicked`, exit (no event) | | Monitor fees | `Accrued`, `FeesRepaid`, `FeeDistributed` | | Track collateral | `CollateralAdded`, `CollateralWithdrawn` | | Liquidation bots | `SeatKicked` (for confirmation) | | Parameter changes | `ParamsUpdated` | #### Liquidation Bot Integration To build a liquidation bot: 1. Monitor `SeatPurchased` to track new positions 2. Periodically call `isHealthy(user)` for all seat holders 3. When unhealthy found, call `kick(user)` 4. Listen for `SeatKicked` to confirm liquidation #### Event Indexing All address parameters with `indexed` modifier can be filtered efficiently: * `user` in seat and collateral events * `kicker` in liquidation events #### Fee Tracking To calculate total fees collected: 1. Sum all `FeeDistributed.toRecipient` events 2. Sum all `FeeDistributed.burned` events for burn statistics #### Utilization Tracking Monitor `SeatPurchased` and `SeatKicked` events to track: * `occupiedSeats` changes * Utilization rate changes * Fee rate implications ## aHYPESeat Contract Interface Complete API reference for the SeatMarket contract. ### Constructor ```solidity constructor( address hypeToken, uint256 _maxSeats, uint256 _minFeePerSecond, uint256 _maxFeePerSecond, address _feeRecipient, uint256 _burnBps ) ``` **Parameters:** | Name | Type | Description | | ------------------ | --------- | --------------------------------- | | `hypeToken` | `address` | aHYPE token contract address | | `_maxSeats` | `uint256` | Maximum number of seats | | `_minFeePerSecond` | `uint256` | Minimum fee rate (WAD per second) | | `_maxFeePerSecond` | `uint256` | Maximum fee rate (WAD per second) | | `_feeRecipient` | `address` | Address to receive fees | | `_burnBps` | `uint256` | Basis points to burn (0-10000) | *** ### User Functions #### purchaseSeat Deposit collateral and occupy a seat. ```solidity function purchaseSeat(uint256 deposit) external nonReentrant ``` **Parameters:** | Name | Type | Description | | --------- | --------- | -------------------------- | | `deposit` | `uint256` | Amount of aHYPE to deposit | **Requirements:** * Caller must not already have a seat * `deposit >= minDepositForSeat()` * `occupiedSeats < maxSeats` * Caller must have approved contract for `deposit` amount **Behavior:** * Transfers aHYPE from caller to contract * Creates new position with `hasSeat = true` * Snapshots current `cumulativeFeePerSeat` * Adds caller to `seatHolders` array **Emits:** `SeatPurchased(address indexed user, uint256 deposit)` *** #### addCollateral Add more collateral to an existing position. ```solidity function addCollateral(uint256 amount) external nonReentrant ``` **Parameters:** | Name | Type | Description | | -------- | --------- | ---------------------- | | `amount` | `uint256` | Amount of aHYPE to add | **Requirements:** * Caller must have a seat * Caller must have approved contract for `amount` **Behavior:** * Transfers aHYPE from caller to contract * Increases `position.collateral` by `amount` **Emits:** `CollateralAdded(address indexed user, uint256 amount)` *** #### repayFees Repay accrued fees to reduce debt. ```solidity function repayFees(uint256 amount) external nonReentrant ``` **Parameters:** | Name | Type | Description | | -------- | --------- | --------------- | | `amount` | `uint256` | Amount to repay | **Requirements:** * Caller must have a seat * `amount <= debtValueOf(caller)` * Caller must have approved contract for `amount` **Behavior:** * Accrues fees to current timestamp * Transfers aHYPE from caller to contract * Reduces `settledDebt` by repayment * Distributes repayment as fees (burn + recipient) * Updates fee index snapshot **Emits:** `FeesRepaid(address indexed user, uint256 amount)` *** #### withdrawCollateral Withdraw excess collateral (must remain healthy). ```solidity function withdrawCollateral(uint256 amount) external nonReentrant ``` **Parameters:** | Name | Type | Description | | -------- | --------- | --------------------------- | | `amount` | `uint256` | Amount of aHYPE to withdraw | **Requirements:** * Caller must have a seat * Position must remain healthy after withdrawal: `collateral - amount >= debt` **Behavior:** * Accrues fees to current timestamp * Settles current debt * Reduces collateral by `amount` * Transfers aHYPE to caller **Emits:** `CollateralWithdrawn(address indexed user, uint256 amount)` *** #### exit Voluntarily exit, settle debt, and receive remaining collateral. ```solidity function exit() external nonReentrant ``` **Requirements:** * Caller must have a seat **Behavior:** * Accrues fees to current timestamp * Calculates final debt * If `debt <= collateral`: * Distributes debt as fees * Returns `collateral - debt` to user * If `debt > collateral`: * Distributes all collateral as fees * User receives nothing * Removes seat and clears position * Removes from `seatHolders` array **Emits:** `FeeDistributed(uint256 toRecipient, uint256 burned)` *** #### kick Liquidate an unhealthy position. ```solidity function kick(address user) external nonReentrant ``` **Parameters:** | Name | Type | Description | | ------ | --------- | -------------------- | | `user` | `address` | Address to liquidate | **Requirements:** * Target must have a seat * Target must be unhealthy: `debt > collateral` **Behavior:** * Accrues fees to current timestamp * Seizes all collateral * Distributes collateral as fees (burn + recipient) * Removes seat and clears position * Removes from `seatHolders` array **Emits:** `SeatKicked(address indexed user, address indexed kicker, uint256 collateralSeized, uint256 debtValue)` *** ### View Functions #### isActive Check if user has a healthy seat (for API gating). ```solidity function isActive(address user) external view returns (bool) ``` **Returns:** `true` if user has a seat AND `collateral >= debt` **Use Case:** Backend access control systems should call this to verify access. *** #### isHealthy Check if a position is healthy. ```solidity function isHealthy(address user) public view returns (bool) ``` **Returns:** `true` if `collateral >= debt` *** #### debtValueOf Get current debt including pending (unaccrued) fees. ```solidity function debtValueOf(address user) public view returns (uint256) ``` **Returns:** `settledDebt + (cumulativeFeePerSeatView() - feeIndexSnapshot)` *** #### utilizationWad Get current utilization rate. ```solidity function utilizationWad() public view returns (uint256) ``` **Returns:** `(occupiedSeats * WAD) / maxSeats` *** #### feePerSecond Get current fee rate per second. ```solidity function feePerSecond() public view returns (uint256) ``` **Returns:** `minFeePerSecond + (maxFeePerSecond - minFeePerSecond) * utilization / WAD` *** #### feePerDay Get current daily fee rate. ```solidity function feePerDay() external view returns (uint256) ``` **Returns:** `feePerSecond() * 86400` *** #### feePerYear Get current annual fee rate. ```solidity function feePerYear() external view returns (uint256) ``` **Returns:** `feePerSecond() * 31536000` *** #### minDepositForSeat Get minimum deposit required for a new seat. ```solidity function minDepositForSeat() public view returns (uint256) ``` **Returns:** Minimum collateral needed (typically 1 day of maximum fees) *** #### getHealthySeats Get array of all healthy seat holder addresses. ```solidity function getHealthySeats() external view returns (address[] memory) ``` **Returns:** Array of addresses with `isActive(addr) == true` **Note:** May be gas-intensive for large seat counts. Use for off-chain queries. *** #### cumulativeFeePerSeatView Get cumulative fee index including pending accruals. ```solidity function cumulativeFeePerSeatView() public view returns (uint256) ``` **Returns:** `cumulativeFeePerSeat + (feePerSecond() * timeSinceLastAccrual)` *** #### positions Get position data for a user. ```solidity function positions(address user) external view returns (Position memory) ``` **Returns:** ```solidity struct Position { bool hasSeat; uint256 collateral; uint256 settledDebt; uint256 feeIndexSnapshot; } ``` *** ### Admin Functions #### setParams Update market parameters. ```solidity function setParams( uint256 _maxSeats, uint256 _minFeePerSecond, uint256 _maxFeePerSecond, address _feeRecipient, uint256 _burnBps ) external onlyOwner ``` **Parameters:** | Name | Type | Description | | ------------------ | --------- | --------------------------- | | `_maxSeats` | `uint256` | New maximum seats | | `_minFeePerSecond` | `uint256` | New minimum fee rate | | `_maxFeePerSecond` | `uint256` | New maximum fee rate | | `_feeRecipient` | `address` | New fee recipient | | `_burnBps` | `uint256` | New burn rate (0-10000 BPS) | **Requirements:** * `_maxSeats >= occupiedSeats` * `_minFeePerSecond <= _maxFeePerSecond` * `_burnBps <= 10000` * `_feeRecipient != address(0)` **Emits:** `ParamsUpdated(uint256 maxSeats, uint256 minFeePerSecond, uint256 maxFeePerSecond, address feeRecipient, uint256 burnBps)` *** #### transferOwnership Transfer contract ownership. ```solidity function transferOwnership(address newOwner) external onlyOwner ``` **Parameters:** | Name | Type | Description | | ---------- | --------- | ----------------- | | `newOwner` | `address` | New owner address | **Requirements:** * `newOwner != address(0)` *** ### Error Conditions | Error | Condition | | ---------------------- | ------------------------------------ | | `AlreadyHasSeat` | User already has a seat | | `NoSeat` | User does not have a seat | | `MarketFull` | All seats are occupied | | `InsufficientDeposit` | Deposit below minimum | | `WouldBecomeUnhealthy` | Action would make position unhealthy | | `CannotKickHealthy` | Target position is healthy | | `RepaymentExceedsDebt` | Repay amount exceeds current debt | | `InvalidParams` | Invalid admin parameters | ## aHYPESeat - Utilization-Based Seat Market SeatMarket is a fee/collateral escrow system that provides gated access through a limited number of "seats." Users lock aHYPE collateral to occupy a seat and accrue fees over time based on system utilization. Unhealthy positions can be liquidated by anyone. ### Key Features * **Limited Capacity**: Fixed maximum number of seats (`maxSeats`) * **Collateralized Access**: Users deposit aHYPE to occupy a seat * **Utilization-Based Fees**: Fee rate scales with seat occupancy * **Liquidation System**: Unhealthy positions can be kicked * **Deflationary Burns**: Portion of fees burned to increase αHYPE value * **Enumerable Holders**: Track all seat holders for backend integration ### Use Cases * API access gating for premium services * Rate-limited access to compute resources * Membership systems with dynamic pricing * Collateralized subscription services * ### Contract Addresses | Contract | Network | Address | | ----------------- | --------------- | ------------------------------------------ | | Sentry SeatMarket | Hyperliquid EVM | 0x6301983885567Ff45aa2A5E5E5456d23A76F7962 | ### Architecture ``` ┌─────────────────────────────────────────────────────────────────┐ │ User Interface │ └─────────────────────────────────────────────────────────────────┘ │ ┌───────────────┴───────────────┐ ▼ ▼ ┌───────────────────────────┐ ┌───────────────────────────────┐ │ aHYPE │ │ aHYPESeat │ │ AlphaHYPEManager05 │ │ SeatMarket01 │ │ │ │ │ │ - Deposit HYPE │ │ - Purchase seat (αHYPE) │ │ - Mint αHYPE │ │ - Accrue utilization fees │ │ - Withdraw αHYPE │ │ - Liquidation system │ │ - Claim HYPE │ │ - Fee distribution + burn │ └───────────────────────────┘ └───────────────────────────────┘ │ ▼ ┌───────────────────────────┐ │ HyperCore Precompiles │ │ │ │ - L1Read (state queries) │ │ - L1Write (mutations) │ │ - Validator delegation │ │ - Spot balance mgmt │ └───────────────────────────┘ ``` ## aHYPESeat core logic ### Fee Model Fees scale linearly with utilization: ``` utilization = occupiedSeats / maxSeats feePerSecond = minFeePerSecond + (maxFeePerSecond - minFeePerSecond) × utilization ``` #### Example Fee Calculation | Utilization | Min Fee (APR) | Max Fee (APR) | Effective Fee | | ----------- | ------------- | ------------- | ------------- | | 0% | 10% | 100% | 10% | | 50% | 10% | 100% | 55% | | 100% | 10% | 100% | 100% | Fees accrue continuously per second and are tracked via a global cumulative index. ### Debt Accounting #### Global Index ``` cumulativeFeePerSeat += feePerSecond × timeDelta ``` The global index grows every second based on current utilization. #### Per-User Tracking Each user stores a snapshot of the cumulative index when they join or settle: ``` userDebt = settledDebt + (currentIndex - userSnapshot) ``` This allows O(1) debt calculation without iterating over time periods. ### Health System A position is **healthy** when: ``` collateral >= debt ``` | Condition | Status | Actions Available | | -------------------- | --------- | -------------------------------------- | | `collateral >= debt` | Healthy | Withdraw excess, add collateral, repay | | `collateral < debt` | Unhealthy | Can be liquidated by anyone | #### Access Gating Backend systems use `isActive(user)` for access control: * Returns `true` if user has a seat AND position is healthy * Returns `false` otherwise ### Liquidation (Kick) When a position becomes unhealthy (`debt > collateral`), anyone can liquidate: ``` kick(unhealthyUser) ``` **Liquidation Process:** 1. Seat is revoked and removed from holder list 2. Position cleared (collateral, debt, snapshot reset) 3. Collateral seized and distributed as fees **Fee Distribution:** * `(100% - burnBps%)` sent to `feeRecipient` * `burnBps%` burned (removed from circulation) ### Parameters | Parameter | Type | Description | | ----------------- | --------- | -------------------------------------- | | `maxSeats` | `uint256` | Maximum concurrent seat holders | | `minFeePerSecond` | `uint256` | Minimum fee rate (WAD, 1e18 = 100%) | | `maxFeePerSecond` | `uint256` | Maximum fee rate at 100% utilization | | `feeRecipient` | `address` | Address receiving non-burned fees | | `burnBps` | `uint256` | Basis points of fees to burn (0-10000) | ### Storage Layout #### Position Struct ```solidity struct Position { bool hasSeat; // Whether user holds a seat uint256 collateral; // aHYPE locked as collateral uint256 settledDebt; // Crystallized debt amount uint256 feeIndexSnapshot; // cumulativeFeePerSeat at join/settle } ``` #### State Variables | Variable | Type | Description | | ---------------------- | ------------------------------ | ---------------------------------- | | `HYPE` | `IERC20` | aHYPE token contract (immutable) | | `maxSeats` | `uint256` | Maximum seats available | | `occupiedSeats` | `uint256` | Current number of occupied seats | | `cumulativeFeePerSeat` | `uint256` | Global fee accumulator (WAD) | | `lastAccrualTime` | `uint256` | Timestamp of last fee accrual | | `positions` | `mapping(address => Position)` | User positions | | `seatHolders` | `address[]` | Array of all seat holder addresses | ### Constants ```solidity uint256 constant WAD = 1e18; // High-precision decimal (18 decimals) ``` ### User Lifecycle #### Joining ``` 1. User calls purchaseSeat(depositAmount) └── Must have >= minDepositForSeat() aHYPE 2. Transfer aHYPE to contract └── Sets collateral = depositAmount 3. Create seat └── hasSeat = true └── feeIndexSnapshot = cumulativeFeePerSeat └── Add to seatHolders array ``` #### Maintaining ``` While holding seat: ├── addCollateral(amount) // Increase safety buffer ├── repayFees(amount) // Reduce debt ├── withdrawCollateral(amount) // Remove excess (must stay healthy) └── Monitor: debtValueOf(user) // Check current debt ``` #### Exiting ``` Voluntary exit: └── User calls exit() ├── Settle debt from collateral ├── Return remaining collateral └── Remove from seatHolders Forced exit (liquidation): └── Anyone calls kick(user) when unhealthy ├── Seize all collateral ├── Distribute as fees (burn + recipient) └── Remove from seatHolders ``` ### Integration Guide #### Checking Access ```solidity // For backend gating if (seatMarket.isActive(user)) { // Grant access } else { // Deny access } ``` #### Getting All Active Seats ```solidity // Returns array of healthy seat holders address[] memory activeUsers = seatMarket.getHealthySeats(); ``` #### Monitoring Debt ```solidity // Get current debt including pending fees uint256 debt = seatMarket.debtValueOf(user); // Get position details Position memory pos = seatMarket.positions(user); uint256 collateral = pos.collateral; // Health check bool healthy = collateral >= debt; ``` ## Security Model Security considerations and safety features of the aHYPESeat protocol. ### aHYPESeat Security Features #### Reentrancy Guard All state-changing functions protected: ```solidity modifier nonReentrant() { require(!_locked, "Reentrant"); _locked = true; _; _locked = false; } ``` #### Checks-Effects-Interactions All functions follow CEI pattern: ```solidity function withdrawCollateral(uint256 amount) external nonReentrant { // Checks require(positions[msg.sender].hasSeat, "No seat"); require(isHealthyAfterWithdrawal(amount), "Would become unhealthy"); // Effects positions[msg.sender].collateral -= amount; // Interactions HYPE.transfer(msg.sender, amount); } ``` #### Health Invariant Positions must remain healthy after any action: ```solidity require(collateral >= debt, "Would become unhealthy"); ``` Unhealthy positions can only be resolved by: * Adding collateral * Repaying fees * Liquidation (`kick`) #### Enumerable Tracking Seat holders tracked in array for iteration safety: ```solidity address[] public seatHolders; ``` Removal swaps with last element to maintain O(1) operations: ```solidity function _removeSeatHolder(address user) internal { // Find and swap with last seatHolders[index] = seatHolders[seatHolders.length - 1]; seatHolders.pop(); } ``` #### Parameter Validation Admin parameter changes validated: ```solidity require(_maxSeats >= occupiedSeats, "Cannot reduce below current"); require(_minFeePerSecond <= _maxFeePerSecond, "Invalid fee range"); require(_burnBps <= 10000, "Invalid burn rate"); require(_feeRecipient != address(0), "Invalid recipient"); ``` ### Trust Assumptions | Component | Trust Level | Notes | | ----------- | ----------- | ---------------------------------------- | | Owner | High | Can change fee parameters, max seats | | aHYPE Token | High | Assumed standard ERC20 behavior | | Liquidators | None | Anyone can liquidate unhealthy positions | ### Token Assumptions aHYPESeat assumes the collateral token (aHYPE): * Implements standard ERC20 interface * No transfer fees or rebasing * No blacklisting or pausing * `transfer` and `transferFrom` return boolean ### Audit Status | Contract | Audit Status | Auditor | | ------------ | ------------ | ------- | | SeatMarket01 | TBD | - | ### Bug Bounty TBD - Contact information for security disclosures. ## aHYPE Events Reference Complete event reference for the AlphaHYPEManager contract. ### Deposit Events #### DepositQueued Emitted when a user deposits HYPE to the queue. ```solidity event DepositQueued(address indexed depositor, uint256 amount); ``` | Parameter | Type | Indexed | Description | | ----------- | --------- | ------- | ------------------------------ | | `depositor` | `address` | Yes | Address that deposited HYPE | | `amount` | `uint256` | No | Amount of HYPE deposited (wei) | *** #### DepositProcessed Emitted when a queued deposit is processed and αHYPE is minted. ```solidity event DepositProcessed(address indexed depositor, uint256 amount, uint256 wrappedAmount); ``` | Parameter | Type | Indexed | Description | | --------------- | --------- | ------- | ------------------------ | | `depositor` | `address` | Yes | Address receiving αHYPE | | `amount` | `uint256` | No | HYPE amount deposited | | `wrappedAmount` | `uint256` | No | αHYPE minted (after fee) | *** ### Withdrawal Events #### WithdrawalQueued Emitted when a user requests a withdrawal. ```solidity event WithdrawalQueued(address indexed withdrawer, uint256 wrappedAmount); ``` | Parameter | Type | Indexed | Description | | --------------- | --------- | ------- | ----------------------------- | | `withdrawer` | `address` | Yes | Address requesting withdrawal | | `wrappedAmount` | `uint256` | No | αHYPE amount to withdraw | *** #### WithdrawalProcessed Emitted when a withdrawal request is settled. ```solidity event WithdrawalProcessed(address indexed withdrawer, uint256 amount, uint256 wrappedAmount); ``` | Parameter | Type | Indexed | Description | | --------------- | --------- | ------- | --------------------------------- | | `withdrawer` | `address` | Yes | Address with processed withdrawal | | `amount` | `uint256` | No | HYPE amount owed | | `wrappedAmount` | `uint256` | No | αHYPE amount burned | *** #### WithdrawalClaimed Emitted when a user claims their processed HYPE. ```solidity event WithdrawalClaimed(address indexed withdrawer, uint256 amount); ``` | Parameter | Type | Indexed | Description | | ------------ | --------- | ------- | ------------------------- | | `withdrawer` | `address` | Yes | Address claiming HYPE | | `amount` | `uint256` | No | HYPE amount claimed (wei) | *** ### Bridging Events #### EVMSend Emitted when HYPE is sent within EVM. ```solidity event EVMSend(uint256 amount, address to); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ----------------- | | `amount` | `uint256` | No | Amount sent | | `to` | `address` | No | Recipient address | *** #### SpotSend Emitted when HYPE is bridged to/from Spot. ```solidity event SpotSend(uint256 amount, address to); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ----------------- | | `amount` | `uint256` | No | Amount bridged | | `to` | `address` | No | Recipient address | *** ### Staking Events #### StakingDeposit Emitted when HYPE is deposited to staking. ```solidity event StakingDeposit(uint256 amount); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | --------------------------- | | `amount` | `uint256` | No | Amount deposited to staking | *** #### StakingWithdraw Emitted when HYPE is withdrawn from staking. ```solidity event StakingWithdraw(uint256 amount); ``` | Parameter | Type | Indexed | Description | | --------- | --------- | ------- | ----------------------------- | | `amount` | `uint256` | No | Amount withdrawn from staking | *** #### TokenDelegate Emitted when HYPE is delegated or undelegated to a validator. ```solidity event TokenDelegate(address indexed validator, uint256 amount, bool isUndelegate); ``` | Parameter | Type | Indexed | Description | | -------------- | --------- | ------- | --------------------------------------------- | | `validator` | `address` | Yes | Validator address | | `amount` | `uint256` | No | Amount delegated/undelegated | | `isUndelegate` | `bool` | No | `true` if undelegating, `false` if delegating | *** ### Event Flow Examples #### Complete Deposit Flow ``` 1. User sends HYPE └── DepositQueued(user, 1000e18) 2. Processor calls processQueues() └── DepositProcessed(user, 1000e18, 999e8) // minus 0.1% fee └── TokenDelegate(validator, 1000e8, false) // delegate to staking ``` #### Complete Withdrawal Flow ``` 1. User calls withdraw(100e8) └── WithdrawalQueued(user, 100e8) 2. Processor calls processQueues() └── StakingWithdraw(100e8) // if needed └── SpotSend(100e8, contract) // bridge if needed └── WithdrawalProcessed(user, 99.9e8, 100e8) // minus 0.1% fee 3. User calls claimWithdrawal() └── WithdrawalClaimed(user, 99.9e18) // scaled to 18 decimals ``` *** ### Monitoring Recommendations #### Key Events for Integrators | Use Case | Events to Monitor | | ------------------------ | -------------------------------------------------------------- | | Track deposits | `DepositQueued`, `DepositProcessed` | | Track withdrawals | `WithdrawalQueued`, `WithdrawalProcessed`, `WithdrawalClaimed` | | Monitor TVL changes | `StakingDeposit`, `StakingWithdraw`, `TokenDelegate` | | Detect bridging activity | `EVMSend`, `SpotSend` | #### Event Indexing All address parameters with `indexed` modifier can be filtered efficiently: * `depositor` in deposit events * `withdrawer` in withdrawal events * `validator` in delegation events ## aHYPE Contract Interface Complete API reference for the AlphaHYPEManager contract. ### Initialization #### initialize Initializes the upgradeable contract. Must be called immediately after deployment. ```solidity function initialize(address validator, uint64 hypeTokenIndex) external initializer ``` **Parameters:** | Name | Type | Description | | ---------------- | --------- | -------------------------------------------- | | `validator` | `address` | Target validator address for HYPE delegation | | `hypeTokenIndex` | `uint64` | HYPE token index on Hyperliquid Spot | **Access:** Can only be called once during proxy deployment. *** ### User Functions #### receive (Deposit) Deposit native HYPE to queue for αHYPE minting. ```solidity receive() external payable ``` **Requirements:** * `msg.value >= minDepositAmount` * `msg.value` must be a multiple of `10^10` wei (8-decimal alignment) * Deposit queue length \< 100 * If `maxSupply > 0`, minting must not exceed cap **Emits:** `DepositQueued(address indexed depositor, uint256 amount)` *** #### withdraw Request withdrawal of αHYPE tokens for underlying HYPE. ```solidity function withdraw(uint256 amount) external nonReentrant ``` **Parameters:** | Name | Type | Description | | -------- | --------- | --------------------------- | | `amount` | `uint256` | Amount of αHYPE to withdraw | **Requirements:** * Caller must have sufficient αHYPE balance * Withdrawal queue length \< 100 **Behavior:** * Burns αHYPE immediately * Locks current exchange rate snapshot for slashing protection * Queues `WithdrawalRequest` for processing **Emits:** `WithdrawalQueued(address indexed withdrawer, uint256 wrappedAmount)` *** #### claimWithdrawal Claim processed HYPE after withdrawal has been settled. ```solidity function claimWithdrawal() external nonReentrant ``` **Requirements:** * Caller must have non-zero `owedUnderlyingAmounts[msg.sender]` **Behavior:** * Transfers owed HYPE to caller (scaled back to 18 decimals) * Zeros owed amount before transfer (reentrancy protection) **Emits:** `WithdrawalClaimed(address indexed withdrawer, uint256 amount)` *** ### Processing Functions #### processQueues Process pending deposits and withdrawals. Can be called once per block. ```solidity function processQueues() external nonReentrant ``` **Access:** * If `processor` is set: only callable by processor * If `processor` is zero address: callable by anyone **Requirements:** * `block.number > lastProcessedBlock` **Behavior:** 1. Validates solvency against EVM holdings 2. Reads HyperCore state (delegator summary, spot balance) 3. Calculates deposit/withdrawal prices 4. Processes deposit queue (mints αHYPE minus fee) 5. Processes withdrawal queue when liquidity permits 6. Balances liquidity across EVM/Spot/Staking **Emits:** Multiple events depending on operations performed *** ### Admin Functions #### setMaxSupply Set the maximum αHYPE supply cap. ```solidity function setMaxSupply(uint64 _maxSupply) external onlyOwner ``` **Parameters:** | Name | Type | Description | | ------------ | -------- | ------------------------------- | | `_maxSupply` | `uint64` | Maximum supply cap (0 = no cap) | **Access:** Owner only *** #### setMinDepositAmount Set the minimum deposit amount. ```solidity function setMinDepositAmount(uint256 _minDepositAmount) external onlyOwner ``` **Parameters:** | Name | Type | Description | | ------------------- | --------- | ---------------------- | | `_minDepositAmount` | `uint256` | Minimum deposit in wei | **Access:** Owner only *** #### setProcessor Set the designated processor address. ```solidity function setProcessor(address _processor) external onlyOwner ``` **Parameters:** | Name | Type | Description | | ------------ | --------- | ----------------------------------------- | | `_processor` | `address` | Processor address (zero = permissionless) | **Access:** Owner only *** #### collectFees Withdraw accumulated protocol fees. ```solidity function collectFees() external onlyOwner nonReentrant ``` **Behavior:** * Transfers accumulated `feeAmount` to owner * Zeros `feeAmount` before transfer **Access:** Owner only *** ### View Functions #### getERC20Supply Get total αHYPE supply including queued withdrawals. ```solidity function getERC20Supply() public view returns (uint256) ``` **Returns:** `totalSupply() + withdrawalAmount` *** #### getUnderlyingSupply Get total HYPE backing available for price calculation. ```solidity function getUnderlyingSupply() public view returns (uint256) ``` **Returns:** Combined HYPE from: * EVM balance (scaled to 8 decimals) * Delegated stake * Undelegated stake * Pending withdrawals from staking * Spot holdings Minus: * `pendingDepositAmount` * `withdrawalAmount` * `feeAmount` * `owedUnderlyingAmount` *** #### decimals Get token decimals. ```solidity function decimals() public pure override returns (uint8) ``` **Returns:** `8` *** #### pendingDepositQueueLength Get number of pending deposits. ```solidity function pendingDepositQueueLength() external view returns (uint256) ``` **Returns:** Length of `depositQueue` *** #### pendingWithdrawalQueueLength Get number of pending withdrawals. ```solidity function pendingWithdrawalQueueLength() external view returns (uint256) ``` **Returns:** Length of `pendingWithdrawalQueue` *** ### Inherited ERC20 Functions Standard ERC20 functions inherited from OpenZeppelin: | Function | Description | | ----------------------------------------- | ------------------------ | | `name()` | Returns "Alpha HYPE" | | `symbol()` | Returns "αHYPE" | | `totalSupply()` | Total minted αHYPE | | `balanceOf(address)` | αHYPE balance of address | | `transfer(address, uint256)` | Transfer αHYPE | | `approve(address, uint256)` | Approve spender | | `transferFrom(address, address, uint256)` | Transfer from approved | | `allowance(address, address)` | Check allowance | | `burn(uint256)` | Burn own αHYPE | | `burnFrom(address, uint256)` | Burn from approved | *** ### Error Conditions | Error | Condition | | ----------------------- | ------------------------------------ | | `InvalidDepositAmount` | Deposit below minimum or not aligned | | `QueueFull` | Queue exceeds 100 entries | | `MaxSupplyExceeded` | Minting would exceed supply cap | | `InsufficientBalance` | Caller lacks αHYPE for withdrawal | | `NothingToClaim` | No owed HYPE to claim | | `AlreadyProcessed` | Queue already processed this block | | `UnauthorizedProcessor` | Non-processor called processQueues | ## aHYPE - Alpha HYPE Liquid Staking Manager AlphaHYPEManager is an upgradeable liquid staking vault for Hyperliquid's native HYPE token. It mints the wrapped Alpha HYPE token (`αHYPE`) and manages the full lifecycle of deposits, validator delegation, reward compounding, and redemptions through HyperCore precompiles. ### Key Features * Queue-based deposits and withdrawals priced against real-time underlying HYPE backing * Dual 0.1% protocol fee applied at mint and burn * Eight-decimal ERC20 supply mirroring Hyperliquid accounting * Automated bridging between EVM balance, Hyperliquid Spot, and staking delegations * Pull-based withdrawals protecting against reentrancy and slashing events * Role-gated processor for trusted queue execution ### Contract Addresses | Contract | Network | Address | | ---------------- | --------------- | ------------------------------------------ | | AlphaHYPEManager | Hyperliquid EVM | 0xe44bd27c9f10fa2f89fdb3ab4b4f0e460da29ea8 | ### Token Model | Property | Value | | -------- | ----------------------------- | | Name | Alpha HYPE | | Symbol | αHYPE | | Decimals | 8 | | Standard | ERC20 (Upgradeable, Burnable) | ### Backing Composition The underlying pool combines: * Contract's EVM balance (scaled to 8 decimals) * Hyperliquid spot holdings * Delegated stake * Undelegated stake * Pending withdrawals (queried via `L1Read`) ## aHYPE Contract Logic ### Supply Accounting ``` getERC20Supply() = circulating αHYPE + queued withdrawal balance getUnderlyingSupply() = total HYPE backing - queued deposits - queued withdrawals - accrued fees ``` ### Fee Structure | Fee Type | Rate | Application | | -------- | ------------- | -------------------------- | | Mint Fee | 0.1% (10 BPS) | Applied when minting αHYPE | | Burn Fee | 0.1% (10 BPS) | Applied when burning αHYPE | Fees accumulate on the contract and can be harvested by the owner via `collectFees()`. ### Operational Flow #### Deposit Flow ``` User sends HYPE ──► Deposit queued ──► processQueues() ──► αHYPE minted │ ▼ Validation: - msg.value >= minDepositAmount - Amount is multiple of 10^10 wei - Queue length < 100 - maxSupply not exceeded ``` #### Withdrawal Flow ``` User calls withdraw(amount) ──► αHYPE burned ──► WithdrawalRequest queued │ ▼ Price snapshot locked (slashing protection) │ ▼ processQueues() settles │ ▼ User calls claimWithdrawal() │ ▼ HYPE transferred ``` #### Queue Processing `processQueues()` executes once per block and: 1. Revalidates solvency by comparing EVM holdings to owed withdrawals 2. Reads HyperCore state via `L1Read.delegatorSummary` and `L1Read.spotBalance` 3. Prices deposits and withdrawals using high-precision ratios 4. Mints `αHYPE` minus mint fee for deposits 5. Settles withdrawal requests when liquidity exists 6. Balances liquidity by: * Bridging HYPE from spot if EVM liquidity is short * Withdrawing/undelegating from staking * Re-deploying idle HYPE to staking when queues are clear ### Roles & Permissions | Role | Capabilities | | ------------- | -------------------------------------------------------------------- | | **Owner** | Configure `maxSupply`, `minDepositAmount`, `processor`; harvest fees | | **Processor** | Execute `processQueues()` once per block (if set) | | **Users** | Deposit HYPE, request withdrawals, claim HYPE | ### Constants ```solidity uint256 constant FEE_BPS = 10; // 0.1% uint256 constant BPS_DENOMINATOR = 10_000; uint256 constant SCALE_18_TO_8 = 1e10; address constant HYPE_SYSTEM_ADDRESS = 0x2222222222222222222222222222222222222222; ``` ### Storage Layout #### Structs ```solidity struct DepositRequest { address depositor; uint256 amount; } struct WithdrawalRequest { address withdrawer; uint256 amount; uint256 pricePerTokenX18; // Snapshot for slashing protection } ``` #### State Variables | Variable | Type | Description | | ------------------------ | ----------------------------- | ------------------------------- | | `validator` | `address` | Target validator for delegation | | `hypeTokenIndex` | `uint64` | HYPE token index on Hyperliquid | | `depositQueue` | `DepositRequest[]` | Pending deposits (max 100) | | `pendingWithdrawalQueue` | `WithdrawalRequest[]` | Pending withdrawals | | `pendingDepositAmount` | `uint256` | Total unprocessed deposit HYPE | | `withdrawalAmount` | `uint256` | Total pending withdrawal αHYPE | | `owedUnderlyingAmounts` | `mapping(address => uint256)` | HYPE owed per user | | `feeAmount` | `uint256` | Accumulated protocol fees | | `maxSupply` | `uint64` | Optional supply cap (0 = none) | | `processor` | `address` | Designated processor (optional) | | `minDepositAmount` | `uint256` | Minimum deposit threshold | | `lastProcessedBlock` | `uint256` | One-per-block guard | ## HyperCore Precompiles The AlphaHYPEManager integrates with Hyperliquid's core through precompiled contracts. These precompiles provide read and write access to the Hyperliquid state. ### Overview | Library | Purpose | Precompile Range | | ------- | ------------------------ | ------------------- | | L1Read | Query Hyperliquid state | `0x0800` - `0x080F` | | L1Write | Mutate Hyperliquid state | `0x3333...3333` | ### L1Read - Read Operations #### Precompile Addresses ```solidity address constant DELEGATOR_SUMMARY = 0x0000000000000000000000000000000000000800; address constant SPOT_BALANCE = 0x0000000000000000000000000000000000000801; address constant POSITION = 0x0000000000000000000000000000000000000802; // ... additional addresses ``` #### delegatorSummary Get staking delegation summary for an address. ```solidity function delegatorSummary(address user) internal view returns (DelegatorSummary memory) ``` **Returns:** ```solidity struct DelegatorSummary { uint64 delegated; // Total delegated stake uint64 undelegated; // Stake being undelegated uint64 totalPendingWithdrawals; // Pending withdrawal amount uint64 nDelegations; // Number of active delegations } ``` **Used for:** Calculating underlying HYPE backing from staked amounts. *** #### spotBalance Get spot balance for a token. ```solidity function spotBalance(address user, uint64 token) internal view returns (SpotBalance memory) ``` **Parameters:** | Name | Type | Description | | ------- | --------- | ------------------------------- | | `user` | `address` | Address to query | | `token` | `uint64` | Token index on Hyperliquid Spot | **Returns:** ```solidity struct SpotBalance { uint64 total; // Total balance uint64 hold; // Amount on hold } ``` **Used for:** Calculating underlying HYPE in Spot holdings. *** #### delegations Get all delegations for an address. ```solidity function delegations(address user) internal view returns (Delegation[] memory) ``` **Returns:** ```solidity struct Delegation { address validator; uint64 amount; uint64 lockedUntil; // Unlock timestamp } ``` *** #### Additional Read Functions | Function | Description | | --------------------------- | ------------------------ | | `position(address, uint16)` | Get perpetual position | | `tokenSupply(uint32)` | Get token supply info | | `tokenInfo(uint32)` | Get token metadata | | `markPrice(uint16)` | Get perpetual mark price | | `oraclePrice(uint16)` | Get oracle price | *** ### L1Write - Write Operations #### CoreWriter Interface All write operations go through the CoreWriter precompile: ```solidity address constant CORE_WRITER = 0x3333333333333333333333333333333333333333; interface CoreWriter { function write(bytes memory action) external; } ``` #### tokenDelegate Delegate or undelegate HYPE to a validator. ```solidity function tokenDelegate(address validator, uint256 amount, bool isUndelegate) internal ``` **Parameters:** | Name | Type | Description | | -------------- | --------- | ----------------------------------------- | | `validator` | `address` | Validator address | | `amount` | `uint256` | Amount to delegate/undelegate | | `isUndelegate` | `bool` | `true` to undelegate, `false` to delegate | **Action Type:** `TokenDelegate` *** #### stakingDeposit Deposit HYPE to staking. ```solidity function stakingDeposit(uint64 amount) internal ``` **Parameters:** | Name | Type | Description | | -------- | -------- | ------------------------------ | | `amount` | `uint64` | Amount to deposit (8 decimals) | **Action Type:** `CDeposit` *** #### stakingWithdraw Withdraw HYPE from staking. ```solidity function stakingWithdraw(uint64 amount) internal ``` **Parameters:** | Name | Type | Description | | -------- | -------- | ------------------------------- | | `amount` | `uint64` | Amount to withdraw (8 decimals) | **Action Type:** `CWithdraw` *** #### spotSend Bridge HYPE between Spot and EVM. ```solidity function spotSend(address destination, uint256 token, uint256 amount) internal ``` **Parameters:** | Name | Type | Description | | ------------- | --------- | ----------------- | | `destination` | `address` | Recipient address | | `token` | `uint256` | Token index | | `amount` | `uint256` | Amount to send | **Action Type:** `SpotSend` *** ### System Addresses ```solidity // HYPE system bridge address - transfers to this address move HYPE between core and EVM address constant HYPE_SYSTEM_ADDRESS = 0x2222222222222222222222222222222222222222; ``` ### Usage in AlphaHYPEManager #### Reading State ```solidity // Get delegation info L1Read.DelegatorSummary memory summary = L1Read.delegatorSummary(address(this)); uint256 stakedHype = summary.delegated + summary.undelegated + summary.totalPendingWithdrawals; // Get spot balance L1Read.SpotBalance memory spot = L1Read.spotBalance(address(this), hypeTokenIndex); uint256 spotHype = spot.total; ``` #### Writing State ```solidity // Delegate to validator L1Write.tokenDelegate(validator, amount, false); // Undelegate from validator L1Write.tokenDelegate(validator, amount, true); // Deposit to staking pool L1Write.stakingDeposit(uint64(amount)); // Withdraw from staking pool L1Write.stakingWithdraw(uint64(amount)); // Bridge from Spot to EVM L1Write.spotSend(address(this), hypeTokenIndex, amount); ``` ### Precision Handling | Context | Decimals | Notes | | --------------- | -------- | --------------------- | | EVM native HYPE | 18 | Standard wei | | L1Read amounts | 8 | Hyperliquid standard | | L1Write amounts | 8 | Must convert from wei | | αHYPE token | 8 | Matches Hyperliquid | **Conversion constant:** ```solidity uint256 constant SCALE_18_TO_8 = 1e10; // Wei to 8 decimals uint256 scaled = weiAmount / SCALE_18_TO_8; // 8 decimals to wei uint256 wei = scaledAmount * SCALE_18_TO_8; ``` ## Security Model Security considerations and safety features of the aHYPE protocol. ### aHYPE Security Features #### Queue Caps Hard limit of 100 entries per queue prevents unbounded loops and DoS attacks: ```solidity require(depositQueue.length < 100, "Queue full"); require(pendingWithdrawalQueue.length < 100, "Queue full"); ``` **Rationale:** Prevents gas exhaustion attacks where an attacker could fill queues with small deposits to make `processQueues()` exceed block gas limits. #### Pull-Based Withdrawals Withdrawals use a two-step claim pattern: 1. `withdraw()` - Burns αHYPE, queues request, records amount owed 2. `claimWithdrawal()` - User pulls their HYPE ```solidity mapping(address => uint256) owedUnderlyingAmounts; ``` **Rationale:** * Eliminates reentrancy vectors during withdrawal processing * Allows batch processing without external calls per user * Users can claim at their convenience #### Slashing Protection Withdrawal requests lock the exchange rate at queue time: ```solidity struct WithdrawalRequest { address withdrawer; uint256 amount; uint256 pricePerTokenX18; // Snapshot } ``` Processing uses the minimum of locked and current price: ```solidity uint256 effectivePrice = min(request.pricePerTokenX18, currentPrice); ``` **Rationale:** If validator is slashed between queue and claim, users don't receive more than the pool can support. #### One-Per-Block Processing ```solidity require(block.number > lastProcessedBlock, "Already processed"); lastProcessedBlock = block.number; ``` **Rationale:** Prevents multiple processing calls in the same block that could exploit price calculation timing. #### Precision Handling * All internal accounting uses 8 decimals (matching Hyperliquid) * Deposits must be multiples of `10^10` wei to avoid dust * `Math.mulDiv` used for high-precision division without overflow ```solidity uint256 constant SCALE_18_TO_8 = 1e10; require(amount % SCALE_18_TO_8 == 0, "Invalid amount"); ``` #### Reentrancy Protection All state-changing functions use `nonReentrant` modifier: ```solidity function withdraw(uint256 amount) external nonReentrant { ... } function claimWithdrawal() external nonReentrant { ... } function processQueues() external nonReentrant { ... } function collectFees() external onlyOwner nonReentrant { ... } ``` #### Access Control | Function | Access | | -------------- | ------------------- | | Deposit | Public | | Withdraw | Public | | Claim | Public | | Process Queues | Processor or Public | | Set Parameters | Owner | | Collect Fees | Owner | | Upgrade | Owner | ### Trust Assumptions | Component | Trust Level | Notes | | --------- | ----------- | ----------------------------------------------------- | | Owner | High | Can upgrade contract, change parameters, collect fees | | Processor | Medium | Can execute queue processing (timing control) | | Validator | High | Delegated HYPE subject to validator behavior | | HyperCore | High | Precompiles assumed to function correctly | ### Known Limitations 1. **Unbonding Period**: Withdrawals may be delayed by staking unbonding period 2. **Queue Limits**: Maximum 100 pending operations per queue 3. **Block Processing**: Only one `processQueues()` call per block 4. **Validator Risk**: Delegated stake subject to slashing ### Audit Status | Contract | Audit Status | Auditor | | ------------------ | ------------ | ------- | | AlphaHYPEManager05 | TBD | - | ### Bug Bounty TBD - Contact information for security disclosures.