コンテンツにスキップ

取引モデルと人間のマーケットメイカー

取引モデルと人間のマーケットメイカー

Section titled “取引モデルと人間のマーケットメイカー”

bitCaster は中央指値注文板(CLOB)を使います。指値注文は板に残り、成行注文またはクロスする指値注文が流動性を取り、決済は Cashu CTF のアトミックスワップでピアツーピアに行われます。

用語は Polymarket CTF Exchange V2 と揃えています。Complementary(補完)= 同じアウトカムセットに対する買いと売り、Mint = 完全に補集合となるアウトカムセット同士の買い注文同士(メイカーが完全な CTF セットを mint する split 担当になる)、Merge = 完全セットに統合する売り注文同士(bitCaster では未対応)。

公開される注文板はプリミティブなアウトカムごとの板です。ABC のカテゴリ市場では、A / Not AB / Not BC / Not C の板を表示します。クライアントは condition-Acondition-Bcondition-C に注文し、注文本文で選択アウトカム側か one-vs-rest の補集合側かを選びます。B|C のような複合 ID は決済と mint keyset の内部識別子であり、公開 market route ではありません。

マーケット詳細のトレードチケットは枚数ベースです。ユーザーは整数の枚数を入力し、クライアントが注文送信前にプロトコル上の額面数量へ変換します。マーケットの divisibility が D の場合、1 枚の額面価値は D 基準単位で、価格分子 kk / D の確率を意味します。価格 kn 枚を買う場合、手数料前のコストは n × k 基準単位で、勝った場合の受取額は n × D 基準単位です。例えば D=100 の sats 建てマーケットでは、価格 30 で 50 枚を買うと、手数料行を除いたコストは 1,500 sats、勝った場合の受取額は 5,000 sats です。

板に残る指値注文は「オンラインで決済可能である」というコミットメントです。メイカーは注文が約定、取消、または期限切れになるまで、ブラウザタブまたは Bot プロセスを接続しておく必要があります。テイカーが注文にマッチしたら、メイカーは TradeHub メッセージに応答し、タイムアウト前にプルーフをロックできなければなりません。

マッチングエンジンがマッチをコミットした時点で、その約定数量は板から取り除かれます。その後のウォレット側アトミックスワップがタイムアウトまたは失敗しても、その数量は自動的には板に戻りません。メイカーはライブ注文をコミット済み流動性として扱い、利用できなくなる前に古い注文を取り消すべきです。

本格的なマーケットメイカーは、たまに開くブラウザではなく Bot を運用するべきです。bitcaster-cli は長時間動作するウォレット兼スワッププロセスとして bitcaster-daemon を使うため、非ブラウザのメイカーもワイヤプロトコルを変えずに参加できます。

Complementary マッチングは、同じアウトカムセットについての買いと売りの通常フローです。

  • 売り手はアウトカムプルーフを買い手向けにロックします。
  • 買い手は sats を売り手向けにロックします。
  • アダプター署名により、2つの mint spend は atomic になります。

売り手側のトークン locktime は、買い手側の sats locktime より設定された安全差分だけ長くなければなりません。これにより、売り手が spend した後、買い手がアダプター秘密を抽出する時間を確保します。

Mint マッチングは、完全に補集合になるアウトカムセットの買い注文同士をマッチさせます。バイナリ市場では YESNO が補集合です。A, B, C のカテゴリ市場では、A の補集合は B|CB の補集合は A|CA|B の補集合は C です。

メイカーは split を行う側になります。

  1. メイカーは通常の sats 担保を選択します。
  2. メイカーは mint にその担保を完全な CTF アウトカムセットへ split させます。
  3. メイカーは自分が欲しいアウトカムセットを保持します。
  4. メイカーはテイカー側のアウトカムセットを、通常の売り手側アトミックスワップとしてロックします。
  5. テイカーは通常の買い手側フローで sats を支払います。

