# HyperFunTrading

## VaultTrading (HyperFunTrading.sol)

`HyperFunTrading.sol` executes Hyperliquid L1 actions through precompiles and CoreWriter.

### Inheritance

```solidity
contract HyperFunTrading is
    UUPSUpgradeable,
    OwnableUpgradeable,
    ReentrancyGuardUpgradeable
```

### Precompile Addresses

```solidity
address public constant PRECOMPILE_PERP_POSITION = 0x0000000000000000000000000000000000000800;
address public constant PRECOMPILE_SPOT = 0x0000000000000000000000000000000000000801;
address public constant PRECOMPILE_WITHDRAWABLE = 0x0000000000000000000000000000000000000803;
address public constant PRECOMPILE_ORACLE = 0x0000000000000000000000000000000000000807;
address public constant PRECOMPILE_PERP_ASSET_INFO = 0x000000000000000000000000000000000000080a;
address public constant PRECOMPILE_ACCOUNT_MARGIN_SUMMARY = 0x000000000000000000000000000000000000080F;
```

| Precompile                       | Returns                                                                                         |
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `0x800` PERP\_POSITION           | `(int64 szi, uint64 entryNtl, int64 isolatedRawUsd, uint32 leverage, bool isIsolated)`          |
| `0x801` SPOT                     | `(uint256 total, uint256 hold, uint256 entryNtl)` in 8 decimals                                 |
| `0x803` WITHDRAWABLE             | `uint64` withdrawable from perp                                                                 |
| `0x807` ORACLE                   | `uint64` oracle price                                                                           |
| `0x80A` PERP\_ASSET\_INFO        | `(string name, uint32 marginTableId, uint32 szDecimals, uint32 maxLeverage, bool onlyIsolated)` |
| `0x80F` ACCOUNT\_MARGIN\_SUMMARY | `(int64 accountValue, uint64 marginUsed, uint64 ntlPos, int64 rawUsd)`                          |

### CoreWriter Actions

```solidity
ICoreWriter public constant CORE_WRITER = ICoreWriter(0x3333333333333333333333333333333333333333);
address public constant USDC_L1_SYSTEM = 0x2000000000000000000000000000000000000000;

// Action IDs
uint24 constant ACTION_LIMIT_ORDER = 1;          // Place perp order
uint24 constant ACTION_SPOT_SEND = 6;            // L1 Spot → EVM
uint24 constant ACTION_USD_CLASS_TRANSFER = 7;   // Spot ↔ Perp
uint24 constant ACTION_ADD_API_WALLET = 9;       // Register API wallet
uint24 constant ACTION_CANCEL_BY_OID = 10;       // Cancel order by oid

// Time In Force
uint8 constant TIF_GTC = 2;  // Good Till Cancel (Limit)
uint8 constant TIF_IOC = 3;  // Immediate Or Cancel (Market)
```

### State Variables

```solidity
address public vault;        // HyperFunToken address
address public factory;      // HyperFunFactory address

// API Wallets (V39)
struct ApiWalletInfo {
    bool active;
    uint256 expiresAt;       // Unix timestamp (type(uint256).max = unlimited)
    string name;
}
mapping(address => ApiWalletInfo) public apiWalletInfo;
mapping(address => bool) public apiWallets;  // Legacy (no expiration)

// Order tracking (V41)
uint128 public orderNonce;   // Unique cloid for each order

// Constants
uint256 public constant MIN_API_WALLET_DURATION = 60 days;
uint256 public constant MAX_API_WALLET_DURATION = 180 days;
```

***

### Trading Functions

#### Market Order

```solidity
function executeMarketOrder(
    uint32 asset,    // Asset index (0=BTC, 1=ETH, 5=SOL...)
    bool isBuy,      // true=long, false=short
    uint64 size,     // Size in 1e8 format
    uint64 price     // Price with slippage (1e8 format)
) external;

// With custom leverage
function executeMarketOrder(
    uint32 asset,
    bool isBuy,
    uint64 size,
    uint64 price,
    uint32 leverage  // 1-maxLeverage, 0=use max
) external;
```

**Flow:**

1. Validate vault has deposits
2. Normalize size to asset's `szDecimals`
3. Ensure margin in L1 Perp (auto-transfer from Spot)
4. Send IOC order to L1 with unique `cloid`
5. Trigger auto-rebalance

#### Limit Order

```solidity
function executeLimitOrder(
    uint32 asset,
    bool isBuy,
    uint64 size,
    uint64 price
) external;

// With custom leverage
function executeLimitOrder(
    uint32 asset,
    bool isBuy,
    uint64 size,
    uint64 price,
    uint32 leverage
) external;
```

**Flow:**

1. Validate vault has deposits
2. Normalize size
3. Ensure margin
4. Send GTC order to L1
5. Trigger auto-rebalance

#### Limit Order Raw (No Margin Check)

```solidity
function executeLimitOrderRaw(
    uint32 asset,
    bool isBuy,
    uint64 size,
    uint64 price
) external;
```

For split orders where margin is pre-transferred. Only sends order, no other L1 actions.

#### Batch Limit Orders

