Transparent token launches with verifiable pricing, escrowed contributions, refund protection and vesting.
LaunchProof is an educational, full-stack token-presale reference: a non-upgradeable Solidity protocol, serious Foundry tests, deterministic deployment scripts, and a polished Next.js interface that reads and writes directly to the chain. It does not use a backend ledger and never substitutes fake deployment data.
LaunchProof is not audited and is not production-ready. It is designed to make presale mechanics inspectable and to demonstrate safer defaults than common tutorials.
- Frontend: launchproof-app.vercel.app
- Network: Ethereum Sepolia (
11155111) - LaunchProofSale:
0x1435…54e4 - Fixed-supply LPF:
0xdca7…147a - LaunchProof demo dUSDC:
0x215b…82b4 - LaunchProof demo dUSDT:
0xbd97…8485 - Rate-limited faucet:
0x27e1…4d89 - Fixed dUSDC/USD feed:
0xe468…ba6b - Fixed dUSDT/USD feed:
0x7d6a…ac3e - Deployment date: 2026-07-21
The V2 sale runs from 2026-07-21 12:00:24 UTC through 2026-08-20 12:00:24 UTC and is fully funded with 30,000,000 LPF. dUSDC and dUSDT claims are 1,000 tokens per asset per wallet every 24 hours. Every displayed asset is a Sepolia-only LaunchProof demo asset; neither stablecoin is issued by or affiliated with Circle or Tether.
All seven repository contracts were independently confirmed through Etherscan API V2 at 2026-07-21T11:48:10.904Z. The canonical live E2E flow successfully claimed 1,000 dUSDC, approved exactly 1 dUSDC, and purchased 20 LPF. Complete addresses, deployment transactions, role-finalization transactions and E2E assertions are preserved in deployments/sepolia-v2.json.
V1 used public mocks whose mint, setAnswer, and setRound functions were unrestricted. A read-only audit confirmed zero sold tokens, zero USD raised, zero purchase events, and zero native/dUSDC/dUSDT escrow before cancellation. V1 was cancelled—not destroyed—using reason LAUNCHPROOF_V1_DEPRECATED_UNRESTRICTED_DEMO_ASSETS in transaction 0xfa90…508d. Its history remains in deployments/sepolia-v1-deprecated.json. The production frontend must never target these V1 assets.
Naive presales frequently forward money immediately, assume every stablecoin is exactly $1, mix decimal systems, price an entire boundary-crossing purchase at the cheapest phase, let an owner rewrite terms mid-sale, or add an emergency withdrawal that defeats refunds. LaunchProof treats those as protocol-design problems: payments stay escrowed, phase pricing is segmented, feeds are validated, economics lock by time, refunds preserve their original asset, and recovery cannot invade liabilities.
- One to ten ordered phases with time- and allocation-based transitions and bounded multi-phase quotations.
- Native ETH and generic-decimal ERC-20 payments priced by Chainlink-compatible feeds.
- Explicit stale, invalid, incomplete-round, L2 sequencer and transfer-tax rejection.
- Purchase-time USD WAD accounting, exact-asset escrow, soft-cap success/failure, cancellation and refunds.
- TGE unlock, optional cliff, linear vesting and repeatable partial claims.
- Least-privilege roles, delayed default-admin transfer, narrowly scoped pause and blocklist.
- Liability-aware sale-token and native-currency recovery.
- Unit, fuzz and stateful invariant tests, plus deterministic local/Sepolia scripts.
- Responsive App Router UI with wallet connection, live previews, slippage protection and role-gated controls.
- A 24-hour-per-wallet faucet whose only supported assets are the capped V2 dUSDC and dUSDT tokens.
The core contract is LaunchProofSale.sol. OracleLib.sol owns feed validation/normalization and VestingMath.sol owns cumulative vesting arithmetic. The frontend's synchronized callable ABI lives in protocol.ts. See Architecture, Math, Security, and Deployment.
flowchart LR
Upcoming -->|saleStart| Active
Upcoming -->|manager cancellation| Cancelled
Active -->|manager cancellation| Cancelled
Active -->|after saleEnd; soft cap met| Successful
Active -->|after saleEnd; soft cap missed| Failed
Successful --> Claims
Successful --> TreasuryWithdrawals
Failed --> ExactAssetRefunds
Cancelled --> ExactAssetRefunds
The effective state is derived from timestamps plus irreversible finalization/cancellation flags. Purchase pause does not pause finalization, claims, refunds or safe recovery.
Each phase stores a scheduled end, cumulative token cap and USD-WAD price. Expired unsold capacity rolls forward but receives the new phase price. A large contribution consumes each phase segment independently; PhaseConsumption events make this reconstructable. Preview and execution call the same internal quotation routine.
Every payment asset records token decimals, feed decimals and maximum staleness. Oracle answers are normalized to 18-decimal USD. Output rounds down; exact capacity costs round up. The worked examples cover six-decimal USDC, 18-decimal ETH, phase crossing, dust and vesting.
The contract records original amount, purchase-time USD value and tokens per beneficiary/per asset. Contributions remain in escrow. Failure or cancellation deletes the position before returning the exact original amount. A gifted purchase belongs economically to its beneficiary, including its refund right; integrators should communicate this explicitly.
After successful finalization, TGE unlock occurs at vestingStart; no incremental amount vests until the cliff ends, after which the remainder vests linearly. Cumulative math makes many partial claims equivalent to one final claim, subject only to documented downward rounding.
- OpenZeppelin
SafeERC20,Math.mulDiv,Pausable,ReentrancyGuard, andAccessControlDefaultAdminRulesare used directly from a pinned release. - Full sale funding is required before any purchase; construction never pulls the allocation.
- Both buyer and beneficiary are blocklist-checked for new purchases. Claims/refunds ignore blocklist and pause so administrators cannot trap funds.
- Supported payment assets never pass through generic recovery. Sale tokens are recoverable only above outstanding entitlement; native recovery excludes escrow.
- No
tx.origin,delegatecall, proxy, unrestricted owner withdrawal, mutable phase terms, or hidden owner path exists.
Read the complete threat model and limitations in SECURITY.md.
contracts/ Foundry project, protocol, libraries, mocks, tests and scripts
app/ Next.js App Router client and Vitest tests
docs/ Architecture, mathematics, security and deployment guides
.github/workflows/ Pinned contract and frontend CI
Makefile Common local workflows
All direct dependencies are exact pins. The selections were checked against official documentation and package compatibility on 2026-07-21.
| Component | Pin | Decision |
|---|---|---|
| Solidity | 0.8.35 |
Latest stable compiler supported cleanly by the selected contract stack; Solidity docs recommend the latest released compiler. |
| Foundry CI | v1.7.1 |
Latest immutable stable Foundry release; local validation may use another reported binary. |
| OpenZeppelin Contracts | v5.6.1 |
Latest audited 5.x release documented in the OpenZeppelin changelog. |
| forge-std | v1.9.7 |
Exact test-library tag. |
| Node / pnpm | Node 22 in CI / pnpm 11.11.0 |
Node exceeds the Next.js 20.9 minimum; package manager is pinned in packageManager. |
| Next.js / React | 16.2.10 / 19.2.7 |
Current stable App Router pair with post-RSC security patches. |
| wagmi / viem | 2.19.5 / 2.55.4 |
Current compatible wagmi 2 release required by RainbowKit, with viem 2.x; see wagmi and viem. |
| RainbowKit / TanStack Query | 2.2.11 / 5.101.3 |
Current compatible wallet and query layers. |
| TypeScript / ESLint | 5.9.3 / 9.39.5 |
Newest stable versions compatible with the current Next.js TypeScript ESLint parser. TypeScript 7 / ESLint 10 were evaluated but are not yet accepted by that stack. |
Chainlink integration follows the official AggregatorV3Interface data-feed API and L2 sequencer guidance. Production/testnet feed addresses are intentionally environment-provided and must be confirmed in the current feed directory.
Prerequisites: Git, Foundry, Node 20.9+ and pnpm 11.11.0.
git clone https://github.com/alsaecas/launchproof.git launchproof
cd launchproof
make install
make checkFor the complete local dApp:
# terminal 1
make anvil
# terminal 2
make deploy-local
# copy the printed real addresses into app/.env.local, then
make devOpen http://localhost:3000. The deployment starts five minutes after the script transaction, allowing time to configure the client. See DEPLOYMENT.md for seeding and Sepolia verification.
cd contracts
forge fmt --check
forge build
forge test -vvv
forge coverage --report summary
forge snapshot
cd ../app
pnpm lint
pnpm typecheck
pnpm test
pnpm buildThe suite covers phase boundaries, four decimal models, oracle failures, lifecycle, escrow, vesting, roles, recovery, transfer-tax rejection, native reentrancy, fuzzed values and stateful invariants. This README does not freeze a coverage percentage because compiler instrumentation and test profiles can change it; the final validation report and local command output are the source of truth.
Validation on 2026-07-21 produced 31/31 passing Foundry tests (including 512 runs per fuzz test and 128 × 64 calls per invariant) and 8/8 passing frontend tests. forge coverage --ir-minimum --report summary—required because the unoptimized constructor otherwise hits stack depth—reported 83.86% lines / 33.85% branches for LaunchProofSale.sol, 100% lines / 85.71% branches for DemoTokenFaucet.sol, and 63.80% lines / 22.40% branches across the full instrumented tree including unexecuted deployment and E2E scripts. These figures are below the aspirational 95%/90% target and are reported without inflation; via-IR source-map warnings also make them approximate.
Use .env.example as the full catalog. Server/deployment secrets (PRIVATE_KEY, RPC and explorer API keys) must remain only in an untracked environment file. NEXT_PUBLIC_* values are intentionally browser-visible and must contain only verified public configuration. Missing frontend addresses produce a configuration warning and zero on-chain reads rather than invented data.
Portfolio screenshots should be captured from the live Sepolia deployment or a real local Anvil deployment. The interface never substitutes placeholder chain data.
| Concept | Concrete implementation |
|---|---|
| Presale | Fully funded, escrowed LaunchProofSale lifecycle |
| Phases | Ordered structs, time/allocation advancement and bounded split quotes |
| Blacklisting | Dedicated manager role; buyer and beneficiary blocked only from new purchases |
| NatSpec | Public API, structures, errors, events and critical math documented in source |
| Emergency withdrawal | Restricted unsupported-token/native-surplus recovery with liability views |
| Periods | Immutable sale timestamps plus TGE, cliff and linear windows |
| DeFi mathematics | USD WAD normalization and full-precision mulDiv rounding rules |
| Stablecoins | Oracle-priced 6-, 8- and 18-decimal ERC-20 test coverage |
| Phase management | Cumulative caps, rollover at new prices and off-chain reconstructable events |
| Chainlink price feeds | Round validation, staleness, decimal normalization and optional sequencer gate |
| Claims | Cumulative TGE/cliff/linear vesting with repeatable partial claims |
| Testing | Unit, fuzz, invariant, frontend render/pure-logic and local deployment checks |
- No audit, formal verification, governance, upgrade path, secondary-market controls, or jurisdiction-specific compliance policy.
- Standard non-rebasing ERC-20 behavior is required; fee-on-transfer inputs are rejected.
- Oracle correctness and liveness remain external trust assumptions.
- The frontend presents the three deployed phases and supports Sepolia ETH, dUSDC and dUSDT; alternate deployments require matching public configuration.
MIT. This software is for education and engineering demonstration only. It is not financial, legal or security advice and must not be represented as audited.