Розробка контрактів краудфандингу (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;           // всього на гаманець
    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

Для launchpad IDO — 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 — червоний флаг для інвесторів. Стандартна схема: 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.

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

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

Softcap та механізм refund. Якщо мінімум не зібраний — покупці повинні отримати ETH назад. Стандартний паттерн: зберігати contributions у маппінгу, pull-pattern для повернення (не push), активувати режим refund через функцію після фіналізації.

Тестування та аудит

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) — ніколи не видаємо більше, ніж продали
  • Після фіналізації та режиму refund: contract balance >= SUM(contributions для невиконаних покупців)

Для продаж із значним обсягом (від $500K) — зовнішній аудит обов'язковий. Мінімум одна команда Tier 2 аудиторів (Pessimistic, MixBytes, Oxorio).

Графік

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