```solidity
function batchLimitOrders(
    uint32 asset,
    bool isBuy,
    uint64[] calldata sizes,
    uint64[] calldata prices,
    uint32 leverage
) external;
```

Execute multiple limit orders in one transaction (max 20 orders). Margin calculated for total position.

#### Close Order

```solidity
function executeCloseOrderAdvanced(
    uint32 asset,
    bool isBuy,
    uint64 size,
    uint64 price,
    bool reduceOnly   // If true, won't flip to opposite side
) external;
```

#### Close Position (Auto)

```solidity
function closePositionAdvanced(
    uint32 asset,
    uint32 slippageBps,  // 100-5000 (1%-50%)
    bool reduceOnly
) external;
```

**Flow:**

1. Read position from L1 precompile
2. Get oracle price
3. Apply slippage
4. Send reduce-only IOC order
5. Sweep excess from Perp → Spot
6. Trigger auto-rebalance

#### Cancel Order

```solidity
function cancelOrder(uint32 asset, uint64 oid) external;
```

Cancel a pending limit order by order ID.

***

### HIP-3 Builder Perps (V46)

For HIP-3 assets (index >= 100000), precompiles don't work. Must provide params from API.

#### Execute Order (HIP-3)

```solidity
function executeOrderBuilder(
    uint32 asset,           // e.g., 110003 for xyz:GOLD
    bool isBuy,
    uint64 size,            // 1e8 format
    uint64 price,           // 1e8 format
    uint32 szDecimals,      // From API
    uint32 maxLeverage,     // From API (1-100)
    bool isLimit            // true=GTC, false=IOC
) external;
```

#### Close Position (HIP-3)

```solidity
function closePositionBuilder(
    uint32 asset,
    bool isBuy,             // Opposite of position direction
    uint64 size,
    uint64 price,
    uint32 szDecimals
) external;
```

#### Standard vs HIP-3

| Feature     | Standard (< 100000)       | HIP-3 (>= 100000)        |
| ----------- | ------------------------- | ------------------------ |
| Oracle      | Precompile 0x807          | Must provide             |
| szDecimals  | Precompile 0x80A          | Must provide             |
| maxLeverage | Precompile 0x80A          | Must provide             |
| Open        | `executeMarketOrder()`    | `executeOrderBuilder()`  |
| Close       | `closePositionAdvanced()` | `closePositionBuilder()` |

***

### Fund Transfer Functions

#### Spot ↔ Perp

```solidity
// L1 Spot → L1 Perp
function transferToPerp(uint64 amount) external;

// L1 Perp → L1 Spot
function transferFromPerp(uint64 amount) external;
```

#### Sweep to Spot

```solidity
// Sweep withdrawable from Perp to Spot (with margin buffer)
function sweepToSpot() external;

// Force sweep all withdrawable
function forceReturnToSpot() external;
```

#### Auto-Rebalance

```solidity
function autoRebalance() external;  // Called by VaultCore
```

Maintains 50% EVM / 50% L1 ratio:

* EVM > 52%: Deposit excess to L1
* EVM < 48%: Withdraw from L1 Spot to EVM

***

### API Wallet Functions

#### Add API Wallet (V39)

```solidity
function addApiWallet(
    address apiWallet,
    string calldata name,
    uint256 durationDays    // 60-180, or 0 for unlimited
) external;
```

Only leader can add. Registers on both EVM and L1.

#### Renew API Wallet

```solidity
function renewApiWallet(
    address apiWallet,
    uint256 durationDays
) external;
```

Extend expiration for active wallet.

#### Remove API Wallet

```solidity
function removeApiWallet(address apiWallet) external;
```

Removes from EVM tracking. L1 registration is permanent (Hyperliquid limitation), but EVM check prevents unauthorized use.

#### Get Status

```solidity
function getApiWalletStatus(address apiWallet) external view returns (
    bool active,
    uint256 expiresAt,
    uint256 daysRemaining,  // type(uint256).max if unlimited
    string memory name
);

function isApiWalletValid(address wallet) external view returns (bool);
```

***

### View Functions

#### L1 Balances

```solidity
function getL1SpotBalance() public view returns (uint256);       // 6 decimals
function getL1SpotBalanceRaw() public view returns (uint256);    // 8 decimals
function getL1AccountValue() public view returns (uint256);      // 6 decimals
function getTotalAssets() public view returns (uint256);         // 18 decimals
```

#### Position Data

```solidity
function getL1Position(uint32 asset) public view returns (int64 szi);

function getL1PositionFull(uint32 asset) public view returns (
    int64 szi,
    uint64 entryNtl
);
```

#### Account Margin

```solidity
function getAccountMarginSummary() public view returns (
    int64 accountValue,
    uint64 marginUsed,
    uint64 ntlPos,
    int64 rawUsd
);
```

#### Oracle & Asset Info

```solidity
function getOraclePrice(uint32 asset) public view returns (uint64);
function getSzDecimals(uint32 asset) public view returns (uint32);
function getMaxLeverage(uint32 asset) public view returns (uint32);
```

#### Size Preview

