Skip to main content

MIP-3 — Permissionless perp market deploy

info

The lane is live and in use. Markets are deployed through it today. A deployed market carries the deployer's dex prefix in its coin, so a market named GRAD:USDCNY belongs to the GRAD dex and not to the primary market set.

One governance off-switch still applies per network: mip3_enabled. Read it before you build on the lane, because a closed switch refuses a deploy call.

Any builder can deploy a new perpetual market on MetaFlux by paying a deploy fee and posting a staking bond. There is no protocol-team gate, no review committee and no allow-list. (Permissionless spot market deploy is the sibling proposal, MIP-1, and it is callable today.)

Why this exists

A core protocol capability. Centralised exchanges curate listings; MetaFlux makes the listing process itself part of the protocol. Builders who want a market for some niche asset do not need permission — they need to pay the current ask and bond stake they can lose.

What a deploy costs

Two independent barriers, and they are not alternatives to each other:

BarrierAmountPaid how
Deploy feeThe current Dutch-clock ask on the perp-deploy streamCharged at register, from your free collateral
Staking bondmip3_deploy_min_stake — about 50,000 MTF by defaultCommitted stake you already hold. Slashable, not spent

The bond is checked at the moment a new market is allocated. Stake below the floor is refused before anything is written, so a rejected deploy is a clean no-op that costs nothing.

info

There is no bid, no escrow and no refund. An earlier draft of this page described an auction where builders escrowed a USDC bid that was refunded on loss and burned on win. The node has never worked that way for perp deploy. A deploy carrying a non-zero bid is rejected outright; the deploy pays the Dutch-clock ask at register instead. Nothing funds a perp-deploy escrow balance and nothing can withdraw from one. Ignore any client code that still builds a bid.

The Dutch clock is a declining ask, not a competitive auction: the price falls over the configured window until someone registers, and registering resets it. You bound your exposure with the max_deploy_fee you sign — if the ask is above that value, the call is rejected and you are charged nothing. The fee leaves free collateral, so an account whose value is committed to open positions is refused even when its total value covers the ask.

Deploy flow

Perp deployment is dispatched by sub-variant, eleven of them, covering the full market lifecycle:

Action tagPurpose
perp_register_assetRegister a new perpetual asset; allocates an AssetId. Pays the fee, requires the bond
perp_set_leverageSet the max leverage cap
perp_set_fee_tierSet the maker / taker fee tier
perp_set_maker_rebateSet the maker rebate (≤ 2 bps)
perp_set_min_sizeSet the market's minimum order size
perp_activate_marketActivate the market. Requires full config
perp_deactivate_marketClose to new orders. Existing positions remain
perp_set_fba_modeSet the matching venue: 0 returns the market to the CLOB, 100-5000 runs a frequent batch auction with that period in ms
perp_set_sub_deployersGrant or revoke a delegate, all powers at once. Deployer-authority only
perp_set_sub_deployer_permsGrant a delegate an exact permission mask. Deployer-authority only
perp_set_oracleRETIRED. Refused — see below
info

Ten, not nine, and not eight. Older copies of this page listed eight and omitted perp_set_sub_deployers; a later copy listed nine and omitted perp_set_fba_mode. The table lists eleven tags, of which perp_set_oracle is refused. Ten are callable.

Delegation is per handler

Only the deployer of record — or a delegate it authorized — may call the lifecycle actions on a market it deployed.

A delegate holds one permission bit per handler, so a grant names the handlers, not the person: you can hand out the price push without handing out the fee rates. The nine bits and the two granting lanes are on perp_set_sub_deployers.

Two rules bound it:

  • Delegating is never delegable. Both granting lanes need the deployer's own authority. A delegate holding every bit still cannot appoint another. There is no bit for it.
  • An upgrade takes nothing away. Every delegate committed before the release reads as the full mask afterwards, exactly the authority it has today. Narrow one by sending the mask you want it to keep.
Grant the mask explicitly

A delegate added by perp_set_sub_deployers alone holds every deployer power. The mask narrows it, so send perp_set_sub_deployer_perms with the mask you want the delegate to keep.

perp_set_oracle is retired

The action wrote a market's oracle source-subset mask, and nothing read the mask. The call returned OK, committed state changed, and the market priced exactly as before.

