Token Sale Allocation System Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Token Sale Allocation System Development
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Token Sale Allocation System Development

Standard problem at token sale launch: either whitelist oversubscribed 20x and most participants get zero, or allocations distributed "first-come, first-served" and bots buy from the side. Allocation system—mechanism for fair distribution of buying rights before sale starts.

System's task: determine who gets allocation, how much, ensure on-chain execution without abuse.

Allocation Calculation Models

Lottery (Random Selection)

Simplest: from N registered, randomly select K winners. Fair, but luck doesn't correlate with involvement or interest.

Randomness source—always a problem on-chain. Chainlink VRF v2—correct production solution:

import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";

contract AllocationLottery is VRFConsumerBaseV2 {
    address[] public applicants;
    address[] public winners;
    
    function drawWinners(uint256 count) external onlyOwner {
        uint256 requestId = COORDINATOR.requestRandomWords(
            keyHash, subscriptionId, 3, 100000, 1
        );
    }
    
    function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) 
        internal override 
    {
        uint256 seed = randomWords[0];
        // Fisher-Yates shuffle to select winners
    }
}

FCFS with Time Batching

Divide sales into time batches: each batch 1 hour, each verified participant buys max X tokens. Bots lose advantage: per-address limit same, speed doesn't help.

Score-Based Allocations

Participants accumulate points pre-sale: token holding, testnet participation, community activity. Allocation proportional to points.

contract ScoreBasedAllocation {
    mapping(address => uint256) public scores;
    uint256 public totalScore;
    uint256 public totalAllocation;
    
    function getAllocation(address user) public view returns (uint256) {
        if (totalScore == 0) return 0;
        return (scores[user] * totalAllocation) / totalScore;
    }
}

Tiered System

Multiple levels with different limits and priorities:

Tier Entry Condition Guaranteed Allocation FCFS Beyond
Gold Stake >= 10,000 tokens 90 days $5,000 Up to $15,000
Silver Stake >= 1,000 tokens 30 days $1,000 Up to $5,000
Bronze KYC passed $200 No
Public FCFS, remainder
enum Tier { NONE, BRONZE, SILVER, GOLD }

mapping(address => Tier) public userTier;

function computeTier(address user) public view returns (Tier) {
    uint256 staked = stakingContract.stakedAmountFor(user);
    uint256 stakeDuration = stakingContract.stakeDurationFor(user);
    
    if (staked >= tierConfigs[Tier.GOLD].minStake && 
        stakeDuration >= tierConfigs[Tier.GOLD].minStakeDays * 1 days)
        return Tier.GOLD;
    
    if (staked >= tierConfigs[Tier.SILVER].minStake && 
        stakeDuration >= tierConfigs[Tier.SILVER].minStakeDays * 1 days)
        return Tier.SILVER;
    
    if (kycRegistry.isVerified(user))
        return Tier.BRONZE;
    
    return Tier.NONE;
}

Execution: Whitelist + Purchase

After allocation determination—publish whitelist (merkle root) and purchase period:

contract TokenSale {
    bytes32 public whitelistRoot;
    mapping(address => uint256) public purchased;
    
    function purchase(uint256 usdcAmount, AllocationProof calldata proof) external {
        // Verify allocation
        bytes32 leaf = keccak256(bytes.concat(
            keccak256(abi.encode(msg.sender, proof.maxAllocationUSD))
        ));
        require(MerkleProof.verify(proof.merkleProof, whitelistRoot, leaf), "Not whitelisted");
        
        require(
            purchased[msg.sender] + usdcAmount <= proof.maxAllocationUSD,
            "Exceeds allocation"
        );
        
        uint256 tokenAmount = (usdcAmount * TOKEN_PRICE_DENOMINATOR) / tokenPriceUSD;
        purchased[msg.sender] += usdcAmount;
        usdc.transferFrom(msg.sender, treasury, usdcAmount);
        token.transfer(msg.sender, tokenAmount);
        
        emit Purchase(msg.sender, usdcAmount, tokenAmount);
    }
}

Sybil Attack Protection

Tier-based and score-based systems vulnerable to Sybil: one participant creates 100 addresses, distributes stake. Protection:

Gitcoin Passport / Proof of Humanity — on-chain identity with Sybil resistance. Integrated as prerequisite: require(passport.getScore(msg.sender) >= MIN_SCORE).

Quadratic scoring — allocation proportional to √(stake), not stake. Reduces large-holder advantage, increases relative reward for small participants.

Staking with lockup — tokens must be staked minimum 30-90 days before snapshot. Expensive for Sybil: must buy tokens early.

Social graph analysis — off-chain: clusters of addresses with similar on-chain patterns (created same day, funded from one source) excluded from whitelist.

Well-designed allocation system—both technique and game theory. Goal: make honest participation cheaper than manipulation. Merkle-based whitelist—minimum baseline; tier staking and Sybil protection—what distinguishes thoughtful launchpad from primitive FCFS.