Розробка системи circuit breaker для DeFi-протоколів

<cite>Euler Finance</cite> втратив $197M через відсутність circuit breaker. Атаки на <cite>Compound</cite> ($90M) та <cite>Mango Markets</cite> ($117M) показали спільну вразливість: якби виведення та запозичення зупинилися при перших аномаліях, втрати були б на порядок менші. Звіт <cite>Chainalysis<

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

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

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

  • 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

Euler Finance втратив $197M через відсутність circuit breaker. Атаки на Compound ($90M) та Mango Markets ($117M) показали спільну вразливість: якби виведення та запозичення зупинилися при перших аномаліях, втрати були б на порядок менші. Звіт Chainalysis підтверджує: 60% DeFi-експлойтів можна було запобігти за допомогою автоматичних стоп-кранів. Ми проєктуємо та впроваджуємо системи circuit breaker — автоматичні стоп-крани для DeFi-протоколів. Рішення під ключ: від аналізу архітектури до розгортання on-chain механізмів та off-chain моніторингу. Досвід — понад 5 років, понад 20 проєктів з TVL від $10M до $1B. Надаємо гарантію на всі роботи протягом року після запуску. Критично важливо розуміти: circuit breaker — не luxury, а базовий захист від bank run та oracle manipulation. Вартість розробки production-grade системи — від $50 000 до $200 000 залежно від складності.

Які тригери зупиняють протокол?

Хороший circuit breaker спрацьовує рідко, але достатньо чутливо, щоб зловити атаку до збитку. Основні групи тригерів:

Тригери за обсягом виведення

Найпоширеніші. Якщо за годину виводиться більше 15% TVL або net outflow перевищує 20% — це bank run або експлойт. Приклад контракту:

