Skip to main content

ERC-4626 Explained: The Tokenized Vault Standard

Learn ERC-4626 tokenized vault standard for yield-bearing assets. Complete guide covering implementation, benefits & DeFi integration.

Written by Eco

ERC-4626 is the Ethereum token standard for tokenized yield-bearing vaults. It defines a single API that any contract holding a productive ERC-20 asset can implement: deposit, mint, withdraw, redeem, plus the math functions that translate between assets and shares. Before EIP-4626 finalized in March 2022, every yield protocol shipped its own interface. Yearn vaults, Aave aTokens, Compound cTokens, and the Maker DSR each carried bespoke functions, and every integrator wrote a custom adapter for each one. The standard collapses that surface area into one Solidity interface, which is why most DeFi yield primitives shipped after 2023 implement it natively.

This article walks through what the standard specifies, why it exists, the full function-by-function interface with Solidity signatures, the live adoption picture across Morpho, Aave, Yearn V3, Sky, Pendle, and the tokenized treasury issuers, the inflation-attack pitfall and how to defend against it, the ERC-7540 and ERC-7575 extensions, and how to write a 4626 vault using the OpenZeppelin reference implementation.

What ERC-4626 Is

ERC-4626 is a tokenized vault standard defined by EIP-4626, authored by Joey Santoro, t11s, Jet Jadeja, Alberto Cuesta Cañada, and Señor Doggo. It was finalized on the Ethereum mainnet specification on March 2, 2022. The standard inherits from ERC-20. A vault contract is itself a fungible token whose units, called shares, represent proportional ownership of an underlying ERC-20 asset.

The mental model is a mutual-fund share class onchain. A user deposits 1,000 USDC into an ERC-4626 vault. The vault mints them 985 shares (assuming an existing share price reflecting accrued yield). The vault then puts the USDC to work, lending it into Aave, supplying it to a Morpho market, or buying tokenized T-bills, depending on the strategy. Yield accrues into the vault's totalAssets balance. The shares stay outstanding, but the asset-per-share ratio rises. When the user redeems, they get back more USDC than they deposited.

Because shares are themselves an ERC-20, they can be transferred, used as collateral, traded on a DEX, or wrapped into another vault. This composability is the standard's most consequential property. A yield position becomes a liquid, programmable token that other contracts can integrate without knowing anything about the underlying strategy.

Why ERC-4626 Exists

Pre-2022, DeFi had no shared abstraction for "deposit a token, get a yield-bearing receipt." Every protocol invented its own. Yearn V2 vaults exposed deposit and withdraw with their own decimals quirks. Aave used aTokens, which were rebasing receipt tokens that increased in balance over time. Compound used cTokens, which were non-rebasing receipts with a moving exchangeRateStored. Maker's DAI Savings Rate used a chi accumulator. Lido wrapped stETH inside wstETH. None of these were interoperable at the interface level.

The integration cost was real. A treasury app that wanted to allocate idle USDC across five protocols had to write five adapters, audit five integration paths, and re-audit each one when a protocol pushed an upgrade. The same problem hit aggregators, vault-of-vaults strategies, leveraged-yield protocols, and any frontend that wanted to display a unified portfolio view. Fei Protocol's engineers, frustrated with this fragmentation, drove the original EIP draft.

EIP-4626 fixed it by standardizing four operations (deposit, mint, withdraw, redeem), four limit functions (maxDeposit, maxMint, maxWithdraw, maxRedeem), four preview functions (previewDeposit, previewMint, previewWithdraw, previewRedeem), and two conversion functions (convertToShares, convertToAssets). Any contract implementing these eight-plus-eight functions plus the underlying asset() getter and totalAssets() reporter is 4626-compliant. An integrator writes one adapter and points it at any compliant vault.

The savings compound across the ecosystem. Take a yield aggregator like Yearn V3. With pre-4626 protocols, integrating a new lending market meant writing custom logic for that market's deposit semantics, custom logic for its receipt token, custom logic for redemption, plus a fresh audit. Adding the same market under 4626 takes a connector contract that implements the standard interface, sometimes under 200 lines of Solidity. Audit firms charge by complexity, so the cost difference can run from $80,000 to $200,000 per integration.

