Back to How-To Guides
HOW-TO10 min read2025-06-23

How to Build a Token Launchpad — IDO and Fair Launch Platform

Token launchpads help projects raise capital and launch tokens to their community. Here is the architecture for building a launchpad platform.

ClickMasters Team
Step-by-step implementation
Expert Assistance

Ready to Build Your Token Launchpad?

Get expert guidance on building a token launchpad for your community.

Complete Guide

Quick Answer

A token launchpad enables projects to raise capital through IDOs with stake-based tier allocations. Investors stake your governance token to earn allocation tiers. Revenue model: 5–10% of IDO raise. Core features: tier-based contributions, hard/soft caps, refund mechanisms, and token claiming. Bot prevention via stake-based tiers, KYC, whitelists, and FCFS within tiers.

Launchpad Architecture Overview

USER JOURNEY:

Investor stakes your launchpad's governance token → earns allocation tiers

Project submits to launchpad for listing review

Approved project launches on the launchpad

Investors participate in sale based on their tier allocation

Tokens distributed at TGE; investor tokens unlock per vesting schedule

REVENUE MODEL:

5–10% of IDO raise (launchpad fee)

Sometimes: token allocation from project

Sometimes: trading fee if integrated DEX

Core Launchpad Contract

Example
contract TokenLaunchpad is ReentrancyGuard {
    
    struct IDOPool {
        address projectToken;
        uint256 tokenPrice;        // USDC per token (scaled)
        uint256 hardCap;           // Max raise in USDC
        uint256 softCap;           // Min raise for success
        uint256 totalRaised;
        uint256 startTime;
        uint256 endTime;
        bool    finalized;
        bool    refundEnabled;     // If soft cap not reached
        uint256 launchpadFeeBps;   // e.g., 500 = 5%
    }
    
    struct Allocation {
        uint256 tier;       // Tier 0 = no stake, 1 = bronze, 2 = silver, 3 = gold
        uint256 maxBuy;     // Max USDC contribution for this tier
    }
    
    mapping(uint256 => IDOPool) public pools;
    mapping(uint256 => mapping(address => uint256)) public contributions; // poolId => user => amount
    mapping(address => uint256) public stakedAmount;  // How much user has staked of your token
    uint256 public poolCount;
    
    IERC20 public usdc;
    IERC20 public launchpadToken;  // Your platform's governance/staking token
    
    // Tier thresholds
    uint256 public constant BRONZE_STAKE = 1_000e18;
    uint256 public constant SILVER_STAKE = 5_000e18;
    uint256 public constant GOLD_STAKE   = 20_000e18;
    
    // Get user's tier
    function getUserTier(address user) public view returns (uint256) {
        uint256 staked = stakedAmount[user];
        if (staked >= GOLD_STAKE) return 3;
        if (staked >= SILVER_STAKE) return 2;
        if (staked >= BRONZE_STAKE) return 1;
        return 0;
    }
    
    // Get max contribution for user's tier in a pool
    function getMaxContribution(uint256 poolId, address user) public view returns (uint256) {
        IDOPool storage pool = pools[poolId];
        uint256 tier = getUserTier(user);
        
        // Tier multipliers (simplified)
        if (tier == 3) return pool.hardCap / 10;  // Gold: 10% of cap
        if (tier == 2) return pool.hardCap / 50;  // Silver: 2% of cap
        if (tier == 1) return pool.hardCap / 200; // Bronze: 0.5% of cap
        return 0;  // No stake: no allocation
    }
    
    // Participate in IDO
    function contribute(uint256 poolId, uint256 usdcAmount) external nonReentrant {
        IDOPool storage pool = pools[poolId];
        
        require(block.timestamp >= pool.startTime, "Not started");
        require(block.timestamp <= pool.endTime, "Ended");
        require(pool.totalRaised + usdcAmount <= pool.hardCap, "Cap reached");
        
        uint256 maxContrib = getMaxContribution(poolId, msg.sender);
        uint256 alreadyContributed = contributions[poolId][msg.sender];
        require(alreadyContributed + usdcAmount <= maxContrib, "Exceeds allocation");
        
        usdc.transferFrom(msg.sender, address(this), usdcAmount);
        contributions[poolId][msg.sender] += usdcAmount;
        pool.totalRaised += usdcAmount;
        
        emit Contributed(poolId, msg.sender, usdcAmount);
    }
    
    // After IDO ends: claim tokens
    function claimTokens(uint256 poolId) external nonReentrant {
        IDOPool storage pool = pools[poolId];
        require(pool.finalized, "Not finalized");
        require(!pool.refundEnabled, "IDO failed - claim refund");
        
        uint256 contribution = contributions[poolId][msg.sender];
        require(contribution > 0, "No contribution");
        
        contributions[poolId][msg.sender] = 0;
        
        uint256 tokensToReceive = contribution * 1e18 / pool.tokenPrice;
        IERC20(pool.projectToken).transfer(msg.sender, tokensToReceive);
        
        emit TokensClaimed(poolId, msg.sender, tokensToReceive);
    }
    
    event Contributed(uint256 poolId, address contributor, uint256 amount);
    event TokensClaimed(uint256 poolId, address claimer, uint256 amount);
}

Frequently Asked Questions

Common questions before following this guide

Clear answers to the most common practical, technical, and implementation questions.

1

Answers

How do launchpads prevent bots from dominating allocations?

Top launchpads use: (1) stake-based tiers (bots would need to stake significant capital per address — expensive to farm many tiers), (2) KYC for participation (one address per person, verified), (3) whitelist/snapshot system (allocations based on historical on-chain activity, not just stake amount), (4) FCFS (first-come-first-served) within tiers — high gas cost discourages bot bids at launch time.

Expert Assistance

Ready to Build Your Token Launchpad?

Get expert guidance on building a token launchpad for your community.