Цю сторінку перекладено автоматично. Оригінал англійською мовою є канонічним. Читати англійською →
Перейти к основному содержимому

Захист маркетмейкера (MMP)

Ліміти виконань у вікні та поведінка автоматичного скасування для маркетмейкерів.

Кожен ендпоінт MMP, прив'язаний до гаманця, вимагає автентифікації EIP-712. Запис конфігурації приймає підпис власника гаманця або авторизованого агента для цього гаманця. Читання доступне лише власнику, підписи авторизованих агентів відхиляються.

MMP застосовується до торгового акаунта, якому належать виконання. Для менеджера з портфельною маржею операції читання та запису, підписані гаманцем менеджера, спрямовуються до його торгового акаунта Account.sol, того самого акаунта, який використовується для розміщення заявок. Відповіді вказують цей акаунт у wallet_address, а послідовність nonce MMP належить цьому акаунту.

Для узгодженості читання після запису надсилайте X-Hypercall-Fence-Wait: 1 у будь-якому запиті на зміну MMP. Успішна відповідь тоді містить X-Hypercall-Fence; передайте це значення як X-Hypercall-Fence в автентифікованому GET. Запити на зміну без заголовка очікування навмисно не повертають fence.

Огляд​

MMP захищає маркетмейкерів від швидких несприятливих виконань шляхом:

  1. Відстеження кумулятивних метрик виконань у ковзному часовому вікні
  2. Скасування заявок у разі перевищення лімітів
  3. Автоматичного скасування всіх інших заявок з увімкненим MMP для тієї самої пари гаманець+базовий актив

Конфігурація​

Встановлення конфігурації MMP​

Ендпоінт: POST /mmp-config

Запит: SetMmpConfigRequest

{
"wallet": "0x...",
"currency": "BTC",
"interval_ms": 60000,
"frozen_time_ms": 300000,
"qty_limit": "1000000",
"delta_limit": "10.0",
"vega_limit": "5.0",
"nonce": 1,
"signature": "0x..."
}

Поля:

  • wallet: адреса гаманця
  • currency: валюта базового активу (наприклад, "BTC", "ETH")
  • interval_ms: довжина ковзного вікна в мілісекундах
  • frozen_time_ms: тривалість заморожування після спрацювання (мілісекунди)
  • qty_limit: необов'язковий ліміт кількості (у контрактних одиницях), серіалізований як десятковий рядок
  • delta_limit: необов'язковий ліміт дельти, серіалізований як десятковий рядок
  • vega_limit: необов'язковий ліміт веги, серіалізований як десятковий рядок
  • nonce: nonce для захисту від повторного відтворення, рівно на одиницю більший за останній зафіксований nonce, повернутий автентифікованим читанням
  • signature: підпис EIP-712 SetMmpConfig над усіма полями запиту

Відповідь: ApiResponse<MmpConfigData>

Отримання конфігурації MMP​

Ендпоінт: GET /mmp-config?wallet=...&currency=...