The Full Interface

The standard defines the following Solidity interface. Every compliant vault must implement each function with the exact signatures below. Code examples come from the OpenZeppelin ERC4626.sol reference implementation.

Asset and accounting view functions

  • function asset() external view returns (address) returns the underlying ERC-20 the vault accepts. Immutable for the vault's lifetime.

  • function totalAssets() external view returns (uint256) returns the total amount of underlying held or accounted for by the vault, including accrued but uncompounded yield. This is the numerator in the share-price calculation.

  • function convertToShares(uint256 assets) external view returns (uint256 shares) is pure math, with no slippage or fees applied. Used by frontends and integrators to estimate share quantities.

  • function convertToAssets(uint256 shares) external view returns (uint256 assets) is the inverse of convertToShares.

Deposit and mint (entry)

  • function deposit(uint256 assets, address receiver) external returns (uint256 shares). The caller specifies the asset amount, and the vault calculates and mints the corresponding shares to receiver. This is the most common entry point.

  • function mint(uint256 shares, address receiver) external returns (uint256 assets). The caller specifies the desired share quantity, and the vault calculates and pulls the required assets. Useful when targeting a precise share balance.

  • function maxDeposit(address receiver) external view returns (uint256 maxAssets) returns the maximum assets receiver can deposit in a single call. Returns type(uint256).max for unbounded vaults, and 0 for paused or capped vaults.

  • function maxMint(address receiver) external view returns (uint256 maxShares) is the equivalent for mint.

  • function previewDeposit(uint256 assets) external view returns (uint256 shares) returns the exact shares the caller will receive at the current block, accounting for fees. Output must equal what deposit() returns at the same block.

  • function previewMint(uint256 shares) external view returns (uint256 assets) returns the exact assets required at the current block.

Withdraw and redeem (exit)

  • function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares). Caller (or approved spender) burns shares from owner to send assets to receiver. Specifies the asset amount, and the vault calculates the shares burned.

  • function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets) is the equivalent specifying shares.

  • function maxWithdraw(address owner) external view returns (uint256 maxAssets) is bounded by share balance and any vault-level liquidity constraints.

  • function maxRedeem(address owner) external view returns (uint256 maxShares) is the same.

  • function previewWithdraw(uint256 assets) external view returns (uint256 shares) returns the exact shares burned.

  • function previewRedeem(uint256 shares) external view returns (uint256 assets) returns the exact assets received.

The standard also requires Deposit and Withdraw events with specific signatures, plus inheritance of all standard ERC-20 functions and events. Vaults inherit decimals from the underlying asset by default, though OpenZeppelin's reference adds an offset (discussed under inflation attacks below) to defend the share price at low totalSupply.

One subtle requirement: the preview functions must return values that match what the corresponding state-changing function would actually produce in the same block. This sounds obvious, but it forces vault authors to be careful with fee calculations and rounding. The standard explicitly prefers integrator deterministic behavior over optimistic estimates.

The Standard Through One Worked Example

Walk a concrete sequence through a USDC vault running a fixed 5% APY strategy.

Block 0. Vault deployed empty. asset() returns USDC (6 decimals). totalAssets() returns 0. totalSupply() returns 0.

Block 1. Alice calls deposit(1_000_000_000, alice), which is 1,000 USDC. The vault mints her 1,000_000_000 shares (the OpenZeppelin reference uses a virtual-shares offset, so she actually receives slightly fewer; assume 1:1 for illustration). totalAssets() returns 1,000 USDC. totalSupply() returns 1,000 shares.

Block 1,000,000 (roughly six months later at 12-second blocks). The strategy has earned 25 USDC. totalAssets() returns 1,025 USDC. totalSupply() is unchanged at 1,000 shares. The share price (convertToAssets(1)) is now 1.025 USDC per share.

