Розробка моделі виявлення інсайдерської торгівлі

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

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

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

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

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

Розробка моделі детекції маніпуляції цінами токенів

Маніпуляція цінами в DeFi — не абстрактна загроза. Flash loan атаки використовують тимчасове викривлення цени токена для дренажу lending протоколів: позич мільярд, маніпулюй цину Oracle, отримай займи під неіснуючу вартість, поверни займ, відчисли прибуток. Mango Markets (жовтень 2022) — $117M вкрадено через маніпуляцію ціною MNGO токена у Mango oracle. CREAM Finance (жовтень 2021) — $130M через flash loan + маніпуляцію цини yUSD.

Модель детекції не попереджує атаку, але дозволяє: (1) зупинити протокол до виконання шкідливої транзакції, (2) вивчати закономірності для покращення захисту Oracle, (3) сповіщати команду в реальному часі.

Типологія маніпуляцій

Flash loan oracle маніпуляція

Класичний вектор: AMM (Uniswap/Curve пул) використовується як price oracle. Атакуючий тимчасово рухає ціну в AMM через великий swap, експлуатує викривлену ціну в протоколі-жертві, повертає AMM до норми.

Сигнатура атаки в on-chain даних:

  • Flash loan транзакція (один блок, одна tx)
  • Всередині tx: великий swap → виклик протоколу-жертви → зворотний swap
  • Різке відхилення spot price від TWAP на початку tx
  • Повернення до нормальної ціни в кінці tx

Sandwich атака на oracle оновлення

Менш відома: атакуючий знає, коли oracle оновлюється при певній умові, фронтрани оновлення, експлуатує період між старою та новою ціною.

Wash trading для інфляції ціни

Серія скоординованих транзакцій між афільованими гаманцями створює штучний обсяг та рух ціни. Мета: підняти ціну токена перед великим продажем або маніпулювати вартістю collateral у lending.

Сигнатура: висока кореляція гаманців, нульові або близькі до нуля P&L цикли, необично низькі slippage при високому обсязі.

Маніпуляція spot з низькою ліквідністю

Для токенів з низькою ліквідністю ($10K-$100K в пулі) малий swap ($50K-$200K) може рухнути ціну на 50-200%. Якщо lending протокол приймає цей токен як collateral з spot price Oracle — експлойт тривіальний.

Статистичні методи детекції

TWAP deviation детектор

Найпростіший та найефективніший метод: порівняти spot price з TWAP (Time-Weighted Average Price).

import numpy as np
from dataclasses import dataclass
from typing import List

@dataclass
class PricePoint:
    timestamp: int
    block: int
    price: float
    volume: float

def compute_twap(prices: List[PricePoint], window_seconds: int) -> float:
    """Обчислити time-weighted середню ціну за вікно."""
    if not prices:
        return 0.0

    current_time = prices[-1].timestamp
    cutoff_time = current_time - window_seconds

    relevant = [p for p in prices if p.timestamp >= cutoff_time]
    if len(relevant) < 2:
        return prices[-1].price

    total_weighted = 0.0
    total_time = 0.0

    for i in range(1, len(relevant)):
        dt = relevant[i].timestamp - relevant[i-1].timestamp
        total_weighted += relevant[i-1].price * dt
        total_time += dt

    return total_weighted / total_time if total_time > 0 else relevant[-1].price

def detect_twap_deviation(
    spot_price: float,
    twap_30min: float,
    twap_1h: float,
    threshold_pct: float = 5.0
) -> dict:
    """
    Виявити значне відхилення між spot та TWAP цінами.
    Повертає оцінку ризику.
    """
    dev_30min = abs(spot_price - twap_30min) / twap_30min * 100
    dev_1h = abs(spot_price - twap_1h) / twap_1h * 100

    severity = 'normal'
    if dev_30min > threshold_pct * 3 or dev_1h > threshold_pct * 4:
        severity = 'critical'
    elif dev_30min > threshold_pct * 2 or dev_1h > threshold_pct * 2.5:
        severity = 'high'
    elif dev_30min > threshold_pct or dev_1h > threshold_pct * 1.5:
        severity = 'medium'

    return {
        'spot': spot_price,
        'twap_30min': twap_30min,
        'twap_1h': twap_1h,
        'deviation_30min_pct': dev_30min,
        'deviation_1h_pct': dev_1h,
        'severity': severity,
    }

Детектор аномалії volume-price кореляції

Нормальний рух ціни супроводжується відповідним обсягом. Різкий рух ціни з аномально високим одностороннім обсягом — сигнал маніпуляції.

