Skip to main content

Funding rates

tip

Stable.

TL;DR

Perpetual positions accrue funding proportional to the perp's premium over the oracle — measured from the depth-weighted impact price, not a single trade — plus a small baseline interest term. Longs pay shorts when the perp trades above the oracle; shorts pay longs when below.

Funding settles discretely, once per asset's funding period — each market has its own period (e.g. 8 h for a major like BTC, 1 h for a fast meme market), governance-configurable per asset (default 1 h). The amount charged at each settlement is the funding accrued over that whole period, capped at a per-asset default of ±2% per period, and settles against the oracle.

This is a discrete, per-asset model: funding is paid in one step at each asset's period boundary — not continuously, and not on a single network-wide hourly clock. It supersedes an earlier scheme that swept a tiny pro-rata payment every few seconds.

Why funding exists

Perps have no expiry, so there's no arbitrage force to peg them to the underlying. Funding does that job: when perp price drifts above spot, longs pay, which incentivises shorts and disincentivises longs until the perp drifts back down. The protocol never takes either side — it's user-to-user.

Formula

The TL;DR above is the conceptual model. The numbers below are the implemented values. Where the prose and the code differ, the code wins; the differences are flagged inline.

How it's computed

The funding rate is driven by a deterministic EMA of the premium (impact price − oracle), refreshed continuously from committed state. The settlement — the actual transfer between longs and shorts — happens discretely, once per asset's funding period (default 1 h, governance-configurable per asset).

Two effects run the cycle:

  • rate update — folds the latest premium sample into the per-asset premium-index EMA each begin-block, then derives and clamps the rate. A live, smoothed rate is therefore available for display at any time.
  • settlement — at each asset's funding-period boundary, settles every open position in that market against the cumulative funding index, moving the full period's accrued funding between position owners.

0. Premium basis — the impact price (not the last trade)

The per-block premium sample is the gap between the perp's impact price and the oracle:

premium = (impact_mid − oracle) / oracle
impact_mid = mid( impact_bid, impact_ask )
impact_bid/ask = VWAP of walking the committed book to fill a fixed notional (default ~$10k)

Using the impact price — the volume-weighted price to fill a real clip — rather than the last trade or the best quote means a single print, or a one-lot order at a silly price, cannot move funding: you have to move genuine depth. This mirrors the reference perp design. (A legacy per-market mode instead samples premium = (mark − oracle)/oracle; new and migrated markets use the impact basis above.)

1. Premium index EMA (per market)

The premium is smoothed by a deterministic EMA (the premium index). The accumulator stores a fixed-point fraction (num, denom) — no floats, exact rust_decimal::Decimal arithmetic so node-to-node state is bit-identical. Each sample folds in as:

num' = num * decay + sample
denom' = denom * decay + 1
value = num / denom
  • sample = latest premium for the asset × the per-asset funding_rate_multiplier (default 1.0; auto-driven by the dynamic-risk engine).
  • decay = 0.5 (proposed default). Clamped to [0, 1] at update time.
  • The premium-index EMA is folded each begin-block; settlement runs once per asset's funding period (default 1 h, governance-configurable per asset).

Status: the funding loop runs entirely from committed market state — no external premium feeder. Each begin-block the rate driver samples the premium (the impact-vs-oracle premium above, one sample per perp market), folds it into the per-asset premium-index EMA, derives the rate (interest + clamp), and caps it. At each asset's funding-period boundary, settlement advances the cumulative funding index and moves size × Δindex between position owners' balances (zero-sum: longs pay shorts or vice versa, no mint/burn). Conservation- and determinism-checked end to end.

2. Rate from the premium index (interest + clamp)

The funding rate is not the raw premium index. The smoothed index premium_idx is combined with a baseline interest term through a per-step clamp:

interest = 0.0000125 / h # = 0.01% / 8h — the baseline carry
clamp = ±0.0005 # per-step bound

funding = premium_idx + clamp( interest − premium_idx, −clamp, +clamp )

When the premium index is small, funding drifts toward the interest baseline; when the premium is large, the premium_idx term dominates and the clamp bounds how hard the interest pulls back each step. Both interest and clamp are per-asset governance-overridable. (The legacy per-market mode instead reads the EMA value directly as the rate, with no interest/clamp transform.)

3. Per-period cap

The funding accrued over a period is clamped to the per-asset cap before it settles:

cap_per_period = 0.02 # ±2% per funding period, per-asset default
funding = clamp(funding, −cap_per_period, +cap_per_period)

The cap is a per-market governance parameter: a dynamic_risk_overrides[asset].funding_rate_cap replaces the 0.02 default when set. Because settlement is per-period, the cap bounds the total funding charged at each settlement to ±2% of notional (default), independent of how long the asset's period is.