Block 1,000,001. Bob deposits 1,000 USDC. previewDeposit(1_000_000_000) returns 1,000 / 1.025 = 975.61 shares. The vault mints him 975 shares. totalAssets() returns 2,025 USDC, and totalSupply() returns 1,975 shares.

Block 2,000,000. Alice redeems all 1,000 shares. previewRedeem(1_000) returns 1,000 / 1,975 × totalAssets(). With more accrued yield (say totalAssets returns 2,075 USDC), Alice gets 1,050.63 USDC, her original 1,000 plus a year of yield.

The accounting is symmetric and pure-pull. Shares represent claims on totalAssets, and totalAssets accrues in the background. No rebasing, no balance changes between blocks for the same shareholder.

Adoption Across DeFi

Most DeFi yield primitives shipped after 2023 implement ERC-4626 natively, and several earlier protocols added it through wrappers.

Morpho.Morpho Vaults are 4626-compliant by design. Each vault is a curator-managed allocation across underlying Morpho Blue markets. As of April 2026, Morpho's vault TVL sits around $4 billion, distributed across roughly 200 active vaults curated by Steakhouse Financial, Gauntlet, MEV Capital, and Re7 Labs, among others. The Steakhouse USDC vault alone holds north of $400M.

Yearn V3.Yearn V3, released in November 2023, made every vault 4626-compliant. V3 vaults aggregate "strategies" (themselves 4626-compliant sub-vaults) into a parent allocator. Yearn V3 TVL sits in the $300 to $500M range across the curve-stable, ETH-yield, and stablecoin verticals.

Aave V3 atokens. Aave atokens are rebasing tokens, which are not 4626-compatible at the interface level. The Aave-Stata wrapper (Static aToken) wraps an aToken into a 4626-compliant non-rebasing share token. Static aToken docs describe the wrapper. Integrations using it include Yearn V3 strategies and several Morpho vaults.

Sky (formerly Maker). The Sky Savings Rate's sUSDS is a 4626-compliant wrapper around USDS earning the SSR. As of April 2026, sUSDS holds roughly $2.4B in USDS deposits at a 6.5% yield. The MakerDAO PSM-vault contracts also expose 4626 interfaces for integrators routing into the Dai Savings Rate.

Lido. Lido's stETH rebases. The wstETH wrapper, which has existed since 2020, predates 4626 but exposes equivalent semantics. A community 4626 wrapper for wstETH ships through several aggregators.

Pendle. Pendle's principal tokens (PT) and standardized yield tokens (SY) are not 4626 themselves, but Pendle accepts 4626 vaults as input assets. Any compliant vault can be split into yield and principal components.

Spark. Spark Lend's sDAI was the first widely adopted 4626 wrapper for Maker's Dai Savings Rate. At its peak in early 2024, sDAI held over $2B in TVL. After Maker's transition to Sky, the equivalent has shifted to sUSDS.

Origin Dollar (OUSD). Origin's wOETH is the 4626-compliant non-rebasing wrapper for OETH (Origin Ether), holding around $80M.

Tokenized treasury bills. The RWA category is where 4626 has become near-universal because integrators absolutely need a unified API. Ondo's USDY exposes a 4626 interface. Backed Finance's bIB01 and Centrifuge's RWA pools both ship 4626 wrappers. Ethena's sUSDe is 4626-compliant. Tracking from RWA.xyz shows tokenized treasury TVL exceeded $12 billion in early 2026 per RWA.xyz, and the bulk of that supply is wrapped or natively exposed via 4626.

Aggregate. A DefiLlama yield-protocol count puts the total addressable 4626 surface, across lending markets, vaults, RWA, and yield wrappers, at roughly $25B in TVL as of April 2026, up from under $1B at the standard's finalization three years earlier.

ERC-4626 and Tokenized Real-World Assets

RWA issuers have converged on 4626 faster than almost any other category, and the reason is integrator demand. A treasury team at a corporation or a DAO is not going to write a custom adapter for every yield product they evaluate. They want one interface that lets them swap between Ondo, Backed, Mountain Protocol's USDM, Hashnote's USYC, and a dozen other tokenized-treasury issuers without rewriting their allocator. The 4626 interface is what makes that swappable.