```solidity
function previewNormalizedSize(uint32 asset, uint64 size) public view returns (
    uint64 normalizedSize,
    uint32 szDecimals,
    uint64 minSize
);
```

#### Debug

```solidity
function getL1AccountValueDebug() public view returns (
    uint64 withdrawable,
    uint256 requiredMargin,
    uint256 accountValue,
    uint32 positionLeverage
);

function getIsolatedPositionDebug(uint32 asset) public view returns (
    int64 szi,
    uint64 entryNtl,
    int64 isolatedRawUsd,
    uint32 leverage,
    bool isIsolated,
    uint64 oraclePrice,
    int256 currentNotional,
    int256 positionValue
);
```

***

### Admin Functions

#### Withdraw from L1

```solidity
// Perp → Spot → EVM in one tx
function withdrawPerpToEVM(uint64 amount) external;

// Withdraw all withdrawable
function withdrawAllPerpToEVM() external;

// Step by step
function withdrawStep1_PerpToSpot(uint64 amount) external;
function withdrawStep2_SpotToEVM(uint64 amount6) external;
function withdrawAllSpotToEVM() external;
```

#### Refill Reserve

```solidity
function refillReserve(uint64 amount) external;
```

Transfer from L1 Perp to Spot (admin only).

#### Reserve Check

```solidity
function checkReserve() external view returns (bool isLow);
```

***

### Events

```solidity
event OrderSent(uint32 indexed asset, bool isBuy, uint64 size, uint64 price);
event OrderCancelled(uint32 indexed asset, uint64 oid);
event ApiWalletAdded(address indexed apiWallet, string name, uint256 expiresAt);
event ApiWalletRemoved(address indexed apiWallet);
event ApiWalletRenewed(address indexed apiWallet, uint256 newExpiresAt);
event FundsTransferred(bool toPerp, uint64 amount);
event WithdrawnFromL1(uint256 amount);
event DepositedToL1(uint256 amount);
event Rebalanced(bool toL1, uint256 amount, uint256 newRatioBps);
event ReserveLow(uint256 currentBalance, uint256 totalAssets);
```

***

### Access Control

```solidity
modifier onlyAdmin() {
    require(msg.sender == IHyperFunToken(vault).admin(), "Not admin");
    _;
}

modifier onlyVaultOrLeader() {
    require(
        msg.sender == vault ||
        msg.sender == IHyperFunToken(vault).leader() ||
        _isApiWalletValid(msg.sender),
        "Not authorized"
    );
    _;
}

modifier onlyVault() {
    require(msg.sender == vault, "Only vault");
    _;
}
```

| Role          | Can Execute                            |
| ------------- | -------------------------------------- |
| Leader        | All trading, API wallet management     |
| API Wallet    | Trading only (if active & not expired) |
| Vault (Token) | `autoRebalance()`                      |
| Admin         | Withdraw functions, `refillReserve()`  |

***

### Internal Mechanisms

#### Size Normalization

Sizes are normalized to asset's `szDecimals` precision:

```solidity
function _normalizeSize(uint32 asset, uint64 size) internal view returns (uint64) {
    uint32 szDec = getSzDecimals(asset);
    uint256 step = 10 ** (8 - szDec);
    uint256 rounded = (uint256(size) / step) * step;
    return uint64(rounded);
}
```

Example: SUI (szDecimals=1) → step = 10^7 → 0.1 SUI minimum

#### Margin Management

Auto-transfers from Spot to Perp when opening positions:

```solidity
function _ensurePerpMargin(
    uint32 asset,
    bool isBuy,
    uint64 price,
    uint64 size,
    uint32 leverage
) internal {
    // Skip for reducing positions
    // Calculate total position after trade
    // Required margin = notional / leverage * 1.05 (5% buffer)
    // Transfer from Spot if available margin < required
}
```

#### Return to Spot

After closing positions, excess margin is swept back:

```solidity
function _returnToSpot() internal {
    uint64 withdrawable = _getWithdrawable();
    uint256 requiredMargin = _calculateRequiredMargin();
    uint256 requiredWithBuffer = requiredMargin * 1.005;  // 0.5% buffer
    uint256 excess = perpValue - requiredWithBuffer;
    // Transfer min(excess, withdrawable) from Perp → Spot
}
```

#### Order Nonce (V41)

Each order has unique `cloid` to prevent L1 duplicates:

```solidity
function _sendOrder(...) internal {
    orderNonce++;
    uint128 cloid = orderNonce;
    bytes memory payload = abi.encode(asset, isBuy, price, size, reduceOnly, tif, cloid);
    // Send to L1...
}
```

***

### Upgrade Authority

```solidity
function _authorizeUpgrade(address) internal override {
    require(factory != address(0), "No factory");
    require(msg.sender == IHyperFunFactory(factory).owner(), "Only factory owner");
}
```

***

### Related Contracts

| Contract          | Role                                |
| ----------------- | ----------------------------------- |
| `HyperFunToken`   | Core vault, calls `autoRebalance()` |
| `HyperFunFactory` | Global settings, upgrade authority  |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hyper-fun.gitbook.io/hypers.fun/smart-contracts/hyperfuntrading.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
