How the ERC-4626 tokenized vault standard works: share accounting, rounding rules, the inflation attack, and how yield strategies are built on top of a vault.

ERC-4626 is an Ethereum token standard which defines a single-asset vault with ERC-20 shares. The vault enables depositing assets, generating proportional shares, and withdrawing the underlying assets plus generated yield. Before ERC-4626 was finalized in early 2022, every lending pool, yield aggregator, and liquidity provider had its own interface for depositing and withdrawing assets. Every integrator had to write adapters for each supported protocol.
The interface does not constrain how a vault will charge fees, how strategies will be executed, or how access to a vault will be controlled. Instead, the ERC-4626 standard provides a rigorous accounting system, fully documented "preview" functions, and rounding discipline to safely manage the vault's money. Subsequent sections elaborate on the required accounting, highlight the well-documented "inflation attack" and how it is contained, and walk through designing particular yield strategies and production-time safety measures on top of a conforming ERC-4626 tokenized vault standard implementation.
Before March 2022, you had to write a custom adapter for every single protocol to integrate their yield vaults. Each of them had their own deposit functions, share math, and even more quirks.
These various deposit interfaces, coupled with differing tokenized vault share pricing logic and idiosyncrasies, required integrators to audit and maintain adapter code for each individual protocol that was to be added to a vault.
This EIP was co-authored by engineers who had encountered tokenized vault fragmentation in the space, which needed to be solved for DeFi composability to work.
ERC-4626 defines a fixed set of functions (e.g. deposit, mint, withdraw, redeem etc.) with a fixed ABI and allows for varying fees, strategies and levels of access control to be implemented by the author of the vault. The result is that DeFi composability is actually made possible, and a single standard-aware aggregator can add support for dozens of vaults with relatively little bespoke work. The full function list is in the EIP-4626 specification, with an overview in the ethereum.org ERC-4626 documentation.
All four core functions of the standard (deposit, mint, withdraw, redeem) compute the vault exchange rate from the same pair of values: totalAssets and totalSupply.

