Перейти к основному содержанию

Офчейн-сервисы

✅ Готово к разработке

Это спецификации офчейн-сервисов, а не смарт-контрактов. Разработчик может реализовать их на основе этого документа.
Шесть ботов, автоматизирующих операции протокола. Все работают на одном VPS, используют общее RPC-соединение и взаимодействуют с ончейн-контрактами через подписанные транзакции. Ни один бот не может извлечь средства — каждый имеет минимальные, строго ограниченные полномочия.
Это не смарт-контракты. Никаких PDA, ончейн-состояния или деплоя программ. Каждый бот — серверный процесс с выделенным кошельком. Все кошельки зарегистрированы ончейн с определёнными ролями.

Обзор сервисов

БотКонтрактИнструкцияЧастотаРоль кошелька
Pool RebalancerNative DEXshift_liquidityКаждые 60 сек (при отклонении > 1%)dex_config.rebalancer
Merkle PublisherYield Distributionpublish_rootКаждые 10 минconfig.publish_authority
Revenue CrankOwnership Tokendistribute_revenueКаждый час (при выполнении условий)Permissionless
Convert & Fund CrankYield Distributionconvert_to_rwtПосле каждого распределения доходаPermissionless
Yield Claim CrankRWT Engine + DEX + OTclaim_yield + compound_yield + claim_yd_for_treasuryКаждые 30 минPermissionless
Nexus ManagerNative DEXnexus_deposit, nexus_swap, nexus_add/remove_liquidityНа основе стратегииdex_config.nexus_manager + Permissionless (deposit)

Pool Rebalancer

Перераспределяет бины концентрированной ликвидности в пулах DEX для отслеживания цены NAV токена RWT. Считывает ончейн NAV из RWT Engine, рассчитывает целевой бин и вызывает shift_liquidity при превышении порога отклонения.

Как это работает

1

Чтение NAV

Запрос к RWT Engine ончейн: rwt_vault.nav_book_value. Это целевая цена для RWT.
2

Чтение состояния пула

Для каждого концентрированного пула: запрос pool_state.active_bin_id и bin_array. Расчёт текущей цены пула по активному бину: price = (1 + bin_step_bps/10000) ^ active_bin_id.
3

Проверка отклонения

deviation = abs(pool_price - nav_price) / nav_price. Если deviation > REBALANCE_THRESHOLD → требуется ребалансировка.
4

Расчёт NAV-бина

Преобразование цены NAV в ID бина:
nav_bin = log(nav_price) / log(1 + bin_step_bps/10000)
5

Выполнение сдвига

Вызов native_dex::shift_liquidity(nav_bin, TARGET_BIN_COUNT). Кошелёк бота подписывает как rebalancer. Ончейн DEX рассчитывает целевое пирамидальное распределение и выполняет diff-ребалансировку:
  • Асимметричная пирамида (2:1 bid/ask с центром на NAV)
  • Перемещение токенов из избыточных бинов → в дефицитные (без полного изъятия)
  • active_bin_id НЕ изменяется — цену двигают только свопы
  • Ликвидность всегда присутствует — без разрыва во время ребалансировки

Конфигурация

ПараметрПо умолчаниюОписание
REBALANCE_THRESHOLD0.01 (1%)Минимальное отклонение NAV для запуска ребалансировки
TARGET_BIN_COUNT40Количество бинов для концентрации вокруг NAV
CHECK_INTERVAL_SECS60Как часто проверять отклонение (секунды)

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Чтение NAVrwt_vault (read)
Чтение биновpool_state, bin_array (read)
Сдвигnative_dex::shift_liquidityrebalancer (signer), dex_config, pool_state (mut), bin_array (mut)

Полномочия

  • МОЖЕТ: вызывать shift_liquidity на любом концентрированном пуле
  • НЕ МОЖЕТ: свопать, добавлять/удалять ликвидность, менять конфигурацию, ставить пулы на паузу
  • При компрометации: может только сдвигать бины (без извлечения средств). Команда заменяет через update_dex_config(rebalancer: new_wallet)

