ERC-4626: The Tokenized Vault Standard, Explained

ERC-4626 is a standard interface for tokenized vaults: smart contracts that take a deposit of one ERC-20 token, issue “share” tokens that represent a claim on the pool, and let holders redeem those shares later for their portion of the underlying assets plus any yield earned. It was authored by Joey Santoro, t11s, Jet Jadeja, Alberto Cuesta Cañada, and Señor Doggo, created as EIP-4626 in December 2021, and now carries Final status.

The short version: a vault built to this standard is itself an ERC-20 token, it exposes the same set of functions no matter which protocol wrote it, and that sameness is the whole point. An integrator who can talk to one ERC-4626 vault can talk to all of them without writing a custom adapter each time.

This guide moves from the plain idea of a vault to the exact interface, the first-depositor attack that broke early implementations, how the standard is built in practice, and where it’s used today.

What Is a Tokenized Vault?

A tokenized vault is a contract that holds a pool of one asset and gives depositors a token in return for their share of the pool. Put money in, get shares; burn shares, get money back. The share balance is your receipt, and its value floats with the pool.

Two units do all the work here, and keeping them straight is most of the battle.

Assets vs. shares. The asset is the underlying ERC-20 the vault accepts and accounts in, such as USDC. A share is the vault’s own token, representing a fraction of everything the vault holds. The exchange rate between them is simply the pool’s total assets divided by the total shares outstanding.

Because a share is minted as a standard ERC-20 token, it inherits everything ERC-20 already does. Wallets can display it, it can be transferred or traded, and it can be used as collateral elsewhere, all without any vault-specific code. That inheritance is written into the standard: every ERC-4626 vault must implement ERC-20 to represent its shares.

The rate is what makes shares interesting. If a vault holds 1,000 USDC backing 1,000 shares, each share is worth one USDC. When the vault’s strategy earns yield and the pool grows to 1,100 USDC, those same 1,000 shares are now worth 1.1 USDC each. Nobody minted new shares; the existing ones just represent more.

Why Did Vaults Need a Shared Standard?

Before 2022, every yield protocol shipped its own vault interface, and that fragmentation was the problem the standard set out to kill. Yearn vaults, Aave’s aTokens, Compound’s cTokens, and the Maker DSR each exposed their own deposit and withdraw functions with their own quirks.

For a single protocol, that’s fine. For anything that wanted to sit on top of several of them, it was a tax. A dashboard, aggregator, or treasury tool had to write and maintain a separate adapter for each vault it touched, and every adapter was a fresh chance to get the accounting wrong.

The standard replaces all of those adapters with one. A wallet or an app that understands ERC-4626 can read any compliant vault’s share price, simulate a deposit, and pull funds out using the exact same calls, whether the vault lends into Aave, supplies a Morpho market, or buys tokenized treasuries underneath. Integration effort drops from “once per vault” to “once, ever.”

Who Actually Uses It?

The standard is the default for yield-bearing vaults across DeFi, used by protocols from Yearn to Aave to Morpho. It shows up anywhere a contract needs to represent “a share of a growing pool” in a way other contracts can read.

Typical users fall into a few groups:

  • Yield aggregators that route capital between strategies and hand depositors a single share token.
  • Lending protocols that wrap a supplied position as a transferable, yield-accruing token.
  • Structured-product and real-world-asset platforms that tokenize treasuries or credit and want standard plumbing.
  • Integrators (wallets, portfolio trackers, treasury tools) that read vault balances and prices without caring how the vault invests.

A few concrete examples show the range:

ProtocolHow it uses ERC-4626
Yearn v3Each vault is an ERC-4626 contract that delegates to multiple strategies, with an allocator rebalancing between them.
Morpho (MetaMorpho)Vaults are ERC-4626 wrappers that allocate deposits across isolated Morpho Blue lending markets.
Aave v3aTokens are exposed as ERC-4626-compatible representations of a supplied asset.
PendleUses the standard to represent yield-bearing positions that other contracts can plug into.