The node refuses it. Nothing replaces it, because it never did anything: the deployer price control is mip3_set_oracle_px (action 210), a different action that stays. The mask field remains in market state, still with no reader, until the next re-genesis.

Where the new market lands

warning

Not in the canonical asset registry. A builder-deployed market is allocated into the deployer's own dex, with an asset id at or above 1000. It is isolated from the primary market set: it never joins the shared perpetual dex, and it does not appear alongside the protocol-listed markets. An earlier version of this page promised the opposite. Only accounts that choose to trade the market are exposed to it.

This isolation is the main containment property of the design. A builder controls the oracle and the fee tier of its own market; keeping that market out of the shared set means those controls cannot reach a trader who never opted in.

Oracle

A deployed market does not price from the validator oracle median. Its index price is pushed by its deployer, through the mip3_set_oracle_px action (210). The deployer, or a delegate holding permission bit 0, signs each push.

Because the deployer operates the oracle for its own market, treat any builder-deployed market as carrying deployer price risk. This is the reason the market is isolated and the reason the bond is slashable.

warning

Two corrections to an earlier version of this page.

  1. The push is gated per chain, not unconditionally live. The action sits behind the mip3_deployer_oracle protocol feature. That feature is active from genesis on a chain that started fresh, and dormant on any other chain until a two-thirds stake ArmFeatures vote arms it. While it is dormant, a push is refused with mip3_deployer_oracle feature not active. Read feature_active from the operator-lane mip3_deployer_oracle read on the network you target — do not assume a posture.
  2. The source subset mask does not decide what a push accepts. The mask is committed per market, but nothing filters prices by it, and no read serves it — see oracle prices. That is why the action that wrote it, perp_set_oracle, is retired. A deployer push is bounded by the price rules below, and by nothing else.

Running the oracle for your market

The order below is the whole operator loop. Each rule has a reason, and the reason is what tells you how to size your own push cadence.

  1. Register and activate the market first. A push at an asset that is not a MIP-3 market is refused. Registration also fixes who may push: the deployer, plus any delegate granted permission bit 0.

  2. Choose the first price with care. A push must sit within ±10 % of the committed anchor — the last committed oracle price, or the market's committed mark price when no oracle price exists. A brand-new market has neither, so the first push has no anchor and any price in (0, 1000000000000] is accepted once. Every later push is chained to that value through the band, so a wrong first price takes several pushes to walk back. The band exists so that one push cannot teleport the mark and mass-liquidate the market.

  3. Expect the first push to change the margin regime. The first push is the moment the market becomes deployer-priced. Cross-margin positions that already exist on the market are migrated into their own strict-isolated buckets. The migration conserves value per account: what leaves cross collateral arrives as isolated margin. Every position opened afterwards is strict-isolated too. The reason is containment — a market whose price one party controls must not share a collateral pool with markets that party does not control.

  4. Push faster than the staleness window. The window is mip3_stale_mark_ms, default 60,000 ms. Governance may set it in [10,000 ms, 600,000 ms], and a cross-field rule ties it to the risk staleness window risk_oracle_staleness_ms (default 60,000 ms, governable in [10,000 ms, 300,000 ms]): the refresh window must stay at or below the staleness window. The two move together so a market can never be judged risk-stale before its own mark refresh has had a chance to fire. Confirm the live values before you size a cadence; do not assume the defaults.

  5. Know what a stale feed costs you. Past the window the market turns reduce-only for opens: an order that opens or increases a position is refused, and a closing order still passes. Nobody is trapped in a position, and nobody can enter one either. This is deliberate. On a market where your feed is the only price, a frozen price with open entry is a free option against every trader on the book.

  6. Monitor with a read, not a stopwatch. the operator-lane mip3_deployer_oracle read reports stale, until_stale_ms, and the reference stamp the gate itself uses. Alert on until_stale_ms, not on your own send time — a push counts only once it is committed.

info

A part-time underlying yields a part-time market. The staleness window is a risk bound, not a trading calendar. If your underlying has venue hours, your feed stops when the venue closes, and the market goes reduce-only for the closure. Widening the window to span a weekend does not fix this — it lets anyone open positions all weekend against a stale Friday price, which is the exact gap risk the reduce-only flip exists to stop. If you want the market open through a closure, publish a live derived price around the clock and stay inside the window.

