Розробка контрактів фармінгу

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску 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

Розробка контрактів yield farming

Контракт yield farming розподіляє винагороди між постачальниками ліквідності пропорційно їхній частці в пулі. Математика простою, але реалізація повна нюансів: від помилок у формулах накопленої винагороди до вразливостей, які дозволяють спорожнити пул винагород через маніпуляцію депозитом. Найвідоміший приклад — MasterChef від SushiSwap, чиї форки коштували протоколам десятків мільйонів через різні помилки реалізації.

Формула накопленої винагороди: чому наївна реалізація не працює

Наївний підхід: зберігати для кожного користувача lastClaimedBlock і обчислювати винагороди як (currentBlock - lastClaimedBlock) * rewardPerBlock * userShare. Проблема в тому, що userShare змінюється при кожному депозиті/виведенні від інших користувачів. Перерахування для всіх користувачів при кожній зміні — це операція O(n), яка при 1000 учасниках коштує мільйони газу.

Алгоритм MasterChef (стиль Compound) вирішує це через accRewardPerShare — накопленої винагороди за одиницю stake, яка тільки зростає:

accRewardPerShare += (newRewards / totalStaked)

Для кожного користувача зберігається rewardDebt — "борг" на момент останньої взаємодії:

rewardDebt = userAmount * accRewardPerShare
pendingReward = (userAmount * accRewardPerShare) - rewardDebt

При депозиті/виведенні оновлюємо accRewardPerShare для поточного моменту, виплачуємо очікувані винагороди та оновлюємо rewardDebt. Це O(1) незалежно від кількості учасників.

Проблема з цілими числами: accRewardPerShare зберігається помноженим на 1e12 (або 1e18 для токенів з 18 десятковими знаками), щоб уникнути втрати точності при діленні. Без цього множення при малих депозитах та великому totalStaked накопленої винагороди заокруглюється до 0.

Основні вразливості контрактів farming

Маніпуляція harvest через flash loan

Атака: в одній транзакції через flash loan взяти великий кредит, задепозитити в контракт farming, зібрати непропорційно велику частку накопленої винагороди, вивести депозит, повернути flash loan. Працює, якщо harvest() не вимагає мінімального часу стейкінгу.

Захист: мінімальний період блокування (навіть 1 блок значно ускладнює атаку) або snapshot-based винагороди (винагороди розподіляються за балансом на момент snapshot, а не поточним).

Не всі протоколи застосовують період блокування — це компроміс UX. Якщо період блокування неприйнятний, формула повинна бути розроблена так, щоб миттєвий депозит-harvest-виведення не давав прибутку (через збір депозиту/виведення).

Reentrancy через harvest + ERC-777

Якщо токен винагороди — ERC-777 (або будь-який токен з hook при передачі), то під час виплати винагороди токен викликає callback у одержувача. Якщо callback повторно викликає harvest() або withdraw() — це reentrancy. Стандартний захист через ReentrancyGuard від OpenZeppelin. Важливо: guard повинен бути на всіх функціях, які змінюють стан І взаємодіють із зовнішніми контрактами.

Вичерпання токена винагороди

Контракт обіцяє rewardPerBlock, але не перевіряє, чи достатньо токенів у пулі винагород. Якщо пул винагород порожній, transfer скасовується — користувачі не можуть ні отримати винагороди, ні вивести депозит (якщо harvest вбудований у withdraw). Паттерн: при виведенні спочатку вивести stake, потім спробувати виплатити винагороди з обробкою недостатнього балансу.

Реалізація з підтримкою кількох пулів

Розширення MasterChef для кількох staking токенів (multi-pool farming):

struct PoolInfo {
    IERC20 stakingToken;
    uint256 allocPoint;         // вага пула в розподілі винагород
    uint256 lastRewardBlock;
    uint256 accRewardPerShare;  // помножено на 1e12
    uint256 totalStaked;
}

struct UserInfo {
    uint256 amount;
    uint256 rewardDebt;
}

PoolInfo[] public poolInfo;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;

uint256 public rewardPerBlock;
uint256 public totalAllocPoint;

allocPoint розподіляє rewardPerBlock між пулами: пул з allocPoint = 100 при totalAllocPoint = 200 отримує 50% винагород. Це дозволяє керувати стимулами без зміни загальної швидкості емісії.

Комісія за депозит та захист від маніпуляцій китів

Комісія депозиту (0,1-0,5%) — додатковий механізм проти flash loan атак та джерело доходу казначейства. Реалізується як вичеркнення при депозиті:

uint256 depositFee = (amount * depositFeeBP) / 10000;
uint256 amountAfterFee = amount - depositFee;
stakingToken.safeTransfer(feeRecipient, depositFee);

depositFeeBP у базових пунктах (100 = 1%). Зміна depositFeeBP через governance з timelock обов'язкова, інакше власник може встановити 100% комісію та конфіскувати всі депозити.

Стек та тестування

Foundry для тестування: fuzzing граничних значень accRewardPerShare, тести сценаріїв багатьох користувачів (10 користувачів з різними депозитами/виведеннями), перевірка інваріантів через тести invariant.

Ключовий інваріант: SUM(pendingRewards для всіх користувачів) <= balance(rewardToken) у контракті. Порушення цього інваріанту означає, що контракт обіцяє більше, ніж має.

Echidna для property-based тестування математики винагород — генерує випадкові послідовності операцій та перевіряє, що інваріанти не порушуються.

Процес та терміни

Проектування (1 день). Вибір моделі винагород (single token vs multi-pool), параметри (rewardPerBlock, depositFee, lock period), модель governance для зміни параметрів.

Розробка (2-3 дні). Базова реалізація та розширення. OpenZeppelin для ReentrancyGuard, SafeERC20, Ownable. Користувацька логіка мінімальна.

Тестування (1-2 дні). Foundry fuzzing, сценарії багатьох користувачів, граничні випадки: нульовий totalStaked, переповнення при множенні, вичерпання пула винагород.

Всього: 3-5 днів до контракту готового до аудиту. Для продакшну рекомендуємо зовнішній аудит — контракти farming зберігають TVL та активно атакуються.