Розробка deflationary-токена (зі спалюванням)

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

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

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

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

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

Розробка deflationary-токена (з спалюванням)

Deflationary токен — це токен, total supply якого зменшується зі часом. Механізм спалювання вбудований у контракт: частина кожного transfer автоматично йде на нульову адресу (address(0)). Звучить просто, але дьявол у деталях реалізації — особливо коли токен повинен працювати з DeFi протоколами.

Два підходи до burn

1. Fee-on-transfer (автоматичне спалювання при transfer)

При кожному transfer автоматично спалюється X% від суми:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";

contract DeflationaryToken is ERC20, Ownable2Step {
    uint256 public burnBps;  // базисні пункти, 100 = 1%
    uint256 public constant MAX_BURN_BPS = 1000;  // 10% максимум
    
    // Адреси виключені з податку (LP пари, роутери)
    mapping(address => bool) public isBurnExempt;
    
    event BurnBpsUpdated(uint256 oldBps, uint256 newBps);
    
    constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply,
        uint256 _burnBps
    ) ERC20(name, symbol) Ownable2Step() {
        require(_burnBps <= MAX_BURN_BPS, "Burn too high");
        burnBps = _burnBps;
        _mint(msg.sender, initialSupply);
    }
    
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        if (burnBps > 0 && !isBurnExempt[from] && !isBurnExempt[to]) {
            uint256 burnAmount = (amount * burnBps) / 10000;
            uint256 sendAmount = amount - burnAmount;
            
            super._transfer(from, address(0), burnAmount);  // burn
            super._transfer(from, to, sendAmount);          // transfer
        } else {
            super._transfer(from, to, amount);
        }
    }
    
    function setBurnBps(uint256 _burnBps) external onlyOwner {
        require(_burnBps <= MAX_BURN_BPS, "Burn too high");
        emit BurnBpsUpdated(burnBps, _burnBps);
        burnBps = _burnBps;
    }
    
    function setBurnExempt(address account, bool exempt) external onlyOwner {
        isBurnExempt[account] = exempt;
    }
}

Критична проблема з fee-on-transfer у DeFi: Uniswap V2 та більшість AMM не підтримують fee-on-transfer токени коректно з коробки. Роутер відправляє amountIn в пул, але пул отримує amountIn - burnAmount. Це викликає revert з помилкою UniswapV2: INSUFFICIENT_INPUT_AMOUNT або невірний розрахунок.

Рішення — використовувати Uniswap V2 функції із суфіксом SupportingFeeOnTransferTokens:

// Виклик з фронтенду або контракту
IUniswapV2Router02(router).swapExactTokensForTokensSupportingFeeOnTransferTokens(
    amountIn,
    amountOutMin,
    path,
    to,
    deadline
);

Але це відповідальність фронтенду та інтеграторів — ваш токен повинен явно документувати, що це fee-on-transfer.

2. Manual burn через buyback-and-burn

Більш передбачуваний механізм: частина доходу протоколу періодично використовується для покупки токена на ринку та його спалювання. Немає проблем з DeFi сумісністю, більш прозорачна економіка.

contract BuybackBurnVault is Ownable2Step {
    IERC20 public immutable token;
    IUniswapV2Router02 public immutable router;
    
    uint256 public totalBurned;
    
    event BuybackExecuted(uint256 bnbSpent, uint256 tokensBurned);
    
    constructor(address _token, address _router) Ownable2Step() {
        token = IERC20(_token);
        router = IUniswapV2Router02(_router);
    }
    
    // Отримуємо BNB від протоколу
    receive() external payable {}
    
    function executeBuyback(
        uint256 bnbAmount,
        uint256 minTokensOut,
        uint256 deadline
    ) external onlyOwner {
        require(address(this).balance >= bnbAmount, "Insufficient BNB");
        
        address[] memory path = new address[](2);
        path[0] = router.WETH();  // WBNB на BSC
        path[1] = address(token);
        
        uint256[] memory amounts = router.swapExactETHForTokens{value: bnbAmount}(
            minTokensOut,
            path,
            address(this),
            deadline
        );
        
        uint256 tokensBought = amounts[amounts.length - 1];
        
        // Спалюємо куплені токени
        token.transfer(address(0), tokensBought);
        totalBurned += tokensBought;
        
        emit BuybackExecuted(bnbAmount, tokensBought);
    }
}

