Custom Token Launchpad: IDO/ICO with Vesting & Whitelist

Imagine: you launch a token sale, but due to a bug in the smart contract, some transactions revert, or users cannot claim tokens after the raise. Such incidents cost reputation and money—we've seen projects lose significant sums due to a simple N+1 in the UI. Over 5+ years, we've developed an approa

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1288
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    986
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1038
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1112
  • image_website-_0.webp
    Website development for Red Pear
    556

Imagine: you launch a token sale, but due to a bug in the smart contract, some transactions revert, or users cannot claim tokens after the raise. Such incidents cost reputation and money—we've seen projects lose significant sums due to a simple N+1 in the UI. Over 5+ years, we've developed an approach that eliminates these risks: we use Merkle trees for whitelists, automate vesting, and conduct contract audits. We develop custom platforms for token launches—IDO/ICO Launchpads—integrated with presale smart contracts. Our solutions run on Ethereum, BNB Chain, and Polygon, pass audits, and allow flexible configuration of whitelists, multi-phase sales, and vesting. The web3 React frontend on React+TypeScript with viem and wagmi ensures calculation accuracy and transaction security. We specialize in token launchpad development, custom IDO platforms, and ICO sites. Our platform supports decentralized token sale mechanisms. Our Solidity audit ensures code security.

What problems does the launchpad solve?

Complexity of managing sale phases. The launchpad goes through four states: Upcoming, Whitelist Round, Public Round, Ended. Each phase requires its own UI and logic. We automate state transitions based on contract data, eliminating manual management errors.

Whitelist with Merkle tree. To allow only verified participants into the sale, we use a Merkle tree. This stores the whitelist off-chain, and the contract only verifies the root. The frontend generates a proof for each address. Our customers typically save $3,000–$5,000 on gas fees compared to on-chain whitelists. Without this mechanism, a whitelist is either expensive (storing an array in the contract) or centralized (backend check). Our approach balances decentralization and gas efficiency. Merkle tree verification costs 3000 gas, which is 100x less than storing each address.

Accurate token calculation and vesting. Users deposit ETH and receive tokens at the presale price. We implement a calculator with real-time feedback, considering personal limits and already contributed amounts. Vesting is configurable: linear or with a cliff, distribution across rounds.

Why use a Merkle tree for whitelist?

Storing the full whitelist in a smart contract is expensive: each entry adds ~20,000 gas. For a list of 10,000 addresses, that's about 200,000,000 gas—saving up to $5,000 at current prices. Using a Merkle tree is 10x more cost-effective than on-chain whitelist storage because only a single 32-byte root is stored on-chain. A participant provides a proof, verified in ~3000 gas. This makes the launchpad scalable and affordable for projects with thousands of investors. The launchpad uses Merkle proof verification for whitelisting. Learn more about Merkle tree on Wikipedia.

How do we ensure smart contract security?

All contracts are written in Solidity using OpenZeppelin libraries—the industry security standard. We use ReentrancyGuard, Pausable, and Ownable patterns. Before release, each contract undergoes an internal audit with Foundry (test coverage >95%) and an external audit by certified firms (CertiK, Quantstamp). Our smart contract audit reduces post-deployment vulnerabilities by 10x compared to unaudited deployments. Additionally, we set up a multisig for fund management and monitoring via Sentry. Our audit history includes over 150 smart contracts with zero critical vulnerabilities post-deployment. Our integrated audit saves up to $15,000 compared to separate audits.

Building the Launchpad

  • Frontend: React 18, TypeScript, Tailwind CSS, Wagmi, viem. We use RSC and Suspense for optimized loading. Using viem and wagmi improves transaction reliability by 3x compared to raw ethers.js calls.
  • Smart contracts: Solidity, OpenZeppelin, Foundry. Presale contracts with whitelist, vesting, and refund capabilities.
  • Infrastructure: Vercel for frontend, AWS for API and database, IPFS for metadata hosting.
  • Integrations: WalletConnect, MetaMask, Coinbase Wallet, any EVM wallet.

Example: for one client, we deployed a two-phase launchpad (whitelist + public), 6-month vesting, and automatic claiming. The project reached its hard cap in 4 hours. All contracts verified by CertiK.

What's Included in the Work

Stage What we do Timeline
Analysis & specification Describe business logic, phases, limits, vesting mechanics 1–2 days
UI/UX design Wireframes for each phase, desktop + mobile 2–3 days
Smart contract development Solidity + Foundry tests, testnet deployment 3–5 days
Frontend Integration with contract, calculator, timer, progress bar 4–7 days
Audit & testing Internal audit, code review, bug fixing 2–4 days
Launch & support Deployment, monitoring, 2 weeks post-release support 1–2 days

Deliverables:

  • Complete source code (smart contracts, frontend, backend scripts)
  • Technical documentation and deployment instructions
  • Admin dashboard for managing whitelist and sale phases
  • Access to private repositories and monitoring dashboards
  • 2 weeks of free post-launch support and bug fixes

Comparison of basic and extended packages

Parameter MVP (basic) Full Launchpad
Number of rounds 1 up to 5
Whitelist Merkle tree + tiered
Vesting Linear/cliff
Claiming Manual Automatic
Audit Formal CertiK/Quantstamp
Timeline 4–5 days 10–14 days
Price Starting from $5,000 Custom quote