Параметри запиту:

  • wallet (обов'язковий)
  • currency (необов'язковий фільтр)

Обов'язкові заголовки:

  • X-Hypercall-Expires-At-Ms: час закінчення дії в Unix-форматі в мілісекундах, не більше ніж на 60 секунд у майбутньому
  • X-Hypercall-Signature: підпис GetMmpConfig над wallet, currency (порожній рядок, якщо пропущено) та часом закінчення дії із заголовка

Відновлений підписант має бути власником гаманця. Підписи авторизованих агентів для цього читання не приймаються.

Відповідь: MmpConfigResponse

{
"success": true,
"data": [
{
"wallet_address": "0x...",
"currency": "BTC",
"interval_ms": 60000,
"frozen_time_ms": 300000,
"qty_limit": "1000000",
"delta_limit": "10.0",
"vega_limit": "5.0",
"enabled": true,
"nonce": 1
}
]
}

Видалення конфігурації MMP​

Ендпоінт: DELETE /mmp-config

Запит: DeleteMmpConfigRequest

{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}

Відповідь: ApiResponse<String>. Успішна команда вимикає числовий авторитетний стан для пари гаманець/базовий актив. Із заголовком запиту X-Hypercall-Fence-Wait: 1 відповідь містить X-Hypercall-Fence для читання з проєкції.

Скидання стану MMP​

Ендпоінт: POST /mmp-config/reset

Запит: ResetMmpRequest

{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}

Відповідь: ApiResponse<String>. Успішна команда очищає вікно виконань MMP і стан заморожування у відтворюваному авторитетному стані. Із заголовком запиту X-Hypercall-Fence-Wait: 1 відповідь містить X-Hypercall-Fence для читання з проєкції.

Поведінка MMP (критично важливо розуміти)​

Які виконання враховуються​

Кожне виконання враховується у вікні MMP кожної сторони, заявка якої має mmp_enabled=true, незалежно від того, чи ця заявка стояла в книзі (мейкер), чи надійшла (тейкер):

  • Котирування в книзі: коли вхідна заявка торгує проти вашої заявки з увімкненим MMP, що стоїть у книзі, це виконання додається до вашого вікна. Саме для цього випадку існує MMP: серія виконань проти ваших котирувань спрацьовує MMP і скасовує ваші решту котирувань з увімкненим MMP за цим базовим активом.
  • Вхідні заявки: заявка з увімкненим MMP, яка забирає ліквідність, враховує власні виконання так само.
  • Комбо та імпліцитні заявки: кожен захищений учасник пакета враховує кожну ногу, якою він торгує, з оцінкою один раз на пакет.
  • Виконання RFQ та RPI поки не враховуються в MMP. Заморожування MMP блокує нові виконання RFQ для замороженого постачальника котирувань.

Кожне виконання вимірюється з вашої сторони: виконання, яке продає колл, додає від'ємну дельту до вікна продавця та додатну до вікна покупця.

Якщо заявка має mmp_enabled=true, але її гаманець не має конфігурації MMP для цього базового активу, MMP закривається в безпечний бік: перше виконання спрацьовує і скасовує заявки цього гаманця з увімкненим MMP за базовим активом. Налаштуйте MMP перед тим, як позначати заявки.

Порядок обробки виконань​

Оцінка MMP відбувається ПІСЛЯ ВИКОНАННЯ:

  1. Рушій зіставляє та спочатку приймає виконання
  2. Потім MMP перевіряє кумулятивні метрики для кожної захищеної сторони виконання
  3. Якщо ліміти сторони перевищено:
    • MMP спрацьовує для гаманця та базового активу цієї сторони
    • Рушій генерує подію MmpTriggered
    • Рушій автоматично скасовує всі відкриті заявки з увімкненим MMP для цієї пари гаманець+базовий актив
    • Якщо стороною, що перевищила ліміт, була вхідна заявка, її залишок зупиняється, і вона переходить у статус CANCELED з причиною "MMP triggered during fill processing"
    • Якщо стороною, що перевищила ліміт, був мейкер у книзі, вхідна заявка продовжує зіставлятися з іншою ліквідністю; інші котирування мейкера з увімкненим MMP вже скасовано

Наслідок: ви можете отримати виконання, які виводять вас за налаштовані пороги, перш ніж MMP спрацює.

Умови спрацювання​

MMP спрацьовує, якщо перевищено будь-який налаштований ліміт:

  • Ліміт кількості: cumulative_qty > qty_limit
  • Ліміт дельти: |cumulative_delta| > delta_limit
  • Ліміт веги: |cumulative_vega| > vega_limit

Кумулятивні метрики обчислюються в межах ковзного вікна (interval_ms).

Поведінка скасування​

Коли MMP спрацьовує:

  1. Вхідна заявка, що спричинила спрацювання: залишок зупиняється, заявка переходить у статус CANCELED з причиною "MMP triggered during fill processing"
  2. Заявка в книзі, що спричинила спрацювання: виконання залишається в силі; залишок заявки, якщо він є, скасовується разом з іншими заявками з увімкненим MMP
  3. Інші заявки: усі відкриті заявки з увімкненим MMP для тієї самої пари гаманець+базовий актив автоматично скасовуються з причиною "Order canceled by MMP trigger"

Примітка: скасовуються лише заявки з увімкненим MMP. Заявки з mmp_enabled=false не зачіпаються.

Поведінка заморожування​

Після спрацювання MMP:

  • Гаманець і базовий актив заморожуються на frozen_time_ms мілісекунд
  • Під час заморожування гаманець виключається з аукціонів RPI та RFQ за цим базовим активом, а комбо- або імпліцитні виконання, які б його заповнили, відхиляються
  • Пряме виконання заявки з увімкненим MMP під час заморожування все одно залишається в силі, після чого знову спрацьовує MMP і скасовує заявки цього гаманця з увімкненим MMP за базовим активом
  • POST /mmp-config/reset достроково завершує заморожування

Розрахунок метрик виконань​

Кількість​

  • Джерело: size виконання (у контрактних одиницях)
  • Кумулятивно: сума всіх виконань у ковзному вікні

Дельта​

  • Джерело: обчислюється на основі символу виконання та GreeksCache
  • Кумулятивно: сума дельт усіх виконань у ковзному вікні

Вега​

  • Джерело: обчислюється на основі символу виконання та GreeksCache
  • Кумулятивно: сума вег усіх виконань у ковзному вікні

Ковзне вікно​

Витіснення з вікна​

Виконання, старші за interval_ms, автоматично витісняються з вікна:

  • Витіснення виконується під час обробки наступного виконання, перед додаванням нового
  • Кумулятивні метрики зменшуються в міру видалення старих виконань

Скидання вікна​

Скиньте стан MMP через POST /mmp-config/reset:

  • Очищає всі виконання у вікні
  • Скидає кумулятивні метрики до нуля
  • Розморожує валюту

Події MMP​

Подія MmpTriggered​

Внутрішня подія (наразі не пересилається клієнтам WS):

MmpTriggeredMessage {
wallet: WalletAddress,
currency: String,
reason: String, // "MMP triggered during fill processing" | "MMP triggered by a resting order fill"
timestamp: u64,
}

Найкращі практики​

Конфігурація​

  1. Встановлюйте доречні ліміти: виходячи з вашої толерантності до ризику та типових розмірів виконань
  2. Використовуйте конфігурації для окремих валют: налаштовуйте для кожного базового активу (BTC, ETH тощо)
  3. Відстежуйте спрацювання MMP: висока частота спрацювань може вказувати на неправильно налаштовані ліміти або несприятливі ринкові умови

Керування заявками​

  1. Вмикайте MMP вибірково: встановлюйте mmp_enabled=true лише для заявок, які ви хочете захистити
  2. Використовуйте узгоджену валюту: переконайтеся, що всі заявки за одним базовим активом використовують ту саму валюту в конфігурації MMP
  3. Обробляйте скасування MMP: реалізуйте логіку для виявлення скасувань, спричинених MMP, і коригування котирувань

Моніторинг​

  1. Відстежуйте спрацювання MMP: стежте за причинами "MMP triggered during fill processing" та "Order canceled by MMP trigger"
  2. Переглядайте вікна виконань: кумулятивні метрики вікна поки не доступні через API; відстежуйте власні виконання для кожного базового активу
  3. Коригуйте ліміти: якщо MMP спрацьовує занадто часто, збільште ліміти; якщо занадто рідко, зменште їх

Поширені проблеми​

MMP спрацьовує занадто часто​

Причини:

  • Ліміти занадто низькі для типових розмірів виконань
  • Несприятливі ринкові умови
  • Швидке котирування, що спричиняє багато виконань

Рішення:

  • Збільште qty_limit, delta_limit або vega_limit
  • Збільште interval_ms, щоб дозволити більше виконань у вікні
  • Зменште частоту котирування

MMP не спрацьовує​

Причини:

  • Ліміти занадто високі
  • MMP не увімкнено для заявок (mmp_enabled=false)
  • Невідповідність валюти (валюта в конфігурації MMP != базовий актив заявки)

Рішення:

  • Зменште ліміти
  • Перевірте mmp_enabled=true для заявок
  • Перевірте, що валюта в конфігурації MMP відповідає базовому активу заявки

Неочікувані скасування​

Симптом: заявки скасовано з причиною "Order canceled by MMP trigger", хоча ви цього не очікували.

Причина: інша заявка для тієї самої пари гаманець+базовий актив спричинила спрацювання MMP.

Рішення: коли MMP спрацьовує, перегляньте всі заявки з увімкненим MMP за тим самим базовим активом.