Условия пропуска

  • Пул на паузе (pool_state.is_active == false)
  • В пуле нет ликвидности (reserve_a == 0 || reserve_b == 0)
  • Отклонение ниже порога
  • С последней ребалансировки прошло < 30 секунд (дебаунс)

Merkle Publisher

Строит деревья Меркла с весами держателей OT офчейн и публикует корни ончейн. Это ядро системы распределения доходности — без опубликованных корней держатели не могут клеймить.

Как это работает

1

Сканирование держателей

Для каждого OT-проекта: вызов getParsedProgramAccounts для получения всех токен-аккаунтов минта OT. Включает обычные кошельки, RWT Vault PDA (хранит OT как обеспечение), PDA пулов DEX (хранят OT в резервах) и OT Treasury PDA. Фильтрация до держателей с ≥ $100 общих протокольных холдингов (OT + RWT вместе).
2

Расчёт весов

Для каждого подходящего держателя (включая PDA):
cumulative_amount = distributor.total_funded * holder_ot_balance / total_eligible_supply
Доля неподходящих держателей → ARL OtTreasury PDA ["ot_treasury", arl_ot_mint] как лист в дереве (доход протокола). Примечание: RWT Vault PDA и PDA пулов DEX — обычные держатели OT в дереве, они клеймят через соответствующие CPI-инструкции (claim_yield, compound_yield). ARL Treasury клеймит через claim_yd_for_treasury на экземпляре ARL OT.
3

Построение дерева

Построение дерева Меркла. Формат листа: sha256(claimant_pubkey_bytes || cumulative_amount_le_bytes).
4

Публикация корня

Вызов yield_distribution::publish_root(merkle_root, max_total_claim). Серверный кошелёк подписывает как publish authority.
5

Сохранение доказательств

Сохранение полного дерева и доказательств в базу данных/файл (необходимо для UI клейма держателей и кранк-ботов).

Конфигурация

ПараметрПо умолчаниюОписание
PUBLISH_INTERVAL_SECS600 (10 мин)Как часто перестраивать и публиковать
MIN_HOLDING_USD100Минимальный холдинг для участия ($100)
PROOF_STORAGEПуть или БД для хранения доказательств для UI клейма

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Чтение держателейТокен-аккаунты OT (чтение через RPC)
Чтение дистрибьютораmerkle_distributor (read)
Публикацияyield_distribution::publish_rootpublish_authority (signer), config, distributor (mut)

Полномочия

  • МОЖЕТ: вызывать publish_root на любом дистрибьюторе
  • НЕ МОЖЕТ: фондировать, клеймить, закрывать дистрибьюторы, обновлять конфигурацию
  • При компрометации: атакующий может публиковать мошеннические корни → опустошить хранилища наград через поддельные клеймы. Команда немедленно заменяет через update_publish_authority. Все публикации видны в событиях RootPublished.
Бот с наивысшим уровнем доверия. Скомпрометированный publish authority может перенаправить доходность на кошельки атакующего. Обеспечьте безопасность keypair и мониторьте события RootPublished.

Стоимость

