Розробка протоколу флеш-позик

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка протоколу флеш-позик
Складний
~1-2 тижні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    587
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Розробка протоколу флеш-займів

Флеш-займ — атомарний кредит: позичають будь-яку суму, роблять що завгодно, повертають в одній транзакції. Якщо повернення не сталося — вся транзакція скасовується. Без колатералю, без кредитної історії. Aave V3 утримує сотні мільйонів у пулах флеш-займів — і це працює, тому що атомарність EVM — абсолютна гарантія.

Але та ж атомарність робить флеш-займи основним інструментом для атак на DeFi. З 10 найбільших взломів останніх трьох років — мінімум 7 використовували флеш-займи як стартовий капітал для маніпуляції оракулом, маніпуляції цінами або атак на governance.

Архітектура протоколу флеш-займів

Механіка виконання

Класична схема Aave V2: пул викликає executeOperation() на адресі receiver, передає активи, receiver робить що потрібно, повертає активи + премію. Весь сценарій — один виклик flashLoan(), одна транзакція, один блок.

Aave V3 додав flashLoanSimple() для одного активу (дешевше за газ) та переробив інтерфейс receiver на IFlashLoanSimpleReceiver. EIP-3156 формалізував стандарт: flashLoan(receiver, token, amount, data) та обов'язковий callback onFlashLoan(). Будуючи протокол для інтеграції — логічно підтримувати обидва інтерфейси.

Типи реалізацій

Single-asset flash loans (EIP-3156 compliant): найпростіший варіант. Один токен, один receiver. Мінімальний газ. Працює для протоколів, які хочуть монетизувати простаївлячу ліквідність.

Multi-asset batch loans (Aave-style): кілька токенів в одній транзакції. Складніша реалізація, але відкриває сценарії типу «позичити ETH + USDC одночасно для арбітражу в пулі». Реалізуєтся через масиви активів/сум в одному викликі.

Callback-less flash loans (Uniswap V2-style): пул передає токени спочатку, receiver повертає в кінці транзакції через окремий виклик. Менш безпечна конструкція — receiver повинен сам перевіряти, що його не викликають повторно.

Ключові проблеми безпеки

Reentrancy через callback флеш-займу

Стандартна пастка: контракт receiver викликає іншу функцію пула всередині executeOperation(). Якщо пул не захищений reentrancy guard на рівні сховища — атакуючий може змінити стан пула до завершення оригінальної транзакції.

// НЕПРАВИЛЬНО: reentrancy можлива
function flashLoan(address receiver, uint256 amount) external {
    uint256 balanceBefore = token.balanceOf(address(this));
    token.transfer(receiver, amount);
    IFlashLoanReceiver(receiver).executeOperation(amount, fee, msg.sender);
    // receiver міг би викликати deposit() і змінити balanceBefore-логіку
    require(token.balanceOf(address(this)) >= balanceBefore + fee);
}

Рішення: модифікатор nonReentrant від OpenZeppelin на flashLoan() і на всі функції, що змінюють стан пула (deposit, withdraw, borrow).

Перевірка caller у контракті receiver

Receiver повинен перевіряти, що executeOperation() викликає саме довірений пул, а не довільна адреса. Без цієї перевірки атакуючий може прямо викликати executeOperation() на receiver, імітуючи флеш-займ.

function executeOperation(
    address asset,
    uint256 amount,
    uint256 premium,
    address initiator,
    bytes calldata params
) external override returns (bool) {
    require(msg.sender == address(LENDING_POOL), "Invalid caller");
    require(initiator == address(this), "Invalid initiator");
    // логіка
}

Облік комісій та проблеми точності

Типова помилка: комісія розраховується як amount * FEE_BPS / 10000, де FEE_BPS = 9 (0.09%). При малих сумах результат округляється до 0 через цілочисельне ділення. Атакуючий розбиває один великий займ на тисячі маленьких і платить нульову комісію.

Захист: мінімальна комісія в абсолютному значенні (наприклад, 1 wei) та перевірка amountOwed > amount — не просто amountOwed >= amount + fee_calculated.

Як будуємо протокол флеш-займів

Стек: Solidity 0.8.x, OpenZeppelin 5.x для ReentrancyGuard та SafeERC20, Foundry для тестування.

Pool контракт зберігає ліквідність провайдерів. Підтримуємо кілька токенів через mapping token => PoolState. PoolState включає: totalLiquidity, totalBorrowed (для обліку одночасних займів), feeAccumulator для LP-нагород.

Fee distribution: комісія з флеш-займів накопичується в пулі та підвищує exchange rate LP-токенів (як Compound cTokens). LP отримують yield без окремого claim — просто при виводі отримують більше базового токена.

Access control: через OpenZeppelin AccessControl. Ролі: PAUSER_ROLE (circuit breaker при атаці), FEE_SETTER_ROLE (під timelock governance), ASSET_MANAGER_ROLE (додавання нових токенів).

Circuit breaker: якщо за один блок з пула ушло більше X% ліквідності — автоматична пауза. Реалізується через mapping _blockLoanVolume та перевірку на початку flashLoan(). Хибні спрацювання можливі при легітимному використанні — порог встановлюємо через governance.

Тестування

Fork-тесты на Ethereum mainnet критичні. Гоняємо через Foundry:

  • Стандартний займ та повернення з комісією
  • Спроба невозврату — транзакція повинна скасуватися
  • Reentrancy атака на flashLoan() через шкідливий receiver
  • Нульова комісія при мінімальній сумі (перевіряємо anti-dust логіку)
  • Паніка: 100 послідовних займів максимального обсягу

Fuzzing в Echidna з інваріантом: totalLiquidity після будь-якої послідовності операцій не менша за суму депозитів мінус зняття.

Легітимні use cases — навіщо це будувати

Флеш-займи — не тільки атаки. Протокол відкриває:

Арбітраж без капіталу: трейдер бачить різницю цін між Uniswap та Curve, позичає займ, виконує арбітраж, повертає. Прибуток — спред мінус газ. DEX-арбітраж вирівнює ціни, роблячи ринки ефективнішими.

Self-liquidation: користувач з позицією в Aave, близькою до ліквідації, позичає флеш-займ, погашає борг, виводить залог, повертає займ. Уникає штрафу від зовнішніх ліквідаторів.

Collateral swap: замінити ETH залог на WBTC без закриття позиції. Одна транзакція замість чотирьох.

Leverage unwinding: закрити leveraged позицію в одній транзакції.

Орієнтири за часом

Базовий EIP-3156 compliant протокол для одного токена — 3-5 днів включаючи тести. Multi-asset пул з LP-токенами та fee distribution — 1-1.5 тижня. Інтеграція з існуючим lending протоколом (додавання флеш-займів на top) — 1-2 тижні залежно від архітектури базового протоколу. Вартість розраховується після аналізу вимог.