It also matters for compliance reasons. A 4626 vault can implement maxDeposit and maxMint to encode KYC gating: if msg.sender is not on the issuer's whitelist, return 0. Ondo's USDY wrapper does this. The standard does not impose any KYC. It just gives issuers a clean place to enforce it without breaking the integrator API.

A second RWA-specific consideration is settlement latency. A tokenized T-bill issuer cannot redeem instantly, because the underlying T-bill has T+2 settlement. The base 4626 spec assumes synchronous redemptions, which does not fit. That gap is what motivated ERC-7540 (covered below).

The institutional flow into onchain treasuries depends on this interface stability. BlackRock's BUIDL, when it launched in 2024, did not initially implement 4626, which forced BlackRock partners like Securitize to write custom integration code. The 2025 wave of issuers, including Franklin Templeton's BENJI variants and Apollo's diversified credit fund tokens, all shipped with 4626 native or 7540 native exposure. At this point, an issuer launching a tokenized fund without 4626 conformance loses access to most DeFi distribution channels by default.

The Inflation Attack and How Vaults Defend Against It

The most discussed pitfall in ERC-4626 is the inflation attack, sometimes called the donation attack or first-depositor attack. The attack works against the share-pricing math at low totalSupply.

The mechanic: an attacker is the first depositor into a fresh vault. They deposit 1 wei of the underlying asset and receive 1 share. They then directly transfer (not deposit, bypassing the share-mint logic) a large amount of the underlying asset into the vault. totalAssets() now reads, say, 10,000 USDC, while totalSupply remains at 1 share. A subsequent victim depositor deposits 5,000 USDC, expecting roughly half ownership. The share-mint formula (assets × totalSupply / totalAssets) gives them 5,000 × 1 / 10,000 = 0 shares, rounded down. The attacker still holds the only share, now backed by 15,000 USDC, and can redeem the entire balance.

The defense most vaults adopted comes from OpenZeppelin's reference implementation: a virtual-shares offset. The vault internally treats totalSupply as if it has 10^decimalsOffset extra shares (typically 10^6, set per-vault). When a real user deposits, the share calculation accounts for these virtual shares, which dilutes any donation-attack profit to a level where it costs the attacker more to mount than they can extract. The offset is configurable. Morpho uses a per-market offset tuned to the asset's decimals, and Yearn V3 inherits OpenZeppelin's default.

An alternative defense is a "dead share" pattern: the deployer's first deposit transaction mints a tiny share quantity to the zero address, locking permanent value into the vault. Aave's Stata wrapper uses a variation. Both approaches accomplish the same thing. They make it economically irrational to attempt the inflation attack.

The attack mattered enough that it is now the first audit-checklist item for any 4626 vault. OpenZeppelin's writeup walks the math in detail. Trail of Bits and Spearbit have both published 4626-specific audit checklists that lead with this attack class. Real-world incidents include a 2023 exploit on a smaller Sherlock-style vault that lost roughly $200,000 to first-depositor manipulation, plus several near-misses caught in pre-deployment audit on protocols including Sommelier and Idle Finance.

Other Common Pitfalls

Beyond the inflation attack, three other pitfalls show up regularly in 4626 audit reports.

Rounding direction errors. Every conversion function has a rounding direction baked in, and it must always favor the vault rather than the user. previewDeposit rounds shares down. previewWithdraw rounds shares up. Get the direction backwards, and a sophisticated user can extract value by repeatedly depositing and redeeming dust amounts. OpenZeppelin's library encodes the correct directions in its Math.Rounding enum, but custom implementations sometimes get this wrong.

Strategy-loss accounting. If the vault's underlying strategy loses money (a lending market default, an oracle exploit downstream, or an LST slashing event), totalAssets() must reflect the loss promptly. Vaults that lazy-evaluate or only recognize losses on user redemption create arbitrage windows where informed users redeem before the loss is booked. Morpho's vault accounting handles this through curator role functions that mark down totalAssets when a market they allocate to becomes bad debt.

