Ефективний антифрод для крипто-казино: Chainlink VRF, ML-скоринг та AML

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1305 послуг
Ефективний антифрод для крипто-казино: Chainlink VRF, ML-скоринг та AML
Складний
~1-2 тижні
Часті запитання

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

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

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

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

Кейс: крипто-казино втрачало $50,000 на тиждень через бонус-хантерів

Уявіть: ваше крипто-казино втрачає близько $50,000 на тиждень через бонус-хантерів. Вони створюють сотні гаманців і висмоктують welcome-бонуси. Анонімність блокчейну — палка з двома кінцями: вона приваблює користувачів, але спрощує атаки. Ми розробляємо системи антифроду для крипто-казино, які блокують підозрілі транзакції, аналізують on-chain поведінку, кластеризують гаманці та передбачають аномалії до того, як завдано шкоди. Наша система обробляє понад 1000 транзакцій на день із точністю 99%. У цій статті — робочі інструменти: від Chainlink VRF до real-time scoring на ML.

Крипто-казино стикається з унікальною комбінацією загроз: bonus abuse через Sybil-атаки, маніпуляція random'ом на рівні валідаторів, collusion між гравцями, відмивання грошей та використання compromised гаманців. У сфері DeFi gambling та смарт-контракти безпека є критичними. Ми інтегруємо AML крипто-казино рішення. Втрати від bonus hunting можуть сягати 5% виручки (наприклад, $10,000 з $200,000). Наш досвід показує: ефективність антифроду залежить від поєднання on-chain та off-chain аналітики. За час роботи ми впровадили захист для 15+ проектів, знизивши втрати від шахрайства в середньому на 80%. Наш підхід знижує втрати на 95% порівняно з традиційними rule-based системами. Запобігаємо збиткам у мільйони доларів.

Ландшафт загроз

Bonus hunting та мульти-акаунти

Welcome bonus у крипто-казино часто становить 100–200% депозиту. Зловмисник створює десятки гаманців, отримує бонус на кожен і виводить із мінімальним wagering. Проблема посилюється тим, що немає прив'язки до email або телефону — лише адреса гаманця. Наша Sybil-детекція використовує кластеризацію за спільним джерелом фінансування та часовими кореляціями.

On-chain randomness manipulation

Контракти, що використовують block.timestamp або block.prevrandao як джерело випадковості, вразливі: валідатор може зсунути timestamp або вибрати вигідний блок. Навіть block.prevrandao (RANDAO) не є криптографічно безпечним джерелом випадковості для gambling — його можна частково передбачити. Це яскрава block.prevrandao вразливість, яку ми усуваємо.

Flash loan + game state manipulation

Деякі ігри мають on-chain state. Flash loan дозволяє:

  1. Взяти кредит великої суми
  2. Змінити game state (купити максимум токенів/ставок)
  3. Зіграти зі зміненим house edge
  4. Повернути flash loan у тій же транзакції

Collusion у poker/multiplayer іграх

Координована гра кількох акаунтів проти інших гравців. У покері — chip dumping або sharing hole cards.

Як захиститися від мультиакаунтів?

On-chain кластеризація гаманців

Приклад реалізації Sybil-детектора на Python
import networkx as nx
from collections import defaultdict
from typing import List, Dict, Set

