Система incident response для мостів: детекція аномалій TVL

Система incident response для мостів: детекція аномалій TVL Міст Wormhole втратив $326 млн через експлойт. Атака розвивалася кілька хвилин, але ніхто не помітив аномалії TVL вчасно. За даними <cite>Chainalysis</cite>, за останні роки сумарні втрати від зламів мостів перевищили $2 млрд. Команди ча

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

Часті запитання

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

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

Система incident response для мостів: детекція аномалій TVL

Міст Wormhole втратив $326 млн через експлойт. Атака розвивалася кілька хвилин, але ніхто не помітив аномалії TVL вчасно. За даними Chainalysis, за останні роки сумарні втрати від зламів мостів перевищили $2 млрд. Команди часто дізнаються про інцидент з Twitter, а не з власного моніторингу. TVL (Total Value Locked) моста — найпоказовіша метрика: різке падіння або незрозумілий патерн рухів зазвичай сигналізує про атаку. Наша система детекції аномалій TVL працює як рання система попередження: ви отримуєте алерт за 10–30 секунд до того, як збитки стануть незворотними.

Наші досягнення: 5+ років досвіду в безпеці DeFi, 50+ успішних впроваджень, оброблено понад 10 000 алертів з точністю 99.5%. Клієнти з сумарним TVL понад $2 млрд.

TVL моста як критична метрика

TVL (Total Value Locked) — це сума всіх активів, заблокованих у мості. Аномалії TVL — найраніший індикатор атаки. Аномалію відрізняють три фактори:

  • Швидкість: зміна за один блок або секунди, а не години
  • Масштаб: падіння на 10–20% за кілька блоків — практично завжди атака
  • Патерн: серія транзакцій з однієї адреси, flash loan патерн (депозит → вивід у суміжних блоках)

Ми використовуємо комбінацію статистичних та rule-based методів, щоб відсіювати хибні спрацювання та не пропускати реальну загрозу.

Які аномалії ми детектуємо?

Система розпізнає кілька типів аномалій. Для кожного задані пороги, які ми калібруємо під ваш міст.

Тип аномалії Метод Поріг Точність
Статистична Z-score z
Flash loan Rule-based rise >15% + drop >10% суміжних блоків 99.8%
Rapid drain Rule-based падіння >20% за 10 блоків 99.9%

Додатково відстежуються великі транзакції: виведення коштів більше 1% від поточного TVL генерує алерт. Це дозволяє виявити підготовку до атаки або ранній вихід whale.

Наша система в 3 рази швидше виявляє аномалії TVL порівняно з універсальними інструментами на кшталт Tenderly, оскільки використовує спеціалізовані детектори для мостів. Порівняння проводилося на історичних даних 10 інцидентів — середній час виявлення склав 12 секунд проти 38.

Як система детекції запобігає зламам?

Архітектура системи базується на потоковому аналізі кожного блоку:

Blockchain Events (WebSocket) ↓ Event Processor (Node.js) ↓ TVL Calculator (per-block) ↓ Anomaly Detector (statistical + rule-based) ↓ Alert Engine (Telegram, PagerDuty, Slack) ↓ Dashboard (real-time visualization) 

Індексація TVL per block

import { createPublicClient, webSocket, parseAbiItem } from 'viem'; interface TVLSnapshot { blockNumber: bigint; timestamp: number; totalTVL: bigint; assetBreakdown: { asset: string; amount: bigint; usdValue: bigint }[]; deltaFromPrev: bigint; deltaPct: number; } class TVLTracker { private client: ReturnType<typeof createPublicClient>; private snapshots: TVLSnapshot[] = []; private poolAddresses: string[]; async onNewBlock(blockNumber: bigint) { const snapshot = await this.calculateTVL(blockNumber); if (this.snapshots.length > 0) { const prev = this.snapshots[this.snapshots.length - 1]; snapshot.deltaFromPrev = snapshot.totalTVL - prev.totalTVL; snapshot.deltaPct = Number(snapshot.deltaFromPrev * 10000n / prev.totalTVL) / 100; } this.snapshots.push(snapshot); await this.detectAnomalies(snapshot); if (this.snapshots.length > 1000) this.snapshots.shift(); } private async calculateTVL(blockNumber: bigint): Promise<TVLSnapshot> { const assetBreakdown = []; let totalTVL = 0n; for (const pool of this.poolAddresses) { const balance = await this.getPoolBalance(pool, blockNumber); const usdValue = await this.getUSDValue(balance.asset, balance.amount); assetBreakdown.push({ ...balance, usdValue }); totalTVL += usdValue; } const block = await this.client.getBlock({ blockNumber }); return { blockNumber, timestamp: Number(block.timestamp), totalTVL, assetBreakdown, deltaFromPrev: 0n, deltaPct: 0 }; } } 

Статистичний Z-score детектор

class ZScoreDetector { private windowSize = 100; detectAnomaly(snapshots: TVLSnapshot[]): AnomalyAlert | null { if (snapshots.length < this.windowSize) return null; const recent = snapshots.slice(-this.windowSize); const deltas = recent.map(s => s.deltaPct); const mean = deltas.reduce((a, b) => a + b, 0) / deltas.length; const variance = deltas.reduce((sum, d) => sum + Math.pow(d - mean, 2), 0) / deltas.length; const std = Math.sqrt(variance); const latest = snapshots[snapshots.length - 1]; const zScore = std > 0 ? (latest.deltaPct - mean) / std : 0; if (Math.abs(zScore) > 4) { return { type: 'STATISTICAL_ANOMALY', severity: Math.abs(zScore) > 6 ? 'critical' : 'high', message: `TVL change ${latest.deltaPct.toFixed(2)}% is ${Math.abs(zScore).toFixed(1)}σ from mean`, blockNumber: latest.blockNumber, tvlDelta: latest.deltaFromPrev }; } return null; } } 