このため、Mint 決済ではメイカーが最初からテイカー側のアウトカムトークンを持っている必要はありません。mint 手数料を含め、完全セットを作れるだけの通常担保が必要です。

Mint マッチのメイカーになり得る板に残る指値買いでは、bitCaster は事前 split をデフォルトにします。注文を板に出す前に、クライアントは通常の sats を完全な CTF アウトカムセットへ split し、生成されたアウトカム proof をローカルに保存し、その注文用に保持側とロック側を予約します。

これにより、ライブ注文が決済可能であることを保ちます。mint が応答しない、またはウォレットが十分な通常担保を選択できない場合、クライアントは決済不能なメイカー注文を残すのではなく、注文提出を失敗させるか注文経路を取り消すべきです。後で Mint テイカーがマッチした場合、メイカーは予約側から約定分だけをロックし、保持側も約定分だけをアクティブポジションとして解放します。未約定数量に対応する残りの proof は注文に予約されたまま残ります。

ブラウザでは、指値買いにデフォルト ON の 事前スプリット チェックボックスとして表示されます。CLI も同じデフォルトを使います。bitcaster-cli order submit ... --no-preflight-split は、マッチ時に split したい運用者向けの明示的な opt-out です。opt-out すると、マッチ到着時に担保が消費済み、別用途に予約済み、または mint が遅い場合に決済失敗リスクが高くなります。

初回リリースの方針は fee-first と maker surplus です。

  • mint は一定の swap/input fee を取る場合があります。
  • テイカーは提示された支払い額に加え、自分側の mint 手数料を負担します。
  • テイカーがメイカーの有利な価格をクロスした場合、その価格改善分はメイカーの余剰として残せます。
  • v1 ではマッチングエンジンはスワップ内で別手数料を取りません。エンジンを Cashu アトミックスワップに挿入すると、非カストディアルなプロトコルが大きく複雑になるためです。

例:メイカーが Buy YES 50 / 100 を出し、テイカーが Buy NO 49 / 100 を出した場合、実際の余剰と手数料処理は約定価格ルールに依存しますが、mint 手数料を払った後の価格改善分をメイカーが受け取れる設計にします。

人間のメイカーは、ライブ注文にコミットしてよい担保だけをウォレットに置き、オフラインになる前に注文を取り消すべきです。ブラウザタブを取引途中で閉じると決済に失敗する可能性があります。Bot と daemon のメイカーは、古い注文、スワップ失敗、予約済み在庫、mint 手数料の変化を監視してください。

bitCaster のマッチタイプ分類は Polymarket CTF Exchange V2 に揃えています。Complementary が買いと売り、Mint が買い同士、Merge が売り同士です。しかし決済モデルは根本的に異なります。Polymarket V2 はバッチ化されたオンチェーンのオペレータートランザクションを通じて Ethereum 上で決済します。bitCaster は Cashu アトミックスワップでピアツーピアに決済します。分類はオンチェーンからオフチェーンに引き継げますが、いくつかの挙動は引き継げません。

バッチ化はしない(設計判断)

Section titled “バッチ化はしない(設計判断)”

Polymarket V2 がマッチを 1 つのオンチェーントランザクションにバッチ化するのは、各トランザクションに固定のベースガスコストがあり、バッチ化することで多数の約定にコストを分散できるからです。bitCaster には分散すべき共有コストがありません。各アトミックスワップは mint とのピアツーピア通信であり、支払うのは mint の proof 単位の入力手数料だけです。複数のマッチを 1 つの決済イベントにまとめても、約定単位の手数料は下がりません。

そこから来る利点は具体的です。プロトコルはより単純になります。オペレーター側のバッチ構築ステップも、バッチ revert の意味論も、バッチごとの nonce もありません。マッチはアトミックスワップを発火させるか失敗するかのいずれかです。レイテンシも下がります。板がクロスした時点でマッチングエンジンが約定を発火します。Polymarket のオペレーターはプロトコル上は同じことができますが、経済的な理由で通常は遅延させます。bitCaster にはその理由がありません。

