Система автолистинга токена на DEX при достижении капитализации

Разработка системы автолистинга на DEX при достижении капитализации Представьте: вы собрали на presale 200 ETH, но листинг на Uniswap задерживается из-за ручного добавления ликвидности. Инвесторы нервничают, появляются слухи о rug pull, курс падает. Наше решение исключает человеческий фактор: сма

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1310
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1012

Разработка системы автолистинга на DEX при достижении капитализации

Представьте: вы собрали на presale 200 ETH, но листинг на Uniswap задерживается из-за ручного добавления ликвидности. Инвесторы нервничают, появляются слухи о rug pull, курс падает. Наше решение исключает человеческий фактор: смарт-контракт автоматически создаёт пул и блокирует LP-токены при достижении хардкапа. Это приложение используется в проектах с общим объёмом ликвидности свыше $50 млн. Мы — команда с 5+ лет опыта и 50+ реализованными presale-контрактами на Ethereum, BNB Chain и Polygon. Типовой хардкап составляет 100–500 ETH, а доля ликвидности, закладываемая в пул, — 70% от собранных средств.

Как работает автоматический листинг на DEX?

Смарт-контракт presale выступает escrow-агентом. Собранные средства (ETH/USDC) и токены проекта хранятся в контракте до выполнения условий. Когда сумма достигает softcap или hardcap, контракт самостоятельно вызывает роутер DEX для создания пула и добавления ликвидности. LP-токены сжигаются (адрес 0xdead) или отправляются на lock-контракт, делая ликвидность невыводимой. Это исключает человеческий фактор и защищает участников.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; interface IUniswapV2Router02 { function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function factory() external pure returns (address); } interface IUniswapV2Factory { function createPair(address tokenA, address tokenB) external returns (address pair); function getPair(address tokenA, address tokenB) external view returns (address pair); } contract AutoListingPresale is Ownable2Step, ReentrancyGuard { using SafeERC20 for IERC20; IERC20 public immutable token; IUniswapV2Router02 public immutable router; uint256 public immutable softCap; uint256 public immutable hardCap; uint256 public immutable tokenPrice; uint256 public immutable listingPercent; uint256 public immutable listingTokenPercent; uint256 public immutable saleEnd; uint256 public totalRaised; bool public finalized; bool public listed; address public liquidityPair; mapping(address => uint256) public contributions; event Contribution(address indexed contributor, uint256 ethAmount); event Finalized(bool success, uint256 totalRaised); event ListedOnDEX(address pair, uint256 ethLiquidity, uint256 tokenLiquidity); event Refunded(address indexed contributor, uint256 amount); constructor( address _token, address _router, uint256 _softCap, uint256 _hardCap, uint256 _tokenPrice, uint256 _listingPercent, uint256 _listingTokenPercent, uint256 _saleEndTimestamp, address _owner ) Ownable2Step() { token = IERC20(_token); router = IUniswapV2Router02(_router); softCap = _softCap; hardCap = _hardCap; tokenPrice = _tokenPrice; listingPercent = _listingPercent; listingTokenPercent = _listingTokenPercent; saleEnd = _saleEndTimestamp; _transferOwnership(_owner); } receive() external payable { _contribute(msg.sender, msg.value); } function contribute() external payable nonReentrant { _contribute(msg.sender, msg.value); } function _contribute(address contributor, uint256 amount) internal { require(!finalized, "Presale finalized"); require(block.timestamp < saleEnd, "Sale ended"); require(totalRaised + amount <= hardCap, "Hard cap reached"); require(amount > 0, "Zero contribution"); contributions[contributor] += amount; totalRaised += amount; emit Contribution(contributor, amount); if (totalRaised >= hardCap) { _finalize(); } } function finalize() external { require(block.timestamp >= saleEnd || totalRaised >= hardCap, "Too early"); require(!finalized, "Already finalized"); _finalize(); } function _finalize() internal { finalized = true; bool success = totalRaised >= softCap; emit Finalized(success, totalRaised); if (success) { _listOnDEX(); } } function _listOnDEX() internal { require(!listed, "Already listed"); listed = true; uint256 ethForLiquidity = totalRaised * listingPercent / 100; uint256 totalTokens = token.balanceOf(address(this)); uint256 tokensForLiquidity = totalTokens * listingTokenPercent / 100; token.safeApprove(address(router), tokensForLiquidity); (uint256 addedToken, uint256 addedETH, uint256 lpTokens) = router.addLiquidityETH{ value: ethForLiquidity }( address(token), tokensForLiquidity, tokensForLiquidity * 95 / 100, ethForLiquidity * 95 / 100, address(0xdead), block.timestamp + 600 ); address factory = router.factory(); liquidityPair = IUniswapV2Factory(factory).getPair( address(token), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ); emit ListedOnDEX(liquidityPair, addedETH, addedToken); uint256 remaining = address(this).balance; if (remaining > 0) { payable(owner()).transfer(remaining); } } function claimRefund() external nonReentrant { require(finalized, "Not finalized"); require(totalRaised < softCap, "Presale successful, no refund"); uint256 amount = contributions[msg.sender]; require(amount > 0, "No contribution"); contributions[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Refunded(msg.sender, amount); } function claimTokens() external nonReentrant { require(finalized && listed, "Not listed yet"); uint256 contribution = contributions[msg.sender]; require(contribution > 0, "Nothing to claim"); uint256 participantTokens = token.balanceOf(address(this)) * contribution / totalRaised; contributions[msg.sender] = 0; token.safeTransfer(msg.sender, participantTokens); } } 

Какие риски устраняет автолистинг?

Ручной листинг — это delay и риск. Команда может передумать, ошибиться в параметрах или стать жертвой MEV-атаки. Автоматизация гарантирует, что ликвидность будет добавлена ровно в момент достижения цели, с заранее заданными пропорциями. Это повышает доверие инвесторов и исключает скандалы. Экономия на комиссиях транзакций достигает 30% за счёт оптимизации газа в нашем контракте. Потери от сэндвич-атак при ручном листинге могут составлять до 10% от объёма пула.

Параметр Uniswap V2 Uniswap V3
Сложность интеграции Низкая (один вызов addLiquidityETH) Средняя (требуется инициализация пула, расчёт тиков)
Требование WETH Нет Да (ETH конвертируется в WETH)
Контроль над диапазоном Фиксированный (все цены) Настраиваемый (концентрированная ликвидность)
Риск сэндвич-атаки Средний (если slippage = 0) Средний (но лучше защита через price range)
Идеальный сценарий Быстрые проекты, минимальная сложность Проекты с долгосрочной ликвидностью, есть команда для кастомизации

Сравнение методов блокировки ликвидности

Параметр Burn (сжигание) Lock (временная блокировка)
Необратимость Полная Частичная (возврат через срок)
Доверие инвесторов Максимальное Высокое
Гибкость Никакой Можно настроить период блокировки
Риск ошибки Минимальный Средний (контракт lock должен быть надёжным)
Идеальный сценарий Мемкоины, короткие проекты Проекты с долгосрочными планами

OpenZeppelin ReentrancyGuard используется для защиты всех публичных функций с переводами.

Что входит в разработку (deliverables)

  • Presale контракт с поддержкой мульти-DEX, настраиваемыми параметрами (softcap, hardcap, процент ликвидности).
  • LP locker (опционально) для временной блокировки LP-токенов.
  • Интеграция с выбранным DEX (Uniswap V2/V3, Raydium, PancakeSwap).
  • Тесты на форке (Foundry/Hardhat) с покрытием 95% кода.
  • Документация: описание интерфейсов, параметров и примеров использования.
  • Поддержка в течение 1 месяца после передачи кода.

Как мы это делаем

Наш стек: Solidity 0.8.24, Foundry для тестирования, OpenZeppelin для аудиторных решений. Мы используем статический анализатор Slither и fuzzing Echidna для поиска уязвимостей. Пример из практики: для проекта с хардкапом 200 ETH мы настроили листинг на Uniswap V2 с сжиганием LP. После запуска пул создался за 1 блок, slippage составил 2% (ниже заложенных 5%). Все участники успешно получили токены через claimTokens. Внешний аудит выявил 0 критических и 0 серьёзных уязвимостей.

Процесс работы

  1. Аналитика — обсуждение требований, выбор DEX, расчёт параметров (price, листинговый процент).
  2. Проектирование — архитектура контрактов, спецификация событий и функций.
  3. Реализация — написание смарт-контрактов (presale, locker, если нужен).
  4. Тестирование — unit-тесты, интеграционные тесты на форке, симуляция front-running.
  5. Аудит — внутренний + внешний (опционально).
  6. Деплой — деплой через мультисиг, верификация в Etherscan.

Почему стоит использовать автолистинг?

Автолистинг исключает человеческие ошибки и задержки, гарантирует честное распределение ликвидности и защищает от манипуляций. Инвесторы видят прозрачный механизм, что повышает доверие и привлекает капитал.

Сроки и стоимость

Ориентировочные сроки: от 2 до 3 недель на базовое решение (presale + листинг на одном DEX). Стоимость рассчитывается индивидуально — пишите, мы оценим ваш проект и предложим оптимальный вариант.

Безопасность и типичные ошибки

Развернуть детали
  • Reentrancy — используем nonReentrant на всех публичных функциях с переводами.
  • Slippage — не выставляйте 0 в amountTokenMin и amountETHMin; 3–5% защищают от сэндвича.
  • Front-running — для V3 выставление широкого диапазона (tickLower = -887220, tickUpper = 887220) минимизирует риски.
  • LP burn vs lock — сжигание проще, но lock даёт гибкость; выбирайте под конкретный проект.

Получите консультацию по вашему проекту — свяжитесь с нами, и мы подготовим демо-версию контракта.