アカウント抽象化モード
ユーザーのアカウント抽象化モードは、スポットと永続契約の残高がどう相互作用するか、および各種アセットが永続契約取引の担保として使用されるかどうかを決定します。
サポートされているモードは以下の通りです。
- 統一アカウント(ほとんどのユーザーに推奨):各アセットの単一残高。この残高はそのアセットのすべてのクロス証拠金ポジションの担保となり、そのアセットのスポット残高と統一されています。例えば、USDC 残高はバリデーター運営の永続契約、XYZ の永続契約、USDC をクォート資産とするスポット取引の単一の供給源です。USDT のスポット残高は、CASH の永続契約と USDT をクォート資産とするスポット取引の単一の供給源です。
- ポートフォリオ証拠金(最も資本効率が高い):適格なすべてのアセット(現在は HYPE、BTC、USDC、USDT)を統一する単一ポートフォリオ。詳細はポートフォリオ証拠金を参照してください。
- マニュアル / 標準(マーケットメイカー、大口の自動化ユーザー、デプロイヤー/builder に推奨):永続契約とスポットの残高は分離、DEX 間の残高も分離。クロス証拠金は各 DEX に個別に適用されます。
完全を期すために、廃止されたもう 1 つのモードを以下に示します。
- DEX 抽象化(廃止):USDC 残高は永続契約残高にデフォルト設定され、その他すべての担保はスポット残高にデフォルト設定されます。重要:HIP-3 DEX のクロス証拠金は、DEX 抽象化ユーザーにとって直感的に動作しません。
重要な詳細:
- Builder code のアドレスは、builder 手数料を獲得するには standard モードである必要があります
- ポートフォリオ証拠金と統一アカウントは、1 日あたり 5 万件のユーザーアクションに制限されます。標準モードにはこのような制限はありません。
- 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;
}