Vault & staking reads
Read queries on POST /info. The endpoint, the request
envelope, the number planes and the error shape are on that page and apply
to every query here.
Per-vault TVL, share price, and strategy
Returns a snapshot of one vault: TVL, share price, and strategy.
Request
{ "type": "vault_state", "vault": "0x<vault_addr>" }
| Field | Type | Required | Meaning |
|---|---|---|---|
vault | hex address | yes | Vault to read |
Response
{
"data": {
"type": "vault_state",
"vault": "0x<addr>",
"name": "MFlux Conservative",
"tvl": "10000000000",
"share_price": "10500000",
"depositor_count": 142,
"high_water_mark": "10500000",
"performance_fee_bps":"1000",
"lock_period_ms": 86400000,
"strategy": "User"
}
}
| Field | Type | Meaning |
|---|---|---|
vault | hex address | Vault address |
name | string | Vault display name |
tvl | Decimal string | Mark-to-market net asset value — see Rules |
share_price | Decimal string | Mark-to-market value of one share — see Rules |
depositor_count | uint | Number of depositors |
high_water_mark | Decimal string | Performance-fee ratchet, not NAV — see Rules |
performance_fee_bps | Decimal string | Performance fee, in basis points |
lock_period_ms | uint64 | Minimum deposit lock period, in milliseconds |
strategy | string | Vault kind: "User" or "Metaliquidity" |
Rules
strategyis the vault's kind,"User"or"Metaliquidity". It is not a free-text strategy label.tvlandshare_priceare mark-to-market NAV: settled cash, plus unrealised PnL on every open position at the latest oracle mark, plus unrealised funding. The Metaliquidity backstop vault also subtracts its pending-loss reserve. This is the same NAV thatvault_withdrawburns shares against, so the read and the payout agree.high_water_markis not NAV. It is a ratchet for performance-fee accounting: profit raises it, a deposit raises it, a withdrawal lowers it, and a trading loss never changes it. In drawdown,high_water_marksits aboveshare_price— the gap is the profit the vault must re-earn before it charges a performance fee again. Never price a redemption offhigh_water_mark.
Per-account staking and delegation state
Returns one account's staking, delegation, and unbonding state.
Request
{ "type": "staking_state", "address": "0x<addr>" }
| Field | Type | Required | Meaning |
|---|---|---|---|
address | hex address | yes | Account to read |
Response
{
"data": {
"type": "staking_state",
"address": "0x<addr>",
"total_staked": "1000000000",
"delegations": [
{
"validator": "0x<val_addr>",
"amount": "500000000",
"lock_months": 6,
"reward_weight": "1250000000",
"since_ts": 1735000000000,
"pending_rewards": "1000000"
}
],
"pending_unstakes": [
{ "amount": "200000000", "matures_at_ts": 1735780000000 }
],
"total_stake": "87600000",
"pending_validator_pool_usdc": "8800.447354",
"n_active_validators": 5,
"reward_source": "fee_funded_on_book_buy"
}
}
The response is FLAT. total_stake, pending_validator_pool_usdc,
n_active_validators and reward_source sit at the top level. There is no
reward_pool object.
lock_months and reward_weight are NOT LIVE YETThe two keys ship with the next node release. A live node serves a delegation row with exactly
validator, amount, since_ts and pending_rewards — the example above shows the target shape,
not today's. Read both keys as optional: absent on a live node, present after the release. A
client that requires either key breaks against the chain you can reach today.
Everything the rules below say about the two keys describes the released behaviour. The rule that
does hold today is the one about pending_rewards: a flexible row accrues nothing, and the served
read gives you no way to see why until these keys land.
| Field | Type | Meaning |
|---|---|---|
address | hex address | Resolved account address |
total_staked | Decimal string | This account's delegated stake only, whole-MTF — the sum of delegations[*].amount. It is "0" for an account that delegates nothing |
delegations[*].validator | hex address | Validator the stake is delegated to |
delegations[*].amount | Decimal string | Stake delegated to this validator, whole-MTF |
delegations[*].lock_months | uint8 | The row's lock tier in committed state: 0 flexible, or 1, 6, 24. It tells a delegator what to change. Do not compute reward_weight from it. NOT LIVE YET — see the notice above |
delegations[*].reward_weight | Decimal string | This row's weight in its validator's reward split, on the same whole-MTF plane as amount. The row's share of a distribution is this weight over the sum of weights at that validator, before the validator's commission. It is a weight, not a payable amount. It is not derivable from lock_months — see the rules below. NOT LIVE YET — see the notice above |
delegations[*].since_ts | uint64 | Last reward-claim time, consensus ms — not the time the delegation began. Committed state keeps the last-claim stamp only. Do not compute a delegation age from it |
delegations[*].pending_rewards | Decimal string | Accrued, unclaimed rewards, whole-MTF. A row whose reward_weight is "0" never accrues here — see the rules below |
pending_unstakes[*].amount | Decimal string | Stake in the unbonding window, whole-MTF |
pending_unstakes[*].matures_at_ts | uint64 | When that amount becomes withdrawable, consensus ms |
total_stake | Decimal string | Total staked MTF across the whole chain, whole-MTF — the denominator this account's delegated stake competes in. Chain-wide, not per-account |
pending_validator_pool_usdc | Decimal string | Fees accrued to the validator pool, not yet distributed, whole USDC. This is the reward the next distribution draws from. A constant value is normal — see the rule below |
n_active_validators | uint64 | Count of validators marked active in committed staking state |
reward_source | string | Always "fee_funded_on_book_buy". Lets a client tell a fee-funded chain from an emission-funded one without inferring it |
Rules
-
reward_weightis served, not derived. Do not rebuild it fromlock_months. Three inputs set the weight, and the read carries only the result.- The lock tier. A flexible row (
lock_months: 0) weighs"0". A locked row weighsamount × 1.0at 1 month,× 2.5at 6 months, and× 4.0at 24 months. - The multiplier the row stored at delegate time. A governance retune of the ladder never rewrites an existing row. So a row can hold a multiplier the current ladder no longer gives.
- The locked-stake allowlist. A locked row whose validator is not in that allowlist is capped to
amount × 1.0, whatever the tier. A 24-month row off the allowlist weighs the same as a 1-month row, not four times it. Governance can drop a validator from the allowlist after you delegate, so a correctly admitted row reaches this state without doing anything.
A caller that rebuilds the ladder from
lock_monthsalone misses the allowlist fallback and over-states the row's share. Read the served value. - The lock tier. A flexible row (
-
A
reward_weightof"0"beside a non-zeroamountis not a late payment. The row earns nothing from a distribution, and it earns nothing from the next one either.pending_rewardsnever grows on that row, so waiting does not change the number. A delegator changes it by locking, not by waiting: undelegate the row, wait out the unbonding window, then delegate again withlock_monthsof1,6or24. The undelegated stake sits inpending_unstakesuntil that window matures and only then reaches the free pool a new delegation draws on, so this is not a same-block swap. Pick a validator on the locked-stake allowlist — a validator off it refuses a locked tier at delegate time. -
This read serves no APR, on purpose. The emission era is over: rewards are funded from fees, not minted on a curve, so there is no annual rate to publish. Do not derive one.
pending_validator_pool_usdcis a snapshot of accrued fees, not a rate — it depends on trading volume that has not happened yet. -
A pool that does not move is not a stalled read.
reward_sourceis"fee_funded_on_book_buy", and the second half of that name is a real step: the distribution spends the pooled USDC on the MTF/USDC book, then pays the MTF it ACQUIRED out by stake weight. It never credits USDC into an MTF-denominated reward, so a buy that fills nothing pays nothing. With no resting asks on MTF/USDC the buy acquires nothing, the distribution is skipped, and the pool carries forward unchanged. The pool is not spent and not stranded; it waits. A pool above the floor therefore does NOT mean a payout is due — checkheighton another read to tell a waiting pool from a frozen connection. -
This read does NOT serve the undelegated free pool.
c_depositcredits a free pool andc_withdrawdebits it, and stake can sit in that pool undelegated for as long as the holder likes. No field on this read reports it.total_stakedtherefore under-reports what an account holds: it counts delegated stake only, so an account with a funded free pool and no delegation reads"0". Do not presenttotal_stakedas the account's whole staked balance. -
The free pool is not the same as
pending_unstakes. Undelegated stake is already free.pending_unstakesis stake still inside its unbonding window, not withdrawable untilmatures_at_ts. -
total_stakedandpending_unstakesare disjoint.token_delegatemoves stake out of the free pool intototal_staked; undelegating moves it out oftotal_stakedintopending_unstakesfor the unbonding window. Only the free pool is the figurec_withdrawreturns to spot with no unbonding window. -
total_stakeandtotal_stakedare different figures with near-identical names.total_stakeis chain-wide;total_stakedis this account. Do not swap them.