Разработка системы голландского аукциона для токенов

Мы разрабатываем смарт-контракты голландского аукциона для справедливого распределения токенов. Классический токен-сейл с фиксированной ценой создаёт одну из двух проблем: либо цена слишком низкая — все токены уходят в первые секунды (газовая война, несправедливое распределение в пользу MEV-ботов),

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

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

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

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

Мы разрабатываем смарт-контракты голландского аукциона для справедливого распределения токенов. Классический токен-сейл с фиксированной ценой создаёт одну из двух проблем: либо цена слишком низкая — все токены уходят в первые секунды (газовая война, несправедливое распределение в пользу MEV-ботов), либо слишком высокая — сейл не заполняется. Голландский аукцион решает обе проблемы за счёт динамического ценообразования: цена начинается высокой и снижается до тех пор, пока спрос не встретит предложение. Цена сейла — это рыночный клиринговый уровень, а не произвольное число из whitepaper. Именно так Paradigm и a16z проводили первые крупные токен-дистрибьюции в DeFi-пространстве. Gnosis Protocol использует вариацию этого механизма для batch аукционов. Наш опыт — 5 лет на рынке и более 30 успешных контрактов. Закажите разработку под ключ — мы сопровождаем проект от идеи до деплоя и аудита.

Почему экспоненциальное снижение цены эффективнее линейного? — разработка системы голландского

Простейшая реализация — линейная функция:

price(t) = startPrice - (startPrice - endPrice) * (t - startTime) / duration 

Проблема линейной модели: большую часть времени цена снижается медленно из-за равномерности. Участники ждут минимума, аукцион не заполняется в середине, все пытаются купить в конце. Экспоненциальное снижение более реалистично описывает рыночное поведение:

function getCurrentPrice() public view returns (uint256) { if (block.timestamp <= startTime) return startPrice; if (block.timestamp >= endTime) return endPrice; uint256 elapsed = block.timestamp - startTime; uint256 duration = endTime - startTime; // Экспоненциальное снижение через 18-decimal fixed point uint256 priceDelta = startPrice - endPrice; uint256 decayFactor = PRBMath.exp(-int256(decayRate * elapsed / duration)); return endPrice + priceDelta * decayFactor / 1e18; } 

На практике большинство production Dutch Auction контрактов используют дискретные шаги снижения (step-down) вместо непрерывной функции — это проще для понимания участниками и дешевле в газе.

Характеристика Линейное снижение Экспоненциальное снижение
Скорость падения в начале Медленная Быстрая
Привлекательность для ранних участников Низкая Высокая
Риск незаполнения Высокий Низкий
Сложность реализации Простая Средняя
Газовые затраты Низкие Умеренные

Как защититься от MEV в Dutch Auction?

В стандартном Dutch Auction все видят текущую цену, и как только она становится "справедливой", все пытаются купить одновременно. MEV-боты front-run реальных покупателей, выставляя более высокий gas price. Результат: газовая война, но уже при клиринговой цене вместо стартовой. Решение — commit-reveal: участники отправляют encrypted commitment (hash от суммы и salt) без раскрытия намерения. После завершения фазы commitment — reveal фаза. Клиринговая цена рассчитывается по совокупному спросу. Это сложнее в реализации, но устраняет front-running полностью. GnosisDAO использовал подобную схему для своих аукционов.

Ключевые контрактные параметры

struct AuctionConfig { uint256 startPrice; // Максимальная цена (например, 1 ETH за токен) uint256 endPrice; // Минимальная цена (например, 0.1 ETH) uint256 startTime; // Unix timestamp начала uint256 endTime; // Unix timestamp конца uint256 totalTokens; // Количество токенов на продажу uint256 minBidAmount; // Минимальная покупка bool allowWhitelist; // Ограничить до whitelist bytes32 merkleRoot; // Merkle root для whitelist } 

Whitelist через Merkle Proof

Если аукцион ограничен для определённых адресов:

function bid(uint256 amount, bytes32[] calldata merkleProof) external payable { if (config.allowWhitelist) { bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); require( MerkleProof.verify(merkleProof, config.merkleRoot, leaf), "Not whitelisted" ); } uint256 currentPrice = getCurrentPrice(); uint256 tokenAmount = msg.value * 1e18 / currentPrice; require(tokenAmount >= config.minBidAmount, "Below minimum"); require(tokensSold + tokenAmount <= config.totalTokens, "Exceeds supply"); tokensSold += tokenAmount; bids[msg.sender] += tokenAmount; emit BidPlaced(msg.sender, tokenAmount, currentPrice, msg.value); } 

Возврат переплаты: клиринговая цена

В классическом Dutch Auction участники платят цену момента покупки. В Fair Dutch Auction (DutchX, Gnosis) — все платят одну клиринговую цену, даже те, кто купил раньше по более высокой. Разница возвращается. Это справедливее, но сложнее в реализации: нужно дождаться конца аукциона, рассчитать клиринговую цену, и дать каждому участнику забрать refund через отдельный claim.

function claim() external { require(auctionEnded, "Auction not ended"); uint256 userBid = bids[msg.sender]; require(userBid > 0, "No bid"); uint256 paid = payments[msg.sender]; uint256 cost = userBid * clearingPrice / 1e18; uint256 refund = paid - cost; bids[msg.sender] = 0; payments[msg.sender] = 0; // Переводим токены token.transfer(msg.sender, userBid); // Возвращаем переплату if (refund > 0) { (bool success, ) = msg.sender.call{value: refund}(""); require(success, "Refund failed"); } } 

Типичные ошибки и уязвимости

Ошибки расчёта клиринговой цены. Если tokensSold не достиг totalTokens — аукцион закрылся по endPrice. Если достиг раньше — клиринговая цена это цена момента заполнения. Контракт должен корректно обрабатывать оба сценария, иначе либо пользователи не получат refund, либо контракт отдаст больше токенов, чем должен.

Округление в пользу контракта. При делении wei на цену возникают remainder. Всегда округляем количество токенов вниз, сохраняем dust как treasury или включаем в burn-механизм.

Reentrancy в claim(). ETH-refund перед или вместе с transfer токенов — классическая точка reentrancy. Обновляем bids[msg.sender] = 0 до любых внешних вызовов.

Отсутствие паузы. Если обнаружена ошибка во время аукциона — нужна экстренная остановка. Функция pause() с multisig-контролем, которая замораживает новые bids, но не блокирует claim для уже сделанных.

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

  • Смарт-контракт Dutch Auction с поддержкой линейного или экспоненциального снижения
  • Механизм commit-reveal для защиты от MEV (опционально)
  • Клиринговая цена с возвратом переплаты через claim
  • Whitelist на основе Merkle Tree
  • Полный набор тестов на Forge + статический анализ Slither
  • Аудит безопасности (внутренний + внешний по желанию)
  • Документация и инструкция по деплою
  • Поддержка после деплоя (2 недели)

Сроки разработки: 3-5 рабочих дней для базового Dutch Auction, до 2 недель для Fair Dutch Auction с commit-reveal. Стоимость рассчитывается индивидуально. Получите консультацию — оценим ваш проект за 1 день.

Почему выбирают нас

  • 5 лет опыта в разработке смарт-контрактов на Solidity и Rust
  • Более 30 успешных проектов в DeFi (гарантия качества)
  • Используем современные инструменты: Foundry, Tenderly, OpenZeppelin
  • Предоставляем сертификаты аудита и формальной верификации по запросу

Свяжитесь с нами, чтобы обсудить ваш проект. Мы подберём оптимальную архитектуру аукциона под ваши требования.