Skip to main content

Staking

info

Live on testnet. Deposit, delegation, undelegation, rewards claiming, and validator registration are active and verified end-to-end across consensus on testnet.

TL;DR

Hold MTF, move it into the staking pool, delegate to a validator, earn staking rewards. The ongoing source is protocol fee revenue: fees fund validators — the 20% validator share of the fee buyback — and validators fund stakers, passing that share down minus commission, already converted to MTF before it reaches you (see Reward sources). Early on this is supplemented by a finite treasury-funded bootstrap budget (never new issuance). A flexible (untiered) delegation unstakes any time; a locked delegation must first mature its lock tier. Either way, undelegated stake then serves a governed unbonding window before it is free to withdraw. Slashing applies to validators who misbehave; delegators face partial slash exposure.

Actors

RoleDescription
ValidatorRuns a consensus node, proposes blocks, votes. Must self-bond above min_self_bond (default 100k MTF).
DelegatorHolds MTF, picks a validator, earns rewards minus the validator's commission.
ProtocolDistributes rewards per block, pro-rata to stake: the validator share of fee revenue plus the treasury bootstrap budget.

Staking flow

Actions

There is no Redelegate and no ClaimUnstaked action — see the notes under each step below for what actually moves stake between those states.

Deposit to / withdraw from the staking pool — c_deposit / c_withdraw

{ "type": "c_deposit", "params": { "amount": "1000" } }
{ "type": "c_withdraw", "params": { "amount": "1000" } }

Move whole-MTF between your spot balance and your free staking pool — an undelegated holding area, not a validator delegation. c_withdraw has no unbonding wait; it only touches the free pool, never a delegation. amount is a decimal string.

Delegate or undelegate — token_delegate

One action handles both directions via is_undelegate:

// delegate: pool -> validator
{
"type": "token_delegate",
"params": { "validator": "0x<val_addr>", "amount": "10000000000", "is_undelegate": false, "lock_months": 0 }
}
// undelegate: leaves the delegation, enters the unbonding queue
{
"type": "token_delegate",
"params": { "validator": "0x<val_addr>", "amount": "10000000000", "is_undelegate": true }
}

lock_months is one of 0 (flexible), 1, 6, 24 — ignored on undelegate. A locked tier (> 0) is only admitted for a governance-allowlisted validator, and re-locks the row's maturity on every addition (so an addition never shortens an in-flight lock). A row holds ONE tier. Adding to an existing delegation with a different lock_months is refused; undelegate the row first, or use a second validator. A locked row cannot start unbonding until its own lock matures; a flexible row (lock_months: 0) can undelegate any time. Delegating funds from the free pool credited by c_deposit — an under-funded pool rejects cleanly, no partial state change.

An EVM contract can delegate too, and it picks a tier the same way. CoreWriter action 3 carries lockMonths as an optional fourth word, and the tier rules above apply unchanged. A three-word call omits it and lands on tier 0, which earns no revenue share. A CoreWriter refusal is silent — the EVM receipt still reports Success — so read the stored tier back from staking_state.

Undelegated stake does not return to your spot balance immediately: it sits in a per-delegator unbonding entry, still slashable, until the governed unbonding window elapses — then a begin-block effect (no action required) credits it back to your free staking pool automatically. Withdraw it to spot from there with c_withdraw.

Claim rewards — claim_rewards

{ "type": "claim_rewards", "params": { "validator": null } }

validator: null claims every delegation's accrued reward at once (plus your own validator-commission bucket, if you run one); validator: "0x<addr>" claims just that one delegation row. Credits your spot MTF balance. No-op — returns claimed: "0" — if nothing is pending.

{ "type": "link_staking_user", "params": { "target": "0x<addr>" } }

Present in the wire vocabulary but always rejects today (linkStakingUser disabled: claim-on-behalf requires target opt-in) — the intended claim-on-behalf-of-a-cold-wallet flow was never wired past this fail-closed guard. Do not rely on it.

Reward sources

Both sources credit the same MTF-denominated unclaimed_reward bucket claim_rewards pays out — there is no separate USDC reward to claim, even though fee revenue is USDC-denominated at the source:

SourceMechanismShare
Fee revenue — validator share of the buybackThe accrued USDC validator-fee pool periodically buys MTF on-book (batched behind a governance-tunable minimum pool size and a time throttle, not every block); the acquired MTF is what gets split belowcommission_bps to the validator, the rest pro-rata by (delegation amount × lock multiplier) across delegators + the validator's own self-stake

A flexible delegation earns no revenue share. The lock multiplier is at lock_months: 0 — see the ve-style table. So a no-lock row weighs zero in the split above and is paid nothing. Lock for at least 1 month to draw a share. A flexible delegation still earns the Tier 1 fee discount; the two ladders are separate.

The split has two levels, and both use the same weight. The acquired MTF is first divided across active validators, then within each validator across its delegators. A validator's slice at the first level is sized by the SAME weighted stake the second level pays out — self-stake at 1.0× plus each delegation row's amount × lock multiplier — not by raw bonded stake. A validator whose delegators are all flexible therefore draws only its own self-stake, and its commission base shrinks with it. | Bootstrap rewards (treasury-funded, early phase) | Begin-block emission from the treasury bootstrap budget — never new issuance | stake_share × (1 - validator_commission), per the APR curve |

Fee revenue is the ongoing source: per the fee flywheel, net fee revenue splits 70% buyback-and-lock / 20% validators / 10% treasury, and the validator 20% funds this path. validator_commission (commission_bps): per-validator, in validator_summaries, capped by governance.

Lock and unbonding

