Разработка торгового бота для DEX на Base
Base — это OP Stack L2 от Coinbase, запущенный в августе 2023. За первый год вырос в один из топ-3 L2 по TVL и активным адресам. Для торговых ботов Base интересен по трём причинам: низкий gas (в 50–100x дешевле mainnet), растущая DEX ликвидность на Aerodrome и Uniswap V3, и специфика sequencer, которая отличается от Ethereum.
Экосистема DEX на Base
Ключевые площадки для интеграции:
| DEX | Модель | Объём (2024) | Особенности |
|---|---|---|---|
| Aerodrome Finance | ve(3,3) AMM + CLOB | $1B+ / день | Форк Velodrome, нативный DEX Base |
| Uniswap V3 | Concentrated liquidity | $500M+ / день | Стандартный V3, те же контракты что mainnet |
| BaseSwap | Fork Uniswap V2 | $50M / день | Меньше ликвидности |
| SushiSwap | V2 + Trident | $20M / день | Мультичейн, кросс-DEX арбитраж |
Aerodrome — приоритет для глубокой интеграции: 60%+ DEX объёма Base проходит через него.
Aerodrome: архитектура, важная для бота
Aerodrome наследует Velodrome V2 архитектуру с двумя типами пулов:
Volatile pools (Pool.sol): стандартная x*y=k формула. Подходит для некоррелированных пар (ETH/USDC, cbBTC/USDC).
Stable pools (Pool.sol с stable=true): кривая x³y + y³x = k — оптимизирована для близких по цене активов (USDC/USDT, cbETH/wstETH). Важно: для стейбл-пулов getAmountOut() даёт другой результат при тех же входных данных.
// Aerodrome Router ABI
const AERODROME_ROUTER = '0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43'
const routes = [{
from: WETH_ADDRESS,
to: USDC_ADDRESS,
stable: false, // Для volatile пары
factory: AERODROME_FACTORY
}]
const amounts = await aerodromeRouter.getAmountsOut(amountIn, routes)
Ошибка, которую делают разработчики с EVM-фоном: используют stable: false для всех пар. Для USDC/USDbC пары это даёт расчётный amountOut в 5–10% хуже реального из-за неправильной кривой.
ve(3,3) и epoch rewards
Aerodrome использует veAERO (locked voting tokens) для направления emissions в пулы. Для арбитражного бота это важно опосредованно: пулы с высокими emissions привлекают больше LP, имеют меньший slippage. Отслеживание голосований и emissions помогает предсказывать, где появится глубокая ликвидность.
Sequencer специфика на Base
Base использует centralized sequencer под управлением Coinbase. Для ботов это принципиально меняет MEV ландшафт:
- Публичного mempool в Ethereum-смысле нет. Sequencer публикует транзакции атомарно.
- Классические sandwich атаки через frontrunning практически невозможны.
- Арбитраж DEX ↔ DEX на Base работает хорошо: нет конкуренции с flashbots bundles в той же форме.
- Latency к sequencer критична: размещение сервера в us-east-1 (AWS) или co-location в San Francisco (ближе к Coinbase инфраструктуре) даёт преимущество.
Транзакции отправляются напрямую в https://mainnet.base.org RPC или через Alchemy/Infura Base endpoints. Для минимальной latency — собственная нода с op-geth или прямой endpoint Coinbase (через партнёрскую программу).
Арбитражная стратегия: Base ↔ межпротокольный
Самый доступный и стабильный MEV на Base — арбитраж между разными DEX:
Аэродром vs Uniswap V3: та же пара (ETH/USDC) торгуется на двух разных площадках с разной ценой из-за асинхронного LP поведения.
Стейблкоин арбитраж: USDC vs USDbC (bridged USDC) vs axlUSDC — часто торгуются с slight discount/premium на разных пулах.
cbETH / wstETH арбитраж: производные ETH активы, цена привязана к ETH через exchange rate. При отклонении от справедливой стоимости — арбитражная возможность.
Базовый цикл бота:
async function checkArbitrage(tokenA: Address, tokenB: Address) {
// Параллельный запрос цен с двух DEX
const [aeroPrice, uniPrice] = await Promise.all([
getAerodromePrice(tokenA, tokenB, amountIn),
getUniswapV3Price(tokenA, tokenB, amountIn)
])
const priceDiff = Math.abs(aeroPrice - uniPrice) / Math.min(aeroPrice, uniPrice)
if (priceDiff > MIN_PROFIT_THRESHOLD) {
const gasEstimate = await estimateArbitrageGas(...)
const gasCostUSD = gasEstimate * gasPrice * ethPrice
const grossProfit = calculateProfit(aeroPrice, uniPrice, amountIn)
if (grossProfit > gasCostUSD * 1.5) { // Минимум 1.5x покрытие gas
await executeArbitrage(...)
}
}
}
Atomic arbitrage через flash loan
На Base доступны Aave V3 flash loans (контракт деплоен на Base). Атомарный арбитраж: берём flash loan → покупаем дешевле → продаём дороже → возвращаем flash loan + fee (0.09%).
Преимущество: не нужен собственный капитал для арбитража. Flash loan fee 0.09% устанавливает минимальный порог прибыльности — разница цен должна быть > 0.09% + gas.
contract BaseArbitrageBot is IFlashLoanSimpleReceiver {
function executeArbitrage(address token, uint256 amount, bytes calldata params) external {
// Запрашиваем flash loan
POOL.flashLoanSimple(address(this), token, amount, params, 0);
}
function executeOperation(
address asset, uint256 amount, uint256 premium,
address, bytes calldata params
) external override returns (bool) {
(address dexA, address dexB, bytes memory swapDataA, bytes memory swapDataB)
= abi.decode(params, (address, address, bytes, bytes));
// Покупаем на dexA (дешевле)
IERC20(asset).approve(dexA, amount);
(bool successA,) = dexA.call(swapDataA);
require(successA, "Swap A failed");
// Продаём на dexB (дороже)
uint256 received = IERC20(outputToken).balanceOf(address(this));
IERC20(outputToken).approve(dexB, received);
(bool successB,) = dexB.call(swapDataB);
require(successB, "Swap B failed");
// Возвращаем flash loan + premium
uint256 repayAmount = amount + premium;
IERC20(asset).approve(address(POOL), repayAmount);
return true;
}
}
Контракт — минималистичный. Никакого storage state — всё через calldata и события.
Мониторинг и управление рисками
Price deviation alerts: если разница цен между DEX превышает 2% — потенциальная аномалия (манипуляция, баг оракула). Бот должен останавливать работу до прояснения.
Gas price tracking: на Base gas нестабилен при высокой нагрузке. Бот должен проверять eth_gasPrice и устанавливать maxFeePerGas динамически. Жёсткий лимит gas price — выше порога арбитраж неинтересен.
Slippage на крупных позициях: расчёт getAmountsOut для суммы X не учитывает, что во время исполнения цена сдвинется. Для крупных свопов нужна симуляция с учётом price impact — либо split на несколько меньших транзакций.
Dead man's switch: если бот не совершал транзакций больше N минут при наличии возможностей — алерт на Telegram/Discord. Могло произойти: нода упала, нет баланса на gas, unexpected revert.
Стек разработки
Бот: TypeScript + viem (предпочтительнее ethers.js для Base из-за лучшей поддержки EIP-1559 типов). Bull (Redis-backed queue) для управления очередью транзакций. Prometheus + Grafana для метрик.
Контракты: Solidity 0.8.24 + Foundry. Fork-тест на Base mainnet через forge test --fork-url https://mainnet.base.org. Foundry поддерживает Base как target network.
Деплой бота: Docker на AWS EC2 (us-east-1) или Fly.io для простоты, с автоматическим рестартом через systemd/Supervisor.
Процесс работы
Исследование (2–3 дня). Анализ MEV возможностей на Base через Dune Analytics, оценка объёмов и конкуренции.
Разработка (1–2 недели). Интеграция с Aerodrome и Uniswap V3, арбитражный движок, flash loan контракт, мониторинг.
Тестирование (3–5 дней). Backtesting на исторических данных Base, paper trading в fork-тестах.
Запуск. Деплой с малыми суммами → мониторинг производительности → масштабирование.







