Minting & Burning
Minting increases SPL token supply by crediting a token account. Burning destroys tokens from a holder's account and reduces supply. Both require correct authority and raw integer amounts.
Search across all documentation pages
Minting increases SPL token supply by crediting a token account. Burning destroys tokens from a holder's account and reduces supply. Both require correct authority and raw integer amounts.
# CLI amounts are UI amounts; burn takes a token account, not the mint
spl-token mint <MINT> <UI_AMOUNT> <RECIPIENT_TOKEN_ACCOUNT>
spl-token burn <TOKEN_ACCOUNT> <UI_AMOUNT>use anchor_spl::token::{self, MintTo, Burn};
token::mint_to(cpi_ctx, amount)?;
token::burn(cpi_ctx, amount)?;When to reach for this:
solana config set --url devnet
MINT=$(spl-token create-token --decimals 9 | awk '/Creating token/{print $3}')
spl-token create-account "$MINT"
ATA=$(spl-token address --token "$MINT" --verbose | awk '/Associated token address/{print $NF}')
# CLI amounts are UI amounts - the CLI scales by the mint's 9 decimals for you
spl-token mint "$MINT" 5 # 5.0 tokens = raw 5_000_000_000
spl-token supply "$MINT"
spl-token burn "$ATA" 1 # burn 1.0 token; burn takes the token account
spl-token supply "$MINT"use anchor_lang::prelude::*;
use anchor_lang::solana_program::program_option::COption;
use anchor_spl::token::{self, Mint, MintTo, Token, TokenAccount};
#[derive(Accounts)]
pub struct IssueReward<'info> {
#[account(mut, mint::authority = mint_authority)]
pub mint: Account<'info, Mint>,
#[account(mut, token::mint = mint)]
pub recipient_ata: Account<'info, TokenAccount>,
pub mint_authority: Signer<'info>,
pub token_program: Program<'info, Token>,
}
pub fn issue_reward(ctx: Context<IssueReward>, amount: u64) -> Result<()> {
require!(amount > 0, ErrorCode::ZeroAmount);
// `mint::authority` already enforces this; the explicit check documents intent
// and avoids the panic that `.unwrap()` on a revoked (None) authority would cause.
require!(
ctx.accounts.mint.mint_authority == COption::Some(ctx.accounts.mint_authority.key()),
ErrorCode::Unauthorized
);
let cpi = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.recipient_ata.to_account_info(),
authority: ctx.accounts.mint_authority.to_account_info(),
},
);
token::mint_to(cpi, amount)?;
Ok(())
}
#[error_code]
pub enum ErrorCode {
Unauthorized,
ZeroAmount,
}What this demonstrates:
mint_authority field; mint_authority is a COption, and .unwrap() on a revoked mint would panictoken::mint = mint pins the destination to this mint before the CPImint_to credits any token account for that mintburn debits signer's token account and updates mint supplysupply: u64 updated on every mint/burnNone means minting is permanently disabled| Step | Supply | Authority |
|---|---|---|
| Create mint | 0 | Mint authority set |
| Mint tokens | Increases | Same |
| Burn tokens | Decreases | N/A |
| Revoke mint auth | Unchanged | Minting disabled |
// Validate mint matches recipient ATA
require_keys_eq!(recipient_ata.mint, mint.key(), ErrorCode::MintMismatch);
require!(amount > 0, ErrorCode::ZeroAmount);MintTo instruction amount of 100 on a 6-decimal mint is 0.0001 tokens. Fix: multiply UI amount by 10^decimals when building instructions.spl-token mint <MINT> 1000000 mints a million tokens, not one. Fix: the CLI takes UI amounts; only instruction data takes raw base units.spl-token burn - burn's first argument is the token account address. Fix: spl-token address --token <MINT> first.mint_authority before UI flows.require_keys_eq! on token_account.mint.| Alternative | Use When | Don't Use When |
|---|---|---|
| Pre-mint full supply then revoke | Fixed-cap launches | Ongoing inflation tokenomics |
| Transfer from treasury ATA | No inflation; redistribute existing supply | Need net-new supply |
| Token-2022 mint close | Reclaim rent on abandoned mint | Active mint |
The pubkey in the mint's mint_authority field, until set to None.
Only account owner or an approved delegate with burn permission via standard SPL rules (owner signs burn).
No. Tokens are destroyed and mint supply decreases.
Yes. Multiple MintTo instructions in one transaction.
Program signs mint_to with PDA seeds as CPI authority.
u64::MAX raw units - plan decimals accordingly for UI sanity.
Yes. Holders burn their own balances; mint authority not required.
Read mint account supply field or spl-token supply <MINT>.
Same concepts; additional extensions may gate transfers after mint.
Common for memecoins and fixed-supply assets after initial distribution completes.
Yes, but revoking mint does not automatically remove freeze authority.
Subscribe to Token program instructions or parse MintTo in transaction logs.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026