4. Payment (per position, per period)

Funding accrues into a cumulative index per market; each position carries its last-settled index (funding_entry). Settlement runs at the asset's period boundary (boundary = floor(ts_ms / period_ms) * period_ms): a market settles only when its boundary has advanced since the last settlement, and it then applies the full period's accrued funding:

payment = size_signed * oracle_px * (cum_global - funding_entry) * funding_rate_multiplier[asset]
funding_entry := cum_global # roll forward at the period boundary

(Zero-sum: longs pay shorts or vice versa, no mint/burn.)

SymbolMeaning / plane
size_signedSigned position size; i128. Long > 0, short < 0.
oracle_pxComposed oracle price — whole-USDC Decimal plane (see mark prices).
cum_global − funding_entryCumulative funding accrued for this market since the position last settled.
decayEMA decay 0.5.
cap_per_periodDefault 0.02 (±2% per funding period); per-market override via dynamic risk.
funding_rate_multiplierPer-asset multiplier, default 1.0, auto-driven by dynamic risk.

funding_rate (the EMA value) is signed: positive → longs pay shorts; negative → shorts pay longs.

Base interest: 0.0000125/h (= 0.01%/8h) — the baseline carry the premium EMA is added to.

⚠️ Settlement model. Funding settles discretely, once per asset's funding period (default 1 h, governance-configurable per asset — e.g. 8 h for BTC, 1 h for a meme market), not continuously and not on a single network-wide hourly clock. The amount charged at each settlement is the funding accrued over that whole period, capped at a per-asset ±2% default. The EMA decay is 0.5; the rate itself is refreshed continuously so a live value is always available for display.

Settlement cadence

Each perpetual market has its own funding period (funding_period_ms, default 1 h), set per asset by governance. Settlement is discrete: the protocol settles a market only when the current consensus timestamp crosses that asset's next period boundary, and it then charges the full period's accrued funding in one step. Different markets settle on their own clocks — a market on an 8 h period and a market on a 1 h period are independent.

Payments settle as balance adjustments — no on-chain trade, no fee. They show on the user's history as kind: "funding".

Known timing gap. Mid-period account value and health do not reflect funding that has accrued but not yet settled — pending funding lands as a single discrete step at the period boundary, not smoothly. The size of that step is bounded by the per-asset cap (≤2% of notional per period by default), so the jump is small; but a position sitting near a liquidation band should account for the next settlement landing as a step rather than a gradual drift.

Gating when the oracle is untrusted

Funding settles against the oracle, so a price the protocol does not trust must not drive a payment. Each period the premium sample is gated: it is skipped (sampled as 0) when

  • the oracle is missing or ≤ 0 for the market, or
  • the oracle is stale beyond funding_oracle_staleness_ms (default 60 s), or
  • the book is too thin to fill the impact notional on both sides (no impact price).

A skipped sample is folded as 0, so the premium-index EMA decays toward 0 and the funding rate fades out rather than settling off a stale or manipulable basis. (See also edge cases.)

info

This is why you can see a large mark↔oracle gap with funding ≈ 0. If a market's oracle feed is broken or distrusted, funding is gated off and decays to 0 — even while the mark (which is built from the book and external perps) sits far from the last good oracle. A wide gap with ~0 funding is the protocol declining to charge funding off a bad oracle, not a funding bug.

A paused or closed market

⚠️ NOT LIVE YET. The rule below ships with the next node release. A live node settles funding on every market, whatever its flags.

Governance can stop trading on a market in steps. Funding follows one rule: funding settles only while a holder can close the position.

Market stateHow a caller reads itFunding
Closing disabledclose: false on markets_meta, whatever the other flags sayStops. No payment settles
Reduce-onlyopen: false with close: true, or halted: true on marketsContinues. A holder can close the position to stop paying
Settledsettled: true on marketsNone. No position is open. See Delisting a perp market

While closing is disabled, the period boundary still advances, so no funding builds up for the paused span. When closing is allowed again, the next boundary charges one period, not the paused span. The liquidation engine also counts no funding for the paused span.

Worked example

Market: BTC perp on an 8 h funding period, current state (oracle plane in whole USDC):

mark = 100.50
oracle = 100.00
premium = mark - oracle = 0.50
EMA(premium) settles toward 0.50 with decay 0.5
funding cap = ±2% per period (default)

Suppose the funding accrued over the period resolves to +0.0005 (0.05 %) — well inside the ±2% per-period cap. Account positions:

long 1 BTC → pays funding
short 0.5 BTC → receives funding
funding = clamp(period_accrual, -0.02, +0.02) = +0.0005 (not capped — far below ±2%)

long 1 BTC:
payment = +1 * oracle_px * Δcum ≈ +1 * 100.00 * 0.0005 = +0.0500 USDC (long pays)

