Розробка контрактів аукціонів на блокчейні

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

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

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

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

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

Розробка контрактів аукціонів на блокчейні

Аукціон на блокчейні — це не просто "приймай ставки та визначай переможця". Відкритість стану EVM робить механіку торгів вразливою до маніпуляцій, які в традиційних системах неможливі. Front-running ставок через MEV, газові війни в останню секунду, griefing через блокування ETH у аутбіддерів — кожен з цих векторів потребує архітектурної відповіді, а не просто перевірки в require.

Механіки аукціонів: English vs Dutch

English Auction (зростаюча ціна)

Класика: ціна зростає, перемагає остання ставка. Для NFT та токенів — найпоширеніший формат. Основна технічна проблема — last-minute sniping та front-running.

У Ethereum-аукціонах без захисту бот бачить транзакцію фінальної ставки в mempool і вставляє свою з більшим gas priority fee. Рішення — time extension: якщо ставка надходить у останні N хвилин перед дедлайном, аукціон автоматично продовжується:

if (block.timestamp > auctionEnd - timeBuffer) {
    auctionEnd = block.timestamp + timeBuffer;
    emit AuctionExtended(auctionId, auctionEnd);
}

timeBuffer зазвичай 10-15 хвилин. Саме так влаштований аукціон Nouns DAO — один з найбільш технічно коректних публічних реалізацій.

Dutch Auction (спадаюча ціна)

Ціна почи­нається висо­ко та знижується зі часом. Учасник платить поточну ціну й одразу отримує актив. Використовується для token-сейлів (Gnosis Protocol, деякі NFT-дропи).

Ключовий параметр — крива снаження ціни. Лінійна крива:

function getCurrentPrice() public view returns (uint256) {
    if (block.timestamp >= endTime) return reservePrice;
    uint256 elapsed = block.timestamp - startTime;
    uint256 totalDuration = endTime - startTime;
    uint256 priceDrop = startPrice - reservePrice;
    return startPrice - (priceDrop * elapsed / totalDuration);
}

Експоненціальна крива більш реалістична для ринкового ціноутворення, але дорожча по газу через exp() — зазвичай апроксимуємо через lookup table або piecewise linear.

Проблеми, які вирішуємо

Газові війни та griefing через refund

У стандартній реалізації English Auction попередня ставка повертається при аутбіддингу:

// Небезпечний паттерн
payable(previousBidder).transfer(previousBid);

Якщо previousBidder — контракт з fallback, який завжди revert, весь аукціон блокується. Це класичний DoS через gas griefing.

Рішення — pull payment pattern: замість автоматичного повернення зберігаємо pending withdrawals у mapping та даємо користувачу самостійно забрати ETH:

mapping(address => uint256) public pendingReturns;

function bid() external payable {
    // ...
    pendingReturns[previousBidder] += previousBid;
    // нова ставка прийнята, стара не повертається автоматично
}

function withdraw() external {
    uint256 amount = pendingReturns[msg.sender];
    if (amount == 0) revert NothingToWithdraw();
    pendingReturns[msg.sender] = 0; // обнулюємо до transfer (reentrancy guard)
    (bool ok,) = payable(msg.sender).call{value: amount}("");
    if (!ok) revert TransferFailed();
}

Commitment scheme проти front-running

Для аукціонів, де важлива секретність ставок до закриття (sealed-bid auction), використовуємо commit-reveal:

  1. Commit phase: учасник відправляє keccak256(abi.encode(bid, salt, address)) — хеш ставки
  2. Reveal phase: учасник розкриває реальну ставку й salt, контракт перевіряє хеш
  3. Переможець визначається тільки після reveal

Обмеження: учасник може не розкрити ставку, якщо розуміє, що програв. Рішення — залог при commit, який згоряє при відсутності на reveal (anti-griefing bond).

Reentrancy у багатолотових аукціонах

При паралельних аукціонах (маркетплейс з множеством лотів) особливо небезпечна reentrancy через ETH-повернення. Використовуємо ReentrancyGuard від OpenZeppelin або паттерн checks-effects-interactions строго:

// Checks
require(bid > currentHighestBid + minBidIncrement);
// Effects — оновлюємо state ДО зовнішніх викликів
highestBid = bid;
highestBidder = msg.sender;
pendingReturns[previousBidder] += previousAmount;
// Interactions — тільки після
emit BidPlaced(msg.sender, bid);

Стек та інструменти

Розробляємо на Solidity 0.8.x з Foundry. Тестуємо fork mainnet через vm.createFork — це дозволяє перевіряти взаємодію з реальними NFT-контрактами (ERC-721, ERC-1155) та Chainlink price feeds для деномінації ставок.

Fuzzing через forge fuzz обов'язковий для функцій з ціновими розрахунками — особливо для Dutch Auction з кривими снаження, де є ризик integer overflow при крайніх значеннях timestamp.

Аукціони для NFT стандартно підтримують ERC-721 та ERC-1155 через IERC721.safeTransferFrom / IERC1155.safeTransferFrom. Контракт аукціону виступає escrow — тримає NFT з моменту листингу до завершення та передає переможцю.

Процес роботи

Аналітика. Визначаємо тип аукціону, активи (NFT/токени/реальні активи), цільовий чейн (Ethereum mainnet, Polygon, Arbitrum), вимоги до конфіденційності ставок.

Проектування. Вибираємо механіку повернення ставок (pull vs push), anti-griefing механізми, параметри time extension. Якщо кілька типів аукціонів — проектуємо модульну архітектуру з базовим контрактом.

Розробка та тестування. Foundry-тести з 95%+ coverage. Обов'язково: fork-тести з реальним mainnet станом, fuzz-тести на цінові функції, invariant tests для перевірки інваріантів (сума всіх pending returns ≤ баланс контракту).

Деплой. Верифікація на Etherscan/Polygonscan. Якщо аукціон для NFT-маркетплейса — інтеграція з фронтендом через wagmi/viem.

Орієнтири по термінам

Одиничний аукціонний контракт (English або Dutch): 3-5 днів включаючи тести. Мультилотовий маркетплейс з обома типами аукціонів та commit-reveal: 2-3 тижні.