Skip to content本文へ移動

HyperEVM Development · DeFi on HyperEVM · 8/8

Composing with L1 Trading

The Composability Vision

The promise of HyperEVM is that smart contracts can compose with the native order book. Contracts read HyperCore through precompiles and write to it through the CoreWriter system contract at 0x3333333333333333333333333333333333333333, so strategies can run fully on-chain or split work between a contract and an off-chain keeper.

Architecture Patterns

Pattern 1: Smart Contract Vault + Keeper

HyperEVM (On-Chain)          L1 (Order Book)
┌─────────────────┐          ┌──────────────┐
│  Vault Contract │          │  Positions   │
│  - Deposits     │          │  - BTC Long  │
│  - Shares       │◄────────►│  - ETH Short │
│  - Accounting   │  Keeper  │  - Funding   │
└─────────────────┘          └──────────────┘

The vault contract manages deposits and share accounting on HyperEVM, while a keeper bot handles the actual trading on the L1. The keeper reads the vault's equity and adjusts positions proportionally.

Pattern 2: On-Chain Price Checks

// A contract that flags when a market's mark price drifts away from its oracle.
// PriceReader is the contract from the "Reading L1 State" lesson.
contract DeviationWatch is PriceReader {
    event Deviation(uint32 perpIndex, uint64 markPx, uint64 oraclePx);

    function check(uint32 perpIndex) external {
        uint64 mark = markPx(perpIndex);
        uint64 oracle = oraclePx(perpIndex);

        // Flag a gap of more than 0.5% of the oracle price, in either direction
        // (an oracle of 0 means the market has no price yet: flag it too)
        uint256 gap = mark > oracle ? uint256(mark - oracle) : uint256(oracle - mark);
        if (oracle == 0 || gap * 1000 > uint256(oracle) * 5) {
            emit Deviation(perpIndex, mark, oracle);
        }
    }
}

A keeper watches for Deviation events and acts off-chain, for example by pausing its own quotes or alerting whoever runs the market.

Pattern 3: Trading Directly via CoreWriter

A contract can place orders for its own HyperCore account by calling sendRawAction on CoreWriter. The payload is a version byte (0x01), a 3-byte action ID, then the ABI-encoded fields. Action 1 is a limit order (action table):

// Testnet only — sketch, no access control
interface ICoreWriter {
    function sendRawAction(bytes calldata data) external;
}

contract CoreTrader {
    ICoreWriter constant CORE_WRITER =
        ICoreWriter(0x3333333333333333333333333333333333333333);

    // limitPx and sz are 10^8 * the human-readable value
    function placeLimitOrder(uint32 asset, bool isBuy, uint64 limitPx, uint64 sz) external {
        bytes memory fields = abi.encode(
            asset, isBuy, limitPx, sz,
            false,       // reduceOnly
            uint8(3),    // tif: 1 = Alo, 2 = Gtc, 3 = Ioc
            uint128(0)   // cloid: 0 = none
        );
        // version 1, action ID 1 (limit order)
        CORE_WRITER.sendRawAction(abi.encodePacked(uint8(1), uint24(1), fields));
    }
}

Things to know:

Cross-Environment Workflows

Deposit Flow

  1. User deposits a linked token (e.g. USDC) into the HyperEVM vault contract
  2. Contract mints shares to user
  3. Contract (or a keeper calling it) transfers the tokens to the token's system address, crediting the contract's HyperCore spot balance
  4. Positions are opened via CoreWriter (contract-driven) or via the API by an agent wallet the contract approved with CoreWriter action 9

Withdrawal Flow

  1. User requests withdrawal on HyperEVM
  2. Contract burns shares, emits event
  3. Proportional HyperCore positions are closed
  4. Funds are moved back to HyperEVM with a CoreWriter spot send (action 6) to the token's system address
  5. Once they arrive in a later EVM block, USDC is sent to the user

Because Core → EVM transfers land in a later block, withdrawals are asynchronous: design them as request-then-claim.

Building a Complete System

// Keeper that connects a HyperEVM vault to HyperCore trading (ethers v6)
import { ethers, EventLog } from "ethers";

class HybridVaultKeeper {
    constructor(
        private vaultContract: ethers.Contract,
        // plus a HyperCore API client of your choice, signing with an agent wallet
    ) {}

    async processDeposit(event: EventLog) {
        const amount = event.args.amount;
        // Move funds to the vault's HyperCore account (system address transfer)
        // Open positions proportional to deposit
    }

    async processWithdrawal(event: EventLog) {
        const shares = event.args.shares;
        // Calculate proportional position to close
        // Close HyperCore positions
        // Move USDC back to HyperEVM, then let the user claim
    }
}

The Future

Directions builders are exploring:

Note that flash-loan-style atomic arbitrage between HyperEVM and HyperCore is not possible: CoreWriter actions execute after the EVM block, with an onchain delay for orders.

HyperEVM 開発 · HyperEVM の DeFi · 8/8

L1 の売買と組み合わせる

組み合わせの狙い

