Token-2022 Extensions: The Security Risk Each One Adds
Quick answer. Token-2022 extensions let an issuer change how its tokens move. The biggest integrator risks: permanent delegates that can drain vaults, hooks and pauses that block transfers, fees that shrink received amounts, and closable mints that can be re-created.
Video transcript
Token-2022 lets an issuer change how its tokens move. Your program inherits every extension the moment it accepts the mint.
The program's source defines twenty-eight extension types. Many carry an authority that can change settings later.
The biggest risks: delegates that drain vaults, hooks and pauses that block transfers, fees that shrink received amounts, and closable mints that can be re-created.
In Stampt's escrow review, Guardian showed a permanent delegate could drain the vault directly, so every claim, cancel and refund would fail. The CPI guard does not stop it.
A transfer hook runs the issuer's program on every transfer. It can fail any transfer, its authority can swap the program, and it can block your own flows.
Fee mints withhold part of each transfer, so code that records the sent amount drifts from its real balance. Credit the balance change instead.
An empty mint with a close authority can be closed and re-created at the same address with different extensions, so check that it was never reinitialized.
Before listing, allowlist mints by address, read their extensions and record every authority. Pass the token program explicitly, credit balance changes, and re-read settings on a schedule.
Guardian's Solana reviews check which extensions a program accepts and what each authority can do. Read the full article, or talk to Guardian.
Token-2022, also called the Token Extensions Program, is Solana's second token program. It adds optional features to mints and token accounts.
The issuer picks the features. Your program inherits every one of them the moment it accepts the mint.
The program's source defines 28 extension types: 19 for mints and 9 for token accounts. Most are set at creation, but many carry an authority that can change settings later.
Every Extension at a Glance
| Extension | What it does | Risk to integrators | What to check |
|---|---|---|---|
| Transfer hook | Calls an issuer program on every transfer | Transfers fail; the hook can be swapped | Hook program, hook authority, extra accounts |
| Permanent delegate | Transfers or burns from any account | Vaults drained without your signature | Delegate unset, or its holder trusted |
| Transfer fee | Withholds a percentage of each transfer | You receive less than was sent | Balance change; current and next fee |
| Confidential balances | Encrypts balances and transfer amounts | Balances unreadable; incoming credits capped | Whether your accounting supports it |
| Default account state | New accounts can start frozen | Your new vault may start frozen | Account state after creation |
| Pausable | Halts transfers, mints and burns | Deposits and withdrawals stop | Who holds the pause authority |
| Mint close authority | Lets an empty mint be closed | Mint re-created with new rules | Close authority; mint history |
| Non-transferable | Tokens cannot change owner | Deposits fail | Reject at listing |
| Permissioned burn | Burns need an authority's co-signature | Your burns fail | Who holds the burn authority |
| Interest-bearing, scaled UI amount | Change only the displayed balance | Prices or limits set on UI amounts | Raw amounts in all math |
| CPI guard | Owner blocks some actions via CPI | Your CPI transfer or approve fails | Delegate flow; transfer success |
| Memo transfer | Incoming transfers need a memo | Your payouts to that account fail | Log a memo before transferring |
| Metadata and group pointers | Point to the mint's metadata or group | Fake mints borrow a known name | Mint and metadata point to each other |
The rest protect holders, such as immutable owner, or support the extensions above, such as TransferFeeAmount on token accounts.
Transfer Hooks
A transfer hook makes Token-2022 call an issuer's program on every transfer.
It is not optional for senders. Solana's docs say a client that does not resolve the hook's extra accounts "can't send the token at all".
What that means for your program:
- The hook can fail any transfer for its own reasons, such as an allowlist or a pause.
- The hook authority can point the mint at a new program, and the extra accounts can change too.
- The hook is not called on self-transfers.
Hooks can block your own flows. In Guardian's LayerZero Solana Console review, whitelist mode stopped every outbound BurnMint send until the escrow token account was whitelisted (L-03, resolved).
If you write the hook
Neodyme recommends these checks for hook programs:
- Restrict which mints the hook serves.
- Check the
transferringflag, which Token-2022 sets during a real transfer. - Check that the token accounts belong to the mint.
Check owners, not just accounts. In the same review, a blacklist hook checked token accounts and the signer, so a blacklisted wallet could use a fresh token account (I-15, acknowledged).
LayerZero kept the design, because owner checks would break account resolution for first-time recipients.
Permanent Delegate
A permanent delegate can transfer or burn any amount from any token account of its mint. It needs neither your signature nor your vault PDA's.
In Stampt's escrow review, Guardian showed such a delegate could drain an escrow vault directly, so every claim, cancel and refund would fail (L-04, resolved).
Three more facts:
- The CPI guard does not stop it, per Solana's program docs.
- It does not reach tokens held in confidential balances.
- It can rotate in one
SetAuthoritycall with no accept step, as the LayerZero review noted (I-12).
Issuers use it for real reasons, such as recovering funds from blocked accounts. If you accept one, handle a vault balance that falls without your instruction.
Transfer Fees and Accounting Drift
A transfer fee mint withholds a percentage of every transfer, capped by a maximum fee. The withheld tokens sit on the recipient's account, out of the recipient's reach.
So the receiver gets less than the sender sent, and code that records the sent amount drifts from its real balance.
In Stampt's escrow, a fee mint left the vault short of its stored amount, so claims, cancels and refunds failed (I-02).
In M0's Solana order flow, fee mints could leave orders only partly fillable (I-06, resolved).
The fee can change, up to 10,000 basis points (100 percent). A new rate takes effect two epochs after it is set, "to avoid rug pulls at the end of an epoch".
Token accounts holding withheld fees cannot close until those fees are harvested or withdrawn.
The fix: credit the balance change, or compute the fee and use TransferCheckedWithFee. The EVM version of this bug is in our weird ERC-20 tokens checklist.
Confidential Transfers
Confidential transfers (Confidential Balances in Solana's docs) encrypt balances and amounts. Addresses, the mint and owners stay public.
Integrators face three changes:
- Pending balances. Incoming funds land in a pending balance and cannot be spent until applied.
- A credit cap. A full pending counter blocks confidential credits until applied. Neodyme notes an attacker can fill it.
- Blind monitoring. Amount-based checks need the mint's auditor key. Deposits and withdrawals stay in the clear.
It relies on Solana's ZK ElGamal Proof program, which the docs say is enabled on mainnet and devnet.
A program cannot read an encrypted balance. Accept these mints only if your accounting works without one.
Closable Mints
With a mint close authority, an empty mint can be closed and re-created at the same address with different extensions.
Neodyme showed the new mint can bypass freezes, soulbound rules and transfer fees through accounts made for the old one.
A re-created mint may no longer show a close authority. Neodyme's advice: check that the mint was never reinitialized.
Integration Checklist
- Allowlist mints by address, never by name or symbol.
- Read a mint's extensions before listing it. Reject types you have not reviewed.
- Record every authority: hook, delegate, fee, pause, freeze, close, burn and metadata.
- Pass the token program explicitly. Associated token addresses differ between programs.
- Use
TransferChecked, resolve hook accounts and simulate before sending. - Credit received amounts from balance changes, not instruction arguments.
- Check that new vault accounts are not frozen.
- Do all math in raw amounts. Interest-bearing and scaled UI amounts are display only.
- Re-read mint settings on a schedule. Authorities can change them after you list.
The token program point is real. In Jupiter's JupUSD program, an account check derived the address with the default SPL Token program, so mints and privileged withdrawals would fail for Token-2022 vaults (L-01, resolved).
How Guardian Reviews Integrations
Guardian's Solana reviews check which token programs and extensions a program accepts, and what each authority can do to its accounts.
A Guardian smart contract audit runs two competing teams on one scope, one manual and one driving frontier AI, over an invariant fuzzing suite.
For scope and cost, see the Solana smart contract audit guide. For account checks, see Solana program security best practices.
Frequently Asked Questions
What are Token-2022 extensions?
Optional features of Solana's Token Extensions Program, set on a mint or a token account. Examples include transfer fees, transfer hooks, permanent delegates, confidential balances and pausing. The program's source defines 28 extension types.
Can a Token-2022 token be drained from my program's vault?
Yes, if its mint has a permanent delegate. It can transfer or burn tokens from any account of that mint without the owner's signature, and the CPI guard does not stop it. Reject such mints, or accept that risk.
How is Token-2022 different from the SPL Token program?
It is a separate program that adds extensions to the standard token features. Associated token addresses differ by program, so pass the right token program explicitly and check which program owns each mint.
Sources
- Solana Docs: Token Extensions
- Solana Docs: Transfer Hook Integration Guide
- Solana Docs: Confidential Balances Integration Guide
- Solana Docs: Confidential Balances, Transfer Tokens
- Solana Docs: Pausable Mint
- Solana Docs: Default State
- Solana Docs: Scaled UI Amount Integration Guide
- Solana Program Docs: Token-2022 Extensions
- GitHub, solana-program/token-2022: ExtensionType definitions (read November 6, 2026)
- GitHub, solana-program/token-2022: transfer fee processor
- GitHub, solana-program/token-2022: transfer processor and hook call
- Neodyme: SPL Token-2022, Don't Shoot Yourself in the Foot with Extensions (September 10, 2024)
- Guardian: Stampt Escrow report (April 1, 2026)
- Guardian: LayerZero Solana Console report (July 20, 2026)
- Guardian: M0 Liquidity Delivery report (January 30, 2026)
- Guardian: Jupiter JupUSD Stablecoin report (December 25, 2025)
Know what every mint can do to your vaults
Guardian reviews Solana programs against the token programs and extensions they accept, before launch.