The common thread: a treasury holding USDC can call the same deposit function on a Yearn v3, Morpho, and Aave vault, and get back shares from each, because all three speak the one interface.

What’s Inside the Interface?

The standard defines sixteen functions and two events. They look like a lot at first, but they’re organized around four actions, each wrapped in a predictable set of helpers.

The four core actions move money in and out:

  • deposit — put in an exact amount of assets, receive shares.
  • mint — specify an exact number of shares to receive, pay whatever assets that costs.
  • withdraw — take out an exact amount of assets, burn whatever shares that costs.
  • redeem — burn an exact number of shares, receive whatever assets they’re worth.

Around each action sit three read-only helpers, which is where the design earns its keep:

Helper typeExamplePurpose
max…maxDepositThe ceiling a user can deposit or withdraw right now, accounting for any caps or pauses.
preview…previewRedeemA simulation of the exact result at the current block, including fees.
convertTo…convertToAssetsA rough, fee-free estimate of the exchange rate, meant for display.

Two more views round it out: asset returns the underlying token’s address, and totalAssets returns everything the vault currently manages. Every deposit or mint emits a Deposit event, and every withdraw or redeem emits a Withdraw event, so reading those events over the Ethereum API is enough to reconstruct a vault’s full flow of funds off-chain.

One detail in the spec matters more than it looks. Vaults are required to round in their own favor, not the user’s. When calculating shares to issue or assets to pay out, the vault rounds down; when calculating what a user must supply, it rounds up. That’s deliberate: a rounding error should cost a fraction of a wei to the pool’s benefit, never open a gap an attacker can widen.

Reading any of these values is a plain eth_call to the vault contract, so the data behind “what’s my position worth” is a single read request rather than a signed transaction. Running the node that serves those calls is the part most teams don’t build themselves. NOWNodes provides RPC access to Ethereum and 120+ other networks, so an app can query previewRedeem or watch Deposit events across chains without syncing and maintaining its own Ethereum client.

What Is the Inflation Attack, and How Do You Prevent It?

The inflation attack, also called the first-depositor or donation attack, is the best-documented way to lose money with a naive vault. It targets the moment a vault is empty and the exchange rate hasn’t been set yet.

The mechanism is nasty in its simplicity. An attacker deposits one wei of the asset and receives one share. They then donate a large amount of the asset directly to the vault contract, not through deposit, so no new shares are minted. Now the pool holds a large balance backing a single share. When a victim deposits a normal amount, the share math rounds their stake down to zero shares, and the attacker, holding the only share, can redeem the entire pool.

The fix that most implementations reach for comes from OpenZeppelin, whose ERC-4626 base contract has shipped a defense since version 4.9. It adds virtual shares and assets to the conversion math: the contract behaves as if a well-funded phantom depositor were always present, so one attacker can’t drag an empty vault to an extreme ratio. OpenZeppelin’s implementation adds one virtual asset and 10**offset virtual shares, where the offset is a _decimalsOffset() value the developer sets.

There’s a real trade-off, and it’s worth stating plainly. Virtual shares make the attack unprofitable rather than mathematically impossible, and the decimal offset defaults to zero, which offers no extra protection unless a developer overrides it. A larger offset makes the attack cost orders of magnitude more than it could ever return, so the recommended posture combines a non-zero offset with internal balance tracking and reverting on zero-share deposits. None of this is automatic; a vault that inherits the base contract and leaves the offset at its default is still relying on the weaker, virtual-shares-only protection.

The standard itself says integrators should review a vault’s implementation for ways to lose deposits before trusting it, since a contract can match the interface without honoring the spec. For any vault that will hold real funds, an independent smart-contract audit belongs on the checklist before launch, not after.

How Do You Build an ERC-4626 Vault?

Most teams don’t write the interface from scratch. They inherit a reference implementation and fill in the strategy, which keeps the fiddly accounting in audited hands.

