Розробка системи стейкінгу та винагород для фан-токенів
Фан-токени — окремна ніша: модель Chiliz/Socios, токени спортивних клубів, музикантів, стрімерів. Механіка відрізняється від DeFi-стейкінгу: тут цінність не тільки фінансова. Власники очікують доступу до екслюзивного контенту, права голосу в опитуваннях ("який колір виїзної форми?"), NFT-дропів, лотерей зустрічей. Стейкінг повинен це відображати.
Технічно це все ще ERC-20 + розподіл винагород, але з нефінансовими механіками винагород зверху. Розберемо, як це влаштовано.
Механіки винагород та їх реалізація
Багаторівневі тири
Класичний підхід для фан-токенів: три-чотири тири з різним набором переваг. Логіка: чим більше застейковано та чим довше, тим вищий тир.
| Тир | Мінімум токенів | Період блокування | Переваги |
|---|---|---|---|
| Bronze | 100 FAN | Нема | Голосування, базовий контент |
| Silver | 500 FAN | 30 днів | + ранній доступ до NFT-дропів |
| Gold | 2000 FAN | 90 днів | + лотерея на мерч/квитки |
| Platinum | 10000 FAN | 180 днів | + зустрічі, екслюзивні дзвінки |
Тир визначається on-chain через контракт стейкінгу. Off-chain сервіси (платформа контенту, система лотереї) читають тир через view-функцію та розблоковують відповідні можливості.
Розподіл винагород: два підходи
Підхід 1 — Pull модель (MasterChef-стиль). Кожний стейкер накопичує pending rewards, які він самостійно забирає. Використовується accRewardPerShare — акумулятор, що оновлюється при кожному deposit/withdraw. Добре масштабується: газ на розподіл винагород платить користувач, а не протокол.
struct UserInfo {
uint256 amount; // застейковано FAN
uint256 rewardDebt; // борг для коректного розрахунку
uint256 lockedUntil; // timestamp розблокування
uint8 tier; // поточний тир
}
function pendingReward(address user) public view returns (uint256) {
UserInfo storage info = userInfo[user];
uint256 accPerShare = accRewardPerShare; // оновлене значення
if (block.timestamp > lastRewardTime && totalStaked > 0) {
uint256 elapsed = block.timestamp - lastRewardTime;
uint256 newReward = elapsed * rewardPerSecond;
accPerShare += newReward * 1e12 / totalStaked;
}
return info.amount * accPerShare / 1e12 - info.rewardDebt;
}
Підхід 2 — Push модель (снапшоти). Команда періодично робить snapshot застейкованих балансів та розподіляє винагради (наприклад, після кожного матчу — розповсюджувати пул винагород усім Gold+ власникам). Реалізується як раунди MerkleDistributor.
Плюс push: можна розповсюджувати non-fungible винагради (NFT) та off-chain цінності (коди доступу). Мінус: потребує регулярних транзакцій від команди протоколу.
Для фан-токенів оптимально: pull-модель для фінансових винагород (токени), push/snapshot для спеціальних подій (NFT-дропи, лотереї).
NFT-інтеграція як винагорода
Популярний паттерн: стейкінг відкриває доступ до мінту екслюзивних NFT. Не безплатно (інакше всі мінтять та продають) — мінт доступний лише при досягненні потрібного тиру та утримання стейку.
Реалізація: NFT-контракт перевіряє контракт стейкінгу у функції mint:
function mintExclusive(uint256 tokenId) external {
IFanStaking staking = IFanStaking(stakingContract);
require(staking.getUserTier(msg.sender) >= GOLD_TIER, "Insufficient tier");
require(!hasMinted[msg.sender][tokenId], "Already minted");
hasMinted[msg.sender][tokenId] = true;
_mint(msg.sender, tokenId);
}
Бонуси за час та loyalty множник
Чим довше адреса тримає стейк без виводу, тим вищий його effective стейк для розрахунку винагород. Механіка: loyaltyMultiplier зростає з часом (наприклад, +10% кожні 30 днів, максимум 200%). При будь-якому withdraw — скидається до 100%.
Зберігайте множник як uint256 відсотків та множте на amount перед розрахунком rewardDebt. Це створює стимул не торкатися стейку — що знижує циркулюючу пропозицію та тиск на ціну.
Голосування для власників
Фан-опитування — це прості on-chain голосування, доступні лише застейкованим адресам потрібного тиру.
Не потрібна повноцінна DAO фреймворк. Достатньо легкого контракту:
function vote(uint256 pollId, uint8 optionIndex) external {
require(stakingContract.getUserTier(msg.sender) >= polls[pollId].minTier, "Tier too low");
require(block.timestamp < polls[pollId].endTime, "Poll ended");
require(!hasVoted[pollId][msg.sender], "Already voted");
hasVoted[pollId][msg.sender] = true;
uint256 weight = stakingContract.getStakedAmount(msg.sender); // голос = вага стейку
polls[pollId].votes[optionIndex] += weight;
emit VoteCast(pollId, msg.sender, optionIndex, weight);
}
Результати публічно верифіковані on-chain, що важливо для довіри фанатів.
Технічні особливості фан-середовища
ERC-20 з обмеженнями трансферу. Деякі фан-токени забороняють трансфер у офіційних маркетплейсах (тільки через схвалені DEX або Chiliz Chain). При розробці стейкінгу враховуйте: якщо токен має обмеження transferFrom, депозит у контракт стейкінгу може бути заблокований. Рішення: whitelist контракту стейкінгу у токені.
Multi-chain розділеність. Chiliz Chain — окремий EVM-сумісний L1. Якщо фан-токен живе там, весь контракт стейкінгу розгортається на Chiliz Chain. Газ дешевий, але екосистема обмежена. Можливо перекидання на Ethereum/Polygon для DeFi інтеграцій.
Нормативна обережність. Фан-токени в деяких юрисдикціях кваліфікуються як цінні папери, якщо дають фінансові права. Стейкінг з токен-наградами посилює цей ризик. Юридична консультація перед запуском — обов'язкова.
Стек та терміни
Solidity 0.8.x + Hardhat або Foundry + OpenZeppelin. Frontend: wagmi + React, якщо Ethereum/Polygon. Для Chiliz Chain — власний JSON-RPC, wagmi з кастомною конфігурацією chain.
Розробка контракту стейкінгу з тирами та pull-моделлю — 2–3 тижні. З NFT-інтеграцією, механізмом лотереї та голосуванням — 4–6 тижнів. Аудит обов'язковий перед запуском з реальними коштами — ще 2–3 тижні.







