Розробка контрактів стейкінгу

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка контрактів стейкінгу
Середній
~3-5 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1309
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1222
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    922
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1151
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    614
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    887

Розробка контрактів стейкингу

Контракт стейкингу — один із базових примітивів DeFi. Користувач депонує токени, отримує винагороди з часом та може вивести кошти. Звучить просто — і саме тому більшість реалізацій містять баги. Правильний механізм розрахунку винагород є нетривіальним, а помилки тут коштують грошей.

Розподіл винагород: алгоритм накопленої винагороди за токен

Наївна реалізація проходить через всіх стейкерів та оновлює їх баланси — це O(n) щодо газу та руйнує контракт при великій кількості користувачів.

Стандартний алгоритм: 累積된 보상당 토큰. Глобальна змінна rewardPerTokenStored накопичує винаграду на 1 токен з моменту розгортання. При кожному deposit/withdraw вона оновлюється. Індивідуальна винагорода обчислюється як (rewardPerToken - userCheckpoint) × userBalance.

uint256 public rewardPerTokenStored;
uint256 public lastUpdateTime;

mapping(address => uint256) public userRewardPerTokenPaid;
mapping(address => uint256) public rewards;

function rewardPerToken() public view returns (uint256) {
    if (totalSupply == 0) return rewardPerTokenStored;
    return rewardPerTokenStored + 
        (block.timestamp - lastUpdateTime) * rewardRate * 1e18 / totalSupply;
}

function earned(address account) public view returns (uint256) {
    return balanceOf[account] * 
        (rewardPerToken() - userRewardPerTokenPaid[account]) / 1e18 
        + rewards[account];
}

Це O(1) — газ не залежить від кількості користувачів. Саме так працює Synthetix StakingRewards, який став еталонною реалізацією.

Основні механіки стейкингу

Період блокування: токени заблоковані на N днів після депозиту. Зменшує тиск на продаж. Потребує збереження depositTime та перевірки при withdraw.

Cooldown для вивільнення: після ініціювання виводу — очікування 7-28 днів. Популярно в PoS протоколах (імітує період unbonding).

Штраф за ранній вивід: при виведенні до закінчення періоду блокування — штраф (наприклад, 10% від суми). Штраф йде до пулу винагород або спалюється.

Множник за час: чим довше стейкинг — тим вища ставка винагород. Реалізується через ярусні множники або лінійний вестинговий множник.

Безпека

Reentrancy: при виплаті винагород через transfer → зовнішній виклик → функція контракту знову. CEI паттерн (Checks-Effects-Interactions): спочатку оновити стан, потім робити transfer.

Втрата точності: поділ у Solidity округлює вниз. При малих сумах або великому totalSupply точність може бути втрачена. Використовуйте масштабуючий коефіцієнт 1e18 (або 1e27 для додаткової точності).

Токен винагород != токен стейкингу: якщо токен винагород та стейкингу однакові — totalSupply включає токени винагород у пулі, що ламає обчислення rewardPerToken. Потрібно акуратно рахувати тільки "застейковані" токени.

Адміністративні ключі: хто може змінити rewardRate? Якщо це EOA — єдина точка відмови. Timelock + multisig — стандарт для production контрактів.

Контракти стейкингу перед розгортанням обов'язково проходять аудит — вони зберігають кошти користувачів та є частими мішенями для експлойтів.