Skip to content
All option guides
Solana token mechanics12 min read

Solana Token-2022 Extensions: Transfer Fees, Hooks, and Account State

Learn how Token-2022 mint and token-account extensions change transfer amounts, required programs and accounts, frozen states, memo rules, and wallet compatibility.

In this guideToken-2022 adds state to mints and token accounts

Short summary

Token-2022 keeps Solana tokens recognizable as mint and token accounts, but optional extensions can change what a transfer does. Check the mint address, owning token program, enabled mint and account extensions, authorities, and receiving-account state before sending. A familiar ticker does not tell you the transfer rules.

Token-2022 adds state to mints and token accounts

Solana’s Token Extensions Program, commonly called Token-2022, adds optional behavior through extension data and instructions. Some extensions live on the mint and affect the token as a whole. Others live on each token account and affect one holder or destination. A mint can have a transfer-fee configuration while each compatible token account stores its own withheld-fee amount.

Extensions are not a universal switch that makes every Token-2022 asset behave alike. The enabled set is stored on chain, some choices must be made during account initialization, and certain combinations are incompatible. For example, the official overview says a non-transferable mint cannot also use transfer fees. Read the actual extension list instead of inferring behavior from the program label. See Solana’s Token Extensions overview.

The extension location matters. A mint-level rule can apply whenever any account transfers that mint; an account-level rule can apply only when that particular token account participates. Account creation may need extra space and associated extension state. Therefore a wallet, exchange, or payment service may need more than basic Token Program support to create an account or complete a send.

The mint address identifies the asset; the ticker is only a label

Names and symbols help people scan a wallet, but they are not unique identifiers. Solana’s token documentation describes each token as having a unique mint address. The token program that owns the mint also matters: the original Token Program and Token-2022 are distinct programs, and their token accounts are not interchangeable just because a screen shows the same ticker.

Before trusting an asset, compare the full mint address with a source you already trust, then check which token program owns it. Inspect the mint’s extensions and authorities, not just its symbol, logo, or metadata. A look-alike symbol can point to a different mint, while two mints with similar names can have different transfer rules. Solana’s mint guide and terminology reference describe mint identity.

Mint-level extension data is only part of the picture. The receiving token account may have its own state, such as a memo requirement or a withheld transfer-fee balance. If a transaction fails, verify both sides of the transfer: the mint configuration and the actual destination token account.

A transfer fee reduces the recipient’s spendable amount

The TransferFeeConfig mint extension sets a transfer-fee schedule with a rate and maximum fee. During a transfer, the sender’s requested gross amount is debited, the recipient’s spendable token amount increases by less than that gross amount, and the fee is recorded as withheld on the destination token account. It is not an extra amount silently added to the recipient’s spendable balance.

For a hypothetical transfer of 10.00 tokens with a 1.5% fee and a 0.20-token cap, the calculated fee is 0.15 tokens, below the cap. If the instruction transfers 10.00 gross, the recipient gets 9.85 spendable tokens and 0.15 is withheld. A higher rate may reach the cap, so calculate the fee from the current on-chain configuration and the exact amount and decimals.

The withheld amount is tracked separately from the recipient’s ordinary token amount. It can be withdrawn from token accounts or first harvested to the mint, but the mint’s withdraw_withheld_authority must authorize withdrawal to a fee-receiver token account. This authority is distinct from the authority that may update the fee schedule. The Token-2022 transfer-fee guide documents both stages and the checked-with-fee instruction.

A transfer hook adds program logic and extra accounts

A mint with a transfer hook stores the hook program address. Each transfer invokes that program through a cross-program invocation, so the hook can enforce custom rules such as an allowlist, a transfer cap, or a required setup. This is not an optional app feature: when the mint has a hook, the transfer must execute it.

The ordinary transfer already names the source token account, mint, destination account, and authority. A hook can require more accounts, listed in an on-chain ExtraAccountMetaList. Those entries can name fixed accounts or derive addresses from the mint, program, instruction, or account data. The sender’s wallet or app must resolve the current list and append the required accounts in the expected order.

If a required account is missing or stale, the hook rejects the transfer, or its custom checks fail, the whole transaction fails atomically. There is no partial token delivery that skips the hook. An issuer can update the hook program or the extra-account list, so old cached details may stop working. Solana recommends simulating a hook-enabled transfer before signing; its integration guide explains account resolution, compatibility, and failure handling.

Default account state can make a new account frozen