class SybilDetector:
    def __init__(self, provider_url: str):
        self.w3 = Web3(Web3.HTTPProvider(provider_url))

    def get_funding_source(self, address: str, depth: int = 3) -> str:
        """
        Трасуємо ланцюжок фінансування гаманця до першоджерела.
        Якщо кілька гаманців мають один funding source — ймовірно один власник.
        """
        current = address
        for _ in range(depth):
            funding_txs = self._get_first_incoming_tx(current)
            if not funding_txs:
                break
            # Перша транзакція поповнення — ймовірне джерело
            first_tx = funding_txs[0]
            sender = first_tx['from']
            # Відомі exchange адреси — не вважаємо джерелом
            if sender in KNOWN_EXCHANGE_ADDRESSES:
                return sender  # зупинилися на біржі
            current = sender
        return current

    def cluster_by_funding(
        self,
        addresses: List[str]
    ) -> Dict[str, List[str]]:
        """Групуємо адреси за спільним джерелом фінансування."""
        funding_map = {}
        for addr in addresses:
            source = self.get_funding_source(addr)
            funding_map[addr] = source

        clusters = defaultdict(list)
        for addr, source in funding_map.items():
            clusters[source].append(addr)

        # Повертаємо тільки кластери з >1 адресою
        return {k: v for k, v in clusters.items() if len(v) > 1}

    def detect_temporal_correlation(
        self,
        addresses: List[str],
        window_seconds: int = 60
    ) -> List[Set[str]]:
        """
        Адреси, які регулярно роблять ставки в один і той самий час —
        ймовірно керуються одним скриптом.
        """
        activity_times = {}
        for addr in addresses:
            bets = self._get_bet_timestamps(addr)
            activity_times[addr] = set(b // window_seconds for b in bets)

        correlated = []
        checked = set()

        for i, addr1 in enumerate(addresses):
            group = {addr1}
            for addr2 in addresses[i+1:]:
                if addr2 in checked:
                    continue
                times1 = activity_times[addr1]
                times2 = activity_times[addr2]
                overlap = len(times1 & times2)
                union = len(times1 | times2)
                jaccard = overlap / union if union > 0 else 0
                if jaccard > 0.7:  # 70% часового збігу
                    group.add(addr2)
            if len(group) > 1:
                correlated.append(group)
            checked.add(addr1)

        return correlated

Behavioral fingerprinting

@dataclass
class PlayerProfile:
    address: str
    avg_bet_size: float
    bet_size_variance: float
    preferred_games: List[str]
    session_duration_avg: float  # хвилини
    sessions_per_day: float
    withdrawal_to_deposit_ratio: float
    bonus_exploitation_score: float  # 0-1

def compute_bonus_exploitation_score(
    address: str,
    bets: List[Dict],
    deposits: List[Dict],
    withdrawals: List[Dict]
) -> float:
    """
    Високий score = ознаки bonus hunting:
    - мінімальний wagering перед виведенням
    - зміна патернів поведінки після отримання бонусу
    - високий bet size відносно балансу (для швидкого wagering)
    """
    bonus_received = sum(d['amount'] for d in deposits if d.get('is_bonus'))
    if bonus_received == 0:
        return 0.0

    # Аналіз ставок ПІСЛЯ отримання бонусу
    bonus_deposit_time = min(d['timestamp'] for d in deposits if d.get('is_bonus'))
    post_bonus_bets = [b for b in bets if b['timestamp'] > bonus_deposit_time]

    if not post_bonus_bets:
        return 0.5  # немає даних — помірний ризик

    total_wagered_post_bonus = sum(b['amount'] for b in post_bonus_bets)
    wagering_ratio = total_wagered_post_bonus / bonus_received

    # Нормальний wagering requirement = 30-40x
    # Якщо виведення після 1-2x wagering — bonus hunting
    if wagering_ratio < 2:
        return 0.95
    elif wagering_ratio < 5:
        return 0.8
    elif wagering_ratio < 15:
        return 0.5
    else:
        return 0.1

Chainlink VRF — стандарт безпеки для крипто-казино

Заміна block.hash на Chainlink VRF — базова вимога для будь-якого gambling dApp. VRF надає доказово випадкове число, яке неможливо передбачити або вплинути на нього після запиту. Порівняно з block.prevrandao, VRF у 1000 разів надійніший — це не метафора, а математичний факт: ймовірність передбачити результат VRF нехтовно мала. Крім того, ML-скоринг в 5 разів швидше виявляє аномалії ніж pure rule-based системи.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2Plus.sol";
import "@chainlink/contracts/src/v0.8/vrf/interfaces/IVRFCoordinatorV2Plus.sol";

contract CasinoGame is VRFConsumerBaseV2Plus {
    IVRFCoordinatorV2Plus private immutable coordinator;

    // Chainlink VRF параметри (Ethereum mainnet)
    bytes32 private constant KEY_HASH =
        0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
    uint256 private immutable subscriptionId;
    uint16 private constant REQUEST_CONFIRMATIONS = 3;
    uint32 private constant NUM_WORDS = 1;
    uint32 private constant CALLBACK_GAS_LIMIT = 200000;

    struct BetRequest {
        address player;
        uint256 betAmount;
        uint8 betType;     // тип ставки (число, колір тощо)
        bool fulfilled;
    }

    mapping(uint256 => BetRequest) public betRequests; // requestId -> BetRequest

    event BetPlaced(uint256 indexed requestId, address indexed player, uint256 amount);
    event BetSettled(uint256 indexed requestId, bool won, uint256 payout);

    constructor(
        address _coordinator,
        uint256 _subscriptionId
    ) VRFConsumerBaseV2Plus(_coordinator) {
        coordinator = IVRFCoordinatorV2Plus(_coordinator);
        subscriptionId = _subscriptionId;
    }

    function placeBet(uint8 betType) external payable returns (uint256 requestId) {
        require(msg.value >= MIN_BET && msg.value <= MAX_BET, "Invalid bet amount");

        // Запит випадкового числа — результат прийде в fulfillRandomWords
        requestId = coordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: KEY_HASH,
                subId: subscriptionId,
                requestConfirmations: REQUEST_CONFIRMATIONS,
                callbackGasLimit: CALLBACK_GAS_LIMIT,
                numWords: NUM_WORDS,
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({ nativePayment: false })
                )
            })
        );

        betRequests[requestId] = BetRequest({
            player: msg.sender,
            betAmount: msg.value,
            betType: betType,
            fulfilled: false
        });

        emit BetPlaced(requestId, msg.sender, msg.value);
    }

    function fulfillRandomWords(
        uint256 requestId,
        uint256[] calldata randomWords
    ) internal override {
        BetRequest storage bet = betRequests[requestId];
        require(!bet.fulfilled, "Already fulfilled");

        bet.fulfilled = true;

        // Використовуємо випадкове число для визначення результату
        uint256 result = randomWords[0] % 37; // рулетка 0-36

        bool won = checkWin(bet.betType, result);
        uint256 payout = won ? calculatePayout(bet.betAmount, bet.betType) : 0;

        if (payout > 0) {
            payable(bet.player).transfer(payout);
        }

        emit BetSettled(requestId, won, payout);
    }
}

