Режимы абстракции аккаунта
Режим абстракции аккаунта пользователя определяет, как взаимодействуют спот-балансы и балансы перпов, а также используются ли различные активы в качестве обеспечения для торговли перпами.
Поддерживаются следующие режимы:
- Единый аккаунт (unified account, рекомендуется для большинства пользователей): единый баланс для каждого актива. Этот баланс обеспечивает все кросс-позиции в этом активе и объединён со спот-балансом в этом активе. Например, баланс USDC является единственным источником для перпов, управляемых валидаторами, перпов XYZ и спот-торговли с USDC в качестве котируемого актива. Спот-баланс USDT является единственным источником для перпов CASH и спот-торговли с USDT в качестве котируемого актива.
- Портфельная маржа (наиболее эффективная по капиталу): единый портфель, объединяющий все подходящие активы, которыми в настоящее время являются HYPE, BTC, USDC, USDT. Подробнее см. в разделе Портфельная маржа.
- Ручной / Стандартный (рекомендуется для маркет-мейкеров, высокообъёмных автоматизированных пользователей и деплойеров/билдеров): отдельные балансы перпов и спота, отдельные балансы DEX. Кросс-маржа применяется к каждому DEX отдельно.
Есть ещё один режим, который был прекращён, указанный здесь для полноты:
- Абстракция DEX (прекращён): балансы USDC по умолчанию идут в баланс перпов, всё остальное обеспечение по умолчанию идёт в спот-баланс. ВАЖНО: кросс-маржа на DEX HIP-3 ведёт себя неинтуитивно для пользователей с абстракцией DEX.
Важные детали:
- Адреса Builder Code должны находиться в стандартном режиме для начисления комиссий билдера
- Портфельная маржа и единый аккаунт ограничены 50 тыс. пользовательских действий в день. Стандартный режим не имеет таких ограничений.
- Для API-пользователей единый аккаунт и портфельная маржа показывают все балансы и удержания в состоянии спот-клирингового дома. Отдельные состояния пользователя перп-dex не имеют смысла.
Примеры действий, подписанных агентом и пользователем, для смены режимов абстракции аккаунта см. в Python SDK и API-документации.
Коэффициент единого аккаунта
Для вычисления точного коэффициента единого аккаунта для мониторинга риска ликвидации:
function computeUnifiedAccountRatio(
multiverse: Record<string, { index: number; collateralToken: number }>,
perpDexStates: Array<{
clearinghouseState: {
crossMaintenanceMarginUsed: number;
assetPositions: Array<{
position: { leverage: { type: string }; marginUsed: number };
}>;
};
}>,
spotBalances: Array<{ token: number; total: number }>,
): number {
const indexToCollateralToken: Record<number, number> = {};
for (const meta of Object.values(multiverse)) {
indexToCollateralToken[meta.index] = meta.collateralToken;
}
const crossMarginByToken: Record<number, number> = {};
const isolatedMarginByToken: Record<number, number> = {};
for (let index = 0; index < perpDexStates.length; index++) {
const dex = perpDexStates[index];
const token = indexToCollateralToken[index];
if (dex === undefined || token === undefined) continue;
crossMarginByToken[token] =
(crossMarginByToken[token] ?? 0) +
dex.clearinghouseState.crossMaintenanceMarginUsed;
for (const ap of dex.clearinghouseState.assetPositions) {
if (ap.position.leverage.type === "isolated") {
isolatedMarginByToken[token] =
(isolatedMarginByToken[token] ?? 0) + ap.position.marginUsed;
}
}
}
let maxRatio = 0;
for (const [tokenStr, crossMargin] of Object.entries(crossMarginByToken)) {
const token = Number(tokenStr);
const spotTotal = spotBalances.find((b) => b.token === token)?.total ?? 0;
const isolatedMargin = isolatedMarginByToken[token] ?? 0;
const available = spotTotal - isolatedMargin;
if (available > 0) {
maxRatio = Math.max(maxRatio, crossMargin / available);
}
}
return maxRatio;
}