Ми часто стикаємося з ситуацією, коли клієнт хоче об'єднати дохідність з різних DeFi-протоколів, але впирається в зоопарк несумісних інтерфейсів. До появи ERC-4626 кожен yield vault реалізовував власний інтерфейс: Yearn V2 мав pricePerShare(), Compound давав exchangeRate(), Aave працював через aToken з rebasing. Написати агрегатор, який працює з кількома vault-ами одночасно, означало підтримувати зоопарк адаптерів. ERC-4626 стандартизував це: один інтерфейс для всіх токенізованих vault-ів. Зараз цей стандарт використовують Yearn V3, Morpho Blue, більшість liquid staking протоколів та всі великі lending агрегатори. Це де-факто стандарт для yield-bearing токенів. Якщо ви розробляєте DeFi-продукт, замовте розробку vault під ключ — заощадите час на інтеграції та аудиті.
Що таке ERC-4626 і чому це важливо для інтеграцій
ERC-4626 — розширення ERC-20 з методами deposit/withdraw активами (underlying asset), mint/redeem shares (vault token), конвертацією між assets та shares. Vault token (shares) — звичайний ERC-20, який торгується та передається. Ціна share зростає в міру накопичення yield. Це фундаментально відрізняється від rebasing (stETH), де кількість токенів змінюється, а ціна постійна.
Математика vault: price per share
Ціна share в ERC-4626: pricePerShare = totalAssets / totalShares.
| Сценарій | Формула shares | Особливість |
|---|---|---|
| Перший депозит | shares = assets | вимагається ініціалізація віртуальними shares |
| Наступні депозити | shares = assets * totalShares / totalAssets | округлення вниз |
| Зняття | assets = shares * totalAssets / totalShares | округлення вгору |
При першому депозиті (totalShares = 0) виникає проблема: будь-яка формула з діленням на нуль невалідна. OpenZeppelin вирішує це через virtual shares: ініціалізуємо totalShares = 10^decimals, totalAssets = 10^decimals, що дає початковий pricePerShare = 1. Документація OpenZeppelin ERC4626
Інфляційна атака на vault
Це реальна вразливість, яка дозволяє першому depositor-у заробити за рахунок наступних. Сценарій: атакуючий депонує 1 wei, отримує 1 share, потім donates великий обсяг активу (минаючи deposit), різко підвищуючи pricePerShare. Наступний користувач депонує 1000 USDC, але через округлення вниз отримує 0 shares — його активи дістаються атакуючому.
Як захиститися від інфляційної атаки?
OpenZeppelin ERC4626 (v5.0+) захищає через віртуальні shares з _decimalsOffset(). Встановлення offset=3 створює віртуальний запас 10^(3+decimals) shares при 10^decimals assets. Атакуючому потрібно депонувати величезну суму для мінімальної вигоди — атака стає економічно невигідною.
function _decimalsOffset() internal view virtual returns (uint8) { return 0; // Збільште до 3 для додаткового захисту } Реалізація базового ERC-4626 vault
Ми використовуємо Foundry, Solidity 0.8.24, OpenZeppelin. Ключовий момент: vault перевизначає totalAssets(), враховуючи не тільки баланс vault, але й активи, задеплоєні в стратегію. Хуки _afterDeposit та _beforeWithdraw керують деплоєм/поверненням коштів.
// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract SimpleYieldVault is ERC4626, Ownable { address public strategy; uint256 public performanceFee; // 500 = 5% constructor( IERC20 asset_, string memory name_, string memory symbol_ ) ERC4626(asset_) ERC20(name_, symbol_) Ownable(msg.sender) {} function totalAssets() public view virtual override returns (uint256) { uint256 vaultBalance = IERC20(asset()).balanceOf(address(this)); uint256 strategyBalance = strategy != address(0) ? IStrategy(strategy).totalAssets() : 0; return vaultBalance + strategyBalance; } function _afterDeposit(uint256 assets, uint256) internal virtual { if (strategy != address(0)) { IERC20(asset()).approve(strategy, assets); IStrategy(strategy).invest(assets); } } function _beforeWithdraw(uint256 assets, uint256) internal virtual { uint256 vaultBalance = IERC20(asset()).balanceOf(address(this)); if (assets > vaultBalance && strategy != address(0)) { IStrategy(strategy).divest(assets - vaultBalance); } } } Чому важливі напрямки округлення?
ERC-4626 явно специфікує округлення: convertToShares та previewDeposit вниз (floor), previewWithdraw вгору (ceil), previewRedeem вниз. Порушення — це audit finding. Округлення завжди на користь vault, інакше можливий drain через безліч маленьких операцій.
Важливі edge cases
Якщо underlying asset — fee-on-transfer токен, vault отримує менше, ніж вказано. Рішення: заміряти реальний баланс після transfer і перераховувати shares. У коді це враховується.
Порівняння стандартів yield-токенів
| Стандарт | Тип | Зручність інтеграції | Ризик маніпуляцій |
|---|---|---|---|
| ERC-4626 | Share-based | Висока | Низький (захист від інфляційної атаки) |
| Rebasing | Balance-changing | Середня | Середній (складність агрегації) |
| Кастомний | Різний | Низька | Високий (немає єдиного інтерфейсу) |
ERC-4626 в 2-3 рази кращий для інтеграцій, ніж кастомні або rebasing-рішення. Це підтверджується практикою: багато протоколів переходять на цей стандарт, знижуючи витрати на розробку та аудит.
Тестування та аудит
Використовуємо офіційний набір property tests: ERC4626 Properties. Foundry fuzz-тести покривають roundtrip-властивості та інваріанти.
function testFuzz_DepositRedeem(uint256 assets) public { assets = bound(assets, 1, 1e30); vm.assume(assets <= token.balanceOf(user)); uint256 shares = vault.deposit(assets, user); uint256 assetsBack = vault.redeem(shares, user, user); // Втрати на округлення не більше 1 wei assertApproxEqAbs(assetsBack, assets, 1); } Гарантуємо проходження зовнішнього аудиту: контракти проходять Slither, Mythril, Echidna. Отримайте консультацію щодо підготовки до аудиту.
Що входить у розробку ERC-4626 vault
- Аналіз вимог — обговорюємо yield-стратегію, fee-модель, цільову мережу (Ethereum, Polygon, Arbitrum та ін.).
- Проектування архітектури — схема взаємодії vault, стратегій, harvester.
- Реалізація смарт-контрактів — Solidity 0.8.x, Foundry, OpenZeppelin.
- Тестування — модульні, fuzz, інтеграційні тести (покриття >95%).
- Розгортання та верифікація в Etherscan.
- Підтримка при проходженні зовнішнього аудиту — консультації та доопрацювання.
- Технічна документація — опис контрактів, схема викликів.
За 5 років роботи ми реалізували понад 30 DeFi-проєктів, включаючи vault-рішення для протоколів з TVL > $100M. Це дозволяє нам передбачати типові проблеми та давати рекомендації щодо архітектури.
Терміни та вартість
Базова реалізація ERC-4626 vault з однією стратегією: 3-5 робочих днів. Повноцінний vault з harvester, fee-механізмом та кількома стратегіями: 2-3 тижні. Вартість розраховується індивідуально після аналізу ваших вимог — зазвичай вона нижча, ніж розробка з нуля з використанням кастомних інтерфейсів.
Зв'яжіться з нами для оцінки вашого проєкту — ми підберемо оптимальну архітектуру. Замовте розробку vault під ключ і отримайте працюючий контракт з готовою тестовою базою.
Отримайте консультацію щодо вашого проєкту — наші інженери допоможуть обрати оптимальну стратегію та знизити ризики.







