Building a Token Presale Platform: Smart Contract Plus Next.js Frontend
End-to-end build notes for a production token presale platform — Solidity contract with tiered pricing, Next.js frontend with wallet UX, and the security gotchas that bit me.
What I'm covering
I've shipped 8 token presale platforms in the last 18 months — different chains, different tokenomics, but the architecture rhymes. This post is the canonical pattern I now reach for, plus the security gotchas that bit me on early ones.
It's an end-to-end build: Solidity contract on EVM, Next.js frontend with wallet UX, deployment, and ops.
The product
A token presale platform lets early supporters buy a project's token at a fixed price, before it lists on a DEX. Features I implement in v1:
Smart contract architecture
Three contracts:
Why three? Separation of concerns. Token logic is standard. Presale logic is custom. Vesting logic has its own security surface. Keeping them separate makes audits easier and lets you upgrade vesting (via a new contract address) without redeploying the token.
Presale.sol key functions
The minimum interface:
Tiered pricing logic
Stored as two arrays: thresholds (how many tokens sold) and prices (token price at that tier). Buy logic:
This split-across-tiers logic is where I see most amateur presales fail. They buy at one fixed price and ignore tier boundaries.
Whitelist
Two patterns:
For most projects, Merkle is the right call. The frontend builds the proof; the contract verifies it.
Vesting
Linear vesting with cliff is the standard:
The Vesting.sol contract holds the bought tokens, releases them to claimants on release calls.
Security gotchas (the part you should not skip)
What bit me on early builds:
1. Reentrancy on refund
A naive refund function that does transfer before updating state can be re-entered by a malicious contract and drained. Solution: update state first, then transfer (checks-effects-interactions), or use OpenZeppelin's ReentrancyGuard. I do both.
2. Front-running the price tier transition
If tier 1 has 10 tokens left at 10 cents and tier 2 starts at 15 cents, an attacker can front-run a large buy by buying first at 10 cents and immediately reselling at 15 cents.
Mitigations: maximum buy per transaction (e.g., 1 percent of supply per tx), per-address cap, or for high-value presales, off-chain order matching with on-chain settlement.
3. Stablecoin decimal mismatch
USDC is 6 decimals on most chains. USDT is 6 on most chains. DAI is 18. Your token is probably 18. Hardcoded decimals in your price calculation will break. Always read decimals from the stablecoin contract at runtime.
4. Rug pull detection
Investors are wary. Reduce rug pull risk by hardcoding the vesting and unlock schedule into the contract (no admin update), locking team allocation in the same vesting contract, and using a timelock for any admin functions. These cost nothing but build trust.
5. Refund precision loss
If users contributed in stablecoin units and your math divides somewhere, refunds can leave dust. Round in the user's favor (always slightly over-refund) and recover dust into the contract reserve.
The frontend (Next.js 14 App Router)
Stack:
Key screens:
The Buy widget is where 80 percent of the UX engineering goes. It needs to detect connected wallet's chain (warn if wrong), pre-approve stablecoin spend if buying with USDC or USDT, show real-time tier transitions, handle slippage or partial fills gracefully, and show clear error messages for known failures.
Deployment
I use Hardhat with hardhat-deploy for deterministic deployments. Deploy order: Token contract (record address), Vesting contract (constructor needs token address), Presale contract (constructor needs token plus vesting addresses), transfer presale-allocated tokens from deployer to presale contract, verify all three on the explorer.
The verify step is critical. Unverified contracts kill investor confidence.
Pre-launch checklist (this is what my clients pay me for)
Before going live on mainnet:
Cost reality
For a typical client engagement (audit-ready contracts plus Next.js frontend plus deployment):
Total: ~6-7 weeks for v1. Add an external audit (Code4rena, Hashlock, etc.) on top — another 2-4 weeks before mainnet.
TL;DR
If you're launching a token and want production-grade contracts plus frontend, contact me.
You might also like
Gas Optimization Tricks I Use on Every Solidity Contract
Ten gas optimization patterns I apply to every Solidity contract before mainnet — storage packing, calldata, custom errors, immutable, unchecked, and the ones that actually move the needle.
Building Secure Staking Platforms with Solidity & Web3.js
A deep dive into creating production-ready staking contracts with daily reward distribution and security best practices.
Real-Time Apps with Next.js Server Actions and WebSockets in 2026
When Server Actions are enough, when you need a WebSocket layer, and how to wire Pusher / Soketi / Ably into a Next.js 14 App Router project without breaking SSR.