def detect_volume_price_anomaly(
    price_changes: List[float],    # % зміна ціни за період
    volumes: List[float],           # обсяг торгів за період
    lookback: int = 100
) -> dict:
    """
    Виявити аномальне співвідношення volume/price рух
    використовуючи Z-score нормалізацію.
    """
    if len(price_changes) < lookback:
        return {'anomaly': False, 'reason': 'insufficient data'}

    # Нормалізуємо за історичним розподілом
    hist_prices = np.array(price_changes[-lookback:])
    hist_volumes = np.array(volumes[-lookback:])

    current_price_change = price_changes[-1]
    current_volume = volumes[-1]

    price_zscore = (current_price_change - hist_prices.mean()) / (hist_prices.std() + 1e-8)
    volume_zscore = (current_volume - hist_volumes.mean()) / (hist_volumes.std() + 1e-8)

    # Аномалія: високий обсяг + великий рух в один бік
    is_anomaly = (
        abs(price_zscore) > 3.0 and     # ціна > 3 std devs від норми
        volume_zscore > 2.5 and          # обсяг > 2.5 std devs від норми
        price_zscore * volume_zscore > 0 # обидва в один напрям
    )

    return {
        'anomaly': is_anomaly,
        'price_zscore': price_zscore,
        'volume_zscore': volume_zscore,
        'current_price_change_pct': current_price_change,
        'volume_vs_avg': current_volume / hist_volumes.mean(),
    }

Flash loan pattern детектор (on-chain)

Flash loan атака має специфічну структуру транзакції. Виявляємо через аналіз call trace:

def analyze_transaction_for_flash_loan(tx_trace: dict) -> dict:
    """
    Аналізує call trace транзакції на ознаки flash loan атаки.
    tx_trace — вихід з debug_traceTransaction або Tenderly API.
    """
    calls = flatten_calls(tx_trace)

    # Шукаємо flash loan паттерн: flashLoan → [вклики] → flashLoan callback
    flash_loan_providers = {
        '0xba12222222228d8ba445958a75a0704d566bf2c8': 'Balancer',  # Balancer Vault
        '0x7d2768de32b0b80b7a3454c06bdac94a69ddc7a9': 'Aave V2',
        '0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2': 'Aave V3',
    }

    involved_flash_loans = []
    large_swaps = []
    target_protocol_calls = []

    for call in calls:
        if call['to'].lower() in flash_loan_providers:
            involved_flash_loans.append({
                'provider': flash_loan_providers[call['to'].lower()],
                'selector': call['input'][:10],
            })

        # Шукаємо великі swap подій
        if is_swap_call(call) and parse_swap_amount(call) > LARGE_SWAP_THRESHOLD:
            large_swaps.append(call)

    # Flash loan + великий swap в одній транзакції = високий ризик
    risk_score = 0
    if involved_flash_loans:
        risk_score += 50
    if len(large_swaps) >= 2:  # swap туди та зворотно
        risk_score += 30
    if has_target_protocol_interaction(calls):
        risk_score += 20

    return {
        'risk_score': risk_score,
        'is_high_risk': risk_score >= 80,
        'flash_loans': involved_flash_loans,
        'large_swaps': len(large_swaps),
        'recommendation': 'BLOCK' if risk_score >= 80 else 'MONITOR',
    }

Детектор wash trading

def detect_wash_trading(
    trades: List[dict],       # {buyer, seller, amount, price, timestamp}
    lookback_hours: int = 24
) -> dict:
    """
    Виявити wash trading паттерни.
    Ознаки: один адрес як buyer та seller,
    або кільце взаємних торгів.
    """
    from collections import defaultdict

    # Будуємо граф торгових відносин
    trade_graph = defaultdict(lambda: defaultdict(float))

    cutoff = int(time.time()) - lookback_hours * 3600
    recent_trades = [t for t in trades if t['timestamp'] >= cutoff]

    for trade in recent_trades:
        trade_graph[trade['buyer']][trade['seller']] += trade['amount']
        trade_graph[trade['seller']][trade['buyer']] += trade['amount']

    wash_pairs = []
    addresses = list(trade_graph.keys())

    for i, addr_a in enumerate(addresses):
        for addr_b in addresses[i+1:]:
            flow_a_to_b = trade_graph[addr_a][addr_b]
            flow_b_to_a = trade_graph[addr_b][addr_a]

            if flow_a_to_b > 0 and flow_b_to_a > 0:
                symmetry_ratio = min(flow_a_to_b, flow_b_to_a) / max(flow_a_to_b, flow_b_to_a)

                # Висока симетрія = підозріле
                if symmetry_ratio > 0.8:
                    wash_pairs.append({
                        'address_a': addr_a,
                        'address_b': addr_b,
                        'flow_ab': flow_a_to_b,
                        'flow_ba': flow_b_to_a,
                        'symmetry': symmetry_ratio,
                    })

    return {
        'wash_pairs_found': len(wash_pairs),
        'suspicious_pairs': wash_pairs[:10],
        'is_suspicious': len(wash_pairs) > 0,
    }