The DefaultAccountState extension is stored on the mint and sets the initial state of newly created token accounts. A mint can make new accounts start frozen. A frozen account cannot be used for normal token operations until the mint’s freeze authority thaws it. The wallet can show an address and a token balance of zero while the destination is still unable to participate in a transfer.

Changing the mint’s default affects future token accounts; it does not automatically thaw accounts that were already created frozen. The mint’s freeze authority is the key that can thaw those accounts, and it may be controlled by an issuer or another authority rather than the recipient. Check both the destination’s current state and the relevant authority. See Solana’s Default State and Freeze Account guides.

This is different from a transfer hook rejecting a transaction. A frozen state is recorded on the token account; a hook is a program invoked during each transfer. Both can block a send, but they require different checks and can involve different authorities.

Memo requirements belong to the receiving token account

The MemoTransfer extension is enabled on a destination token account, not on the mint. When enabled, an incoming Transfer or TransferChecked must have a memo instruction immediately before the token transfer in the same transaction. A transfer from that account does not require a memo just because it has the extension.

If the required memo is absent or out of order, the token program rejects the transfer. This rule can matter when paying an exchange deposit address or another service that uses a memo to associate a payment with a user. A memo is not a substitute for checking the recipient address, and a sender cannot remove a requirement configured on someone else’s receiving account. Read the Memo Transfer guide and follow the receiver’s exact deposit instructions.

Wallet support depends on the specific extension set

Token-2022 does not mean that every wallet handles every extension. A client that does not resolve transfer-hook accounts cannot send a hook-enabled token, though receiving one does not itself require the wallet to execute the hook. A client also needs to account for transfer fees when it shows the expected net amount, and for account state or memo rules that can make a destination unavailable.

Support can differ between receiving, displaying, creating an account, and sending. An app may recognize the ticker but not decode a newer extension, build the extra hook accounts, or show the withheld amount separately. A service may accept the mint but require a one-time setup or a particular receiving account. Ask which mint address, token program, and extension configurations the destination supports; do not assume that a successful address lookup means a send will work.

Some extension settings can be changed by authorities, and some extensions cannot be added after an account is initialized. For a hook, both the hook program address and its extra-account list can change. Re-read mutable configuration for each send flow, simulate the exact transaction, and surface a clear error before the user signs. The extension overview explains initialization and incompatible combinations.

Check the whole transfer before signing

Start with the full mint address and owning token program. Read the mint’s enabled extensions and relevant authorities, then inspect the exact destination token account for frozen state, memo requirements, and any account-level extension data. A ticker or a token list entry is not enough to predict the instruction’s behavior.

For a transfer-fee mint, calculate the gross amount, current rate, cap, decimals, and expected spendable amount. Confirm whether the receiving service expects the gross amount or a particular net amount. For a hook, fetch the current hook program and extra-account list, satisfy any setup the hook needs, and simulate the fully assembled transaction. For a memo-required destination, put the memo instruction immediately before the transfer.

Suppose a wallet proposes sending 10.00 units to a destination. If the verified mint takes 1.5% up to 0.20, the receiver’s spendable increase is 9.85 units. If that account is frozen, the fee calculation does not make it usable; if it requires a memo, the transaction also needs the memo in the correct position; if the hook rejects the sender, no tokens arrive. Read the simulation result and recipient instructions before approving.

The practical check is: verify mint and program, inspect extensions and authorities, inspect the receiving account, calculate the net transfer, include hook accounts or memo when required, and simulate. These mechanics describe transaction behavior; they do not imply any investment outcome. For how Solana account addresses are derived, see [PDAs and associated token accounts](/learn/solana-program-derived-addresses-seeds-bump-off-curve-explained). For the network fee charged if a transaction fails, see [Solana transaction fees](/learn/solana-transaction-fees-base-priority-compute-units-explained).

Common questions

Q1Does every Token-2022 token charge a transfer fee?

No. Transfer fees are an optional mint extension. Inspect that mint’s actual extension data and current fee configuration.

Q2Can a wallet receive a token with a transfer hook but be unable to send it?

Yes. Receiving does not execute the hook. Sending requires a client that can resolve the hook program’s required accounts and build the transfer.

Q3Does a matching ticker prove that two tokens are the same asset?

No. Use the full mint address and verify its owning token program. Names and symbols are display metadata, not unique identifiers.

Sources and further reading

Report an issue

We’ll prepare an email with this article link. Mark receives the report only after you send it

Quick check

Read the guide? Check yourself with 3 questions

Question 1 / 3

Question 01

Where is a Token-2022 transfer fee withheld during a transfer?

Choose an answer to see the explanation

Options glossary