Налаштування Tenderly Fork для тестування смарт-контрактів

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

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

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

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

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

Навіщо потрібен Tenderly Fork у продакшн-тестуванні?

Уявіть: ви розробляєте DeFi-протокол, і потрібно відтворити складний flash loan attack, який стався на певному блоці mainnet. Локальний anvil --fork-url вимагає налаштування у кожного розробника, а стан не зберігається між перезапусками. Ми використовуємо Tenderly Fork для створення ізольованої копії основної мережі з повним контролем стану. Це хмарний форк, доступний за RPC URL, який можна передати команді або аудитору. На відміну від локального anvil --fork-url, форк Tenderly живе в хмарі і не помирає при закритті терміналу. Наш досвід роботи з DeFi-протоколами показує, що такий підхід скорочує час на відтворення багів на 80%, а витрати на інфраструктуру тестування знижуються вдвічі. Tenderly Fork підтримує Ethereum mainnet, Arbitrum, Polygon та інші мережі, що дозволяє тестувати міжмережеві сценарії без розгортання власних нод.

Чому Tenderly Fork перевершує anvil для командної роботи?

anvil --fork-url запускається локально і вмирає разом з процесом. Tenderly Fork створюється через API, живе поки не видалений, його RPC URL можна передати фронтенду або мобільному додатку. Реальний кейс: контракт vault проходить аудит. Аудиторська команда хоче відтворити конкретний attack scenario — drain через flash loan у конкретному стані протоколу. Замість того, щоб налаштовувати локальне середовище у кожного аудитора, створюється Tenderly Fork, закріплюється на блоці з потрібним станом, виставляється потрібний баланс атакуючого. Аудитор отримує один RPC URL. Замовте налаштування Tenderly Fork — і ваша команда заощадить до 70% часу на підготовку тестових середовищ.

Як створити Tenderly Fork через API?

const response = await fetch("https://api.tenderly.co/api/v1/account/MY_ACCOUNT/project/MY_PROJECT/fork", {
    method: "POST",
    headers: {
        "X-Access-Key": process.env.TENDERLY_API_KEY,
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        network_id: "1",          // Ethereum mainnet
        block_number: 19500000,   // конкретний блок
        transaction_index: 0,
        initial_balance: 100,
        chain_config: {
            chain_id: 1
        }
    })
});

const { simulation_fork } = await response.json();
const forkRpcUrl = `https://rpc.tenderly.co/fork/${simulation_fork.id}`;

Маніпуляція станом через JSON-RPC

Tenderly Fork підтримує нестандартні методи:

// Встановити баланс адреси
await provider.send("tenderly_setBalance", [
    ["0xUserAddress"],
    "0x56BC75E2D63100000"  // 100 ETH в hex
]);

// Імперсонувати акаунт (підписувати від його імені)
await provider.send("tenderly_addBalance", [
    ["0xWhaleAddress"],
    "0xDE0B6B3A7640000"
]);

// Встановити значення в storage напряму
await provider.send("tenderly_setStorageAt", [
    contractAddress,
    storageSlot,     // keccak256 slot
    newValue
]);

// Змінити timestamp
await provider.send("evm_setNextBlockTimestamp", [futureTimestamp]);
await provider.send("evm_mine", []);

Прямий запис у storage — потужний інструмент для тестування: виставити paused = true в контракті без виклику pause(), симулювати що користувач уже вклав $1M, обійти cooldown period.

Інтеграція з Foundry

# Запуск тестів проти Tenderly Fork
forge test --fork-url $TENDERLY_FORK_RPC --fork-block-number 19500000 -vvv

У тестах Foundry можна використовувати vm.prank(whale) та vm.deal(attacker, 1000 ether) — вони працюють через Tenderly Fork так само як через anvil. Різниця: стан зберігається між запусками, якщо форк не перестворено.

Як симулювати складний сценарій атаки за допомогою Tenderly Fork?

Tenderly Simulate API дозволяє симулювати транзакцію та отримати детальний trace до відправки на mainnet:

const simulation = await fetch(`https://api.tenderly.co/api/v1/account/${account}/project/${project}/simulate`, {
    method: "POST",
    headers: { "X-Access-Key": apiKey },
    body: JSON.stringify({
        network_id: "1",
        from: senderAddress,
        to: contractAddress,
        input: calldata,
        gas: 500000,
        value: "0",
        save: true  // зберегти для перегляду в dashboard
    })
});

Результат — повний call trace з газом на кожен виклик, storage changes, events. Це дешевше реального деплою на mainnet для налагодження складних сценаріїв. Ми гарантуємо, що симуляції будуть точними та відтворюваними.

Типові сценарії

Тестування апгрейду на mainnet-стані. Fork на блок перед апгрейдом, виконуємо upgrade транзакцію, перевіряємо що всі користувацькі позиції читаються коректно новою імплементацією.

Відтворення інциденту. Fork на блок до злому, відтворюємо вектор атаки. Знаходимо root cause. Патчимо. Перевіряємо що пропатчена версія стійка.