The common path looks like this:

  1. Inherit a base contract. Extend OpenZeppelin’s ERC4626, which already implements the full interface, the ERC-20 share logic, and the inflation-attack defenses.
  2. Point it at an underlying asset. Pass the ERC-20 the vault will accept into the constructor.
  3. Override totalAssets. This is the one function your strategy must define, since only your contract knows where the deposited capital actually sits and what it’s currently worth.
  4. Set a decimal offset. Override _decimalsOffset() to a non-zero value to harden the empty-vault state against the inflation attack.
  5. Add the strategy. Wire in the logic that puts deposits to work, whether that’s lending, staking, or buying another asset.

OpenZeppelin isn’t the only option. The EIP’s own reference implementations include a minimal Solidity version in Solmate and a demo in Vyper, both useful for understanding the mechanics even if you ship on a different base. Whichever you pick, the goal is the same: write as little new accounting code as possible, because the accounting is exactly where vaults get exploited.

What Comes After ERC-4626?

The base standard is intentionally narrow. It covers a single underlying asset and assumes deposits and withdrawals settle instantly, which fits liquid on-chain assets but not everything. Two extensions pick up the slack.

ERC-7540 adds asynchronous deposit and redemption flows. It splits each action into a request and a later claim, which suits assets that can’t settle in one block, such as real-world-asset funds, private credit, or staking with an unbonding period. It extends ERC-4626 rather than replacing it, so a protocol already integrated with 4626 can adapt with minimal changes, and it’s in production: Centrifuge, which co-authored the extension, runs ERC-7540 vaults backing more than $1.6 billion in real-world-asset pools.

Those extra state transitions are also extra attack surface. As Jeroen Offerijns, Centrifuge’s CTO and an EIP-7540 co-author, put it, asynchronous flows demand “extensive testing of the flows, and auditing of any asynchronous vault implementation.”

ERC-7575 goes the other direction, extending the standard toward vaults with multiple underlying assets. Adoption is earlier than ERC-7540’s, but it points at where the vault pattern is heading as more complex products move on-chain.

Conclusion

ERC-4626 won by being boring in the right way. It doesn’t dictate how a vault earns yield; it only standardizes how deposits, shares, and withdrawals are expressed, so any wallet or contract can read any vault without bespoke code. That single interface is why a treasury can allocate across Yearn v3, Morpho, and Aave with the same three calls.

If you’re integrating vaults, the practical takeaways are short: shares are ERC-20 tokens, use preview functions for exact numbers and convert functions only for display, and never trust a vault’s compliance without reviewing its inflation-attack handling. If you’re building one, inherit an audited base, override totalAssets, and set a real decimal offset.

Either way, the work sits on top of reliable chain access. Reading share prices, simulating redemptions, and tracking vault events are all RPC calls, and NOWNodes provides that access across Ethereum and 120+ networks so teams can focus on the vault logic instead of node operations.

FAQ

Does ERC-4626 guarantee yield?

No. The standard defines how a vault accounts for shares and assets, not how it invests. Whether your shares gain value depends entirely on the strategy the vault runs; a compliant vault can lose money just as easily as it can earn it.

Why is ERC-4626 limited to one underlying asset?

The standard was scoped to a single ERC-20 per vault to keep the interface simple and composable, which is also why share pricing is a clean assets-divided-by-shares calculation. Vaults that need several underlying tokens use the ERC-7575 extension instead.

Are ERC-4626 vault shares transferable?

Usually, yes. Because shares are standard ERC-20 tokens, they can be sent, traded, or used as collateral by default. The standard does allow a vault to be non-transferable by reverting on transfer and transferFrom, but that’s a deliberate choice, not the norm.

What’s the difference between convertToAssets and previewRedeem?

convertToAssets returns a rough, fee-free estimate of what shares are worth and is meant for display; it can be implemented as a manipulation-resistant oracle. previewRedeem returns the exact amount you’d receive right now, including fees, and is accurate but manipulable by on-chain conditions, so it should not be used as a price oracle. They are not interchangeable.