ERC-4626 shares are units of a vault token; assets are units of the underlying ERC-20 token the vault manages. Their conversion can change without your share balance changing. Use the preview for the operation you intend, check the owner's current limit, and reconcile the confirmed asset transfer separately from the accounting estimate.
Name both tokens before reading a balance
An ERC-4626 vault exposes a common interface for shares backed by one underlying ERC-20 asset. Its asset() method identifies that underlying token. A wallet's balance of the vault token counts shares; it does not directly count underlying tokens. The Ethereum developer guide introduces these two sides of the interface.
Keep three quantities separate in a worksheet: your shares, the vault's total share supply, and its reported managed assets. None is a dollar valuation. An accounting conversion can increase because assets increase, because supply decreases, or because the implementation changes how it values its holdings. The cause needs its own evidence.
Amounts returned by contracts are integers in the relevant token's base units. Read the asset and share decimals separately before formatting either number. The ERC-20 decimals and amount guide explains that display step; a readable wallet balance is unsuitable as an unscaled contract argument.
If a wallet displays an indexed lending balance or a liquidity position identifier, identify that instrument before applying these calls. The lending receipt-token guide covers indexed balances, while LP tokens versus position NFTs explains why one NFT does not mean one interchangeable share.
Choose what stays fixed in the operation
The four operations come in pairs. deposit and withdraw fix an asset quantity. mint and redeem fix a share quantity. Use the matching preview rather than reversing a rounded result from another method. The official method reference describes what each operation supplies and returns.
| Operation | Quantity you specify | Preview returns |
|---|---|---|
deposit | Assets paid into the vault | Shares expected from previewDeposit |
mint | Shares to receive | Assets required by previewMint |
withdraw | Assets to receive | Shares required by previewWithdraw |
redeem | Shares to burn | Assets expected from previewRedeem |
An accounting conversion serves a different purpose. convertToAssets and convertToShares omit operation-specific fees and round down. Previews include the applicable entry or exit fees, but ignore the corresponding user and vault limits. These distinctions are specified in ERC-4626's conversion and preview rules.
For example, an application asking how many shares it needs to deliver seven assets should request previewWithdraw(7). Taking convertToShares(7) and treating it as the withdrawal cost can understate the shares required, even in a vault without fees.
Follow a donation through an exact ledger
This hypothetical example uses the default conversion logic of OpenZeppelin Contracts v5.4.0, with decimal offset zero. It assumes an ordinary underlying token, no fees, sufficient balances and approvals, and no activity between the stated steps. All figures are deliberately small integer base units. For an asset with six decimals, the opening 999 units would display as 0.000999 tokens. These are teaching inputs, not live quotes or dollar values.
Call reported assets A and outstanding shares S. In the pinned v5.4.0 implementation, the conversion includes one virtual asset unit and, at offset zero, one virtual share unit. The factor is (A + 1) / (S + 1) asset base units per share base unit. Its default totalAssets() reads the underlying token balance held by the vault.
In that implementation, deposits round the issued shares down and redemptions round the returned assets down. Minting rounds the required assets up; withdrawals round the required shares up. Those input amounts must be sufficient to deliver the specified output.
Those virtual units are calculation terms. They do not add a spendable token to the vault or mint another share into a wallet. Do not add them to an asset-transfer or total-supply reconciliation.
Alice begins with 40 share base units. Bob begins with none. Other holders own the rest of the supply. A third party then transfers 200 underlying units directly to the vault without calling deposit or receiving shares. Every quantity in the following table is in base units.
| Completed step | Assets A | Shares S | Alice's shares | Bob's shares |
|---|---|---|---|---|
| Opening snapshot | 999 | 799 | 40 | 0 |
| Direct donation of 200 | 1,199 | 799 | 40 | 0 |
| Bob deposits 5 | 1,204 | 802 | 40 | 3 |
| Alice withdraws 7 | 1,197 | 797 | 35 | 3 |
The donation changes the conversion
At the opening snapshot, Alice's conversion is 40 × 1,000 / 800 = 50 asset units. After the donation it is 40 × 1,200 / 800 = 60. Her share count stays at 40 throughout that step.
The ten-unit increase is backed by an external transfer in this example. Calling it strategy earnings would invent a source of growth. The same ending conversion could arise through another mechanism, but that would require different transaction and accounting evidence.
The donation affects this ledger because its selected totalAssets() includes the transferred balance. A vault with different managed-asset accounting needs its own check. The standard leaves allocation and accounting details to implementations; a direct transfer should not be assumed to affect every vault identically.
Bob's deposit rounds the issued shares down
Immediately after the donation, five asset units correspond to 5 × 800 / 1,200, or approximately 3.333333 share units. Rounding down discards the fractional base unit and issues three shares. Assets increase by five and supply increases by three.
The next calculation uses the new totals: A is 1,204 and S is 802. Bob's three shares now redeem for the rounded-down value of 3 × 1,205 / 803, which is four asset units. His five-unit contribution and four-unit redemption quote differ because this tiny example rounds both steps. No fee was charged.
Do not repair the ledger by recording 3.333333 shares as if they were minted. Record three actual base units and preserve the five-unit asset contribution. Display precision cannot restore a fractional base unit the contract never issued.
Alice's withdrawal rounds the required shares up
Before Alice withdraws, the exact calculation for seven assets is 7 × 803 / 1,205, approximately 4.664730 shares. The accounting convertToShares(7) rounds down to four. The operation-specific previewWithdraw(7) rounds up to five under the selected implementation.
The difference has a practical consequence: redeeming four shares at this state produces only six asset units after rounding down. Four shares therefore cannot be substituted for the cost of withdrawing exactly seven assets. Alice's successful withdrawal burns five shares and transfers seven underlying units to her.
The vault reconciliation closes at 999 + 200 + 5 − 7 = 1,197 assets and 799 + 3 − 5 = 797 shares. Alice has 35 shares remaining, and Bob has three. Their remaining balances need a fresh conversion using that final state; the rate before the withdrawal belongs to the earlier snapshot.
Understand what a preview leaves unresolved
In this fee-free example, convertToAssets and previewRedeem agree for the same input and state. A customized exit fee can make the redemption preview lower. OpenZeppelin's fee-customization guide shows why each preview needs its own fee treatment. Explain any gap between a conversion and a preview before using it to adjust a ledger.
Limits require a separate read. In a vault that temporarily disables redemption, maxRedeem(owner) must reflect that restriction, while a redemption preview ignores that limit. A positive preview alone does not establish that the owner can exit. Check maxWithdraw(owner) for an asset-sized withdrawal or maxRedeem(owner) for a share-sized redemption, as required by the standard's limit methods.
For a successful base ERC-4626 operation under the previewed conditions, redemption pays at least its preview and withdrawal burns no more shares than its preview. The v5.4.0 interface documentation specifies these same-transaction bounds. An intervening state change can invalidate the comparison even within a composed transaction. A read made earlier also does not lock a later transaction's state. Another deposit, donation, realized loss or fee change can alter the result before execution. Save both state references.
Also inspect the actual caller, owner, recipient and necessary token approvals. A limit read does not supply authorization for another address to spend the owner's shares. Where an integration offers minimum-output or maximum-input checks, verify that the transaction actually enforces the intended bound.
Build an exit record you can reproduce
For one observation, keep balances and conversion calls on the same state reference. Record a block hash where available, rather than combining several unrelated latest-state reads. The state root versus receipts root guide explains why a balance snapshot and a transaction receipt provide different evidence.
Use the following worksheet for an asset-sized withdrawal. For a share-sized redemption, replace its preview and limit with the corresponding redemption methods.
| Record | Validation question |
|---|---|
| Chain, vault, implementation and asset | Are these the intended contracts and version? |
| Raw balance, raw supply and both decimals | Are shares and assets kept in separate units? |
State reference and totalAssets | Do all reads describe the same state and accounting basis? |
convertToAssets for the held shares | What accounting estimate is being displayed? |
previewWithdraw and maxWithdraw | What share cost and owner limit apply to the intended size? |
| Confirmed burn and recipient transfer | What actually left the account and reached the recipient? |
Test the smallest relevant input as well as the intended size. OpenZeppelin's rounding and donation discussion explains how deposits can round to zero shares and how donated assets can worsen that exposure. Its virtual-offset design addresses that mechanism, but a familiar standard name still requires inspecting the deployed implementation and its overrides.
Classify a deposit, a direct donation and an exit as separate flows. Keep network costs in their own denomination. If a quote differs from a receipt, compare the state, fees, rounding and operation before adding a balancing entry.
For Alice's seven-unit withdrawal, the useful record is five shares burned, seven underlying units received, 35 shares remaining, and the state used for each calculation. Keep those four fields together whenever a dashboard turns a share balance into an asset amount.