Reentrancy on non-standard ERC-20s. USDT, for example, has non-standard transfer semantics: it does not return a bool on success, which trips up implementations that check for return values. Other tokens (PAXG, fee-on-transfer tokens) deduct fees in transfer, breaking the totalAssets accounting. The standard does not preclude such tokens, but vaults integrating them must explicitly handle the quirks. The weird-erc20 catalog lists every documented edge case.

Extensions: ERC-7540 and ERC-7575

Two material extensions to 4626 have shipped or are in late draft.

ERC-7540: asynchronous vaults. Finalized in March 2024, ERC-7540 extends 4626 to support deposits and redemptions that do not settle in the same transaction. Two new flows: requestDeposit and requestRedeem. The user calls requestDeposit, the vault registers a pending request, and at some later block (after off-chain settlement, oracle update, or governance approval), the vault fulfills it. This is the interface tokenized-treasury issuers and credit funds needed. Centrifuge implemented 7540 across its RWA pools in mid-2024. Ondo and Backed have shipped 7540-compliant variants for institutional pools. Pendle uses 7540 to support PT/YT splitting on slow-settling underlying.

ERC-7575: multi-asset vaults.ERC-7575, in late draft as of early 2026, addresses LP-position vaults where the vault holds two or more underlying tokens (for example, a Uniswap V3 LP position). The standard externalizes the share-token contract from the vault contract, allowing one share to represent claims on multiple underlying assets. Use cases include LST-LRT bundles, Uniswap V4 hook positions, and basis-trade vaults that hold both spot and a perpetual position.

Several variants in the wild, including vault-with-hooks patterns from Morpho Blue and Euler V2, extend 4626 with custom modifier hooks (pre-deposit, post-redeem) but stay nominally 4626-compliant at the interface level. Integrators that only call standard functions do not need to know about the hooks.

A draft ERC-7535 covers native-ETH 4626 vaults, where the underlying asset is ETH itself rather than an ERC-20. Without 7535, native-ETH vaults must wrap ETH to WETH for the asset() return value, which adds friction and gas. Adoption of 7535 has been slower because most production vaults already accept WETH and the wrap step is well-tooled.

Writing a 4626-Compliant Vault

The path of least resistance is OpenZeppelin's reference. Inherit ERC4626.sol, pass the underlying asset to the constructor, and override the strategy logic. A minimal vault looks like:

contract MyVault is ERC4626 {
constructor(IERC20 asset_) ERC4626(asset_) ERC20("My Vault", "mv") {}
function totalAssets() public view override returns (uint256) {
return asset.balanceOf(address(this)) + _strategyAssets();
}
}

The deposit/mint/withdraw/redeem implementations come for free from the parent. The integrator overrides totalAssets() to include any assets deployed in external strategies (lent, supplied, staked) and optionally overrides _deposit and _withdraw hooks to push capital into and pull it out of those strategies on each user action.

