Documentation
How HUME works, written from the deployed contracts. Each section names the source files it was checked against. Fees, leverage and caps are read from the chain, not written here.
This is Robinhood Chain Testnet. It uses test tokens with no value, mock prices and simulated traders, so nothing here is real money. See Known limits. The chain, the settlement token and the protocol token address are under Network and token.
Overview
HUME trades perpetuals and options on tokenized stocks, ETFs and crypto assets. Both products share one vault, one market registry, one price router and one risk manager. There is no order book: you trade against the vault at the oracle price.
The vault is the only contract that holds tokens. It records each account's balance, locks margin for open positions, and pays or collects profit and loss when a position closes. Every contract is a proxy that an admin can upgrade, so the code behind an address can change (see Known limits).
Checked againstcore/HumeVault.solcore/MarketRegistry.sol
Network and token
HUME runs on Robinhood Chain Testnet (chain ID 46630), an Ethereum L2. Gas is paid in ETH. Every contract address is listed in full under Every contract on the Features page.
Settlement token. Margin, fees, profit and loss and option premiums are all in a mock settlement token with no value, which anyone can mint on testnet. View the token on the explorer
Markets. Each market is a tokenized stock, ETF or crypto asset, in groups such as US, China and crypto. A market with a price feed trades. A few China names have only a reference price and no feed, so they show a price and refuse trades. Prices come from the oracle router (see Price feeds). The list of markets, and their leverage and limits, are under Live parameters.
Protocol token. The protocol token is not one of the trading contracts, and trading does not need it. It has not launched yet. When it does, its contract address will appear here and on the home page, and only there; check any address you are given against those two places:
Deposit, trade, withdraw
Deposit the settlement token into the vault first. The vault only accepts tokens the collateral manager lists. Your available balance is your deposit, plus realized profit, minus locked margin and fees.
A trade needs the margin and the fee available at the same time. The fee is charged on top of the margin, not taken out of it.
You can withdraw any available balance at any time. If you hold a cross-margin position, the vault refuses a withdrawal that would leave the account within 10% of its margin requirement or below it.
The pool. The vault is the other side of every trade. It pays a winner from its pool: the tokens it holds beyond what it owes users. Losses and fees add to the pool, and the team funds it at launch. A winner can close while the losing side has not closed yet, so the pool covers that gap. If the pool cannot cover a payout, the close reverts with InsufficientPoolReserves and the position stays open. It closes once losing positions settle or the pool is topped up. To keep this rare, each market also limits how far long and short open interest may differ, and an order on the smaller side is never refused for that reason.
Checked againstcore/HumeVault.solrisk/CrossMarginManager.solrisk/RiskManager.sol
Perpetuals
A perpetual has no expiry. You choose long or short, the margin you put up, and a leverage multiple. Position size is the margin times the leverage.
size (notional) = margin × leverage initial margin = size × initial margin rate maintenance = size × maintenance margin rate PnL (long) = size × (mark − entry) ÷ entry PnL (short) = size × (entry − mark) ÷ entry
Before a position opens, the risk manager checks three things. The leverage must be one of the market's allowed tiers. The size must be under the per-position limit. The market's total open interest must stay under its cap. If any check fails, the transaction reverts and nothing is charged.
The taker fee is a share of the position size, set per market. You choose a limit price and a deadline on every market order. The order reverts if the oracle price is worse than your limit, or if the deadline has passed. You can add margin or size to a position, reduce it, or close it fully. A reduction charges the taker fee on the size removed.
Checked againstperps/PerpsEngine.solrisk/MarginEngine.solrisk/RiskManager.sol
Limit, stop-loss and take-profit orders
A limit order opens a position when the mark price reaches your price: at or below it for a long, at or above it for a short. Margin and fee leave your balance when the order fills, not when you place it. Cancel an open order at any time.
A stop-loss or take-profit closes an open position when the mark price reaches your trigger. A long's stop-loss and a short's take-profit fire when price falls to the trigger. The other two fire when price rises to it. A trigger on the wrong side of the current price is rejected.
Anyone can execute a limit or trigger order once its price is reached, and the protocol does not run this for you. Orders are filled by a keeper service, so a fill can lag the price. A trigger order has no slippage limit, because a stop-loss has to get out.
Checked againstperps/PerpsEngine.solperps/PerpOrderManager.sol
Liquidation
A position is liquidatable when its margin ratio drops under the market's maintenance margin rate.
margin ratio = (margin + unrealized PnL) ÷ size
liquidatable when = margin ratio < maintenance margin rate
liquidation price = entry ± entry × (maintenance − margin) ÷ size
(+ for a long, − for a short)Anyone can liquidate an eligible position. The engine settles funding, releases the margin, and settles the PnL. Then it takes two charges from what the owner has left: the market's liquidation fee on position size, and a liquidator reward of 5% of the position's margin. Together they are capped at the owner's remaining balance, so a liquidation never reverts on a deeply losing position.
If the loss is bigger than the owner's balance, the shortfall is covered in order: other collateral in a cross account, then the insurance fund. Anything still uncovered is emitted as a BadDebt event. Bad debt is recorded, not spread across other users. In a cross account, only the worst position can be liquidated first.
Nothing in the protocol itself calls liquidate, so a position stays open until someone does.
Checked againstperps/LiquidationEngine.solrisk/MarginEngine.sol
Funding
Funding is meant to keep the perpetual price near the index. Each interval (one hour by default) the rate is set to the gap between mark and index price, capped at 1% per interval by default. Longs pay shorts when the mark is above the index, and shorts pay longs when it is below.
rate (bps) = (mark − index) ÷ index × 10,000 (clamped) payment = size × change in cumulative rate ÷ 10,000
Today the rate is always zero. The oracle router returns the same price for mark and index, so there is no gap to charge. The funding code runs but moves no money until a separate mark-price source exists.
Checked againstperps/FundingManager.soloracle/OracleRouter.sol
Options
Options are European, cash-settled calls and puts. You can only buy them. You pay a premium, and your maximum loss is that premium plus the fee. There is no delivery of the underlying token, only a payout in the settlement token.
Quotes. The premium is not computed onchain. HUME's pricing service signs a quote for your exact trade, and the contract checks that signature. A quote expires after a short time and works once. A quote for a different account, strike or expiry is rejected. The price you pay is therefore only as fair as that signer, and today it uses simple placeholder inputs.
Price bounds. The contract also checks every signed premium against the market. When you open, it cannot be zero, cannot be below the option's intrinsic value at the current price (2% is allowed for movement since the quote), and cannot be above the value of the underlying. When you close, it cannot be above that value. These bounds limit what a wrong or stolen quote can charge or pay; they do not make the price fair inside the bounds. Opening an option needs a fresh oracle price.
call payout = max(settlement − strike, 0) × contract size × contracts put payout = max(strike − settlement, 0) × contract size × contracts
Limits. Every option you buy is checked against the market's position size limit and open interest cap, and the fee is a share of the premium.
Closing early. Before expiry you can sell the position back at a signed close quote. The close fee is a share of that premium.
Expiry. Once a series expires, anyone can settle it. The first valid oracle price at or after expiry is recorded and never changes. An in-the-money option pays the formula above minus the settlement fee. An out-of-the-money option pays nothing. The app alerts you when an option of yours has expired, and gives you a Settle button.
A series settles 50 positions per call, so a large series is finished over several calls. You never wait for that: you can settle your own position at once, whatever else is in its series, and the Settle button does exactly that.
The default contract size is one underlying token. Strikes and expiries are chosen by the app, so the contract has no fixed list of them.
Checked againstoptions/OptionsEngine.soloptions/OptionSettlement.soloptions/OptionMarket.sol
Lending
Lending is a separate engine from the trading vault. A pair locks one stock token as collateral and lends one token against it. The pair live today is TSLA collateral and USDG borrowed. A pair is isolated: its loans cannot draw on any other pair or on the trading vault.
You can borrow up to the pair's borrow limit, a share of the collateral's value. Past a second, higher share (the liquidation limit) the loan can be liquidated. The health factor is that single number.
loan to value = debt ÷ collateral value health factor = liquidation limit ÷ loan to value liquidated when health factor < 1
When a loan is liquidated, anyone can repay part of the debt and take the matching collateral plus a bonus of 5%. You keep what is left. The collateral price is pushed by an authorised feeder into a sanity oracle. By default it rejects an update that jumps more than 15% in one step and treats a price older than an hour as stale, and a stale price blocks lending. The borrow limit, the liquidation limit and the caps are read from the pair and shown on the Lending page. Caps are small on purpose.
Checked againstcredit/HumeCreditPair.solcredit/HumeCreditRouter.solcredit/HumeCreditVault.sol
Pons market
Pons is a separate token launcher. The Pons page lists tokens launched there and lets you buy and sell them for ETH. This is spot trading, not a perpetual: there is no leverage and no vault. Hume lists tokens and adds no fee.
A swap goes through a router that trades in the token's own Uniswap v4 pool. The router holds no funds between calls and has no owner. It rebuilds the pool from the Pons factory, so it cannot be pointed at a pool the factory does not know. The review step shows the price, the price impact and the least you will receive. The site sets that minimum a few percent under the quote, and the swap reverts if the pool pays less.
Risk. Anyone can launch a Pons token. Hume does not vet them, pools can be thin, and a token can lose all its value.
Checked againstpons/HumePonsRouter.sol
Copy trading
Copy trading mirrors another trader's new perpetual trades into a separate copy account that holds only the budget you choose. Your main account is never touched. The copy account is a subaccount you own. HUME's executor is a delegate on it: it can open and close positions and can never withdraw.
Trades are sized in proportion to balances. If the trader risks 10% of their balance, your copy account risks 10% of its balance. Positions the trader already holds when you start are not copied. When a trade would break one of your limits (per trade, total exposure, highest leverage), it is skipped, and the Copy trading page shows the skip with its reason. Nothing is copied in part.
Limits of this design. The executor enforces your limits, they are not written into the contract. A bug in the executor could break a limit, but it cannot take money out. You can stop at any time and withdraw what is left. Copies can lag the trader by minutes. Copy trading is on testnet today.
Checked againstaccounts/Subaccount.solaccounts/SubaccountFactory.sol
Leaderboard and PNL card
The leaderboard ranks traders by PNL (realised plus unrealised), by ROI on capital deployed, or by volume, over all time. Ties break on volume, then on wallet. It is built from the same events as every other page, and a wallet can hide itself from it.
A PNL card turns a closed position into a shareable image: market, side, PNL and ROI. The link carries the same figures. On testnet, wallets run by HUME to keep the market active are marked Simulated on the board and on their cards.
Price feeds
Every contract reads prices through the oracle router, in 18 decimals. Each market has a primary feed and an optional fallback. A price older than the maximum age (one hour by default) is rejected, and the trade reverts. If both feeds work, they must agree within 10% (default), or the read reverts. If only one works, its price is used.
A pauser key can pause a market's oracle. While it is paused, every read for that market reverts, which blocks opening, closing, liquidation and settlement there.
Pausing. A pauser key can also stop new trading in one market, or in every market at once. Closing positions, liquidation and settlement keep working when trading is stopped. The pauser cannot turn anything back on, or change a price source or a limit: only the admin can, so a stolen pauser key can stop trading but not take funds.
Price feeds. Prices come frommock feeds that HUME moves for the demo, so testnet prices are not real. The feeds report each token's price with 8 decimals. The router converts them to 18. Stock feeds update on the equity market schedule, 24 hours a day, 5 days a week. When a feed has not updated within the maximum age, reads for that market revert. Opening, closing, liquidation and settlement wait for the next fresh price. An option that expires in that window settles at the first valid price after expiry.
Checked againstoracle/OracleRouter.soloracle/PriceValidator.sol
Live parameters
These figures are read from the risk and fee contracts now. Basis point values are shown as percentages. Amounts are in the settlement token. An admin can change them, so treat this table, not any other page, as current.
Reading parameters from the chain…
Known limits
- Upgradeable contracts. Every contract is a proxy that an admin can upgrade, so the code behind an address can change. Read the current values under Live parameters.
- Market hours. Stock prices update 24 hours a day, 5 days a week. While a feed is stale, its market cannot open, close or liquidate positions.
- Pool size. Options are buy-only and the vault pool pays winners. If the pool runs low, winning closes wait until losing positions settle or the pool is topped up (see The pool).
- Quote signer. One signing service sets option premiums. The contract bounds them, but the signer can still choose any premium inside the bounds.
- Funding is inactive, as described above.
- Alerts need an open tab. Take-profit, stop-loss, liquidation and expiry alerts appear only while the app is open in your browser.
Verify it yourself
Do not rely on this page alone. Every contract address, in full, is listed under Every contract on the Features page, with a link to the block explorer. Start with the vault, which holds all deposited funds.
If this page and the chain disagree, the chain is right. Tell us and we will correct the page.
