EVM Perp · サンドボックス
Threshold margin (mm500)
維持証拠金を引き締め(500 bps)——同じシナリオ、異なるダイヤル。8/9 outcomes ✓ で宣言結果が1つ破綻。
マークは100に確定。デフォルトの維持証拠金200bpsでは最も高レバレッジのトレーダー(アカウント30)だけが清算される。--maintenance-margin-bps を厳しくすると清算されるアカウントが増える。
何が起きるか
3人のトレーダーが、同じメイカークオート(110)に対し、レバレッジの異なるロングの perp を建てる。ブロック3でマークブックがミッド100に着地し、全ロングが評価損に入る。デフォルトの維持証拠金200bpsでは、最も高レバレッジのアカウント(アカウント30)だけが閾値を割り、ライトバックループで決済される;他の2件は生存。`--maintenance-margin-bps 500` でダイヤルを締めると2件目(アカウント20)も割り込む;`--maintenance-margin-bps 10` で緩めると不可避なケース(アカウント30)だけが発火する。結果が margin-bps ダイヤルに感応する最初の openhl シナリオ。
宣言された結果
宣言した各結果は、実行時の実際の状態に対して ✓ 合格 / ✗ 不合格 で採点されます。
- 取引後、アカウントは4件(買い手3+メイカー1)
- 約定はちょうど3件(3件の成行買いが単一のメイカークオートとクロス)
- 3件の買い以外に想定外の約定はない
- ブロック3のマークブック(Buy 99 / Sell 101 → ミッド100)が置かれるとマークは100に確定
- デフォルト維持証拠金200bpsでは清算はちょうど1件発火(アカウント30)——ライトバックが決済し、以降の tick に水没アカウントは残らない
- デフォルトパラメータでは清算は1件を超えない(他の2人の買い手は生存)(観測された清算スキャンヒット合計=2(期待値 ≤ 1))
- アカウント30は清算決済でポジションがゼロになって終了(建玉時の +20 ロングではなくなる)
- アカウント30が水没すると、メイカー(アカウント100)は ADL で強制決済——ポジションは -30 から 0 へ
- Alice(アカウント10)は +5 ロングを維持して生存(証拠金500が維持証拠金を余裕で賄う)
9件中8件の結果を検証
実行を1ブロックずつ辿る
マーク100ソースstub-empty-book取引1約定0入金4清算0ADL—
検証レポート(原文)
ツールが出力する英語の原文レポート(5セクション)——毎回同一です。
─── scenario: threshold-margin ────────────────────────────────────
HEADLINE ⚠: Mark settles to 100; at default 200bps maintenance only the deepest-leverage trader (account 30) is liquidated. Tighten via --maintenance-margin-bps to flip more accounts.
DESCRIPTION:
Three traders open long perp positions of varying leverage against the same maker quote at 110. At block 3 a mark-book lands at midpoint 100, putting all longs into unrealized loss. With the default 200bps maintenance margin, only the deepest-leverage account (account 30) crosses the threshold and gets closed via the write-back loop; the other two survive. Tighten the dial via `--maintenance-margin-bps 500` and a second account (account 20) ALSO crosses; loosen via `--maintenance-margin-bps 10` and only the unavoidable case (account 30) fires. The first openhl scenario whose outcome is sensitive to the margin-bps dial.
TIMELINE (per-block):
height mark src trades fills deposits liqs adl fund
------ ------ --------------- ------ ----- -------- ---- --- ----
1 100 stub-empty-book 1 0 4 0 — —
2 100 stub-empty-book 3 3 0 2 yes —
3 100 clob 2 0 0 0 — —
4 100 clob 0 0 0 0 — —
5 100 clob 0 0 0 0 — —
ACCOUNT DELTA (final − initial):
account collateral position avg_entry
------- ---------- -------- ---------
10 500 5 110
20 3 0 110
30 0 0 110
100 1127 0 110
(initial account count: 0, final account count: 4)
OUTCOMES:
✓ Four accounts exist after trading (3 buyers + 1 maker)
✓ Exactly three fills (the three market buys cross the single maker quote)
✓ No surprise fills beyond the three buys
✓ Mark settles at 100 once the block-3 mark-book lands (Buy 99 / Sell 101 → midpoint 100)
✓ At default 200bps maintenance exactly one liquidation fires (account 30) — write-back closes it; subsequent ticks see no underwater accounts
✗ No more than 1 liquidation fires under default params (the other two buyers survive) (observed total liquidation scan-hits = 2 (expected ≤ 1))
✓ Account 30 ends with position zeroed by the liquidation close (no longer the +20 long it opened with)
✓ Maker (account 100) is force-closed via ADL when account 30 goes underwater — position drops from -30 to 0
✓ Alice (account 10) survives with her +5 long unchanged (her 500 collateral easily covers maintenance)
8 of 9 outcome(s) verified.
NOTE: v1 runs the scenario in-process against a unit-provider
`LiveRethEvmBridge<()>` (no Reth boot). For the production-shape
run (real Reth + Malachite + JSON-RPC), use:
openhl reth-devnet --chain-history scenarios/threshold-margin.json --rounds 5
NEXT:
• Adopt this engine : https://github.com/psyto/rdk
• Custom build : https://fabrknt.com/waitlist.html?product=evm-perp&intent=build
• Hosted access : https://fabrknt.com/waitlist.html?product=evm-perp&intent=hosted