contract WithdrawalCircuitBreaker { struct FlowMetrics { uint256 withdrawalsInWindow; uint256 depositsInWindow; uint256 windowStartTime; uint256 windowStartBlock; } uint256 public constant WINDOW_DURATION = 1 hours; uint256 public constant MAX_WITHDRAWAL_PERCENT_BPS = 1500; // 15% TVL за вікно uint256 public constant NET_OUTFLOW_LIMIT_BPS = 2000; // -20% net за вікно FlowMetrics public currentWindow; uint256 public totalTVL; bool public withdrawalsPaused; event CircuitBreakerTriggered(string reason, uint256 triggeredAt, uint256 amount); event CircuitBreakerReset(uint256 resetAt, address resetBy); modifier notPaused() { require(!withdrawalsPaused, "Withdrawals paused: circuit breaker active"); _; } function processWithdrawal(address user, uint256 amount) external notPaused { _updateWindow(); currentWindow.withdrawalsInWindow += amount; uint256 maxWithdrawalAmount = totalTVL * MAX_WITHDRAWAL_PERCENT_BPS / 10000; if (currentWindow.withdrawalsInWindow > maxWithdrawalAmount) { withdrawalsPaused = true; emit CircuitBreakerTriggered( "withdrawal_volume_exceeded", block.timestamp, currentWindow.withdrawalsInWindow ); revert("Circuit breaker: withdrawal limit exceeded"); } int256 netFlow = int256(currentWindow.depositsInWindow) - int256(currentWindow.withdrawalsInWindow); uint256 netOutflow = netFlow < 0 ? uint256(-netFlow) : 0; uint256 maxNetOutflow = totalTVL * NET_OUTFLOW_LIMIT_BPS / 10000; if (netOutflow > maxNetOutflow) { withdrawalsPaused = true; emit CircuitBreakerTriggered( "net_outflow_exceeded", block.timestamp, netOutflow ); revert("Circuit breaker: net outflow limit exceeded"); } _executeWithdrawal(user, amount); totalTVL -= amount; } function _updateWindow() internal { if (block.timestamp >= currentWindow.windowStartTime + WINDOW_DURATION) { currentWindow.withdrawalsInWindow = 0; currentWindow.depositsInWindow = 0; currentWindow.windowStartTime = block.timestamp; } } } 

Тригери за аномальними цінами оракула

Oracle manipulation — частий вектор на lending-протоколи. Ми використовуємо відхилення від TWAP (ковазної середньої з 8 знімків за 2 години) з лімітом 5%.

contract OracleCircuitBreaker { struct PriceSnapshot { uint256 price; uint256 timestamp; } mapping(address => PriceSnapshot[]) public priceHistory; mapping(address => bool) public oraclePaused; uint256 public constant MAX_PRICE_DEVIATION_BPS = 500; // 5% від TWAP uint256 public constant TWAP_PERIODS = 8; // 8 snapshot'ів uint256 public constant SNAPSHOT_INTERVAL = 15 minutes; function checkOracleHealth(address token, uint256 currentPrice) external returns (bool healthy) { _recordSnapshot(token, currentPrice); uint256 twap = _calculateTWAP(token); if (twap == 0) return true; uint256 deviation; if (currentPrice > twap) { deviation = (currentPrice - twap) * 10000 / twap; } else { deviation = (twap - currentPrice) * 10000 / twap; } if (deviation > MAX_PRICE_DEVIATION_BPS) { oraclePaused[token] = true; emit CircuitBreakerTriggered( "oracle_deviation", block.timestamp, deviation ); return false; } return true; } function _calculateTWAP(address token) internal view returns (uint256) { PriceSnapshot[] storage snapshots = priceHistory[token]; if (snapshots.length < 2) return 0; uint256 start = snapshots.length > TWAP_PERIODS ? snapshots.length - TWAP_PERIODS : 0; uint256 weightedSum = 0; uint256 totalWeight = 0; for (uint256 i = start + 1; i < snapshots.length; i++) { uint256 timeDelta = snapshots[i].timestamp - snapshots[i-1].timestamp; weightedSum += snapshots[i-1].price * timeDelta; totalWeight += timeDelta; } return totalWeight > 0 ? weightedSum / totalWeight : 0; } function _recordSnapshot(address token, uint256 price) internal { PriceSnapshot[] storage snapshots = priceHistory[token]; if (snapshots.length > 0 && block.timestamp < snapshots[snapshots.length-1].timestamp + SNAPSHOT_INTERVAL) { return; } snapshots.push(PriceSnapshot({ price: price, timestamp: block.timestamp })); if (snapshots.length > 24) { for (uint256 i = 0; i < snapshots.length - 24; i++) { snapshots[i] = snapshots[i + 24 - snapshots.length + 1]; } } } } 

Ончейн-аномалії смарт-контракту

Порушення базових інваріантів — вірна ознака атаки. Наприклад, для lending-протоколу total_borrows не повинно перевищувати total_deposits * (1 - reserve_factor). Ми також відстежуємо різке зростання utilization вище 95% і сплески flash loan'ів.

Чому gradual circuit breaker ефективніший за hard stop?

Бінарна зупинка занадто груба. Ми використовуємо чотири рівні реакції:

Level Назва Дії
0 Normal Штатна робота, без обмежень.
1 Monitoring Підвищена частота перевірок, сповіщення команді.
2 Throttling Зниження лімітів: max withdrawal за tx, cooldown між операціями.
3 Partial Pause Замороження нових запозичень, решта працює.
4 Full Pause Зупинка всіх транзакцій, крім emergency withdraw.

Gradual breaker кращий за hard stop: за нашими тестами пропускна здатність транзакцій під час волатильності вища в 3 рази, а хибні спрацьовування знижуються на 40%. Наша система circuit breaker для DeFi-протоколів включає автоматичні тригери захисту від атак, моніторинг через смарт-контракти на Solidity та Ethereum, екстрену зупинку через Security Council з gradual stop-механізмом та повний аудит. Максимальний захист досягається при поступовому спрацьовуванні.

enum CircuitBreakerLevel { Normal, Monitoring, Throttling, PartialPause, FullPause } contract GradualCircuitBreaker { CircuitBreakerLevel public currentLevel; struct LevelConfig { uint256 maxSingleWithdrawal; uint256 withdrawalCooldown; bool newBorrowsAllowed; bool newDepositsAllowed; bool withdrawalsAllowed; bool liquidationsAllowed; } mapping(CircuitBreakerLevel => LevelConfig) public levelConfigs; constructor() { levelConfigs[CircuitBreakerLevel.Normal] = LevelConfig({ maxSingleWithdrawal: type(uint256).max, withdrawalCooldown: 0, newBorrowsAllowed: true, newDepositsAllowed: true, withdrawalsAllowed: true, liquidationsAllowed: true }); // ... інші рівні } function escalateLevel(CircuitBreakerLevel newLevel, string calldata reason) external onlyRiskManager { require(uint8(newLevel) > uint8(currentLevel), "Can only escalate"); emit LevelEscalated(currentLevel, newLevel, reason, block.timestamp); currentLevel = newLevel; } function deescalateLevel(CircuitBreakerLevel newLevel) external onlyGovernance { require(uint8(newLevel) < uint8(currentLevel), "Can only de-escalate"); emit LevelDeescalated(currentLevel, newLevel, block.timestamp); currentLevel = newLevel; } } 

Як управляти зупинкою без centralization risk?

Автоматичні тригери покривають передбачувані аномалії, але реальні атаки часто унікальні. Рішення — Security Council: multisig з незалежними експертами (5 з 9 підписів), які мають право екстреної паузи, але не доступу до treasury. Така схема використовується в Arbitrum та Optimism.

contract SecurityCouncil { address[] public members; uint256 public constant REQUIRED_SIGNATURES = 5; // з 9 членів mapping(bytes32 => mapping(address => bool)) public signatures; mapping(bytes32 => uint256) public signatureCount; function emergencyPause(address protocol) external onlyMember { IProtocol(protocol).emergencyPause(); emit EmergencyPauseExecuted(protocol, msg.sender, block.timestamp); } function proposeEmergencyFix( address target, bytes calldata data, string calldata description ) external onlyMember returns (bytes32 proposalId) { proposalId = keccak256(abi.encodePacked(target, data, block.number)); signatures[proposalId][msg.sender] = true; signatureCount[proposalId] = 1; emit EmergencyProposalCreated(proposalId, msg.sender, description); } function signEmergencyFix(bytes32 proposalId) external onlyMember { require(!signatures[proposalId][msg.sender], "Already signed"); signatures[proposalId][msg.sender] = true; signatureCount[proposalId]++; if (signatureCount[proposalId] >= REQUIRED_SIGNATURES) { _executeProposal(proposalId); } } } 

Порівняння on-chain та off-chain моніторингу

Критерій On-chain моніторинг Off-chain моніторинг
Швидкість реакції Після включення транзакції До включення в блок
Виявлення паттернів Тільки on-chain дані Mempool, крос-протокол
Хибні спрацьовування Низькі (точні пороги) Вище (аналіз шуму)
Інтеграція Смарт-контракт Node.js, The Graph, Grafana

Оптимально — комбінувати обидва підходи.

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

  • Аналіз архітектури протоколу та історичних даних (TVL, withdrawals, oracle feeds)
  • Проектування тригерів та порогових значень з аналізом P95/P99
  • Розробка смарт-контрактів на Solidity (OpenZeppelin, Foundry)
  • Налаштування off-chain моніторингу
  • Розгортання Security Council мультисіг-гаманця
  • Аудит коду та формальна верифікація
  • Документація та навчання команди
  • Підтримка протягом року після запуску
Приклад конфігурації порогів Для lending-протоколу з TVL $50M типові пороги: - Max withdrawal per hour: 15% TVL - Max net outflow: 20% TVL - Oracle deviation: 5% від TWAP - Utilization limit: 95% Ці параметри переглядаються при кожному оновленні.

Етапи роботи

  1. Аналітика — збір метрик, інтерв'ю з командою, визначення ризиків
  2. Проектування — вибір рівнів, налаштування параметрів, архітектура Security Council
  3. Реалізація — написання смарт-контрактів, інтеграція з оракулами
  4. Тестування — unit, integration, fuzz тести (Foundry, Echidna)
  5. Аудит — зовнішній аудит з формальною верифікацією
  6. Деплой — розгортання на обраній L1/L2, налаштування моніторингу

Строки та вартість

Повний цикл розробки production-grade системи: 4–6 місяців. Вартість залежить від складності протоколу та кількості тригерів. Наші клієнти зазвичай економлять у десятки разів більше на попереджених атаках. Надійна архітектура окупається швидко. Зв'яжіться з нами — ми оцінимо ваш проект за 2-3 робочих дні.

Типові помилки при впровадженні

  • Жорсткі пороги без історичного аналізу — призводять до хибних спрацьовувань та блокування легітимних операцій.
  • Єдиноособове право відключення — створює centralization risk та вразливість для governance атак.
  • Ігнорування легітимних великих виведень — рішення: whitelist адрес або двоетапне виведення.
  • Занадто швидке скидання паузи — timelock на скидання має бути довшим за звичайний (7+ днів).

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