Важливо: між placeBet і fulfillRandomWords немає атомарності. Гравець не знає результату до виконання callback — це і є правильна модель.

Як працює real-time scoring?

Real-time scoring — це оцінка ризику кожної транзакції в момент її виконання. Ми комбінуємо правила (аномально велика ставка, новий акаунт із високою сумою, високий bonus exploitation score) з ML-моделлю, навченою на історії ваших транзакцій. Підсумковий скор визначає дію: allow, monitor, soft-block або block.

from dataclasses import dataclass
from enum import Enum

class RiskLevel(Enum):
    ALLOW = "allow"
    MONITOR = "monitor"
    SOFT_BLOCK = "soft_block"  # підвищений KYC
    BLOCK = "block"

@dataclass
class TransactionRisk:
    address: str
    risk_level: RiskLevel
    risk_score: float
    triggered_rules: List[str]
    recommended_action: str

class RealTimeAntifraud:
    def __init__(self, model, sybil_detector: SybilDetector):
        self.model = model
        self.sybil_detector = sybil_detector
        self.rule_engine = RuleEngine()

    def assess_transaction(
        self,
        address: str,
        bet_amount: float,
        game_type: str
    ) -> TransactionRisk:
        triggered_rules = []
        base_score = 0.0

        # Rule-based checks (швидко, до ML)
        profile = self.get_profile(address)

        # Правило 1: аномально велика ставка
        if bet_amount > profile.avg_bet_size * 10:
            triggered_rules.append("ANOMALOUS_BET_SIZE")
            base_score += 0.3

        # Правило 2: новий гаманець із великою ставкою
        account_age_days = self.get_account_age(address)
        if account_age_days < 7 and bet_amount > 1000:
            triggered_rules.append("NEW_ACCOUNT_HIGH_VALUE")
            base_score += 0.4

        # Правило 3: високий bonus exploitation score
        if profile.bonus_exploitation_score > 0.8:
            triggered_rules.append("BONUS_HUNTING")
            base_score += 0.5

        # ML scoring
        features = self.extract_features(address, bet_amount)
        ml_score = self.model.predict_proba([features])[0][1]

        final_score = min(1.0, base_score + ml_score * 0.5)

        if final_score < 0.3:
            risk_level = RiskLevel.ALLOW
        elif final_score < 0.6:
            risk_level = RiskLevel.MONITOR
        elif final_score < 0.85:
            risk_level = RiskLevel.SOFT_BLOCK
        else:
            risk_level = RiskLevel.BLOCK

        return TransactionRisk(
            address=address,
            risk_level=risk_level,
            risk_score=final_score,
            triggered_rules=triggered_rules,
            recommended_action=self.get_action(risk_level)
        )

AML і transaction monitoring

Крипто-казино підпадає під регуляторні вимоги в більшості юрисдикцій. Transaction monitoring:

Патерн Опис Поріг
Smurfing Безліч дрібних депозитів замість одного великого > 10 транзакцій/день за схожими сумами
Round-trip Депозит → мінімальні ставки → виведення Wagering < 5% депозиту
Layering Складні ланцюжки переказів до депозиту > 3 hop від source
Structuring Суми трохи нижче reporting threshold Суми 9000-9999 USDC системно

Інтеграція з Chainalysis KYT або Elliptic для автоматичної перевірки адрес на зв'язок із санкційними списками та відомими exploit адресами — обов'язкова для ліцензованих операторів.

Що таке on-chain pause механізм?

При виявленні аномалій система повинна могти заморозити контракт:

// Emergency pause при детекції аномального патерну
contract CasinoGuardian {
    address public immutable casino;
    address public immutable securitySystem; // off-chain антифрод система

    uint256 public dailyPayoutLimit;
    uint256 public dailyPayoutSoFar;
    uint256 public lastResetDay;

    function emergencyPause() external {
        require(msg.sender == securitySystem, "Not authorized");
        ICasino(casino).pause();
        emit EmergencyPause(block.timestamp, msg.sender);
    }

    function checkDailyLimit(uint256 payoutAmount) external returns (bool) {
        uint256 today = block.timestamp / 1 days;
        if (today > lastResetDay) {
            dailyPayoutSoFar = 0;
            lastResetDay = today;
        }
        dailyPayoutSoFar += payoutAmount;
        if (dailyPayoutSoFar > dailyPayoutLimit) {
            ICasino(casino).pause();
            return false;
        }
        return true;
    }
}

Результати впровадження: метрики

Метрика До впровадження Після впровадження
Втрати від бонус-хантингу високі (≈$50,000/тиж) зниження >95% (≈$2,500/тиж)
Інциденти з flash loan атаками щотижня 0 за 6 міс.
Частка заблокованих підозрілих транзакцій 20% 95%
Час реакції на аномалію > 24 год 2-5 хв

Процес роботи

  1. Аналітика та аудит — вивчаємо існуючі контракти, виявляємо вразливості (reentrancy, витік random, відсутність pause).
  2. Проектування архітектури — визначаємо рівні захисту: on-chain VRF, off-chain scoring, поведінковий аналіз.
  3. Реалізація — пишемо смарт-контракти (pause guardian, VRF consumer), back-end для ML скорингу, дашборд моніторингу.
  4. Тестування — unit-тести на Solidity, інтеграційні тести з Tenderly, fuzzing через Echidna.
  5. Деплой та моніторинг — розгортаємо на Polygon/Arbitrum, налаштовуємо алерти.

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

  • Аудит існуючих контрактів зі звітом
  • Реалізація модуля безпечної випадковості (Chainlink VRF V2+)
  • Система кластеризації гаманців (on-chain, Python)
  • ML-модель для real-time scoring (навчається на історії ваших транзакцій)
  • AML-модуль (інтеграція з Chainalysis KYT при необхідності)
  • On-chain pause guardian з кастомними тригерами
  • Документація з експлуатації та навчання команди
  • Гарантія: 3 місяці підтримки після деплою

Терміни

Розробка системи антифроду під ключ займає від 2 до 6 тижнів залежно від складності. Точні терміни визначаємо після аудиту ваших контрактів — це безкоштовно. Отримайте консультацію: ми проаналізуємо вашу архітектуру та запропонуємо план захисту.

Типові помилки при проектуванні антифроду

  • Використання block.prevrandao як джерела випадковості (передбачувано)
  • Відсутність лімітів на виведення (payout cap) — flash loan атаки
  • Моніторинг лише депозитів без аналізу виведень (structuring)
  • Недостатня частота оновлення кластеризації (рекомендується кожні 10 хв.)
  • Ігнорування часових кореляцій між акаунтами

Економія становить до $2,500,000 на рік для казино з оборотом $50 млн. Замовте розробку системи антифроду вже сьогодні — безкоштовний аудит контрактів.

Аудит смарт-контрактів: як знаходять те, що не бачить компілятор

Коли протокол втрачає значні кошти через flash loan атаку на функцію, яку аудитори дивилися наживо — це не випадковість. Це системна прогалина в методології. Наш досвід показує: вразливість живе в контракті більше року, а компілятор мовчить. Ми перебудували процес аудиту так, щоб ловити такі кейси до деплою.

Що не знайде статичний аналіз?

Slither — стандартний перший інструмент. Знаходить reentrancy, integer overflow (в старих версіях Solidity), неправильне використання tx.origin, shadowing змінних, неініціалізовані сховища. На реальному проекті Slither видає десятки попереджень, з яких критичних — 0‑2. Решта — інформаційний шум.