Price units. px is a whole-USDC decimal string, never the 1e8 book plane, and it is signed verbatim — the exact bytes you send are the bytes inside the signature digest. See mip3_set_oracle_px for the frozen signing type and the full rejection table.

Limits

Governance sets the bounds a deployed market must fall within. The defaults below are the shipped values, not a promise about the live network — governance can move any of them, so confirm the current value through validator governance before you rely on it:

BoundMeaning
max_leverageHighest leverage a deployed market may set. Protocol cap is 50
max_taker_fee_dbpsHighest taker fee, in deci-bps. Default 500, i.e. 50 bps
mip3_fee_ceiling_bpsGovernance fee ceiling, in bps
max_oiHighest open interest a market may carry, in whole units of the base asset
max_oi_per_secondHighest open-interest increase admitted per one-second window, in whole units of the base asset
mip3_max_deploys_per_epochNew registrations allowed per deploy epoch — a fixed window of 100,000 committed rounds, about 3 hours at the current cadence. Not the staking epoch. 0 means uncapped
warning

A 0 limit means uncapped, not blocked. mip3_fee_ceiling_bps and mip3_max_deploys_per_epoch are 0 on the live network today, and max_oi_per_second defaults to 0. A 0 leaves each of them fully open. These are rate controls. The off-switch is mip3_enabled, a separate governance flag that closes the whole lane. Never read a 0 cap as "deployment is closed".

mip3_fee_ceiling_bps and mip3_max_deploys_per_epoch both bind admission today.

Unit trap. max_oi and max_oi_per_second are in whole units, not in lots. Both are single values that apply to every market, and a lot means a different real quantity on each one, so a shared lot count could not state a single real limit. The chain converts each value into a market's own size plane before it applies it.

Unit trap. mip3_fee_ceiling_bps is in basis points; the fee fields on the wire are in deci-bps, tenths of a basis point. The two differ by a factor of 10.

Four further fields appear in the configuration but are reserved and unused: max_active_markets, min_self_stake, bid_increment, and a second min_deploy_stake. Nothing reads them. The live staking bond is mip3_deploy_min_stake. Do not build against the reserved four.

Liquidation on a deployed market

A deployed market carries its own backstop settings, set by governance per asset. They decide how a failing account on that market is closed.

SettingWhat it doesEnforced today
modeDisabled closes on the book and never escalates to the backstop tier. Enabled uses the normal ladder. Capped is meant to bound the treasury's exposureDisabled and Enabled only
band_floorRaises the health level at which the market escalates, ahead of the global bandYes
deficit_capThe bound Capped was meant to applyNo. 0 is the only accepted value, and 0 means no cap

A market with no settings defaults to Disabled when it prices from its own deployer oracle.

caution

A vote that sets deficit_cap to a non-zero value is refused: deficit_cap must be 0 (no cap). The refusal is deliberate. A capped deficit leaves the remainder with no owner: the shortfall above the cap is neither paid by the treasury nor assigned to anyone, so the books do not balance. 0 means "no cap", which is the only sound setting. Capped and Enabled therefore stay behaviourally identical, and the mode name is kept only because the wire encoding is name-based.

warning

The protocol's Metaliquidity vault does NOT backstop a deployed market. The vault backstop is live on the core markets since 2026-08-18 — there it takes over a failing position ahead of the netting, and pays deficit ahead of ADL. A deployed market is refused at both entry points, whether or not it prices from its own oracle, so its bad debt can never reach the vault's liquidity providers.

Plan for it. Your market's shortfall is handled by its own backstop settings, its own participants and, past those, the deficit waterfall — never by protocol LP capital.

After deploy

Liquidity is the builder's problem; the protocol provides no seed orders.

Builders typically bootstrap depth by combining a deploy with a liquidity source on the same market — MIP-2 Metaliquidity, an external market maker drawn in by builder-fee rebates, or a user-created vault.

MIP-4

A market deployed here can be the underlying of an option series, if it carries a live price feed. The option lane keeps its own collateral: it does not share the margin account of the perpetual. See MIP-4 — Options.

See also