Розробка системи стейкінгу токенів з доходністю
Стейкінг з доходністю — один з базових строительних блоків DeFi. Реалізацій багато: від простого «lock tokens, get more tokens» до складних систем з veToken моделлю, gauge voting та bribe markets (Curve, Convex, Balancer). Вибір архітектури залежить від мети: утримання холдерів, governance, incentivization ліквідності.
Розберемо дві найбільш використовувані моделі — MasterChef-style та ve-модель — та поговоримо, де кожна з них проигрує.
MasterChef-стиль: базова архітектура
Оригінальний SushiSwap MasterChef до сих пір форкується сотнями проектів. Суть: один контракт управляє кількома пулами, кожний пул отримує долю від загальної емісії токена пропорційно allocPoint.
Математика accRewardPerShare
Ключова інваріанта: pending(user) = user.amount * accRewardPerShare / PRECISION - user.rewardDebt.
accRewardPerShare монотонно зростає з кожним новим блоком (або секундою). При deposit/withdraw користувач оновлює rewardDebt, «обнулюючи» поточний пендинг (який спочатку йому виплачується).
function _updatePool(uint256 pid) internal {
PoolInfo storage pool = poolInfo[pid];
if (block.timestamp <= pool.lastRewardTime) return;
uint256 elapsed = block.timestamp - pool.lastRewardTime;
uint256 reward = elapsed * rewardPerSecond * pool.allocPoint / totalAllocPoint;
// mint reward tokens (або transfer з reward wallet)
rewardToken.mint(address(this), reward);
pool.accRewardPerShare += reward * 1e18 / pool.totalStaked;
pool.lastRewardTime = block.timestamp;
}
Проблема MasterChef: якщо нема нагород (rewardPerSecond = 0 або бюджет вичерпан) — користувачі йдуть. Модель повністю залежить від постійної емісії, що dilute-ит токен нескінченно. APY падає по мірі зростання TVL, що створює нестабільний flywheel.
Reward у кількох токенах
Мульти-reward стейкінг — кожний пул починисляє кілька типів наград одночасно. Референс: Synthetix StakingRewards (audited, widely forked).
// Кілька rewarders для одного пулу
mapping(address => RewardInfo) public rewardInfo; // rewardToken -> RewardInfo
struct RewardInfo {
uint256 rewardRate; // reward per second
uint256 lastUpdateTime;
uint256 rewardPerTokenStored;
mapping(address => uint256) userRewardPerTokenPaid;
mapping(address => uint256) rewards;
}
Важливо: при додаванні нового reward-токена після запуску — retroactive початіслення для вже існуючих стейкерів не повинні відбуватися. Новий rewardPerTokenStored стартує з поточного моменту.
veToken модель: довгостроковий стейкінг
Curve Finance ввела veCRV — vote-escrowed CRV. Ідея: lock CRV на строк від 1 тижня до 4 років, отримуєш veG пропорційно amount × time_remaining / max_lock_time. veG: не трансфабельний, постійно decay до нуля по мірі закінчення блокування.
Це змінює incentive: щоб зберегти вплив, потрібно регулярно продовлювати lock. Великі холдери, зацікавлені у довгостроковому управлінні, тримають максимальний lock.
Реалізація ve-механіки
struct LockedBalance {
int128 amount;
uint256 end; // timestamp кінця блокування (округлено до тижня)
}
function create_lock(uint256 value, uint256 unlock_time) external nonReentrant {
LockedBalance memory locked = _locked[msg.sender];
require(locked.amount == 0, "Withdraw old tokens first");
uint256 rounded_unlock = (unlock_time / WEEK) * WEEK; // округлення до тижня
require(rounded_unlock >= block.timestamp + WEEK, "Lock too short");
require(rounded_unlock <= block.timestamp + MAXTIME, "Lock too long");
_deposit_for(msg.sender, value, rounded_unlock, locked, CREATE_LOCK_TYPE);
}
Voting power лінійно убувває: при створенні lock на 4 роки — voting power максимальна, кожну тиждень зменшується. Це потребує checkpoint-механізму для зберігання історії (Curve зберігає точки на кожну тиждень у point_history).
Складність реалізації ve-моделі: чесна та газово-ефективна реалізація — це ~500-800 строк Vyper/Solidity з продуманим checkpoint алгоритмом. Використання готової референсної реалізації Curve (MIT ліцензія) з адаптацією — переважніше написання з нуля.
Gauge voting та бриб-маркет
Поверх ve-стейкінгу будується gauge система: холдери veToken голосують за розподіл емісії між різними пулами. Пул, отримавши більше голосів — отримує більше наград.
Це створює "gauge wars": проекти, що бажають мати deep ліквідність свого токена, платять veToken-холдерам за голоси. Votium (для Curve), Hidden Hand (для Balancer/Aura) — готові bribe-платформи. Інтеграція з цими платформами — стандартна практика для нових протоколів.
Порівняння моделей
| Характеристика | MasterChef | veToken |
|---|---|---|
| Складність реалізації | Низька | Висока |
| Довгостроковое утримання | Слабке | Сильне |
| Governance influence | Ні | Вбудований |
| Gas cost claim | Низька | Середня |
| Ризик інфляції | Високий | Контрольований |
| Time-to-market | 1-2 тижні | 4-8 тижнів |
Безпека: типові уразливості
Reentrancy при claim. Якщо reward-токен має ERC-777 хук або токен з callback — зловмисник може рекурсивно вызвати claim, отримуючи багаторазові награди до оновлення rewardDebt. Захист: nonReentrant модифікатор + CEI паттерн (effects перед interactions).
Flash loan маніпуляція. Атакуючий бере flash loan, робить величезний deposit, чекає одного блока (якщо reward per block), забирає, виводить. При reward per second — навіть одного блока достатньо. Захист: мінімальний lock період або reward тільки за цілі епохи (epoch-based snapshots).
Oracle manipulation для reward у USD. Якщо контракт розраховує reward у доларах через on-chain oracle (Chainlink) — маніпуляція ціною токена може змінити reward rate. Краще зберігати reward rate у token units, не USD.
Економіка стейкінгу
APY = (річна емісія наград / TVL) × 100%. При TVL = $1M та емісії $100K/рік → APY = 10%.
Ошибка: запускати з високим APY (300-1000%) для привабення TVL, а потім знижувати. Це створює mercenary capital: TVL йде разом зі зниженням APY. Краще: помірний стабільний APY (20-50%) з довгостроковим vesting наград, що знижує sell pressure.
Для реальної стійкості reward повинні мати non-dilutive джерело: комісії протоколу (як у Uniswap v3 fee switch), revenue sharing, а не чиста емісія.
Процес та терміни
MasterChef з мульти-наградами та frontend — 3-4 тижні розробки + 2 тижні аудиту. veToken система з gauge voting — 6-10 тижнів розробки, обов'язковий 3-4 тижні аудиту. Фундаментальна рекомендація: для veToken — fork референсного Curve VotingEscrow з модифікаціями, а не написання з нуля.







