Розробка системи віртуального AMM для perpetuals
Perpetual futures без віртуального AMM — це або orderbook (вимагає market makers, складно для децентралізованого запуску), або funding rate arbitrage з oracle price (вразливо до маніпуляції). vAMM вирішує задачу price discovery для безстрокових фьючерсів через віртуальні резерви: реальних токенів у пулі немає, але механізм ціноутворення працює так, ніби вони є. Perpetual Protocol v1 першим впровадив цю модель, v2 переїхав на Uniswap V3 як ціновий рушій.
Математика vAMM та її проблеми
Віртуальні резерви та k
vAMM використовує x * y = k, де x та y — віртуальні резерви, не реальні токени. Трейдер відкриває long ETH: віртуальний USDC йде в пул, віртуальний ETH виходить. Ціна зсувається як у звичайному AMM.
Головна проблема: вибір початкового k визначає глибину ринку. Занадто малий k — висок price impact, торгувати невигідно. Занадто великий k — позиції можна відкрити без помітного зсуву ціни, але funding rate не працює як повинен.
У Perpetual Protocol k перераховувався при зміні ліквідності — механізм називається liquidity migration. При зміні k всі відкриті позиції повинні бути перераховані за новими віртуальними резервами. Помилка у цьому перерахунку = неправильне PnL для всіх утримувачів позицій.
Формально: якщо трейдер відкрив long при x1, y1 та шукає свою exit price при нових x2, y2 після k-resizing — потрібно коректно маппити його entry point через invariant ratio. Без цього протокол недооцінює або переоцінює PnL.
Механізм funding rate
Funding rate — механізм прив'язки vAMM ціни до spot oracle. Якщо vAMM ціна вище oracle (long premium): long-утримувачі платять short-утримувачам. Це створює арбітражний стимул відкривати short, що повертає ціну до oracle.
Формула funding rate (8-годинна): FR = (markPrice - indexPrice) / indexPrice / 8
Де markPrice — TWAP vAMM за останні 8 годин, indexPrice — oracle price (Chainlink).
Вразливість: при низькій ліквідності vAMM хтось з достатнім капіталом може зсунути markPrice, зібрати несправедливий funding з контрпозицій. Це не flash loan атака — flash loans не переживають кілька блоків, але multi-block маніпуляція можлива.
Захист: cap на funding rate (зазвичай 0.1% за 8 годин = 0.3% на день = ~109% річних), що робить маніпуляцію дорогою відносно профіту.
Insurance fund та bad debt
При різкому русі ціни проти великої позиції з leverage — liquidation може не встигнути закрити позицію до того, як collateral піде в нуль. Протокол приймає убиток — bad debt. Insurance fund покриває ці випадки.
Джерела insurance fund:
- Частина trading fees (зазвичай 10-25%)
- Ліквідаційні штрафи від трейдерів
- Початкове фінансування від команди/DAO
При нульовому insurance fund bad debt розмазується по всіх утримувачах зворотної сторони — socialised loss. Це суттєво порушує очікування користувачів, тому потрібен явний механізм та моніторинг balance insurance fund.
Архітектура контрактів
ClearingHouse — Центральний координатор
ClearingHouse керує відкриттям/закриттям позицій, розрахунком PnL, ліквідаціями та funding payments. Це найскладніший контракт системи.
Ключові функції:
function openPosition(OpenPositionParams calldata params) external returns (uint256 base, uint256 quote);
function closePosition(ClosePositionParams calldata params) external returns (uint256 base, uint256 quote);
function liquidate(address trader, address baseToken) external;
function settleFunding(address trader, address baseToken) external;
PnL трейдера: openNotional (USDC еквівалент при відкритті) vs closeNotional (при закритті) + накопичений funding payments.
Зберігання позицій: маппінг trader → token → Position. Position включає openNotional, openNotionalSharesAsBase (для concentrated liquidity моделі), lastTwPremiumGrowthGlobal (для розрахунку накопленого funding).
AccountBalance — Ізоляція margin
Isolated margin vs cross margin — архітектурне рішення з серйозними trade-off-ами:
Cross margin: весь collateral трейдера використовується як маржа для всіх позицій. Більш капіталоефективно, але втрата на одній позиції може ліквідувати всі.
Isolated margin: кожна позиція має окремий collateral. Ліквідація однієї позиції не торкається інших. Складніше у реалізації — потрібен AccountBalance контракт з per-position collateral tracking.
Для initial launch рекомендуємо cross margin з опціональною ізоляцією на рівні UI (користувач сам обмежує розмір позиції). Ізольований margin додає складність ліквідації — потрібно визначати який collateral належить якій позиції при частинних ліквідаціях.
Vault та управління collateral
Vault приймає USDC (або інший collateral), видає internal accounting token. При відкритті позиції funds lock-уються у vault, при закритті — повертаються з PnL.
ERC-4626 стандарт застосимий якщо vault yield-bearing (collateral інвестується в Aave поки не задіяний). Це поліпшує UX: трейдери отримують yield на невикористаний collateral. Ризик: Aave exploit = втрата collateral. Потрібен circuit breaker: миттєвий вивід з Aave при аномальних подіях через guardian multisig.
Oracle інтеграція
Oracle — критично важливий компонент. Використовуємо Chainlink aggregator для index price (ETH/USD). Але Chainlink heartbeat = 1 година для стейблкоїнів, 1 година для ETH — занадто рідко для активної торгівлі.
Рішення: Chainlink Data Streams (pull-based, оновлення щомісяці 100ms) або Pyth Network (Solana native, але EVM-сумісна версія через pythnet з sub-second оновленнями). Для perpetuals на Ethereum L2 — Pyth + Chainlink composite: Pyth для realtime mark price, Chainlink для settlement.
Захист від stale price: якщо oracle не оновлювався > N хвилин (configurable), призупиняємо відкриття нових позицій. Ліквідації продовжуються — критично для solvency протоколу.
Ліквідації
Partial vs full liquidation
При partial ліквідації закривається частина позиції, достатня щоб повернути margin ratio вище maintenance margin. Користувач втрачає менше. Але обчислення оптимального partial liquidation amount — нетривіально: потрібно вирішити рівняння margin_after_partial = (notional - liquidated_notional) * maintenance_margin.
Full liquidation — простіше, але агресивніше. Для малих позицій (< $500) — full ліквідація виправдана gas-економією.
Liquidation incentives
Ліквідаторам потрібен стимул. Стандартна схема: ліквідаційний penalty = 2.5% від notional позиції, з яких 1.25% іде ліквідатору, 1.25% в insurance fund.
Проблема з MEV: ліквідації видні в mempool, боти роблять sandwich, атакуючи сам протокол або примушуючи ліквідації раніше через oracle маніпуляцію. Flashbots Protected Transactions для liquidation ботів.
Стек та тестування
Solidity 0.8.x + Foundry + OpenZeppelin. Chainlink + Pyth для oracle. Foundry fork-тести на Arbitrum mainnet state: тестуємо ліквідаційні сценарії з реальними цінами ETH з історичних даних. Echidna з invariant тестами:
- Інваріант:
totalLongExposure == totalShortExposure + netSkew(vAMM zero-sum) - Інваріант:
vaultBalance >= sum(allPositionCollateral) + insuranceFund - Інваріант: після будь-якої ліквідації
marginRatio(trader) >= maintenanceMarginRatio
Порушення будь-якого інваріанту — критичний баг.
| Контракт | Функцій | Складність аудиту |
|---|---|---|
| ClearingHouse | 15-20 | Дуже висока |
| AccountBalance | 10-15 | Висока |
| Vault | 8-10 | Середня |
| vAMM | 12-18 | Висока |
| InsuranceFund | 5-8 | Середня |
| Oracle adapter | 3-5 | Середня |
Процес роботи
Аналітика (5-7 днів). Економічна модель: leverage limits, funding rate caps, insurance fund initial size, collateral types (single vs multi-collateral). Вибір чейна: Arbitrum One найбільш популярен для perp DEX.
Проектування (7-14 днів). Formal specification інваріантів. Storage layout ClearingHouse (критично — міграція дорога). Інтерфейси між контрактами.
Розробка (8-12 тижнів). vAMM → Vault → AccountBalance → ClearingHouse → Oracle adapters → Liquidation engine. Паралельно — фронтенд (wagmi + viem + recharts для P&L графіків).
Аудит (обов'язковий). Perp протокол — один з найбільш аудируємих класів DeFi. Мінімум два незалежних аудити рекомендовано для TVL > $5M.
Орієнтири за часовими рамками
Базовий vAMM з одним market, cross margin, full liquidation — 6-8 тижнів. Production-ready мультимаркет протокол з isolated margin, partial liquidation, insurance fund та multi-oracle — 2-4 місяці. Аудит — 4-8 тижнів додатково.
Вартість залежить від кількості ринків, collateral типів та вимог до децентралізації governance.







