SPL Token Best Practices
Rules for correct, safe SPL Token handling on Agave 4.1.1 - from mint launch through program CPIs and client reads.
How to Use This List
- Apply A before creating any mainnet mint
- Review B before shipping on-chain vault or payment code
- Use C when building wallets, dashboards, and indexers
A - Mint Launch
- Pick decimals once at mint init. Immutable forever - match industry (6 for stablecoins, 9 for SOL-like).
- Revoke mint authority after distribution. Fixed supply is the standard trust signal unless inflation is documented.
- Revoke freeze authority for community tokens. Unless compliance requires freeze, holders should not face account freezes.
- Document authority transactions publicly. Indexers and explorers should match your announcements.
- Verify mint pubkey on-chain before marketing. Typos in URLs cause irreversible user loss.
B - On-Chain Programs
- Use
transfer_checkedwith mint decimals. Prevents cross-decimal confusion in multi-asset programs. - Constrain
token::minton everyTokenAccount. Stops vault deposits of wrong assets. - Validate ATA addresses via derivation. Do not trust user-supplied token account pubkeys blindly.
- Sign PDA vault CPIs with
new_with_signer. Missing seeds is the top vault transfer failure. - Use
token_interfacewhen accepting Token-2022. ClassicTokenprogram constraint rejects extension mints. - Reject zero-amount transfers/mints. Wastes CU and confuses analytics.
C - Clients & Operations
- Convert UI amounts with BigInt/string math. Never
float * 1e6for production payment amounts. - Read decimals from mint RPC, not constants. Multi-token apps need per-mint decimals.
- Fund recipient ATAs (
--fund-recipientor idempotent create). Transfers fail without destination token account. - Reuse WSOL ATA for active traders. Avoid repeated wrap rent churn.
- Show raw and UI amounts in admin tools. Support debugging decimal incidents.
- Revoke stale delegate approvals after DeFi swaps. Reduces wallet drain risk.
FAQs
What is the single most important launch step?
Revoke mint authority after final mint, if fixed supply is promised.
Should programs use transfer or transfer_checked?
transfer_checked in all Anchor programs handling multiple mints.
How do I verify a token is safe?
Read mint authorities on-chain, supply, and program ID - never UI badges alone.
Should I subsidize ATA creation?
Yes for consumer onboarding when users lack SOL for rent - budget explicitly.
Classic Token or Token-2022 for new fungible?
Token-2022 only when you need extensions; classic Token has widest compatibility today.
How do I test token flows?
Surfpool 0.12.0 or LiteSVM 0.6.x with devnet mints before mainnet launch.
What about wrapped SOL?
Always sync_native after lamport deposit; unwrap dust after DeFi.
How do indexers track balances?
Parse Token program instructions plus periodic getTokenAccountsByOwner reconciliation.
Can I upgrade mint parameters?
Decimals and program are fixed - plan migration as new mint + holder migration if needed.
Should treasury use multisig mint authority?
Yes for DAO emissions - document timelock and on-chain pubkey.
Related
- SPL Token Basics - section overview
- Authorities - revoke details
- SPL Token in Programs - CPI patterns
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.