EIP-712 Order Format
Arenaton orders use EIP-712 typed data so the same order can be signed by Flutter, validated by the Go exchange, and verified by settlement contracts. The registry for the selected environment supplies the chain ID, collateral token, and verifying contract.
This page is the docs-level shape. Contract tests and Go/Dart parity tests remain the source of truth before launch.
Domain
Section titled “Domain”{ "name": "ArenatonExchange", "version": "1", "chainId": 80002, "verifyingContract": "0x..."}Production uses Polygon PoS 137. Paper Trading uses Polygon Amoy 80002.
Primary Type
Section titled “Primary Type”ArenatonOrder| Field | Type | Rule |
|---|---|---|
maker | address | User-controlled Smart Account or Raw EOA Mode address. |
accountType | string | smartAccount or rawEoa. |
marketId | string | API Market identifier. |
conditionId | bytes32 | CTF condition for the Market. |
outcomeIndex | uint8 | 0 for YES, 1 for NO in binary Markets. |
side | string | buy or sell. |
price | uint256 | Price in collateral micros. |
quantity | uint256 | Share quantity in collateral micros. |
collateralToken | address | Registry/Market collateral token. |
expiry | uint256 | Unix timestamp after which the order is invalid. |
nonce | uint256 | Maker nonce. |
salt | bytes32 | Unique random salt for digest uniqueness. |
feeRateBps | uint256 | Fee rate in basis points. Must not exceed the Fee Ceiling. |
chainId | uint256 | EIP-155 chain ID. |
verifyingContract | address | Settlement contract for the selected environment. |
liveStateVersion | uint256 | Market Live State Version at signing time. |
Type String
Section titled “Type String”const orderType = "ArenatonOrder(address maker,string accountType,string marketId,bytes32 conditionId,uint8 outcomeIndex,string side,uint256 price,uint256 quantity,address collateralToken,uint256 expiry,uint256 nonce,bytes32 salt,uint256 feeRateBps,uint256 chainId,address verifyingContract,uint256 liveStateVersion)";Order Digest
Section titled “Order Digest”domainSeparator = hash(EIP712Domain)structHash = hash(ArenatonOrder)digest = keccak256("\x19\x01" || domainSeparator || structHash)Strings such as accountType, marketId, and side are hashed before inclusion in the struct hash.
Submission Payload
Section titled “Submission Payload”{ "order": { "maker": "0x...", "accountType": "smartAccount", "marketId": "paper-btc-above-100k-15m", "conditionId": "0x...", "outcomeIndex": 0, "side": "buy", "price": "550000", "quantity": "1000000", "collateralToken": "0x...", "expiry": "1777939200", "nonce": "1", "salt": "0x...", "feeRateBps": "25", "chainId": "80002", "verifyingContract": "0x...", "liveStateVersion": "1" }, "signature": "0x..."}Paper orders submit to:
POST /api/paper/ordersProduction order intake remains gated until production readiness is complete.
Validation Gates
Section titled “Validation Gates”The server and settlement path must reject orders when:
- chain ID does not match the selected environment,
- verifying contract does not match the registry,
- collateral token does not match the Market,
- signature is invalid,
- account mode is unsupported,
- Live State Version is stale,
- order is expired, canceled, or already fully filled,
- fee rate exceeds the Fee Ceiling,
- order would self-trade against the same beneficial account.
Signature Modes
Section titled “Signature Modes”Raw EOA Mode uses normal ecrecover verification.
Smart Account mode uses ERC-1271 verification:
IERC1271(account).isValidSignature(digest, signature)The digest must be identical across Flutter, Go, and Solidity. Any field addition, type change, or string normalization change requires parity tests in all three layers.