Two separate durations apply, and only one is a per-delegation choice:

  • Lock tier (lock_months: 0/1/6/24) — your own choice at delegate time. A locked row cannot start unbonding before it matures; a flexible (0) row can undelegate any time.
  • Unbonding window — governance-set (7 days on live testnet today; a vote can only raise it, never below a 7-day floor). Applies after undelegating, regardless of lock tier. Read your own entry's maturity from staking_state's pending_unstakes[].matures_at_ts rather than assuming a fixed value.
StateEarns rewards?Slashable?
Active (delegated)yesyes
Unbonding (after is_undelegate: true)noyes (until matured)
Matured, sitting in the free staking poolnono

Slash exposure during unbonding is the trap — a validator that gets slashed mid-unbond drags the unbonding delegators down with them, even though they've signalled exit.

Slashing

Validators are slashed for:

OffenceSlashPunishment to delegator
Double-sign (signed two conflicting blocks at same height)5% of stake + jailPro-rata 5% of delegation lost
Downtime (missed downtime_blocks consecutive proposer slots)0.1% of stake + jailPro-rata 0.1% lost
Vote on invalid fork5% + permanent removalPro-rata 5%

Slashed delegators see their delegation.amount reduced at the slash block. No notice — slashing is consensus-derived.

Mitigations:

  • Pick well-operated validators (uptime track record, commission stability).
  • Diversify across validators (a single validator slash hits only that portion).
  • Avoid validators near min_self_bond (more likely to exit ungracefully).

Validator selection

curl -X POST https://api.testnet.mtf.exchange/info -d '{"type":"validator_summaries"}'

Returns the active validator set ({epoch, total_stake, n_active, validators[]}); each entry carries:

{
"validator": "0x<val>",
"signer": "0x<signer>",
"validator_index": 3,
"stake": "10000000000000",
"self_stake": "100000000000",
"commission_bps": "500",
"is_active": true,
"is_jailed": false,
"first_active_epoch": 12
}

Pick by:

  • Commission (commission_bps): lower → higher net APR. But beware bait-and-switch (cap raises).
  • Self-stake (self_stake): higher → operator has skin in the game.
  • Jail status (is_jailed): a currently-jailed validator earns nothing until unjailed.
  • Active (is_active): only is_active: true validators are in the live signing set.

APR estimation

The staking_state /info query type is live — it returns the effective bootstrap-reward APR the begin-block reward effect actually applies, plus its committed inputs:

curl -X POST https://api.testnet.mtf.exchange/info -d '{"type":"staking_state","address":"0x<addr>"}'
{
"type": "staking_state",
"data": {
"total_stake": "1000000",
"pending_validator_pool_usdc": "25.75",
"n_active_validators": 1,
"current_epoch": 2,
"reward_source": "fee_funded_on_book_buy"
}
}

⚠️ The emission era is over, and this read no longer publishes an APR. The fields effective_apr, effective_apr_bps, governance_rate_bps, emission_floor_stake and is_gross_pre_commission used to be documented here and are not on the wire. The stake curve (0.08 × √(50M / max(total_stake, 50M))) described the emission the chain no longer runs.

Rewards are FEE-FUNDED. The 20% validator share of the fee buyback accrues into pending_validator_pool_usdc, and the epoch distribution pays it out. So the reward is whatever fees the period earned, divided by stake — it is not a rate the chain can publish in advance.

The distribution BUYS the reward asset; it does not convert it. The pooled USDC is spent on the MTF/USDC book, and only the MTF actually acquired is paid out by stake weight. This is what keeps the platform from subsidising: USDC never credits into an MTF-denominated reward at a made-up rate. The cost is that a thin book delays the payout. With no resting asks on MTF/USDC the buy acquires nothing and the distribution is skipped, leaving the pool untouched for the next attempt. A pool that sits at a constant value is that case, not a fault.

There is no APR field, and do not compute one from these values. The pending pool is accrued fees at an instant, not an annualised rate: projecting it forward assumes trading volume that has not happened. A delegator's realised return is their WEIGHTED share of each distribution — amount × lock multiplier, which is zero for a flexible row — less their validator's commission (commission_bps, in whole basis points as a decimal string).

Edge cases

Show edge cases
  • Validator exits while you're unbonding. Your unbonding stake transfers to the next-in-queue validator at the slash block. You can redelegate post-exit if you prefer a different validator; the lock continues against the new validator.
  • Active set turnover. If the validator drops out of the active set (their delegations drop below the cutoff), your stake earns no rewards while they're out. You can redelegate to an active validator.
  • Self-bond minimum. A validator whose self-bond falls below min_self_bond (via slashes or withdrawals) gets jailed; delegators don't earn during jail.

Sequence — full cycle

See also

FAQ

Show FAQ

Q: Can I stake and trade simultaneously? A: Yes — staked MTF and USDC trading balances are separate sub-balances of the same account.

Q: Do I need an agent wallet to stake? A: No, and you cannot delegate one for this: every staking action (c_deposit, c_withdraw, token_delegate, claim_rewards) is master-only — there is no agent-resolvable owner field, unlike order and margin actions.

Q: Can I cancel an unbonding, or move it to a different validator without the wait? A: No — there is no redelegate action. Once you undelegate, the stake serves the full unbonding window before it is free; only then can you delegate it elsewhere.

Q: Where do staking rewards come from? A: Fee revenue is the ongoing source: validators receive the 20% validator share of the fee buyback (70% buyback-and-lock / 20% validators / 10% treasury) and distribute it to their stakers minus commission. Early on, a finite treasury-funded bootstrap budget tops this up. The protocol never mints new MTF — total supply is fixed (tokenomics).