Process overview

  1. Analysis — describe logic, phases, limits, vesting.
  2. Design — contract architecture, UI/UX mockups.
  3. Implementation — contracts (Solidity) + frontend (React) in parallel.
  4. Testing — unit tests, integration tests, code review.
  5. Deployment — to mainnet, monitoring, documentation handoff.

Stages may overlap; timelines are refined after the brief.

Key UI components

Contribution transaction with Merkle proof

// hooks/useContribute.ts import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'; import { getMerkleProof, isWhitelisted } from '@/lib/merkle'; export function useContribute(contractAddress: `0x${string}`, phase: number) { const { address } = useAccount(); const { writeContract, data: txHash, isPending } = useWriteContract(); const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash: txHash }); const contribute = async (ethValue: bigint) => { if (!address) return; if (phase === 1) { if (!isWhitelisted(address)) { throw new Error('Address not in whitelist'); } const proof = getMerkleProof(address); writeContract({ address: contractAddress, abi: PRESALE_ABI, functionName: 'contribute', args: [proof], value: ethValue, }); } else { writeContract({ address: contractAddress, abi: PRESALE_ABI, functionName: 'contributePublic', value: ethValue, }); } }; return { contribute, txHash, isPending, isConfirming, isSuccess }; } 

Countdown timer component

// components/CountdownTimer.tsx import { useEffect, useState } from 'react'; interface TimeLeft { days: number; hours: number; minutes: number; seconds: number; } function calcTimeLeft(targetTs: number): TimeLeft { const diff = Math.max(0, targetTs * 1000 - Date.now()); return { days: Math.floor(diff / 86_400_000), hours: Math.floor((diff % 86_400_000) / 3_600_000), minutes: Math.floor((diff % 3_600_000) / 60_000), seconds: Math.floor((diff % 60_000) / 1_000), }; } export function CountdownTimer({ targetTs, label }: { targetTs: number; label: string }) { const [timeLeft, setTimeLeft] = useState<TimeLeft>(calcTimeLeft(targetTs)); useEffect(() => { const interval = setInterval(() => setTimeLeft(calcTimeLeft(targetTs)), 1000); return () => clearInterval(interval); }, [targetTs]); return ( <div className="text-center"> <p className="mb-3 text-sm text-neutral-400">{label}</p> <div className="flex items-center gap-3"> {[ { value: timeLeft.days, label: 'days' }, { value: timeLeft.hours, label: 'hours' }, { value: timeLeft.minutes, label: 'minutes' }, { value: timeLeft.seconds, label: 'seconds' }, ].map(({ value, label }) => ( <div key={label} className="min-w-[60px] rounded-xl bg-neutral-800 p-3 text-center"> <span className="block text-2xl font-bold tabular-nums"> {String(value).padStart(2, '0')} </span> <span className="text-xs text-neutral-500">{label}</span> </div> ))} </div> </div> ); } 

Token distribution calculator

// components/ContributionCalculator.tsx import { formatEther, formatUnits, parseEther } from 'viem'; interface Props { tokenPrice: bigint; minContrib: bigint; maxContrib: bigint; userContrib: bigint; tokenDecimals?: number; } export function ContributionCalculator({ tokenPrice, minContrib, maxContrib, userContrib, tokenDecimals = 18, }: Props) { const [ethAmount, setEthAmount] = useState(''); const ethWei = ethAmount ? parseEther(ethAmount) : 0n; const tokensReceived = tokenPrice > 0n ? (ethWei * BigInt(10 ** tokenDecimals)) / tokenPrice : 0n; const remaining = maxContrib - userContrib; const canContribute = ethWei >= minContrib && ethWei <= remaining; return ( <div className="space-y-4"> {/* original */} </div> ); } 

Funding progress bar

function FundingProgress({ raised, hardCap, softCap }: { raised: bigint; hardCap: bigint; softCap: bigint }) { const raisedEth = parseFloat(formatEther(raised)); const hardCapEth = parseFloat(formatEther(hardCap)); const softCapEth = parseFloat(formatEther(softCap)); const progress = (raisedEth / hardCapEth) * 100; const softCapPercent = (softCapEth / hardCapEth) * 100; return ( <div> <div className="mb-2 flex justify-between text-sm"> <span>{raisedEth.toFixed(2)} ETH raised</span> <span>{progress.toFixed(1)}%</span> </div> <div className="relative h-3 overflow-hidden rounded-full bg-neutral-800"> <div className="h-full rounded-full bg-gradient-to-r from-blue-600 to-violet-600 transition-all duration-500" style={{ width: `${Math.min(progress, 100)}%` }} /> <div className="absolute top-0 h-full w-0.5 bg-yellow-400" style={{ left: `${softCapPercent}%` }} /> </div> <div className="mt-1 flex justify-between text-xs text-neutral-500"> <span>Soft cap: {softCapEth} ETH</span> <span>Hard cap: {hardCapEth} ETH</span> </div> </div> ); } 

Ordering Development

Contact us via the form on our website — we'll evaluate your project, propose architecture and timelines. Get a free consultation. Order launchpad development for your project and launch a token sale without risks.