Skip to main content
The HyperliquidGridStrategy lets a syndicate run a grid-trading book across whitelisted Hyperliquid perp assets. USDC is pulled from the vault and parked on HyperCore margin via the L1Write precompile. A keeper EOA (the proposer) drives the grid by calling updateParams every ~60s with batched limit orders. The strategy keeps an on-chain mirror of every resting GTC CLOID it has placed, so settlement can self-cancel without keeper assistance.
Not yet available on Robinhood testnet (chain 46630), Sherwood’s current deployment target. This strategy depends on Hyperliquid/HyperEVM precompiles and will come online as Sherwood expands to more chains.
This strategy holds leveraged perp positions on a centralized-matching venue. A run-away market or keeper outage can leave grids one-sided; HyperCore liquidations destroy vault equity up to the deposit. Use conservative leverage, set per-order and per-tick caps at init, and monitor positions directly on Hyperliquid.

Architecture

Lifecycle

PhaseWhat happensWho calls
ExecutePull USDC → bridgeUsdcToSpot (EVM → HC spot via Circle) → sendUsdClassTransfer (spot → perp margin). Leverage is set off-chain via the exchange API before the proposal opens.Governor (proposal execution)
Finalize-for-HyperCoreOne-time finalizeForHyperCore(0, FinalizeVariant.FirstStorageSlot, 0) so HC auto-credits bridged USDC to this clone’s spot account. initialize() stamps address(this) into slot 0 (_hcSelf); HC reads it post-block to confirm registration — no deployer-nonce math. The CLI runs it as a separate tx immediately after initialize().Proposer
ExecutedKeeper calls updateParams with one of: place batch of GTC orders, cancel a list of CLOIDs, atomic cancel-and-place. Each order’s CLOID is tracked in _liveCloids[ai].Proposer only
Book accountingWhile Executed, the strategy tracks its own HyperCore equity (L1Read.accountMarginSummary) for keeper/monitoring purposes. This is the strategy’s internal book — it is not a vault live-NAV source. Vault deposits/redeems during the proposal go through the Lane B async queue.Keeper (read)
SettleWalk every tracked CLOID and cancel, then force-close all asset positions (reduce-only IOC at min/max price), then request async USD transfer back to spot.Governor
SweepsweepToVault() pushes USDC to the vault when async transfer arrives. Repeatable for partial arrivals. initiateReturn() is permissionless and re-runs the spot transfer if residual perp equity remains.Anyone

Batch Calls

Execute

Settle

After settle(), anyone can call strategy.sweepToVault() once the async USD transfer lands. Funds can only flow to the vault.

InitParams

On-chain risk caps:
  • leverage must be 1–50; maxOrderSize and maxOrdersPerTick must be non-zero
  • assetIndices is bounded at 32 entries; trading any non-whitelisted asset reverts with AssetNotWhitelisted
  • Each individual order’s sz * limitPx / 1e6 must be ≤ maxOrderSizeOrderTooLarge otherwise. This is a per-order bound, not a cumulative exposure cap; the keeper is trusted to compose grids correctly within whitelisted assets.
  • A single updateParams call may not place more than maxOrdersPerTick orders (TooManyOrders)

Proposer Actions (Executed state)

Encoded as updateParams(abi.encode(action, ...)):
ActionEncodingDescription
1 — place grid(uint8, GridOrder[])Place a batch of GTC limit orders. Each GridOrder is (assetIndex, isBuy, limitPx, sz, cloid). CLOIDs are tracked on-chain so settlement can self-cancel.
2 — cancel(uint8, uint32 assetIndex, uint128[] cloids)Cancel an explicit list of CLOIDs by asset.
3 — cancel-and-place(uint8, uint32 assetIndex, uint128[] cancelCloids, GridOrder[] orders)Atomic: cancel given CLOIDs then place the new batch. Used to refresh a side of the grid in one tx.
Position state is not tracked on-chain — the keeper reads HyperCore directly (L1Read.position2) to know fills. The on-chain CLOID mirror exists purely so _settle can self-cancel resting orders before the IOC sweep.

Vault Liquidity During a Proposal

This strategy is Lane B only by design — it does not override positions(), so the vault reports no priceable position and there is no oracle instant-lane. While a grid proposal is active, vault deposits and redeems go through the Lane B async queue: requestDeposit / requestRedeem escrow in the VaultWithdrawalQueue and settle at the single frozen, realized per-proposal price stamped when the proposal settles. Outside a proposal, entry/exit is instant ERC-4626 against vault float. See Deposits & Withdrawals for the full two-lane model.

Internal book accounting

Separately from vault NAV, the strategy tracks its own HyperCore book for keeper and monitoring purposes: it sums HyperCore perp equity (L1Read.accountMarginSummary), HyperCore spot USDC, and the strategy’s EVM USDC balance, all in USDC-6-decimal units, reconciling that observable total against the in-flight high-water mark (inFlightToHc) with a Circle-fee-sized tolerance (a cross-block bridge window falls back to inFlightToHc so the internal figure stays stable). This is the strategy’s private accounting — the vault never reads it as a live-NAV source; vault pricing during a proposal is Lane B only.

Risk Notes

  • HyperCore registration is required before execute. The CLI calls finalizeForHyperCore(0, FinalizeVariant.FirstStorageSlot, 0) immediately after initialize(). Without it, the EVM → HC-spot bridge in _execute() can’t auto-credit the clone’s HC spot account, so the subsequent spot → perp class transfer operates on an empty balance and the funds never reach margin. finalizeForHyperCore reverts with AlreadyFinalized if called twice.
  • Settlement order matters. _settle walks _liveCloids[asset] from the tail and pops, guaranteeing resting orders are cancelled before the reduce-only IOC sweep. This eliminates the race where a resting buy could fill against the force-close at a stale price.
  • Async settlement. settle() does not immediately return funds. After IOC fills, residual perp balance lingers; sweepToVault() may need to be called multiple times. initiateReturn() is permissionless and re-runs the spot transfer if any perp equity remains.
  • Liquidation: HyperCore liquidates positions that breach maintenance margin. The on-chain contract has no view into liquidation state — settlement and sweep still work, but returned USDC may be well below depositAmount.
  • No off-chain risk system on-chain. Per-order caps are the only on-chain limit. Cumulative grid exposure is the keeper’s responsibility.

CLI Usage

FlagDescriptionDefault
--amount <n>USDC collateral to deploy (omit to use full vault balance at execute time)dynamic-all
--leverage <n>Per-asset leverage (1–50)5
--max-order-size <amount>Max USD per individual order10000
--max-orders-per-tick <n>Max orders placed per updateParams call20
--asset-indices <list>Comma-separated HyperCore perp asset indices0
After the proposal executes, the keeper drives the grid with sherwood proposal update-params using the action encodings above. A reference grid loop ships in cli/src/grid/ — see cli/src/grid/SKILL.md for the signal stack and ATR-based level placement.

Addresses (HyperEVM reference)

ContractAddress
HyperliquidGridStrategy template0x20348e428050031647d671F0e24752C01D4b7379
USDC0xb88339CB7199b77E23DB6E890353E22632Ba630f
SyndicateFactory0xd05Ae0E8bcf13075C29817c805d6Cc14F214393a
SyndicateGovernor0x67AD3D5F3d127Ef923Fd6f67b178633c408D3fd3