short 0.5 BTC:
payment = -0.5 * oracle_px * Δcum ≈ -0.5 * 100.00 * 0.0005 = -0.0250 USDC (short receives 0.0250)

(Payment uses size_signed * oracle_px * (cum_global - funding_entry); here Δcum is the funding accrued since the position last settled.) The transfer lands once at the period boundary; the ±2% per-period cap bounds the most a single settlement can charge.

Funding caps & dynamic limits

ParameterDefaultSource / override
funding cap (per period)0.02 (±2%)dynamic_risk_overrides[asset].funding_rate_cap (governance vote)
funding period1 h per assetset_funding_config (governance vote) — see below
EMA decay0.5set_funding_ema_decay (governance vote) — see below
rate-update cadencebegin-blockprotocol-fixed
base interest0.0000125/h (0.01 %/8h)protocol-fixed
funding_rate_multiplier1.0per-asset, auto-driven by dynamic risk

The per-asset funding_rate_multiplier is auto-driven from 30-day realized volatility by the dynamic-risk engine, scaling the premium sample before it enters the EMA.

The EMA decay is votable

The EMA decay is one number for the whole chain, moved by a two-thirds-stake validator vote, set_funding_ema_decay. Bounds are [0.01, 0.99], and both ends are hard:

  • 0 is the unset value, and it would also stop the fold from reading any history.
  • A decay near 1 freezes the rate for hours.

The fold runs every 8 seconds, so the half-life is ln(0.5) / ln(decay) folds — 0.5 is one fold (8 s) and 0.99 is about 9.2 minutes. Raise the decay to make funding steadier and slower to react; lower it to make funding track the premium more closely.

The enactment appears on validator_votes as changes[*].field: "bole_pool.funding_ema_decay".

Per-asset funding config (governance)

A market's funding period and oracle basis are set per asset by a stake-weighted validator vote (set_funding_config):

FieldMeaning
assetPerp market id
use_binanceWhether to include the external CEX reference in the premium basis
funding_period_msOptional; the asset's settlement period in milliseconds. Omit to leave the current period untouched.

So a major market can be put on an 8 h period while a fast-moving listing runs on a 1 h period, independently. The per-asset funding_rate_cap override (the ±2% default above) is a separate dynamic-risk parameter, voted the same way.

Funding history

Per-account history via POST /info user_fills — funding payments appear with kind: "funding" and the relevant asset.

Per-market history:

curl -X POST https://api.testnet.mtf.exchange/info \
-H 'content-type: application/json' \
-d '{"type":"funding_history","coin":"BTC"}'

Returns the ordered ring of (ts_ms, premium) samples (see funding_history):

{
"type": "funding_history",
"data": {
"coin": "BTC",
"samples": [
{ "ts_ms": 1700000000000, "premium": "0.0015" },
{ "ts_ms": 1700000008000, "premium": "-0.0007" }
]
}
}

A dedicated fundingTicks WS channel is on the WS roadmap; poll funding_history meanwhile.

What funding doesn't do

  • No relation to fees. Funding is user-to-user; fees are maker/taker rebates to the venue. See fees.
  • No interest on collateral. USDC balance does not accrue interest from funding. Funding is purely about closing the mark-oracle gap.
  • Not predictable across long windows. Funding can flip sign hour-to-hour. Don't model it as a constant carry.

Edge cases

Show edge cases
  • Position open/close between settlements. Funding is applied at the asset's period boundary, not continuously — a position's funding events line up with its market's funding period. Account value and health do not reflect pending (accrued-but-unsettled) funding until the boundary lands; see the known timing gap.
  • Negative regime. A market with the perp persistently below the oracle (shorts paying longs) sees funding_rate negative for sustained periods; longs receive funding.
  • Oracle stale / thin book. The premium sample is gated to 0 and the rate decays toward 0 — see Gating. Funding does not settle off a distrusted oracle.

See also

FAQ

Show FAQ

Q: Is funding the same as on a CEX? A: Same mental model, and the cadence is familiar: each market settles on its own period (e.g. 8 h for a major, 1 h for a fast listing), set per asset by governance. The ±2% per-period cap is what bounds a sustained one-sided rate.

Q: Can funding force-liquidate me? A: Yes — a funding payment reduces account_value, and it lands as a discrete step at the period boundary (not a gradual drip). The step is bounded by the ±2% per-period cap, but if your position is large and the rate is persistently against you, that periodic debit can push you from the T0 band into T1. Watch health around your market's funding times.

Q: Does funding apply to spot positions? A: No. Funding is a perp mechanism only. Spot positions accrue no carry.

Q: Are funding receipts taxable? A: That's not a protocol question. Talk to your jurisdiction's accountants.