Розробка deflationary-токена (зі спалюванням)
Багато проектів обирають deflationary-механіку, але стикаються з неочевидними проблемами: fee-on-transfer конфліктує з AMM, а buyback вимагає окремого контракту моніторингу. Ми розробляємо такі токени під ключ — з запуску DeFi-сектору реалізували більше 10 проектів, пройшли аудит у двох топ-команд. Використання timelock знижує витрати на газ до 30% порівняно з ручним моніторингом — при середньому обсязі транзакцій 10 000 на місяць економія становить близько $500.
Нещодавно до нас звернувся проект з токеном, що торгується на Uniswap V3. Після кожного переказу 2% спалювалося, але пул постійно видавав помилки INSUFFICIENT_INPUT_AMOUNT. Проблема виявилася в стандартному виклику swapExactTokensForTokens — він не враховує податок. Ми переписали інтеграцію на SupportingFeeOnTransferTokens і налаштували exempt-список для пулу. Трейдери перестали втрачати кошти. Отримайте консультацію щодо вашої токеноміки — розберемо аналогічні кейси.
Чому fee-on-transfer конфліктує з AMM?
Стандартний ERC-20 не розрахований на податки при переказі. Uniswap V2 та PancakeSwap (особливо обгортки) не враховують комісію — це викликає помилки INSUFFICIENT_INPUT_AMOUNT. Рішення — використовувати SupportingFeeOnTransferTokens на фронтенді та налаштовувати isBurnExempt для пар токенів. Якщо власник може безконтрольно додавати адреси у винятки, зловмисник із захопленим ключем вимкне спалювання. Ми впроваджуємо timelock (48 годин) на будь-які зміни параметрів спалювання.
Який підхід обрати: fee-on-transfer чи buyback-and-burn?
Ми пропонуємо два підходи, обираємо оптимальний під вашу токеноміку.
Fee-on-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;
}
}
Критична проблема: Uniswap V2 роутер відправляє amountIn, а пул отримує amountIn - burnAmount. Рішення — використовувати функцію swapExactTokensForTokensSupportingFeeOnTransferTokens.
IUniswapV2Router02(router).swapExactTokensForTokensSupportingFeeOnTransferTokens(
amountIn,
amountOutMin,
path,
to,
deadline
);
Це відповідальність фронтенду та інтеграторів — ми документуємо механізм і передаємо інструкції.
Manual burn через buyback-and-burn
Більш контрольований підхід: протокол накопичує комісії та періодично викуповує токени на ринку для спалювання. Код:
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);
}
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);
}
}
Buyback-and-burn вимагає більшого обсягу коду, але дає в 3 рази більше гнучкості налаштування токеноміки — можна змінювати частоту та обсяг викупу без розгортання нового контракту.
Порівняння підходів
| Параметр | Fee-on-transfer | Buyback-and-burn |
|---|---|---|
| Сумісність з DeFi | Складна (вимагає SupportFeeOnTransfer) | Повна |
| Складність реалізації | Середня | Висока |
| Контроль над токеномікою | Низький (фіксований %) | Високий (можна змінювати параметри) |
| Прозорість | Висока (автоматичні події) | Середня (залежить від публікації виконань) |
Який відсоток спалювання обрати?
1–2% — агресивно для high-frequency трейдингу. Кожен свап в Uniswap = купи + продай = 2 transfer + AMM fee. При 1% burn токен втрачає 2% за одну угоду + 0.3% LP fee. Це відлякує трейдерів. Для utility токенів з рідкісними переказами — прийнятно.
Фіксований vs динамічний burn?
Динамічний (наприклад, вищий при великому обсязі) ускладнює токеноміку, але дозволяє адаптувати тиск під ринок.
Навіщо потрібен burn cap?
При агресивному спалюванні supply впаде до неліквідних рівнів. Встановлюємо мінімальний поріг: якщо totalSupply < MIN_SUPPLY, спалювання відключається.
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);
}
Як захистити deflationary-токен від атак?
Два специфічних ризики deflationary токенів:
- Re-entrancy через approve. Якщо в
_transferє зовнішні виклики (наприклад, автоматичний свап частини комісії) — класична атака. Рішення:ReentrancyGuard+ CEI патерн. - Маніпуляція exempt-списком. Використовуйте timelock на зміни для проектів із серйозним TVL.
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];
}
Ми використовуємо OpenZeppelin Ownable2Step для управління правами.
З яких етапів складається розробка?
- Консультація та аналіз токеноміки (1 день).
- Проектування механіки (fee-on-transfer або buyback-and-burn).
- Розробка контрактів + написання тестів (Foundry/Hardhat) — 5–8 днів.
- Тестування сумісності з Uniswap/PancakeSwap — 1–2 дні.
- Деплой, верифікація, налаштування LP пари — 1 день.
- Опціонально: налаштування сабграфа для моніторингу (2–3 дні).
- Документація та навчання команди.
| Етап | Тривалість |
|---|---|
| Аналіз токеноміки | 1 день |
| Розробка та тестування | 5–8 днів |
| Інтеграція з AMM | 1–2 дні |
| Деплой та верифікація | 1 день |
| Сабграф (опціонально) | 2–3 дні |
Терміни орієнтовно: від 5 до 12 днів залежно від складності механізму та необхідності інтеграції з сабграфом. Для всіх проектів гарантуємо 30-денну підтримку після деплою. Зв'яжіться з нами для аналізу вашої токеноміки. Отримайте консультацію щодо вибору механізму спалювання.
Що входить у роботу
- Аудит та оптимізація токеноміки.
- Розробка смарт-контрактів (Solidity 0.8.x).
- Написання unit- та fuzz-тестів (Foundry).
- Деплой у обрану мережу (Ethereum, BSC, Polygon).
- Верифікація на Etherscan/BscScan.
- Налаштування exempt-списку під AMM.
- Підготовка документації для інтеграторів.
- 30-денна гарантія на контракти.







