ERC-4626 is a standard for yield-bearing vaults. You deposit an underlying ERC-20 asset and receive vault SHARES — themselves an ERC-20 — representing your proportional claim. As the vault earns yield, each share becomes redeemable for more of the underlying asset. A single standard interface means aggregators and front-ends can integrate any vault uniformly.
1interface IERC4626 /* is IERC20 */ {2function asset() external view returns (address);3function totalAssets() external view returns (uint256);4function deposit(uint256 assets, address receiver)5external returns (uint256 shares);6function redeem(uint256 shares, address receiver, address owner)7external returns (uint256 assets);8function convertToShares(uint256 assets) external view returns (uint256);9function convertToAssets(uint256 shares) external view returns (uint256);10}
The core math: shares = assets * totalSupply / totalAssets (and the inverse for redemptions). When the vault's totalAssets grows from yield while share supply is unchanged, every share is now worth more underlying. Depositing mints shares; withdrawing burns them for the proportional assets. previewDeposit / previewRedeem let callers simulate rounding before acting.
The inflation (donation) attack: against an empty vault, an attacker can be the first depositor of 1 wei, then directly 'donate' a large amount of the asset to the vault to massively inflate the share price, causing a victim's subsequent deposit to round down to ZERO shares — stealing it. Mitigations: OpenZeppelin's virtual shares / decimals-offset, or seeding a non-trivial initial deposit at launch.
1// Deposit assets for shares, later redeem shares for assets2await asset.write.approve([vault, amount]);3const shares = await vault.write.deposit([amount, me]);4// ...time passes, vault earns yield...5const assetsBack = await vault.write.redeem([shares, me, me]);
Connect your wallet to mark this lesson as complete
Earn 25 EFFORT tokens