Дефляційна модель: важливі питання

Перед вибором механізму потрібно відповісти на кілька питань, які визначають архітектуру:

Процент burn: 1–2% — це агресивно для high-frequency трейдингу. Кожний свап на Uniswap = buy + sell = 2 transfer + AMM fee. При 1% burn токен втрачає 2% за одну торгову операцію плюс 0.3% LP fee. Це відпугує трейдерів. Для utility токенів з нечастими transfer — прийнятно.

Фіксований vs динамічний burn: динамічний (наприклад, вищий burn при великому обсязі) створює складну tokenomics, але дозволяє настроювати тиск під ринкові умови.

Burn cap: при достатньо великому burn supply рано чи пізно упаде до неліквідних рівнів. Розумно задати мінімальний поріг: якщо totalSupply < MIN_SUPPLY, burn відключається.

uint256 public constant MIN_SUPPLY = 1_000_000 * 10**18;  // 1M токенів — мінімум

function _transfer(address from, address to, uint256 amount) internal override {
    if (burnBps > 0 && !isBurnExempt[from] && !isBurnExempt[to]) {
        uint256 burnAmount = (amount * burnBps) / 10000;
        
        // Не спалюємо якщо упадемо нижче мінімума
        uint256 currentSupply = totalSupply();
        if (currentSupply > MIN_SUPPLY) {
            if (currentSupply - burnAmount < MIN_SUPPLY) {
                burnAmount = currentSupply - MIN_SUPPLY;
            }
            super._transfer(from, address(0), burnAmount);
            super._transfer(from, to, amount - burnAmount);
            return;
        }
    }
    super._transfer(from, to, amount);
}

Мониторинг та аналітика

Дефляційна механіка безсенсовна без прозорості. Користувачі повинні бачити динаміку спалювання:

// Событие для трекінгу в subgraph
event TokensBurned(address indexed from, address indexed to, uint256 amount, uint256 newTotalSupply);

function _transfer(address from, address to, uint256 amount) internal override {
    // ... логіка burn ...
    if (burnAmount > 0) {
        emit TokensBurned(from, address(0), burnAmount, totalSupply());
    }
}

Через The Graph subgraph будується дашборд: денний burn rate, накопилений спалений, прогнозований supply через N років при поточному burn rate.

Безпека

Два специфічні ризики deflationary токенів:

Re-entrancy через approve: якщо _transfer має зовнішні виклики (наприклад, автоматичний свап частини burn в ETH) — класична re-entrancy атака. Рішення: ReentrancyGuard + CEI паттерн.

Маніпуляція exempt-списком: якщо власник може додати будь-яку адресу в isBurnExempt, злоумисник з захопленим owner-ключем може відключити burn та порушити обіцянки tokenomics. Використовуйте timelock на зміни exempt-списку для проектів із серйозним TVL.

// Timelock для критичних змін
uint256 public constant BURN_CHANGE_TIMELOCK = 48 hours;
mapping(bytes32 => uint256) public pendingChanges;

function scheduleBurnBpsChange(uint256 newBps) external onlyOwner {
    bytes32 changeId = keccak256(abi.encodePacked("burnBps", newBps));
    pendingChanges[changeId] = block.timestamp + BURN_CHANGE_TIMELOCK;
}

function executeBurnBpsChange(uint256 newBps) external onlyOwner {
    bytes32 changeId = keccak256(abi.encodePacked("burnBps", newBps));
    require(pendingChanges[changeId] != 0, "Not scheduled");
    require(block.timestamp >= pendingChanges[changeId], "Timelock active");
    burnBps = newBps;
    delete pendingChanges[changeId];
}

Терміни та обсяг

Розробка (контракти + тести) — 5–8 днів. Тестування сумісності з Uniswap/PancakeSwap — 1–2 дні. Розгортання + верифікація + налаштування LP пари — 1 день. Subgraph для аналітики burn — опціонально, 2–3 дні.