Polymarket V2 の Mint では、エクスチェンジコントラクトが両買い手から USDC を受け取り、トレードと原子的に ConditionalTokens.splitPosition を呼び出します。split のガスはトランザクションを通じて分散されます。

bitCaster Mint では、メイカーが split を行います。メイカーは自分のウォレットから通常の sats を選択し、mint にそれを完全な CTF アウトカムセットへ split させ、自分が欲しい補完側を保持し、テイカー側を通常のアトミックスワップ枝にロックします。ここから 2 つの帰結があります。第一に、メイカーは完全セットの両側を一時的に保持することになります。テイカーが完了に失敗すると、メイカーは別の対向を見つけるか、もう一度 mint 手数料を払って merge し直すまで、不要な補完側を抱え込みます。Polymarket の原子的なオンチェーン取引にはこの「在庫が詰まる」失敗モードがありません。第二に、mint 入力手数料はメイカーが負担します。Polymarket の splitPosition のガスはオンチェーントランザクションを通じて分散されますが、bitCaster の proof 単位手数料は split を提出した者、ここではメイカーが払います。これは実際の経済的非対称性です。bitCaster のメイカーは完全セット在庫を供給するコストを負います。

事前 split ポリシーはこれを部分的に緩和します。注文を板に出す前にメイカーが split し、完全セットの両側を予約済み在庫として保持できるようにするからです。これは「未約定の可能性のある注文に担保を拘束する」代わりに「マッチ時に mint が応答しない競合状態を避ける」というトレードオフです。

Polymarket の atomicity は Ethereum から来ます。エクスチェンジトランザクションはマッチの両側をコミットするか、どちらもコミットしないかのいずれかです。中間状態はありません。

bitCaster の atomicity は、NUT-11 P2PK の支出条件上の Schnorr アダプタ署名と、ロックされた proof の locktime + リファンド pubkey から来ます。2 者の mint spend は、共有トランザクションではなくアダプタ関係を通じて atomic になります。コストは、片方がスワップ途中で locktime ウィンドウ内にオフラインになると「partial lock held」状態が残ることです。ロックされた proof は locktime 経過後にリファンドキーで回収可能ですが、それまでは経済的に凍結されます。Polymarket にはこの失敗モードがありません。

Merge: 不可能ではなく、設計上の保留

Section titled “Merge: 不可能ではなく、設計上の保留”

Polymarket V2 の Merge(売り同士)はオンチェーン split プリミティブの自然な拡張です。ConditionalTokens.mergePositionssplitPosition の逆操作で、ガスは 1 つのトランザクションを通じて分散されます。

bitCaster は現時点で Merge をサポートしません。オフチェーンの売り同士は連続するアトミックスワップ枝として実現可能ですが、各枝が固有の mint 入力手数料を払うため、メイカーが merger になるパターンは、Mint のメイカーが splitter になるパターンほど明確にネット黒字ではありません。需要が枝ごとのコストを正当化するかどうかは未解決の問題であり、Merge の不在は実際の取引データを待つ保留であって、プロトコル上の制約ではありません。

事前 split に Polymarket 側の対応物はない

Section titled “事前 split に Polymarket 側の対応物はない”

Polymarket V2 では mint がトレードと原子的に行われるため、事前に充填するメイカー保持在庫モデルが存在しません。オフチェーンモデルではメイカーは在庫をローカルに保持し、注文を板に出す前に split しておくことで、「マッチ時の mint 可用性」をウォレット側の資本コミットに置き換えます。事前 split は bitCaster 固有の信頼性最適化であり、オンチェーンでは存在しない失敗モードに対処します。

マッチタイプ分類は Polymarket V2 から移植可能です。決済モデルは移植できません。bitCaster はプロトコルの単純さと板がクロスした時点での即時約定を得ますが、その代わりに Mint におけるメイカー側の在庫リスク、オフチェーン atomicity から来る partial-lock リカバリの面、そして保留中の Merge 実装を引き受けます。