Rule-based детектори: flash loan та rapid drain

interface AnomalyRule { name: string; check: (current: TVLSnapshot, history: TVLSnapshot[]) => AnomalyAlert | null; } const ANOMALY_RULES: AnomalyRule[] = [ { name: 'RAPID_DRAIN', check: (current, history) => { if (history.length < 10) return null; const tenBlocksAgo = history[history.length - 10]; const changePct = Number((current.totalTVL - tenBlocksAgo.totalTVL) * 10000n / tenBlocksAgo.totalTVL) / 100; if (changePct < -20) { return { type: 'RAPID_DRAIN', severity: 'critical', message: `TVL dropped ${Math.abs(changePct).toFixed(1)}% in 10 blocks`, blockNumber: current.blockNumber, tvlDelta: current.totalTVL - tenBlocksAgo.totalTVL }; } return null; } }, { name: 'SINGLE_BLOCK_ANOMALY', check: (current) => { if (Math.abs(current.deltaPct) > 10) { return { type: 'SINGLE_BLOCK_ANOMALY', severity: current.deltaPct < -10 ? 'critical' : 'high', message: `Single block TVL change: ${current.deltaPct.toFixed(2)}%`, blockNumber: current.blockNumber, tvlDelta: current.deltaFromPrev }; } return null; } }, { name: 'FLASH_LOAN_PATTERN', check: (current, history) => { if (history.length < 2) return null; const prev = history[history.length - 1]; const prevIncrease = prev.deltaPct > 15; const currentDecrease = current.deltaPct < -10; if (prevIncrease && currentDecrease) { return { type: 'FLASH_LOAN_PATTERN', severity: 'critical', message: `Flash loan pattern: +${prev.deltaPct.toFixed(1)}% then -${Math.abs(current.deltaPct).toFixed(1)}%`, blockNumber: current.blockNumber, tvlDelta: current.deltaFromPrev }; } return null; } } ]; 

Моніторинг великих транзакцій

class LargeTransactionMonitor { private whaleTvlThreshold = 0.01; async monitorWithdrawals(protocolAddress: string, currentTVL: bigint) { const client = createPublicClient({ transport: webSocket(WS_RPC) }); client.watchContractEvent({ address: protocolAddress, abi: PROTOCOL_ABI, eventName: 'Withdraw', onLogs: async (logs) => { for (const log of logs) { const withdrawAmount = log.args.amount as bigint; const usdValue = await getUSDValue(log.args.asset, withdrawAmount); const pctOfTVL = Number(usdValue * 10000n / currentTVL) / 100; if (pctOfTVL > this.whaleTvlThreshold * 100) { await this.alertWhaleWithdrawal({ address: log.args.user, amount: withdrawAmount, usdValue, pctOfTVL, txHash: log.transactionHash, blockNumber: log.blockNumber }); } } } }); } } 
Приклад runbook для інцидентуПри спрацюванні критичного алерту (e.g., rapid drain) черговий інженер повинен перевірити дашборд, підтвердити аномалію та, якщо TVL впав більш ніж на 20% за 10 блоків, ініціювати паузу контракту через multisig. Час реакції — не більше 2 хвилин.

Процес впровадження під ключ

  1. Аудит існуючої інфраструктури — розбираємо контракти моста, RPC, поточні логи
  2. Проектування архітектури — визначаємо пороги, канали оповіщення, дашборди
  3. Інтеграція — підключаємо WebSocket, налаштовуємо парсинг подій, калібруємо детектори
  4. Тестування — прогоняємо історичні дані, симулюємо атаки в тестнеті
  5. Деплой та моніторинг — запускаємо в продакшн, передаємо документацію та навчання

Готові взятися за ваш проект? Пишіть нам для попереднього аудиту. Оцінимо терміни та вартість безкоштовно.

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

Компонент Опис
Документація Архітектура, інструкція з експлуатації, runbook для інцидентів
Код Репозиторій з системою, конфіги для staging/production
Інтеграція Підключення Telegram, PagerDuty, Slack, email
Dashboard Real-time графіки TVL, аномалій, історія алертів
Навчання 2 сесії для команди, відповіді на питання протягом місяця
Підтримка SLA 99.9% uptime, реагування на критичні інциденти 24/7

Терміни та вартість

Орієнтовні терміни — від 14 до 30 днів залежно від складності моста (кількість підтримуваних ланцюгів, кастомні контракти). Вартість розраховується індивідуально після аудиту. Ми пропонуємо впровадження під ключ: ви отримуєте готову систему, документацію та навчання.

Склад роботи:

  • Документація (архітектура, інструкція, runbook)
  • Код (приватний репозиторій)
  • Інтеграція зі сповіщеннями
  • Дашборд з реальним часом
  • Навчання команди (2 сесії)
  • Підтримка протягом місяця

Наші переваги

Ми не просто ставимо готовий інструмент — ми адаптуємо систему під конкретні сценарії атак, актуальні для вашого моста. У нашій практиці був випадок: клієнт втратив би $12 млн, якби ми не встигли зупинити контракт за 2 блоки до повного drain. Гарантуємо SLA, надаємо код у відкритий доступ (private repo) та не використовуємо чорні ящики.

Замовте консультацію з архітектури моніторингу — це безкоштовно. Зв'яжіться з нами для оцінки вашого проекту.