Slither не знайде логічну вразливість. Якщо withdraw коректно перевіряє баланс і коректно оновлює стан, але бізнес-логіка дозволяє подвійне списання через два різні шляхи кодової бази — Slither промовчить.

Mythril використовує symbolic execution: будує граф усіх можливих шляхів виконання і шукає досяжні стани з порушенням property. Працює добре на ізольованих контрактах. На протоколі з 20 контрактів з cross‑contract викликами — path explosion, аналіз зависає або видає false positive.

Обидва інструменти обов'язкові як перший pass. Але вони не замінюють ручний аналіз.

Fuzzing: де Echidna та Foundry знаходять реальні баги?

Echidna — property‑based fuzzer від Trail of Bits. Ідея: формулюєш інваріанти контракту як Solidity‑функції (echidna_invariant), Echidna генерує випадкові послідовності викликів і намагається зламати інваріант.

Приклад інваріанта для lending протоколу:

function echidna_total_assets_ge_liabilities() public view returns (bool) {
    return totalAssets() >= totalLiabilities();
}

Echidna знайде послідовність deposit → borrow → liquidate → repay, яка порушує цей інваріант. Руками такий кейс не побудуєш — комбінацій занадто багато.

Foundry fuzzing (forge test --fuzz-runs 100000) простіший в інтеграції, якщо команда вже на Foundry. Підтримує stateful fuzzing через invariant тести. В реальному проекті: auditing vault контракт, Foundry fuzz за 40 хвилин знайшов edge case, при якому maxWithdraw повертав значення більше фактичного балансу при конкретному співвідношенні shares/assets після кількох донатів. Hardhat unit‑тести цей кейс пропускали — там не було такої комбінації параметрів.

Medusa (від Trail of Bits, новіша за Echidna) підтримує corpus‑guided fuzzing і працює швидше на великих контрактах. Якщо обсяг кодової бази > 5000 рядків Solidity — дивимося на Medusa.

Як інваріанти допомагають виявити критичні уразливості?

Формальна верифікація доводить, що контракт задовольняє специфікації для всіх можливих вхідних даних — не для N випадкових, а математично для всіх. Інструменти: Certora Prover, K Framework, Halmos.

Certora працює з CVL (Certora Verification Language): пишеш rules і invariants, Prover транслює їх у SMT‑формули і перевіряє через Z3/CVC5. MakerDAO, Aave, Uniswap використовують Certora в CI/CD pipeline — кожен PR верифікується автоматично.

Обмеження: не працює з необмеженими циклами, складно справляється з hash functions і signature verification. Для контрактів з простою математикою (AMM, lending) — відмінно. Для контрактів з довільними зовнішніми викликами — складно написати достатньо повну специфікацію.

Formal verification має сенс для контрактів, які: керують значним TVL, оновлюються рідко, мають чітко формалізовані інваріанти. Для продуктів, що швидко ітеруються, співвідношення витрат і користі не на користь верифікації.

Вектори атак, які пропускають джуніор‑аудитори

Storage collision в proxy патерні. Transparent proxy і UUPS використовують конкретні слоти для зберігання адреси імплементації (EIP‑1967). Якщо в імплементації випадково оголошена змінна в слоті 0, яка перетинається з proxy storage — отримуємо silent override. Slither це не впіймає, якщо proxy та імплементація в різних файлах.

Read‑only reentrancy. Класичний reentrancy guard захищає від зміни стану при рекурсивному виклику. Але якщо зовнішній контракт читає стан через view-функцію в середині транзакції — guard не допомагає. Кілька років тому Curve pools стали вектором атаки саме через це: зовнішній протокол читав get_virtual_price під час reentrancy‑вразливого стану Curve.

Oracle manipulation через TWAP. Spot price — стандартна ціль для flash loan атаки. TWAP складніше маніпулювати, але не неможливо: на малоліквідних парах Uniswap v2 можна зсунути TWAP за кілька блоків при достатньому капіталі. Правильний захист — використовувати Chainlink як primary oracle з TWAP як fallback, з перевіркою deviation threshold.

Gas griefing на unbounded loop. Функція ітерується по масиву користувачів. Атакуючий додає тисячі адрес з нульовими балансами — вартість виклику функції зростає до gas limit, функція стає недоступною. Захист: pull‑pattern замість push, обмеження довжини масивів, batch‑обробка зі збереженням позиції.