On-chain Oracle захист

Модель детекції доповнюється on-chain захистом в самому Oracle. Chainlink CCIP Price Feed має вбудовані circuit breaker-и, але кастомні oracle (Uniswap V3 TWAP, Curve EMA) вимагають ручного захисту:

contract ManipulationResistantOracle {
    IUniswapV3Pool public immutable pool;
    uint32 public constant TWAP_PERIOD = 1800;  // 30 хвилин
    uint256 public constant MAX_DEVIATION_BPS = 500; // 5%

    function getPrice() external view returns (uint256) {
        uint256 spotPrice = _getSpotPrice();
        uint256 twapPrice = _getTWAPPrice(TWAP_PERIOD);

        // Перевіряємо що spot не відхилився більш ніж на MAX_DEVIATION від TWAP
        uint256 deviation = spotPrice > twapPrice
            ? (spotPrice - twapPrice) * 10000 / twapPrice
            : (twapPrice - spotPrice) * 10000 / twapPrice;

        if (deviation > MAX_DEVIATION_BPS) {
            // Під час маніпуляції — повертаємо TWAP, не spot
            return twapPrice;
        }

        return spotPrice;
    }

    function _getTWAPPrice(uint32 period) internal view returns (uint256) {
        uint32[] memory secondsAgos = new uint32[](2);
        secondsAgos[0] = period;
        secondsAgos[1] = 0;

        (int56[] memory tickCumulatives,) = pool.observe(secondsAgos);
        int56 tickDiff = tickCumulatives[1] - tickCumulatives[0];
        int24 avgTick = int24(tickDiff / int56(uint56(period)));

        return TickMath.getSqrtRatioAtTick(avgTick);
    }
}

Pipeline та інфраструктура

Blockchain ноди (Alchemy/QuickNode)
        ↓ WebSocket streams
Event Processor (Node.js)
        ↓
Detection Models (Python FastAPI)
        ├── TWAP Deviation Checker
        ├── Volume Anomaly Detector
        ├── Flash Loan Analyzer
        └── Wash Trading Detector
        ↓
Risk Aggregator
        ├── Score < 40: log only
        ├── Score 40-70: alert команді
        └── Score > 70: auto-pause + alert
        ↓
Actions: Telegram/PagerDuty + Circuit Breaker

Latency критична: від появи підозрілої pending транзакції до виконання pause повинно пройти < 3 секунд.

Дані для навчання та тестування

Історичні атаки — найкращий источник ground truth. Публічно задокументовані інциденти:

Дата Протокол Тип атаки Ущерб
2021-10 Cream Finance Flash loan + oracle $130M
2022-04 Beanstalk Governance flash loan $182M
2022-10 Mango Markets Spot маніпуляція $117M
2023-03 Euler Finance Flash loan дренаж $197M

Кожна атака задокументована на rekt.news та має on-chain дані (transaction hashes). Відтворення на Foundry fork: forge test --fork-url $ETH_RPC --fork-block-number [pre-attack block].

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

Аналіз загроз (1 тиждень). Карта можливих векторів маніпуляції для конкретного протоколу. Які Oracle використовуються, їхня ліквідність, які функції залежать від ціни.

Розробка detection моделей (2-3 тижні). Python ML сервіс з TWAP deviation + volume anomaly + flash loan pattern детекторами. Backtest на історичних даних.

On-chain Oracle захист (1 тиждень). Manipulation-resistant oracle обгортка, якщо поточний Oracle уразливий.

Circuit breaker інтеграція (1 тиждень). Detection → auto-pause pipeline.

Аудит та тестування (1 тиждень). Відтворення відомих атак на fork, перевірка детекції.

Мониторингова інфраструктура (1-2 тижні). Event streaming, alerting, dashboards.

Повний цикл: 2-2,5 місяці. Стоимість — після оцінки scope та підтримуваних ланцюгів.