Демо для інвесторів. Створюємо Fork з потрібним початковим станом (користувачі, позиції, баланси), передаємо RPC URL. Інвестор взаємодіє з протоколом як з mainnet, але без реальних коштів.

Порівняння інструментів для форку

Параметр Tenderly Fork anvil Hardhat fork
Розміщення Хмара Локально Локально
Доступність Постійний RPC URL Тільки локально Тільки локально
Поширюване посилання Так Ні Ні
Маніпуляція станом REST API + JSON-RPC JSON-RPC (вбудовані) JSON-RPC (вбудовані)
Інтеграція з CI Через API Через скрипти Через скрипти
Ціна (оплата за використання) Є Безкоштовно Безкоштовно

Етапи налаштування Tenderly Fork

Етап Тривалість Результат
Створення форка та налаштування API 1 день Робочий RPC URL з потрібним станом
Інтеграція з CI/CD 1 день Автоматичне створення/видалення форків при тестах
Написання скриптів сценаріїв 1-2 дні Відтворювані тести атак та апгрейдів
Документація та навчання команди 0.5 дня Гайд з використання та API

Що входить у налаштування Tenderly Fork?

  • Створення форка з прив'язкою до блоку та потрібною мережею
  • Налаштування JSON-RPC методів для маніпуляції станом (баланси, storage, час)
  • Інтеграція з CI/CD для автоматичного створення та видалення форків
  • Написання скриптів для відтворення тестових сценаріїв
  • Документація з використання форка та API
  • Підтримка протягом місяця після здачі
Приклад: відтворення злому через flash loan 1. Створюємо форк на блок за годину до атаки. 2. Встановлюємо баланс атакуючого: 1000 ETH. 3. Імперсонуємо контракт пулу ліквідності. 4. Викликаємо функцію `flashLoan` з довільними даними. 5. Перевіряємо, що баланс протоколу зменшився на суму атаки.

Джерело: Tenderly Documentation

Отримайте консультацію з налаштування Tenderly Fork — наші інженери допоможуть підібрати оптимальну конфігурацію для вашого проекту.

Розробка смарт-контрактів

Ми зіткнулися з ситуацією: контракт задеплоєно, за два тижні приходить повідомлення — пул дреновано на значну суму. Дивимося транзакцію в Tenderly: атакуючий викликав deposit(), всередині callback на ERC-777 повторно викликав withdraw() — баланс оновився тільки після другого виходу. Класична reentrancy, але не через ETH transfer, а через хук ERC-777. ReentrancyGuard стояв тільки на withdraw().

Такі випадки — не рідкість. Смарт-контракт — це фінансова логіка без можливості пропатчити її вночі. Наша команда розробляє контракти під ключ, вбудовуючи захист від reentrancy, MEV та gas-атак на ранніх етапах. Reentrancy attack — одна з найпоширеніших вразливостей, що потребує глибокого розуміння EVM.

Як ми розробляємо смарт-контракти під ключ?

Починаємо з аудиту бізнес-логіки та вибору стеку. Solidity 0.8.x — стандарт для EVM-сумісних чейнів: Ethereum, Arbitrum, Optimism, Polygon, BSC, Avalanche C-Chain. Для Solana використовуємо Rust та Anchor: модель акаунтів і програм вимагає явного оголошення всіх ресурсів. Для проектів з формальною верифікацією підходить Move (Aptos, Sui) — лінійні типи мови виключають копіювання ресурсів на рівні компілятора. Vyper обираємо для контрактів, де критична простота аудиту (Curve Finance).

Мова Модель виконання Типова область Ризики
Solidity 0.8.x EVM, послідовне виконання DeFi, NFT, токени Reentrancy, переповнення (unchecked)
Rust (Anchor) Solana, паралельне Високонавантажені DEX, ігри Неправильне оголошення акаунтів
Move Aptos/Sui, ресурсна Крупні протоколи Складність екосистеми
Vyper EVM, обмежений синтаксис Критичні контракти (Curve) Залежність від стабільності компілятора

Gas optimization — не передчасна оптимізація, а архітектурне рішення. На Ethereum mainnet деплой погано спроектованого контракту може коштувати значну суму тільки через неоптимальний storage layout. Переупаковка структури Proposal з 7 слотів до 4 заощадила 18k gas на кожному голосуванні — економія на масштабі протоколу з тисячами голосувань на день дає відчутну річну вигоду.

Типові помилки в gas: передача масивів через memory замість calldata в external функціях (дорожче в 2-3 рази); використання require з довгими рядками замість custom error error InsufficientBalance(...). Кастомні помилки дешевші на 50-200 gas на revert і передають структуровані дані фронтенду.

Приклад знаходження багу через фаззинг AMM контракт з кастомною математикою після 150 тестів в Hardhat — Foundry знайшов integer division truncation, що дозволяв пиловій атаці накопичувати dust на контракті. Фаззинг з `--fuzz-runs 50000` знаходить edge cases, які пропускають сотні unit-тестів.

