DocsProtocolMON-20 Standard

Protocol

MON-20 Standard

The complete specification for inscription data format, validation rules, and protocol semantics on Monad.

What is MON-20?

MON-20 is the inscription standard for fungible tokens on Monad. It defines the JSON schema that must be embedded in every valid inscription transaction, the set of permitted operations, and the rules the indexer uses to derive balances from the sequence of events.

The standard is intentionally inspired by BRC-20 on Bitcoin, adapted for the EVM environment where the Monad contract acts as a trustless anchor instead of a UTXO chain.

Standard version

All payloads must include "p": "mon-20" to identify the standard. Future protocol versions will use different values (e.g. "mon-20-v2"). Unknown protocol identifiers are ignored by the indexer.

Payload structure

Every MON-20 inscription is a UTF-8 JSON string passed as the argument to the inscribe(string) contract function. The top-level fields common to all operations are:

FieldTypeDescriptionRequired
pstringProtocol identifier. Must be "mon-20".YES
opstringOperation type. One of "deploy", "mint", or "transfer".YES
tickstringTicker symbol. 1–5 lowercase alphanumeric characters. Case-insensitive on input, stored lowercase.YES

Deploy

The deploy operation registers a new MON-20 ticker on the protocol. Once deployed, no other address can deploy the same ticker. The deployer receives no initial balance — tokens must be minted separately.

deploy.json
{
"p": "mon-20",
"op": "deploy",
"tick": "moni",
"max": "21000000",
"lim": "5000"
}
FieldTypeDescriptionRequired
pstringMust be "mon-20".YES
opstringMust be "deploy".YES
tickstringUnique ticker symbol (1–5 chars, a-z 0-9).YES
maxstringMaximum total supply. Numeric string, no decimals. Cannot be changed after deploy.YES
limstringMaximum amount any single mint operation can claim.YES
decstringDecimal places (default: 18). Optional.NO

Irreversible

Deployments are permanent. The ticker, max supply, and per-mint limit cannot be modified after the deploy inscription is confirmed. Choose parameters carefully.

Mint

The mint operation claims tokens for the caller's address. The amount must not exceed the per-mint limit set at deploy time, and the cumulative minted supply must not exceed the max supply.

mint.json
{
"p": "mon-20",
"op": "mint",
"tick": "moni",
"amt": "5000"
}
FieldTypeDescriptionRequired
pstringMust be "mon-20".YES
opstringMust be "mint".YES
tickstringTicker to mint. Must already be deployed.YES
amtstringAmount to mint. Must be ≤ lim set at deploy.YES
Minting a fully-exhausted ticker (where remaining supply < amt) causes the indexer to ignore the inscription. The protocol fee is still charged. The UI will warn you before submitting if the ticker is near max supply.

Transfer

The transfer operation moves tokens from the caller's balance to a recipient address. The caller must hold at least the specified amount.

transfer.json
{
"p": "mon-20",
"op": "transfer",
"tick": "moni",
"amt": "500",
"to": "0xRecipientAddress"
}
FieldTypeDescriptionRequired
pstringMust be "mon-20".YES
opstringMust be "transfer".YES
tickstringTicker to transfer.YES
amtstringAmount to transfer. Must be ≤ caller's balance.YES
tostringRecipient EVM address (checksummed or lowercase).YES

Validation rules

On-chain (contract level)

  • msg.value must equal exactly 10 MON (10 × 10¹⁸ wei)
  • Payload string must be non-empty
  • Transaction must be sent to the MonadInscriptions contract address

Off-chain (indexer level)

  • Payload must be valid JSON with p = "mon-20"
  • op must be one of: deploy, mint, transfer
  • tick must match [a-z0-9]{1,5}
  • For deploy: tick must not already exist
  • For mint: tick must exist; amt ≤ lim; remaining supply ≥ amt
  • For transfer: tick must exist; sender balance ≥ amt; to must be a valid EVM address
  • Numeric string fields (max, lim, amt) must parse as positive integers with no decimals

Ordering and conflicts

When two transactions compete — for example, two wallets racing to deploy the same ticker — the indexer uses block number + transaction index as the canonical ordering. The lower index wins. The later transaction's inscription is confirmed on-chain but ignored by the indexer; its protocol fee is not refunded.

Monad's parallel execution

Monad executes transactions in parallel using optimistic concurrency. Transaction ordering within a block is still deterministic and agreed upon by all nodes. Indexers use this canonical order as the tiebreaker for all race conditions.