Разработка модели обнаружения инсайдерской торговли

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка модели обнаружения инсайдерской торговли
Сложная
от 2 недель до 3 месяцев
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

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

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

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

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

Flash loan oracle manipulation

Классический вектор: AMM (Uniswap/Curve пул) используется как price oracle. Атакующий временно двигает цену в AMM через большой trade, использует искажённую цену в протоколе-жертве, возвращает AMM к норме.

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

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

Sandwich attack на oracle update

Менее известный вектор: атакующий знает что oracle обновляется при определённом условии, фронтраннит обновление, эксплуатирует период между старой и новой ценой.

Wash trading для price inflation

Серия координированных сделок между аффилированными кошельками создаёт искусственный объём и движение цены. Цель: поднять цену токена до исполнения крупной продажи или для манипуляции lending collateral value.

Сигнатура: высокая коррелированность между кошельками, чистые нулевые или близкие к нулю P&L циклы, необычно низкий slippage при высоком объёме.

Low-liquidity spot manipulation

Для токенов с низкой ликвидностью ($10K-$100K в пуле) небольшой trade ($50K-$200K) может двинуть цену на 50-200%. Если lending протокол принимает этот токен как collateral с spot price Oracle — exploit тривиален.

Статистические методы детекции

TWAP deviation detector

Самый простой и эффективный метод: сравнивать 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:
    """Compute time-weighted average price over window."""
    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:
    """
    Detect significant deviation between spot and TWAP prices.
    Returns risk assessment.
    """
    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 correlation anomaly detector

Нормальное движение цены сопровождается соответствующим объёмом. Резкое движение цены при аномально высоком объёме в одном направлении — сигнал манипуляции.

def detect_volume_price_anomaly(
    price_changes: List[float],    # % изменение цены за период
    volumes: List[float],           # объём торгов за период
    lookback: int = 100
) -> dict:
    """
    Детектирует аномальное соотношение объём/движение цены
    используя 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 detector (on-chain)

Flash loan атака имеет специфическую структуру транзакции. Детектируем через анализ call trace:

def analyze_transaction_for_flash_loan(tx_trace: dict) -> dict:
    """
    Анализирует call trace транзакции на признаки flash loan атаки.
    tx_trace — output от 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 detector

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 и инфраструктура

Блокчейн ноды (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 manipulation $117M
2023-03 Euler Finance Flash loan drain $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 detectors. Backtest на исторических данных.

On-chain Oracle защита (1 неделя). Manipulation-resistant oracle wrapper, если текущий Oracle уязвим.

Интеграция с circuit breaker (1 неделя). Detection → auto-pause pipeline.

Аудит и тестирование (1 неделя). Воспроизведение известных атак на fork, проверка детекции.

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

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