You hold a token. You did not trade, transfer, stake or touch it. Your balance is different this morning than it was last night, and there is no transaction in your history to explain it.
On Solana that is not a hack and not a display bug. It is one of two Token-2022 extensions doing exactly what they were built for: making the number a wallet shows depend on time, not on transactions. The raw amount in your account never changed. The interpretation of it did. Here is what the node computes, where the number comes from, why every tax tool and most archives get it wrong, and how to read your own balance correctly.
Two Extensions, One Idea: The Display Is a Function of the Clock
Interest-bearing mints carry a rate, in basis points per year, and a timestamp. The raw token amount is fixed; the displayed amount is the raw amount compounded continuously at the rate since the mint's initialisation, with a separate average rate for periods before the last rate change. Nothing accrues on chain. The "interest" is a formula applied at display time.
Scaled-UI-amount mints carry a multiplier, and optionally a scheduled new multiplier with the timestamp at which it takes effect. The displayed amount is the raw amount times the multiplier in force now. A stock-split token, a rebasing wrapper, a share class with a periodic revaluation — all one multiplier field.
In both cases, the on-chain balance in your token account is a plain integer that only transactions change. The extension tells readers how to present it.
What the Node Actually Does When You Ask
When an RPC serves a parsed token account, a token supply, or a token account balance for one of these mints, it reads the extension config from the mint and evaluates it against the node's own clock — the bank's current unix timestamp. The same account, queried a minute apart, returns a different display amount. Queried from two nodes whose clocks differ by a slot — 300 ms at today's mainnet slot time, 250 ms from epoch 1037 — it can return two different amounts at the same moment.
The node also refuses to give you a floating-point shortcut. The parsed balance carries a uiAmount field that is a nullable number, and for interest-bearing and scaled mints it is null. The lossless fields are amount (the raw integer) and uiAmountString (the server's decimal rendering). Any code that does arithmetic on uiAmount has a null at exactly the mints where the number matters most; any code that recomputes the string from amount and decimals locally gets the plain, un-scaled value and is simply wrong.
Worth knowing: the interest rate is a signed 16-bit integer. Negative rates are representable. A mint can be configured so that the displayed balance of every holder declines over time, with no transfer, no burn and no event in anyone's history. It is a legitimate instrument for some products and an unlabelled drain in others.
Why Archives and Tax Tools Get It Wrong
The historical record compounds the problem.
The archive that backs long-tail transaction history stores token balances by regenerating the decimal string from amount and decimals on read, and stores a null uiAmount as 0.0. Every product that reconstructs a wallet's history from the archive sees the un-scaled amount for these mints, and sees zero where the node said "not representable". Cost-basis tools, portfolio trackers and explorers that lean on archived history will present a balance for these tokens that never existed.
The live node gets it right because it evaluates the extension against the clock. The archive cannot, because it stored the answer to a question whose answer changes with time.
What This Means for Three Kinds of People
- Holders. Your balance did not move; its label did. If the token is interest-bearing, the rate is on the mint and you can read it. If it is scaled, the multiplier and any scheduled change are on the mint too — including a future multiplier with the timestamp it takes effect, which is the closest thing Solana has to a pre-announced rebase.
- Traders. Price a position off
amountand the current multiplier or rate, never off a cached display amount. A quote built on a stale display is a quote for the wrong quantity. - Anyone doing tax or accounting. Every "balance changed" moment for these mints is a valuation change, not a transaction, and the archive-derived history you export will not show it. The raw amount and the extension config at each date are the only honest inputs.
How to Read the Mint Yourself
Fetch the mint account with parsed encoding. In its extensions you will find either the interest-bearing config — current rate, pre-update average rate, initialisation and last-update timestamps — or the scaled-UI config — current multiplier, new multiplier, and the effective timestamp of the new one. Those fields, plus your raw amount, produce your display balance at any moment you choose, on any machine.
If the parsed mint shows an extension the decoder cannot name, your reader is older than the mint; update it before trusting anything it displays.
Time-Varying Balances: Questions People Actually Ask
Why did my Solana token balance change without a transaction?
The mint is interest-bearing or uses a scaled UI amount. Your raw balance is unchanged; the displayed amount is computed from a rate or multiplier against the current time.
Why does uiAmount come back null for some Solana tokens?
The node refuses to give a floating-point value for mints whose display depends on time. Use amount (the raw integer) and uiAmountString (the server’s rendering) instead.
Can an interest-bearing token have a negative rate?
Yes. The rate is a signed 16-bit value, so the displayed balance of every holder can decline over time with no transfer or burn in anyone’s history.
Why does my portfolio tracker show the wrong balance for these tokens?
Archived history regenerates the display from the raw amount and decimals, and stores a null display as zero. Only a live node evaluating the extension against the clock returns the right number.
The One Habit That Avoids Every Error Above
Treat amount as the balance and everything else as presentation. The raw integer is what you own; the rate or multiplier is how the issuer has asked it to be shown today. Read both, compute the display when you need it, and never store the display as if it were a fact about the account.
— The Rate Is On the Mint —
Read the extension before you price the position.
The token audit reads a mint's extensions and authorities straight from the chain — including the interest rate or multiplier that decides what your displayed balance will be tomorrow, and whether it can go down.
Another Token-2022 capability hides the amount entirely rather than restating it — confidential transfers — and it has its own rules about what a reader can and cannot see.
RPC behaviour read from the Agave validator source at commit beee69b958: rpc/src/parsed_token_accounts.rs, account-decoder/src/parse_token_extension.rs and the archive's stored-token-amount type in storage-proto. Field names move between RPC versions — check the current docs before writing against them.