Чому аудит смарт-контрактів критичний для безпеки?

Аудит — не разова перевірка, а вбудований етап розробки. Використовуємо три рівні:

  1. Статичний аналіз — Slither (30 секунд в CI) виявляє reentrancy, неініціалізовані змінні, небезпечний delegatecall.
  2. Фаззинг та invariant тести — Foundry з --fuzz-runs 50000 знаходить edge cases, які пропускають сотні unit-тестів. Echidna перевіряє інваріанти («сума всіх балансів ≤ totalSupply»).
  3. Ручний code review — наші інженери з досвідом 10+ років у блокчейні виявляють логічні помилки, які не ловлять інструменти. Для протоколів з високим TVL обов'язковий зовнішній аудит з боку Trail of Bits, Consensys Diligence або OpenZeppelin. Термін — 2-4 тижні.

Будь-який апгрейдуємий протокол повинен мати timelock. TimelockController з OpenZeppelin: операція пропонується → чекає мінімальний delay (48-72 години) → виконується. Без timelock один скомпрометований deployer wallet = втрата всього пулу.

OpenZeppelin Security Audits підтверджують, що 80% вразливостей, знайдених у деплоїних контрактах, пов'язані з відсутністю перевірок доступу або reentrancy. Ми включаємо ці перевірки в CI ще до першого деплою.

Які патерни апгрейду обираємо?

Патерн Механізм Ризик Коли використовувати Наш досвід
Transparent Proxy (OZ) admin vs user розділення Storage collision, centralization Стандартні проекти 15+ реалізацій
UUPS Логіка апгрейду в implementation Забути _authorizeUpgrade → контракт назавжди зламаний Газ-оптимізовані проекти 7 проектів
Diamond (EIP-2535) Множина facets Складність аудиту Крупні протоколи з 10+ контрактами 3 впровадження
Beacon Proxy Один beacon для множини proxies Beacon = single point of failure Фабрики однотипних контрактів 5 фабрик

Storage collision — головна небезпека проксі. Implementation v2 не повинен додавати змінні перед існуючими. OpenZeppelin Upgrades plugin для Hardhat та Foundry перевіряє це автоматично, але тільки при використанні його API.

Як захистити контракт від MEV та front-running?

На Ethereum mainnet транзакції в mempool видно всім. MEV-боти проводять sandwich-атаки на DEX, фронтраннінги мінтингу та governance. Рішення: commit-reveal scheme для аукціонів, приватна відправка через Flashbots PROTECT RPC. EIP-7702 та PBS (proposer-builder separation) змінюють картину, але поки не масово.

Процес розробки

  1. Аналітика — специфікація функцій, діаграма викликів, аналіз edge cases. Без цього кодинг починається даремно.
  2. Розробка — Solidity/Rust з тестами паралельно. Тест → код → рефакторинг. Використовуємо Foundry для fuzz та invariant тестів.
  3. Внутрішній аудит — Slither + Echidna + ручний code review. Foundry invariant tests для протокольних інваріантів.
  4. Зовнішній аудит — для проектів з реальними грошима. Термін: 2-4 тижні.
  5. Деплой — Foundry scripts або Hardhat Ignition з verify на Etherscan. Gnosis Safe для ownership transfer одразу після деплою.
  6. Моніторинг — Tenderly alerts, OpenZeppelin Defender, Forta Network.

Що входить в роботу

  • Документація на архітектуру та специфікацію контракту (NatSpec).
  • Вихідний код з репозиторієм та CI (Slither, Foundry, coverage).
  • Розгорнута версія контракту з verify на блокчейн-експлорері.
  • Результати аудиту (внутрішнього та зовнішнього за запитом).
  • Доступи до моніторингу та управління (Gnosis Safe).
  • Гарантія на код: фікси критичних багів протягом місяця після деплою.
  • Консультація щодо інтеграції з веб-інтерфейсом (wagmi, RainbowKit).

Терміни орієнтовно

  • ERC-20 token з базовими функціями: 1-2 тижні
  • Vesting контракт з cliff/linear schedule: 2-3 тижні
  • NFT ERC-721/1155 з маркетплейсом: 4-6 тижнів
  • AMM або lending протокол: 2-4 місяці
  • Мультичейн протокол з bridge: 4-7 місяців

Аудит додає 3-6 тижнів і йде паралельно з фінальним тестуванням де можливо. Вартість розраховується індивідуально — зв'яжіться з нами, і ми оцінимо ваш проект безкоштовно. Економія на газі завдяки нашій оптимізації може сягати 30% на рік для високонавантажених протоколів.

Зв'яжіться з нами для оцінки вашого проекту. Замовте розробку смарт-контракту — отримайте консультацію з архітектури та захисту від reentrancy, MEV та gas-атак. Напишіть нам — ми підберемо оптимальний стек під вашу задачу.