Розробка Launchpad для фан-токенів
Фан-токени — це не utility-токени у класичному сенсі та не governance у розумінні DeFi. Це інструмент монетизації фан-аудиторії, яка у 99% випадків не є крипто-нативною. Клуб хочет монетизувати лояльність, болільник хочет почуття причетності та екслюзивних привілегій, платформа бере комісію. Launchpad для фан-токенів повинен обслуговувати саме цю модель — не permissionless DeFi, а керований onboarding для масової аудиторії.
Специфіка fan-token launchpad vs класичний IDO launchpad
Класичний IDO launchpad працює з крипто-нативною аудиторією: MetaMask, USDT, розуміння gas fees, tolerance до ризику. Fan-token launchpad працює з болільником, який прийшов з мобільного додатку клубу і, можливо, вперше чує слово «кошелек».
Ключові відмінності:
| Параметр | IDO Launchpad | Fan Token Launchpad |
|---|---|---|
| Аудиторія | Крипто-нативна | Мейнстрім / спортивні болільники |
| Onboarding | MetaMask + USDT | Email / соціальні мережі, fiat on-ramp |
| Токен utility | Governance, yield | Голосування за клуб, екслюзивний контент |
| Ціноутворення | Market-driven | Керуване клубом, bonding curve |
| Нормативне | DeFi grey area | Ближче до цінних паперів у деяких юрисдикціях |
| Вторинний ринок | DEX | Керуваний AMM з контролем ліквідності |
Архітектура токена та bonding curve
Механіка фан-токена
Фан-токени Chiliz-стилю (FC Barcelona BAR, Juventus JUV) будуються на кількох принципах:
- Обмежена емісія: фіксована пропозиція, керована клубом
- Привязка utility: голосування, доступ до контенту, NFT drops, зустрічі з гравцями
- Керована ліквідність: клуб або платформа контролює ліквідність, немає permissionless AMM
- Fiat gateway: покупка за фіат через карту або локальні платіжні методи
Bonding curve для первинного продажу
Замість фіксованої ціни або Dutch auction для фан-токенів часто використовується bonding curve — ціна зростає по мірі продажів. Це створює FOMO і винаграджує ранніх покупців.
contract FanTokenBondingCurve {
IERC20 public immutable fanToken;
uint256 public immutable initialPrice; // ціна першого токена в USD (scaled 1e6)
uint256 public immutable slope; // крутизна кривої (scaled 1e18)
uint256 public tokensSold;
// Лінійна bonding curve: price = initialPrice + slope * supply
function getCurrentPrice() public view returns (uint256) {
return initialPrice + (slope * tokensSold / 1e18);
}
// Вартість покупки amount токенів починаючи з поточної пропозиції
function getBuyCost(uint256 amount) public view returns (uint256) {
// Інтеграл лінійної функції: сума площі трапеції
uint256 priceAtStart = getCurrentPrice();
uint256 priceAtEnd = initialPrice + (slope * (tokensSold + amount) / 1e18);
return (priceAtStart + priceAtEnd) * amount / 2 / 1e6; // у базовій валюті
}
function buy(uint256 tokenAmount, uint256 maxCost) external payable nonReentrant {
uint256 cost = getBuyCost(tokenAmount);
require(cost <= maxCost, "Price slippage exceeded");
require(msg.value >= cost, "Insufficient payment");
tokensSold += tokenAmount;
fanToken.safeTransfer(msg.sender, tokenAmount * 1e18);
// Повернення надлишку
if (msg.value > cost) {
payable(msg.sender).transfer(msg.value - cost);
}
emit TokensPurchased(msg.sender, tokenAmount, cost);
}
}
Параметри initialPrice та slope налаштовуються для кожного клубу. Типовий діапазон початкової ціни — $1–5, кінцева ціна при повному розміщенні — $5–20.
Фіатний onboarding
Це ключова відмінність fan-token launchpad від DeFi платформи. Болільник не повинен знати про gas, він повинен натиснути «Купити» та заплатити картою.
Custody та custodial wallet
Два підходи до управління кошельками користувачів:
Повністю custodial (підхід Chiliz): платформа тримає приватні ключі. Користувач бачить баланс токенів, але не має on-chain кошелька. Максимальна простота UX, мінімальні вимоги до користувача. Мінус: централізація, платформа повинна дотримуватися custody regulations.
MPC wallet (рекомендований підхід): Multi-Party Computation кошелек. Приватний ключ розділений між користувачем (через його пристрій/акаунт) та платформою. Жоден бік не має повного ключа. Користувач підписує транзакції через SDK, не бачачи raw private key. Платформа не має повного ключа — не несе custody ризику.
Провайдери MPC wallet-as-a-service: Privy, Dynamic, Web3Auth, Capsule. Усі підтримують social login (Google, Apple, email).
// Privy integration — створення embedded wallet через social login
import { usePrivy, useWallets } from '@privy-io/react-auth';
function FanTokenPurchase() {
const { login, authenticated, user } = usePrivy();
const { wallets } = useWallets();
const embeddedWallet = wallets.find(w => w.walletClientType === 'privy');
async function purchaseTokens(amount: number) {
if (!authenticated) {
await login(); // Google/Apple/email login → автоматично створює embedded wallet
return;
}
const provider = await embeddedWallet!.getEthereumProvider();
const walletClient = createWalletClient({
account: embeddedWallet!.address as `0x${string}`,
transport: custom(provider)
});
// Користувач підписує транзакцію через UI Privy — не бачить raw tx
const hash = await walletClient.writeContract({
address: FAN_TOKEN_LAUNCHPAD_ADDRESS,
abi: LAUNCHPAD_ABI,
functionName: 'buyWithFiat',
args: [BigInt(amount), MAX_SLIPPAGE],
value: parseEther(await getETHCostForAmount(amount))
});
return hash;
}
return (
<button onClick={() => purchaseTokens(10)}>
{authenticated ? 'Купити 10 токенів' : 'Увійти та купити'}
</button>
);
}
Fiat-to-crypto конвертація
Користувач платить фіатом — платформа конвертує в крипто та виконує транзакцію. Варіанти:
On-ramp провайдери: Stripe Crypto (через Link), MoonPay, Transak, Ramp Network. Інтегруються через віджет або API. Обробляють KYC/AML, підтримують карти, банківські переводи, Apple Pay.
// Transak integration для on-ramp
function initiateFiatPurchase(fanTokenAmount: number, userAddress: string) {
const transak = new Transak({
apiKey: process.env.TRANSAK_API_KEY,
environment: 'PRODUCTION',
defaultCryptoCurrency: 'ETH',
walletAddress: userAddress,
// Кастомізація під клуб
themeColor: '009900', // колір клубу
hostURL: window.location.origin,
widgetHeight: '570px',
widgetWidth: '450px',
// Webhook для відслідковування статусу
webhookStatusUrl: `${API_BASE}/transak-webhook`,
});
transak.init();
// Після успішного on-ramp — автоматично вызиваємо purchase
transak.on(Transak.EVENTS.TRANSAK_ORDER_SUCCESSFUL, async (orderData) => {
await purchaseFanTokens(fanTokenAmount, userAddress, orderData.status.id);
});
}
Utility та engagement механіки
Сам по собі токен без utility не має сенсу. Launchpad повинен включати інфраструктуру для utility.
Голосування для клубу
contract FanVoting {
struct Vote {
string question;
string[] options;
uint256 startTime;
uint256 endTime;
uint256 minTokensToVote; // мінімальний холдинг для участі
bool resultsPublic; // публічні або приховані до окончення
}
struct VoteResult {
mapping(uint256 => uint256) voteCounts; // option index => token weight
mapping(address => bool) hasVoted;
mapping(address => uint256) votedOption;
}
mapping(uint256 => Vote) public votes;
mapping(uint256 => VoteResult) internal results;
IFanToken public fanToken;
function castVote(uint256 voteId, uint256 optionIndex) external {
Vote storage v = votes[voteId];
VoteResult storage r = results[voteId];
require(block.timestamp >= v.startTime && block.timestamp <= v.endTime);
require(!r.hasVoted[msg.sender], "Already voted");
uint256 balance = fanToken.balanceOf(msg.sender);
require(balance >= v.minTokensToVote, "Insufficient tokens");
// Vote weight = кількість токенів
r.voteCounts[optionIndex] += balance;
r.hasVoted[msg.sender] = true;
r.votedOption[msg.sender] = optionIndex;
emit Voted(msg.sender, voteId, optionIndex, balance);
}
}
Приклади голосувань, які клуби дійсно проводять: вибір музики на стадіоні, дизайн лімітованої форми, вибір благодійної організації для пожертви, питання до капітана команди.
Екслюзивні NFT drops для холдерів
contract FanExclusiveNFT is ERC721, ERC2981 {
IFanToken public immutable fanToken;
uint256 public minTokensRequired;
uint256 public mintPrice;
mapping(address => bool) public hasMinted;
function mintExclusive(uint256 tokenId) external payable {
require(fanToken.balanceOf(msg.sender) >= minTokensRequired, "Not enough fan tokens");
require(!hasMinted[msg.sender], "Already minted");
require(msg.value >= mintPrice, "Insufficient payment");
hasMinted[msg.sender] = true;
_safeMint(msg.sender, tokenId);
// Royalties через ERC-2981
_setTokenRoyalty(tokenId, clubTreasury, 500); // 5%
}
}
Вторинний ринок з керованою ліквідністю
Фан-токени не повинні торгуватися як DeFi токени з permissionless ліквідністю — клуб хочет контролювати волатильність ціни. Рішення: власний AMM з параметрами.
contract FanTokenAMM {
// Модифікована xy=k формула з price bounds
uint256 public minPrice; // клуб встановлює floor
uint256 public maxPrice; // клуб встановлює ceiling (опціонально)
uint256 public tokenReserve;
uint256 public ethReserve;
function swap(uint256 tokenAmount, bool isBuy) external payable nonReentrant {
uint256 newPrice = _calculateNewPrice(tokenAmount, isBuy);
// Price floor: клуб може выкупувати токени нижче minPrice
if (!isBuy && newPrice < minPrice) {
revert PriceBelowFloor(newPrice, minPrice);
}
_executeSwap(tokenAmount, isBuy);
}
// Клуб добавляє ліквідність з виручки
function addClubLiquidity() external payable onlyClub {
tokenReserve += _calculateTokensForETH(msg.value);
ethReserve += msg.value;
}
}
Price floor захищає холдерів від різкого знецінення та створює довіру до токена. Клуб фінансує buyback з дохідів від квитків, мерчандайзу, спонсорства.
Адміністративна панель клубу
Клуб повинен управляти екосистемою токена без технічних знань:
- Dashboard: поточна ціна, holders, trading volume, voting активність
- Голосування: створити питання → встановити час → опублікувати результати
- NFT drops: завантажити арт, встановити умови, запустити mint
- Buyback: додати кошти в liquidity pool одною кнопкою
- Аналітика: демографія холдерів, паттерни покупок, engagement score по болільниках
Нормативні соображення
Фан-токени у деяких юрисдикціях можуть кваліфікуватися як securities. Ключові питання при дизайні:
- Utility-only: токен не дає права на дохід клубу, дивіденди або equity. Тільки non-financial utility.
- No investment advertising: маркетинг будується на fan engagement, не на інвестиційному потенціалі
- KYC/AML: обов'язковий для fiat on-ramp. Для крипто-нативних покупок — за вимогою юрисдикції
- Geo-restrictions: США, деякі випадки ЄС (MiCA compliance) потребують спеціального підходу
Стек та терміни
| Компонент | Технологія | Термін |
|---|---|---|
| Smart contracts | Solidity + Foundry | 4–5 тиж |
| MPC wallet + social login | Privy / Dynamic SDK | 2–3 тиж |
| Fiat on-ramp | Transak / MoonPay | 1–2 тиж |
| Backend API | Node.js + PostgreSQL | 3–4 тиж |
| Frontend (mobile-first) | React Native / Next.js | 4–6 тиж |
| Club admin panel | React + shadcn/ui | 2–3 тиж |
| Аудит контрактів | 3–4 тиж |
Повний цикл розробки: 19–27 тижнів. Половина роботи — UX для non-crypto аудиторії, яка ніколи не простить "gas fee exceeded".







