Skip to Content
nullPointdocs

NAV and the share price

The contract values the vault itself, checks what the agent reports, and stops the vault when the numbers don't add up.

What the vault is worth

NAV (net asset value) is everything the vault owns minus what it owes. Share price = NAV ÷ all shares. Deposits and withdrawals are priced off it, so it has to be hard to fake.

flowchart TB
q[1Click quotes, signed<br/>report_prices] --> px[Stored price per coin<br/>at most 120 s old]
bal[Balances read on-chain<br/>intents.near mt_batch_balance_of] --> spot[Coin value = balance x price]
bal --> usd[Idle USDC]
px --> spot
rep[Agent's report<br/>Hyperliquid account value, short sizes] --> chk{Check against the<br/>last accepted report}
last[Last report + collateral moved since<br/>+ price change on the open short] --> chk
chk -- within 2% plus dust --> hlv[Hyperliquid value accepted]
chk -- outside --> pause[Vault pauses<br/>owner investigates]
spot --> hedge{Short equals coin<br/>within 2%?}
hedge -- no --> pause
hedge -- yes --> nav
usd --> nav[NAV = idle USDC + coin value<br/>+ Hyperliquid value - amounts owed]
hlv --> nav
nav --> sp[Share price = NAV / shares<br/>recorded on a schedule]
stale{Any price older<br/>than 120 s?} -. yes: report dropped, old NAV kept .-> rep
How the contract computes NAV
PartSourceCan the agent fake it?
Idle USDCRead by the contract from intents.nearNo
Coin heldBalance read by the contract from intents.nearNo
Coin price1Click quotes verified by the contractOnly by choosing among real quotes; they carry 1Click's fee, so the error leans low
Hyperliquid accountReported by the agentWithin the drift check below

The report check

The contract can't read Hyperliquid, so the agent reports the account value and the shorts. The contract compares that with what it expects:

expected = last accepted value + collateral moved since + change in value of the open short from the price moves

A report is accepted when it's within max_report_drift_bps (2%) of the largest of the short's value, the old value and the expected value, plus a dust allowance (0.5 USDC testnet, 1.5 USDC mainnet). Collateral sent to Hyperliquid counts at the amount 1Click quoted to deliver.

If the gap is bigger, the contract pauses the vault: no deposits, withdrawals or swaps until the owner investigates. Funding and price moves fit inside the check; a stolen key reporting a made-up number doesn't.

A report built on a price older than 120 seconds is simply dropped, not treated as a violation. The old NAV stays, and the agent reports again next run.

Vault states

stateDiagram-v2
state "Vault" as vault {
  [*] --> Running
  Running --> Paused: report outside the check, or owner
  Paused --> Running: owner unpauses
}
state "Withdrawal" as wd {
  [*] --> Queued: request_withdraw
  Queued --> Signed: fulfill_withdraw (agent)
  Signed --> Done: execute_withdraw (agent or you)
  Signed --> Failed: payout rejected
  Failed --> Signed: signed again
}
state "Strategy" as mode {
  [*] --> Hedging
  Hedging --> Rotating: switch accepted
  Rotating --> Hedging: old coin gone
  Hedging --> Parked: no coin pays
  Parked --> Hedging: funding back above 3%
}
Vault, withdrawal and strategy states

The record

The contract keeps a history of (time, NAV, shares), about 500 entries, written at most every 10 minutes on testnet and every 30 on mainnet. The dashboard charts the share price from it. A gap in that history means the agent stopped reporting, which makes it a cheap uptime record too.

Fees in the NAV

The performance fee is taken inside the report: if the new share price is above the high-water mark, the contract mints 5% of the gain to the treasury as shares before it records the new price. See Fees.

On this page