~2.60/меснаOTпроект(144транзакцииpublishroot/день×30дней× 2.60/мес на OT-проект (144 транзакции publish_root/день × 30 дней × ~0.0006/TX).

Revenue Crank

Запускает распределение дохода OT при выполнении условий. Проверяет баланс RevenueAccount каждого OT-проекта и вызывает distribute_revenue, если баланс выше минимума и период ожидания прошёл.

Как это работает

1

Проверка баланса

Для каждого OT-проекта: чтение баланса ATA RevenueAccount. Если balance < min_distribution_amount ($100), пропуск.
2

Проверка кулдауна

Чтение revenue_config.last_distribution_ts. Если now - last_distribution_ts < 604,800 (7 дней), пропуск.
3

Распределение

Вызов ownership_token::distribute_revenue. Permissionless — любой кошелёк может вызвать.
  1. Сначала вычитается комиссия протокола: 0.25% (25 bps) от общего баланса → areal_fee_destination (USDC ATA Areal Finance)
  2. Остаток распределяется пропорционально настроенным направлениям (по умолчанию):
    • 70% (7,000 bps) → YD Accumulator (USDC)
    • 20% (2,000 bps) → OT Treasury
    • 10% (1,000 bps) → Crank USDC ATA → Nexus через nexus_deposit
Пример: 1,000дохода1,000 дохода → 2.50 комиссия Areal → 997.50остаток997.50 остаток → 698.25 YD / 199.50Treasury/199.50 Treasury / 99.75 Nexus

Конфигурация

ПараметрПо умолчаниюОписание
CHECK_INTERVAL_SECS3600 (1 час)Как часто проверять каждый OT-проект
OT_PROJECTSСписок адресов минтов OT для мониторинга

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Чтение балансаRevenueAccount ATA (read)
Чтение кулдаунаrevenue_config (read)
Распределениеownership_token::distribute_revenuecrank (signer), ot_config, revenue_config (mut), revenue_ata (mut), destination ATAs (mut)

Полномочия

  • Permissionless — специальная роль кошелька не требуется. Любой кошелёк может запустить распределение.
  • При компрометации: нет риска — кранк только запускает распределение на предварительно настроенные ончейн-направления. Не может менять направления или извлекать средства.

Convert & Fund Crank

Конвертирует накопленные USDC в YD Accumulator PDA в RWT и депонирует в хранилища наград дистрибьютора. Должен запускаться сразу после каждого распределения дохода, чтобы минимизировать время между поступлением USDC и доступностью RWT для клеймов.

Как это работает

1

Проверка аккумулятора

Для каждого OT-проекта: чтение баланса USDC ATA аккумулятора. Если 0, пропуск.
2

Конвертация

Вызов yield_distribution::convert_to_rwt(max_swap_amount). Атомарная инструкция, которая:
  1. Свопает USDC → RWT на DEX (до цены NAV)
  2. Минтит остаток по NAV через RWT Engine
  3. Вычитает комиссию протокола 0.25% в RWT
  4. Депонирует чистый RWT в хранилище наград
  5. Обновляет состояние вестинга (блокирует ранее вестированное, запускает новый вестинг)

Конфигурация

ПараметрПо умолчаниюОписание
CHECK_INTERVAL_SECS300 (5 мин)Как часто проверять аккумуляторы
MAX_SWAP_RATIO0.5Максимальная доля USDC для свопа на DEX (остаток минтится по NAV)

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Чтение балансаAccumulator USDC ATA (read)
Конвертация + фондированиеyield_distribution::convert_to_rwtcrank (signer), config, distributor (mut), accumulator, ATAs, DEX accounts, RWT Engine accounts

Полномочия

  • Permissionless — любой кошелёк может вызвать. Accumulator PDA подписывает все внутренние переводы.
  • При компрометации: нет риска — инструкция только конвертирует USDC, уже находящиеся в Accumulator, в RWT в хранилище наград. Не может перенаправить средства.

Триггер

В идеале запускается сразу после того, как Revenue Crank распределит USDC в Accumulator. Может опрашивать по интервалу как запасной вариант.

Yield Claim Crank

Клеймит доходность в RWT из merkle-потоков YD от имени трёх типов ончейн PDA:
  1. RWT Vault PDA — хранит позиции OT, получает доходность как держатель OT. Заклеймленный RWT распределяется: 70% NAV / 15% Nexus / 15% ARL Treasury.
  2. PDA пулов DEX — пулы OT/RWT хранят OT в резервах и получают доходность. Заклеймленный RWT автоматически компаундится в резервы пула, принося выгоду всем держателям LP.
  3. OT Treasury PDA — доля доходности неподходящих держателей (< $100) выделяется OT Treasury PDA в дереве Меркла. Заклеймленный RWT остаётся в казначействе.

Как это работает

1

Получение доказательств

Чтение последних доказательств Меркла из хранилища доказательств Merkle Publisher для:
  • RWT Vault PDA (один на протокол)
  • Каждого PDA пула OT/RWT, содержащего OT (один на пул)
2

Клейм для RWT Vault

Вызов rwt_engine::claim_yield(cumulative_amount, proof). Permissionless-инструкция, которая:
  1. Выполняет CPI к yield_distribution::claim с vault PDA как claimant
  2. Распределяет заклеймленный RWT: 70% остаётся в vault (рост NAV), 15% → кошелёк кранка, 15% → ARL Treasury
  3. Обновляет total_invested_capital и пересчитывает NAV
  4. Кранк затем вызывает native_dex::nexus_deposit для маршрутизации 15% RWT в Nexus с отслеживанием принципала
3

Компаунд для пулов DEX

Для каждого пула OT/RWT: вызов native_dex::compound_yield(cumulative_amount, proof). Permissionless-инструкция, которая:
  1. Выполняет CPI к yield_distribution::claim с pool PDA как claimant
  2. Заклеймленный RWT добавляется напрямую в резервы пула (авто-компаунд)
  3. Все держатели LP получают выгоду пропорционально — индивидуальный клейм не требуется
4

Клейм для ARL Treasury (доходность неподходящих)

Вызов ownership_token::claim_yd_for_treasury(cumulative_amount, proof) на экземпляре ARL OT. Клеймит доходность неподходящих держателей из ВСЕХ OT-проектов как протокольный доход:
  1. Выполняет CPI к yield_distribution::claim с ARL OtTreasury PDA как claimant
  2. Заклеймленный RWT поступает на RWT ATA ARL Treasury
  3. RWT является протокольным доходом — может быть потрачен управлением ARL Futarchy через spend_treasury
Вызывается один раз на дистрибьютор (один на OT-проект) — у каждого дистрибьютора отдельное дерево Меркла с ARL Treasury как листом для доли неподходящих держателей этого проекта.

Конфигурация

ПараметрПо умолчаниюОписание
CLAIM_INTERVAL_SECS1800 (30 мин)Как часто пытаться клеймить
PROOF_SOURCEХранилище доказательств Merkle Publisher (БД или API)
OT_RWT_POOLSСписок адресов пулов OT/RWT для компаунда

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Чтение доказательствОфчейн: хранилище доказательств Merkle Publisher
Клейм для vaultrwt_engine::claim_yieldcrank (signer, mut), rwt_vault (mut), dist_config, RWT ATAs, YD CPI accounts
Компаунд для пулаnative_dex::compound_yieldcrank (signer, mut), pool_state (mut), target_vault (mut), YD CPI accounts
Клейм для казначействаownership_token::claim_yd_for_treasurycrank (signer, mut), ot_treasury, treasury_rwt_ata, YD CPI accounts
Маршрут в Nexusnative_dex::nexus_depositcrank (signer), nexus (mut), token accounts

Полномочия

  • Permissionless — любой кошелёк может вызвать все три инструкции. PDA подписывают свои CPI-клеймы внутренне.
  • При компрометации: нет риска — заклеймленный RWT поступает на предварительно настроенные ончейн-направления. Не может менять пропорции распределения, направления или перенаправлять компаунд пула.

Зависимость

Требует, чтобы Merkle Publisher опубликовал корень, включающий RWT Vault PDA и PDA пулов как claimants. Если валидное доказательство отсутствует, клейм завершится ошибкой InvalidProof.

Nexus Manager

Управляет позициями Liquidity Nexus PDA в пулах DEX. Nexus хранит ликвидность, принадлежащую протоколу (финансируется из 10% дохода OT + 15% доходности RWT). Бот-менеджер решает, когда и куда размещать этот капитал. Принципал заблокирован навсегда — только прибыль от LP (комиссии за свопы, авто-компаунд) может быть выведена в Areal Treasury authority.

Как это работает

1

Депозит капитала

После того как OT distribute_revenue отправляет 10% USDC кранку, или после того как RWT claim_yield отправляет 15% RWT кранку — кранк вызывает native_dex::nexus_deposit для маршрутизации токенов в Nexus с отслеживанием принципала. Это единственный способ поступления капитала в Nexus.
2

Мониторинг баланса Nexus

Чтение балансов RWT и USDC Liquidity Nexus. Проверка наличия неразмещённого капитала.
3

Оценка пулов

Анализ пулов DEX: TVL, объём, спред, утилизация. Определение пулов, нуждающихся в дополнительной ликвидности.
4

Размещение ликвидности

Вызов native_dex::nexus_add_liquidity для предоставления LP в целевые пулы. Также может вызвать nexus_swap для ребалансировки между токенами перед добавлением.
5

Ребалансировка

Периодическая ребалансировка позиций: nexus_remove_liquidity из неэффективных пулов, nexus_add_liquidity в более выгодные пулы.
6

Вывод прибыли

Authority (командный мультисиг) периодически вызывает nexus_withdraw_profits для отправки прибыли LP в Areal Treasury. Вывести можно только сумму сверх принципала. Менеджер должен сначала выполнить nexus_remove_liquidity, чтобы вернуть токены на ATA.

Конфигурация

ПараметрПо умолчаниюОписание
CHECK_INTERVAL_SECS300 (5 мин)Как часто оценивать позиции
MIN_DEPLOY_AMOUNT1,000,000 ($1 RWT)Минимальная сумма для размещения за одну операцию
MAX_POOL_CONCENTRATION0.5 (50%)Максимальная доля капитала Nexus в одном пуле

Ончейн-взаимодействие

ДействиеИнструкцияАккаунты
Депозитnative_dex::nexus_depositcrank (signer), nexus (mut), token accounts
Чтение балансаNexus ATAs (read)
Свопnative_dex::nexus_swapnexus_manager (signer), dex_config, nexus, pool accounts
Добавление LPnative_dex::nexus_add_liquiditynexus_manager (signer), dex_config, nexus, pool accounts
Удаление LPnative_dex::nexus_remove_liquiditynexus_manager (signer), dex_config, nexus, pool accounts
Вывод прибылиnative_dex::nexus_withdraw_profitsauthority (signer), dex_config, nexus (mut), token accounts

Полномочия

  • МОЖЕТ: свопать, добавлять/удалять ликвидность, используя средства Nexus PDA
  • НЕ МОЖЕТ: выводить принципал, менять конфигурацию DEX, ставить пулы на паузу
  • При компрометации: атакующий может совершать невыгодные сделки со средствами Nexus (LP в плохие пулы, свопы по плохим ценам), но не может извлечь принципал — защищено ончейн (ata_balance - withdrawal >= principal). Команда заменяет через update_nexus_manager.
Доверие к менеджеру: Nexus Manager распоряжается ~25% потока капитала протокола (10% дохода OT + 15% доходности RWT). Мониторьте позиции и P&L. В V2 он может стать AI-агентом с автоматизированной стратегией.

Общая инфраструктура

Все шесть ботов работают на одном VPS с общей конфигурацией:

Архитектура

┌──────────────────────────────────────────────────────┐
│                    VPS ($10/мес)                      │
│                                                      │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────┐ │
│  │   Pool       │  │   Merkle     │  │  Revenue   │ │
│  │  Rebalancer  │  │  Publisher   │  │   Crank    │ │
│  │  (60с цикл)  │  │  (10мин цикл)│  │  (1ч цикл) │ │
│  └──────┬───────┘  └──────┬───────┘  └──────┬─────┘ │
│         │                 │                 │        │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────┐ │
│  │  Convert &   │  │  Yield Claim │  │   Nexus    │ │
│  │  Fund Crank  │  │    Crank     │  │  Manager   │ │
│  │  (5мин цикл) │  │  (30мин цикл)│  │  (5мин)    │ │
│  └──────┬───────┘  └──────┬───────┘  └──────┬─────┘ │
│         │                 │                 │        │
│         └────────────┬────┴────────┬────────┘        │
│                      ▼             ▼                  │
│              ┌──────────────┐ ┌──────────┐           │
│              │  Общий RPC   │ │ Кошельки │           │
│              │  (Helius)    │ │  (.keys) │           │
│              └──────┬───────┘ └────┬─────┘           │
└─────────────────────┼──────────────┼─────────────────┘
                      │              │
                      ▼              ▼
              ┌─────────────────────────┐
              │    Блокчейн Solana      │
              └─────────────────────────┘

Кошельки

БотТип кошелькаЗарегистрирован как
Pool RebalancerВыделенный keypairdex_config.rebalancer
Merkle PublisherВыделенный keypairconfig.publish_authority
Revenue CrankОбщий кранк-кошелёкPermissionless (без регистрации)
Convert & FundОбщий кранк-кошелёкPermissionless (без регистрации)
Yield ClaimОбщий кранк-кошелёкPermissionless (без регистрации)
Nexus ManagerВыделенный keypairdex_config.nexus_manager
Три permissionless-бота могут использовать один кошелёк. Три привилегированных бота требуют выделенных keypair.

Переменные окружения

ПеременнаяОписание
RPC_URLЭндпоинт Solana RPC (бесплатного тарифа Helius достаточно)
REBALANCER_KEYPAIRKeypair кошелька Pool Rebalancer
PUBLISHER_KEYPAIRKeypair кошелька Merkle Publisher
NEXUS_MANAGER_KEYPAIRKeypair кошелька Nexus Manager
CRANK_KEYPAIRОбщий кошелёк для permissionless-операций
RWT_VAULT_ADDRESSPDA хранилища RWT Engine
CONCENTRATED_POOLSСписок адресов концентрированных пулов (требуется перезапуск при изменении)
OT_PROJECTSСписок {ot_mint, distributor, accumulator, revenue_config} на проект (требуется перезапуск при изменении)

Оценка стоимости

КомпонентСтоимость/мес
VPS$10
Комиссии Solana TX (~500 TX итого)~$0.30
RPC (бесплатный тариф Helius)$0
Итого~$10/мес

Операционные требования

ТребованиеДетали
ИнфраструктураVPS, постоянно работающий, systemd или Docker
Баланс SOLКаждый кошелёк: ~0.1 SOL на комиссии TX
МониторингЛогирование каждой TX с именем бота, инструкцией, результатом
АлертингАлерт, если любой бот не работает > 15 минут
Управление ключамиKeypair зашифрованы в покое, никогда не коммитятся в git
Политика перезапускаАвто-перезапуск при падении, экспоненциальный бэкофф

Оптимизации на основе событий

Вместо чисто интервального опроса боты могут подписываться на события Solana для более быстрой реакции:
СобытиеЗапускает
CapitalAdjusted (RWT Engine)Pool Rebalancer проверяет немедленно (NAV изменился)
SPL-перевод дохода на RevenueAccountRevenue Crank проверяет немедленно
StreamConverted (YD)Merkle Publisher публикует новый корень (total_funded изменился)
RootPublished (YD)Yield Claim Crank клеймит немедленно (доступно новое доказательство)

Порядок развёртывания

  1. Деплой всех смарт-контрактов
  2. Бутстрап: initialize_* всех контрактов, установка authority, регистрация кошельков
  3. Регистрация кошельков ботов ончейн:
    • update_dex_config(rebalancer: rebalancer_pubkey) — Pool Rebalancer
    • update_dex_config(nexus_manager: manager_pubkey) — Nexus Manager
    • Publish authority задаётся при initialize_config — Merkle Publisher
  4. Пополнение кошельков ботов ~0.1 SOL каждый
  5. Запуск всех сервисов, проверка логов
  6. Передача authorities командному мультисигу

Сводка по доверию

БотУровень доверияПри компрометации
Pool RebalancerНизкийМожет сдвинуть бины в плохие позиции. Без извлечения средств. Замена кошелька.
Merkle PublisherВысокийМожет публиковать поддельные корни → опустошить хранилища наград. Немедленная замена + мониторинг.
Revenue CrankНетPermissionless. Может только запускать распределение на заданные направления.
Convert & FundНетPermissionless. Конвертирует в заданное хранилище.
Yield ClaimНетPermissionless. Клеймит на заданные направления.
Nexus ManagerСреднийМожет совершать невыгодные сделки со средствами Nexus. Не может извлечь. Замена кошелька.