HyperEVM の約束は、スマートコントラクトがネイティブの板と組み合わさることです。コントラクトは precompile で HyperCore を読み、0x3333333333333333333333333333333333333333 にある CoreWriter というシステムコントラクトで HyperCore に書き込みます。そのため戦略は、すべてチェーン上で動かすことも、コントラクトとチェーン外の keeper で仕事を分けることもできます。

構成の型

型1: スマートコントラクトの vault + keeper

HyperEVM (On-Chain)          L1 (Order Book)
┌─────────────────┐          ┌──────────────┐
│  Vault Contract │          │  Positions   │
│  - Deposits     │          │  - BTC Long  │
│  - Shares       │◄────────►│  - ETH Short │
│  - Accounting   │  Keeper  │  - Funding   │
└─────────────────┘          └──────────────┘

vault コントラクトは HyperEVM 上で預け入れと持ち分の計算を受け持ちます。実際の売買は keeper のボットが L1 で行います。keeper は vault の資産額を読み、それに比例してポジションを調整します。

型2: チェーン上で価格を点検する

// A contract that flags when a market's mark price drifts away from its oracle.
// PriceReader is the contract from the "Reading L1 State" lesson.
contract DeviationWatch is PriceReader {
    event Deviation(uint32 perpIndex, uint64 markPx, uint64 oraclePx);

    function check(uint32 perpIndex) external {
        uint64 mark = markPx(perpIndex);
        uint64 oracle = oraclePx(perpIndex);

        // Flag a gap of more than 0.5% of the oracle price, in either direction
        // (an oracle of 0 means the market has no price yet: flag it too)
        uint256 gap = mark > oracle ? uint256(mark - oracle) : uint256(oracle - mark);
        if (oracle == 0 || gap * 1000 > uint256(oracle) * 5) {
            emit Deviation(perpIndex, mark, oracle);
        }
    }
}

keeper は Deviation イベントを見張り、チェーンの外で対応します。たとえば自分の気配値を止めたり、市場を運営する人に知らせたりします。

型3: CoreWriter で直接売買する

コントラクトは、CoreWriter の sendRawAction を呼ぶことで、自分の HyperCore 口座の注文を出せます。中身は、バージョンの1バイト(0x01)、3バイトの操作 ID、そのあとに ABI でエンコードした項目が続きます。操作 1 は指値注文です(操作の一覧)。

// Testnet only — sketch, no access control
interface ICoreWriter {
    function sendRawAction(bytes calldata data) external;
}

contract CoreTrader {
    ICoreWriter constant CORE_WRITER =
        ICoreWriter(0x3333333333333333333333333333333333333333);

    // limitPx and sz are 10^8 * the human-readable value
    function placeLimitOrder(uint32 asset, bool isBuy, uint64 limitPx, uint64 sz) external {
        bytes memory fields = abi.encode(
            asset, isBuy, limitPx, sz,
            false,       // reduceOnly
            uint8(3),    // tif: 1 = Alo, 2 = Gtc, 3 = Ioc
            uint128(0)   // cloid: 0 = none
        );
        // version 1, action ID 1 (limit order)
        CORE_WRITER.sendRawAction(abi.encodePacked(uint8(1), uint24(1), fields));
    }
}

知っておくこと:

環境をまたぐ流れ

預け入れの流れ

  1. ユーザーが、紐づけ済みのトークン(例: USDC)を HyperEVM の vault コントラクトに預けます
  2. コントラクトがユーザーに持ち分を発行します
  3. コントラクト(またはそれを呼ぶ keeper)が、トークンをそのトークンのシステムアドレスに送ります。これでコントラクトの HyperCore の現物残高に入金されます
  4. ポジションは、CoreWriter で建てるか(コントラクトが主導)、コントラクトが CoreWriter の操作 9 で承認した agent wallet から API で建てます

引き出しの流れ

  1. ユーザーが HyperEVM 上で引き出しを申し込みます
  2. コントラクトが持ち分を焼却し、イベントを出します
  3. 比例する分の HyperCore のポジションを閉じます
  4. CoreWriter の現物送金(操作 6)で、トークンのシステムアドレスに送り、資金を HyperEVM に戻します
  5. あとの EVM ブロックで届いたら、USDC をユーザーに送ります

Core → EVM の送金はあとのブロックで届きます。そのため引き出しは非同期になります。「申し込んでから受け取る」形で設計してください。

システム全体を作る

// Keeper that connects a HyperEVM vault to HyperCore trading (ethers v6)
import { ethers, EventLog } from "ethers";

class HybridVaultKeeper {
    constructor(
        private vaultContract: ethers.Contract,
        // plus a HyperCore API client of your choice, signing with an agent wallet
    ) {}

    async processDeposit(event: EventLog) {
        const amount = event.args.amount;
        // Move funds to the vault's HyperCore account (system address transfer)
        // Open positions proportional to deposit
    }

    async processWithdrawal(event: EventLog) {
        const shares = event.args.shares;
        // Calculate proportional position to close
        // Close HyperCore positions
        // Move USDC back to HyperEVM, then let the user claim
    }
}

これから

作り手たちが試している方向です。

HyperEVM と HyperCore の間で、フラッシュローンのような一度にまとめた裁定はできません。CoreWriter の操作は EVM ブロックのあとに実行され、注文にはさらにチェーン上の遅れがあるからです。