Audit considerations specific to 4626 vaults: rounding direction (always round in the vault's favor, toward 0 on deposit-out, toward share-down on withdraw), reentrancy on the underlying token (some tokens like USDT have non-standard transfer behavior), strategy-loss handling (totalAssets must reflect realized losses), and the inflation-attack defense. Cyfrin's 4626 property test suite is the closest thing to a standard fuzzing battery for compliance verification.

Gas costs vary. A bare ERC4626.sol deposit-redeem cycle costs roughly 130k to 180k gas without strategy. Add 80k to 200k for a single external Aave/Compound/Morpho interaction. Vault-of-vaults patterns can balloon past 500k per call. On L2 deployments (Arbitrum, Base, Optimism), the absolute cost is much lower, but the relative ratio between bare and integrated vaults stays the same.

Solady, the gas-optimized library by Vectorized, ships an alternative ERC-4626 implementation that shaves roughly 5,000 to 8,000 gas per call versus OpenZeppelin's reference, primarily through tighter assembly in the conversion math. Production deployments often pick OpenZeppelin for audit familiarity and Solady for high-throughput vaults where gas costs hit user economics.

Stablecoin Yield Built on ERC-4626

The largest practical use of 4626 today is stablecoin yield. Sky's sUSDS, Spark's sDAI before the Sky transition, Morpho's USDC vaults, Yearn's stable-only V3 vaults, and Ethena's sUSDe collectively account for the bulk of the standard's TVL. Tokenized treasury wrappers (sUSDY, wUSDM) fold institutional yield into the same interface.

This concentration is not random. Stablecoins are the asset class where users are most yield-sensitive (because the upside is bounded by APY rather than price appreciation) and where the integrator surface is broadest (every wallet, payroll provider, treasury app, and fintech wants to plug stablecoin yield in). The 4626 interface is the connective tissue that lets a USDC depositor on one frontend earn yield generated by a curator on a Morpho market while a different frontend lists the same vault as an option for their users.

For a deeper read on which stablecoin yield products use 4626 and how they compare on yield, custody, and risk, see Eco's coverage of stablecoin yield strategies and the stablecoin landscape on Coinbase.

Eco's Role

For users routing into a 4626-compliant yield vault from a different chain, Eco Routes lets users deposit USDC from any chain into a vault on the home chain in a single transaction. The flow combines Eco's cross-chain intent settlement with a direct call into deposit() on the destination vault, so the user never holds USDC on the target chain. They receive vault shares directly. That keeps integrations with Morpho, sUSDS, sUSDe, and tokenized-treasury issuers chain-agnostic from the user's perspective. Eco handles the routing, and the vault contract itself is unchanged.

FAQ

What is ERC-4626 in plain terms?

ERC-4626 is the Ethereum standard for tokenized yield-bearing vaults. It defines a uniform Solidity interface (deposit, mint, withdraw, redeem, plus accounting functions) so any contract holding a productive ERC-20 asset exposes the same API. Integrators write one adapter and point it at any compliant vault.

What's the difference between deposit and mint in ERC-4626?

Deposit takes an asset amount and computes the shares minted. Mint takes a target share quantity and computes the assets pulled. Most users call deposit because they are thinking in dollar amounts. Aggregators and contract callers often use mint to land on a precise share balance for downstream accounting.

Why does ERC-4626 matter for tokenized treasury bills?

Tokenized treasury issuers like Ondo, Backed, Mountain, and Hashnote ship 4626 wrappers because integrators (treasury teams, allocators, DeFi protocols) need a unified API to swap between issuers. Without 4626, every issuer would force its own custom integration. With 4626, an allocator can rebalance across issuers without contract changes.

What is the inflation attack on ERC-4626 vaults?

The inflation attack lets the first depositor into a fresh vault donate underlying assets directly to the contract, inflating totalAssets while totalSupply stays at one share. A second depositor's share calculation rounds down to zero, and the attacker keeps the deposited value. OpenZeppelin's virtual-shares offset and "dead share" patterns are the standard defenses.

What does ERC-7540 add to ERC-4626?

ERC-7540 extends 4626 with asynchronous flows (requestDeposit and requestRedeem) for vaults that cannot settle synchronously. Tokenized treasuries, credit funds, and any RWA position with off-chain settlement use 7540. Centrifuge, Ondo's institutional pools, and several Pendle integrations have shipped 7540-compliant variants since 2024.

Can ERC-4626 vault shares be used as collateral?

Yes. Because shares are themselves ERC-20 tokens, lending markets like Morpho, Euler V2, and Aave V3 can list them as collateral assets. A user can deposit USDC into a Morpho vault, receive vault shares, and borrow against those shares, earning yield on the deposit while taking out a loan against it.

How much TVL is held in ERC-4626 vaults today?

Aggregate TVL across 4626-compliant vaults (Morpho, Yearn V3, Sky, Spark, Pendle, Ethena, Origin, plus tokenized-treasury wrappers) sits around $25 billion as of April 2026. Three years after the standard finalized in March 2022, it has become the default interface for new yield primitives.

Did this answer your question?