deposit(assets, receiver) allows us to fix the amount of assets to deposit and receive the exact amount of shares. mint(shares, receiver) is the inverse, fixing the amount of shares to mint and calculating the required amount of assets. We can use these functions when a specific value needs to be fixed on the caller's side of the contract.
The ERC-4626 share price is simply totalAssets() / totalSupply(). This price naturally moves as the total yield accrued on assets increases, and the supply of shares remains constant. Thus, convertToShares and convertToAssets functions automatically decrease and increase in value, respectively, as the share price rises without the need for rebases.
Preview functions take into account the respective fees and EIP-defined rounding behavior (e.g. deposits get shares rounded down, and withdrawals get the shares burned rounded up, to the vault's benefit). The functions should be used by callers to validate the resulting execution output, with the caveat that for fee-on-transfer assets the preview cannot be exact.
Yield in DeFi comes from many places, so architects can pick from several DeFi vault yield strategy patterns. This relates to the risk and complexity of operation that the architect is willing to take on.
A simple vault that 100% deposits assets into an Aave market is a single integration path that has minimal states to switch through and easy audit cases. The main tradeoff is concentrated protocol risk and no rebalancing when the market rate compresses or hits a supply cap.
The yield from multiple strategies is aggregated within a vault, an allocator on top of multiple ERC-4626 compliant strategy contracts that can all be hot swapped without depositors having to move funds. The Morpho implementation, for example, has a multi-strategy vault where governance is split from the curator of each market, who can set individual supply caps for idle liquidity.
An RWA tokenized vault would need off-chain yields to be reported to totalAssets() by a trusted reporter or price oracle. This introduces a trust assumption that on-chain strategies could avoid entirely. Staleness checks and manipulation guards on the off-chain report would need to be implemented before going into production.
Three mistake scenarios causing significant loss in production are outlined below for share-price logic errors.
First, an attacker makes the first deposit of 1 wei into a new vault. Then the attacker donates a large amount of assets to the contract. Due to the high exchange rate, a victim who then deposits assets to the vault will receive 0 shares (due to rounding down), and all their assets will be transferred to the attacker.
This kind of attack on OpenZeppelin's ERC4626 implementation would have a cost that's proportional to the constant offset added to totalSupply and totalAssets in order to mitigate share price manipulation. Thus, the attack would be too expensive as long as the donation amount is reasonable. The reasoning is documented in OpenZeppelin's analysis of exchange rate manipulation in ERC-4626 vaults.
A fee-on-transfer token means the vault receives less than the nominal deposit amount; if shares are minted against the nominal amount, totalAssets() is over-counted and the exchange rate is corrupted. A rebasing token (such as stETH) vault requires a custom totalAssets() method that can read the current rebasing balance and return the correct value.
We start every vault architecture by asking one question: should we extend an existing architecture or start from scratch? The answer to this question is largely determined by the fee model and access model of the vault.
The OpenZeppelin ERC4626 implementation already has virtual share inflation mitigation 'baked in' so it's the safest starting point for most teams to build on. You'd only want to implement a custom ERC-4626 if totalAssets() is called in a hot loop and you're hitting high gas costs, or the underlying asset is somehow non-standard and requires custom accounting pathways.
OpenZeppelin's implementation of the standard leaves access control to be implemented on top by RWA teams and other institutional teams. A permissioned vault would for example then implement a restriction on maxDeposit and maxMint for non-approved addresses in a vault's contracts. This can be done by layering on top of the standard implementation an ERC-3643 compliance module that checks KYC status of all incoming transfers.
Vaults' fee architectures usually grant the vaults' fee recipient upon every interaction the minting of new shares for them. This way, the shares are diluted proportionally to the holder's shares of the Vault's total shares, as opposed to e.g., pulling assets from a Vault. Performance fees additionally typically require a high-water mark, i.e., they have to be disabled while a loss that has not yet been covered by the corresponding performance fee is being recouped.
In production, three different protocols implement the same interface in different ways.
Aave ERC-4626 compatibility is done with a thin adapter contract that has a very minimal API surface. The wrapper implementation of the standard interface for totalAssets() delegates to Aave's internal liquidity index, so no change to Aave's core contracts is required.
Morpho's vaults are natively ERC-4626 compliant and take a different approach from wrappers: they keep the risk parameters of the curator role out of the core vault interface.
Pendle uses yield tokenization for their vaults, splitting them into a Principal Token and a Yield Token to create fixed-rate and leveraged-yield positions.
Just because a standard has interfaces defined does not mean that a vault is safe. There are consistently 3 surfaces of attack found in production audits of vaults.
Vault reentrancy attack surface: Reentrancy occurs when a contract does external calls before Vault updates share state. For the standard sequence of actions for depositing to mint shares (deposit->strategy->mint), reentrancy MUST be handled for the deposit in case it is re-entered, allowing it to mint an additional share for same underlying assets.
totalAssets manipulation is arguably the highest security risk for strategy-backed vaults implementing the ERC-4626 standard, here even higher than Vault reentrancy. Total assets for a share can be manipulated by flash loan attacks or even simply by oracle lag, misleading the price for all investors that deposit in the same block. As price feeds are typically external (i.e. off chain), they need to be checked for staleness and protected by adequate circuit breakers.
A full audit of a vault will typically cover its strategy code as well as hooks for fees, as well as general security in the access control. A Foundry invariant fuzzer can be used to test that totalAssets() is at least the sum of redeemable assets across all shareholders. Issues with ERC-4626 compliant code hidden in the strategy itself will typically pass any interface level compliance tests without issue, which is why a smart contract security review has to cover the strategy layer.
The fungible share model laid out in this standard can be (and often is) adapted quite well for basic vaults, but introduces a host of unnecessary complexity in others.
Non-fungible vault positions like Uniswap v3 LP tokens or even per-depositor lock-up periods, can not be handled by the above model as they break the pro-rata share assumption. Moreover, structures with tranched levels of seniority versus juniority require completely separate accounting and thus cannot be expressed with a single share price.
To make matters worse, the overhead from ERC-4626's totalAssets() function re-computing all the vault's positions on every deposit can compound with the number of live positions in the vault. It's easy to add a caching layer to that function, but then you have to worry about the cache going stale.
Many vaults implement the standard as a thin wrapper on top of their existing (likely more sophisticated) internal accounting systems, allowing integrators to still take advantage of the compliance of a compliant read interface while custom vault designs live beneath the standard's interface.
Shipping a vault requires more than interface conformance.
A DeFi vault checklist includes Foundry invariant tests for share-price monotonicity (e.g. deposit then withdraw), and covers a test case for a 1 wei first deposit followed by a very large subsequent donation (to test for inflation attack mitigations).
Using UUPS or Transparent proxies for vault upgrades introduces storage collision and initializer re-entrancy risks to consider when scoping out the emergency pause and strategy ejection paths before launch.
Smart contract engineering for vaults is a design decision that can be improved by selecting a proper partner with specific experience in production ERC-4626 deployments and their test methodology, such as DESH's smart contract development services.
ERC-4626 is an Ethereum token standard. The main thing that this standard does is to establish a standard interface for "yield-bearing vaults", that is, for accounts that hold deposits and pay out interest (or other yields) in the form of tokens. More concretely, it specifies a contract interface for vaults that can be "deposited into" and "withdrawn from" as if they were a simple account. To that end, ERC-4626 vaults first issue a new share token, then update an exchange rate between that share and the underlying assets in the vault as more interest is generated.
As ERC-4626 does rely on share-price accounting, it is vulnerable to the exchange rate between assets and shares being manipulated. This is particularly problematic for low-liquidity vaults shortly after deployment of a vault, as the price of shares can be manipulated by an attacker donating assets to a vault in order to inflate the price before others buy in. Virtual shares, minimum deposit sizes for the initial deposit, and dead-shares all are considered to help mitigate such an attack, and thus are generally considered to be required.
deposit takes an exact asset amount and computes the shares issued, while mint takes an exact share amount and computes the assets pulled. Most users call deposit because they think in asset terms; aggregators and contracts often call mint to land on a precise share balance.
ERC-4626 is not suitable for vaults that hold non-fungible assets, complex multi-asset vaults or even vaults with highly volatile fees. Such vaults typically need to track yield on a per investor basis with custom terms for each investor. Although a vault with ERC-4626 compatible wrapper could be implemented for such vaults, a custom vault architecture is usually more practical.



