Разработка контрактов краудфандинга (ICO/IDO/IEO)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка контрактов краудфандинга (ICO/IDO/IEO)
Средний
~3-5 дней
Часто задаваемые вопросы

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

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

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1306
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1217
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    919
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1146
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    609
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    884

Разработка контракта краудфандинга (ICO/IDO/IEO)

ICO, IDO и IEO — три разных механизма продажи токенов с разной архитектурой смарт-контрактов, разными требованиями к безопасности и разными правовыми рисками. Путать их на этапе проектирования — дорогостоящая ошибка.

ICO (Initial Coin Offering) — прямая продажа токенов из контракта. Полный контроль, никаких посредников, но и никаких гарантий для покупателей. Расцвет 2017–2018, сейчас ассоциируется с высоким риском мошенничества и регуляторным вниманием.

IDO (Initial DEX Offering) — продажа через DEX-механизм (Uniswap, PancakeSwap, Raydium). Ликвидность добавляется одновременно с продажей, цена определяется рынком или через специализированную launchpad платформу.

IEO (Initial Exchange Offering) — продажа через централизованную биржу. Биржа выступает посредником и KYC провайдером. Смарт-контракт в этом случае — упрощённый, основная логика на стороне биржи.

Структура crowdsale контракта

Базовая архитектура, применимая для большинства продаж:

contract TokenSale {
    using SafeERC20 for IERC20;

    IERC20 public immutable token;
    address public immutable treasury;

    // Конфигурация раундов
    struct Round {
        uint256 price;          // wei за 1 token (с учётом decimals)
        uint256 allocation;     // всего токенов в раунде
        uint256 sold;
        uint256 minPurchase;
        uint256 maxPurchase;    // per wallet cap
        uint256 startTime;
        uint256 endTime;
        bool    whitelistRequired;
    }

    Round[] public rounds;
    uint256 public activeRound;

    mapping(address => uint256) public purchased;           // total per wallet
    mapping(address => bool)    public whitelist;
    mapping(address => bool)    public claimed;

    // Vesting: токены выдаются не сразу
    uint256 public tgePercent;      // % сразу при TGE
    uint256 public cliffEnd;        // timestamp конца cliff периода
    uint256 public vestingEnd;      // timestamp конца vesting

    event TokensPurchased(address indexed buyer, uint256 ethAmount, uint256 tokenAmount, uint256 round);
    event TokensClaimed(address indexed claimant, uint256 amount);
}

Вычисление количества токенов

Частая ошибка: неправильная обработка decimals. Если ETH имеет 18 decimals, а токен — тоже 18, формула тривиальна. Но если токен имеет 6 decimals (USDC-style) или 0 (редкий случай) — расчёт другой.

function calculateTokens(uint256 ethAmount, uint256 roundIndex) public view returns (uint256) {
    Round storage round = rounds[roundIndex];
    // price хранится как wei ETH за 1 полный токен (с учётом token decimals)
    // Например: если 1 token = 0.001 ETH, то price = 0.001 * 1e18 = 1e15
    return (ethAmount * 10**token.decimals()) / round.price;
}

Whitelist и KYC

Для IDO на launchpad-платформах — whitelist через merkle proof (экономия gas на хранении):

bytes32 public whitelistMerkleRoot;

function purchaseWithProof(bytes32[] calldata proof) external payable {
    bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
    require(
        MerkleProof.verify(proof, whitelistMerkleRoot, leaf),
        "Not whitelisted"
    );
    _purchase();
}

Обновление корня Merkle-дерева при добавлении новых адресов — off-chain операция (generateMerkleTree + setMerkleRoot on-chain). Важно: при обновлении root старые proof инвалидируются — нужна либо плавная миграция, либо хранение нескольких root-ов для перекрывающихся окон.

Vesting механизм

Продажа без vesting — красный флаг для инвесторов. Стандартная схема: 10% TGE (token generation event) + 6 месяцев cliff + 18 месяцев линейный vesting.

function claimableAmount(address beneficiary) public view returns (uint256) {
    uint256 total = purchased[beneficiary];
    if (total == 0) return 0;

    uint256 tgeAmount = (total * tgePercent) / 100;
    uint256 vestingAmount = total - tgeAmount;

    if (block.timestamp < cliffEnd) {
        // Только TGE часть доступна (если TGE уже прошёл)
        return tgeReleased[beneficiary] ? 0 : tgeAmount;
    }

    if (block.timestamp >= vestingEnd) {
        return total - claimed[beneficiary];  // всё
    }

    // Линейный vesting после cliff
    uint256 elapsed = block.timestamp - cliffEnd;
    uint256 duration = vestingEnd - cliffEnd;
    uint256 vestedAmount = (vestingAmount * elapsed) / duration;

    uint256 totalClaimable = tgeAmount + vestedAmount;
    return totalClaimable - claimed[beneficiary];
}

Риски и защиты

Front-running при старте продажи. MEV-боты отслеживают mempool и вставляют транзакции в первый блок продажи. Для fair launch: commit-reveal схема или randomized start block.

Reentrancy при возврате ETH. Если в логику включён refund (например, при недостижении softcap), функция возврата должна использовать checks-effects-interactions pattern и ReentrancyGuard.

Manupulation с ценой через большой purchase. При bonding curve моделях (цена растёт с каждой покупкой) — возможна манипуляция через фиктивные покупки с последующей перепродажей. Решение: минимальный lock period или фиксированная цена в раунде.

Owner privilege abuse. Функции setPrice(), withdraw(), pause() должны иметь либо timelock, либо multisig (Gnosis Safe). Бесконтрольный owner — причина большинства rugpull сценариев.

Softcap и refund механизм. Если не собрали minimum — покупатели должны получить ETH обратно. Стандартный паттерн: хранить contributions в mapping, pull-pattern для возврата (не push), активировать режим refund через функцию после finalization.

Тестирование и аудит

Foundry fuzzing обязателен для crowdsale контрактов:

function testFuzz_purchaseCalculation(uint256 ethAmount, uint256 decimals) public {
    ethAmount = bound(ethAmount, 0.001 ether, 100 ether);
    decimals = bound(decimals, 0, 18);
    // Проверяем, что не бывает overflow при разных комбинациях
    uint256 tokens = sale.calculateTokens(ethAmount, 0);
    assertGt(tokens, 0, "Zero tokens for non-zero ETH");
}

Ключевые инварианты для fuzzing:

  • SUM(purchased) <= total allocation — никогда не продаём больше, чем есть
  • SUM(claimed) <= SUM(purchased) — никогда не выдаём больше, чем продали
  • После finalization и refund mode: contract balance >= SUM(contributions для unfulfilled покупателей)

Для продаж с существенным объёмом (от $500K) — внешний аудит обязателен. Минимум одна команда из Tier 2 аудиторов (Pessimistic, MixBytes, Oxorio).

Сроки

Стандартный crowdsale контракт с vesting и merkle whitelist — 5–7 рабочих дней разработки + 2–3 дня тестирования. С нестандартной логикой (bonding curve, multi-currency, dynamic rounds) — 2–3 недели.