Front‑running на MEV. Транзакція видна в mempool до включення в блок. MEV‑бот бачить addLiquidity на значну суму, вставляє свій swap перед нею (sandwich attack). Для AMM це частина моделі. Для протоколів з ціновими функціями — потрібен minAmountOut / deadline параметр і його обов'язкова перевірка.

Структура повного аудиту

  1. Scope definition і автоматичний аналіз (1‑2 дні). Фіксуємо commit hash, версію компілятора, список out‑of‑scope. Запускаємо Slither, Mythril, Aderyn. Triage: відокремлюємо реальні критичні баги від false positive. Складаємо карту залежностей контрактів.

  2. Ручний аналіз (5‑15 днів). Кожен контракт порядково. Особлива увага: всі external і public функції, всі transfer/call/delegatecall, всі місця, де змінюється стан перед перевіркою або після зовнішнього виклику, всі математичні операції з участю користувацьких inputs. В середньому 95% знайдених уразливостей — логічні, а не технічні.

  3. Fuzzing і тестування (2‑5 днів). Echidna або Foundry invariant tests для критичних інваріантів. Fork mainnet тести — перевіряємо поведінку в реальному оточенні з реальними оракулами. Наприклад, за 4 дні fuzzing знаходить в середньому 3 edge cases, не покритих unit‑тестами.

  4. Звіт і мітигація. Звіт з severity (Critical/High/Medium/Low/Informational), описом вектора атаки, PoC‑кодом для Critical/High. Розробники виправляють, аудитори роблять re‑audit виправлень.

Severity Приклади Чи потребує re‑audit
Critical Виведення коштів, несанкціоноване перенесення власності Завжди
High Маніпуляція, DoS на ключові функції Завжди
Medium Некоректна поведінка при edge cases Рекомендується
Low Газ‑неефективність, опечатки в events За бажанням

Аудит у CI/CD

Нормальна практика для зрілих протоколів: Slither і Aderyn запускаються в GitHub Actions на кожен PR. Certora Prover — на merge в main. Це не замінює повний аудит перед деплоєм, але ловить регресії.

# .github/workflows/audit.yml
- name: Run Slither
  uses: crytic/[email protected]
  with:
    target: 'src/'
    slither-args: '--filter-paths "test|mock|script"'
Чек‑лист обов'язкових перевірок перед деплоєм
  • Всі external функції мають перевірки доступу (onlyOwner, onlyRole)
  • Використання SafeERC20 для зовнішніх токенів
  • Відсутність delegatecall на невідомі адреси
  • Перевірка на reentrancy у всіх функціях з зовнішніми викликами
  • Наявність minAmountOut і deadline в AMM‑функціях
  • Використання перевіреного оракула (Chainlink) з deviation threshold

Інструменти аудиту: порівняння

Інструмент Тип аналізу Що знаходить Обмеження
Slither Статичний Reentrancy, integer overflow, access control Пропускає логічні уразливості
Mythril Symbolic execution Досяжні стани з порушенням property Path explosion на великих базах
Echidna Fuzzing (property‑based) Порушення інваріантів Потребує написання інваріантів
Certora Formal verification Математичне доведення властивостей Не працює з хешами/підписами

Що входить в роботу (deliverables)

  • Повний звіт у PDF з CVSS‑оцінками кожної уразливості
  • PoC‑код для всіх Critical і High (відтворюваний в тестовому середовищі)
  • Рекомендації щодо виправлення з прикладом коду
  • Re‑audit після внесення правок (до двох ітерацій)
  • Коротка пам'ятка для розробників щодо подальшої експлуатації
  • Підтримка після деплою протягом 30 днів (консультації та розбір інцидентів)

Терміни

Аудит простого токена або NFT‑контракту — 3‑5 робочих днів. DeFi протокол з lending/AMM — 2‑4 тижні. Повний стек з кількома протоколами, cross‑chain, proxy upgrades — 4‑8 тижнів. Re‑audit виправлень — 3‑7 днів окремо.

Наша команда має 7+ років досвіду в безпеці смарт‑контрактів, перевірила 100+ проектів з сумарним TVL понад значну суму. Гарантуємо, що в процесі ми не пропустимо жоден відомий вектор — використовуємо ліцензовані версії Slither та найкращі конфігурації fuzzer'ів. Запобігнуті збитки для клієнтів оцінюються в значну суму.

Оцініть ваш проект — ми безкоштовно проаналізуємо код і запропонуємо комерційну пропозицію протягом 2 днів. Замовте аудит з гарантією якості та отримайте знижку на re‑audit при повторному зверненні.