はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

今回は、注文板を使うDEXで出金処理を二段階に分けることで、ユーザーが自分の資産を確実に引き出せるように設計した仕組みを提案しているERC6787についてまとめていきます!

以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。

他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。

概要

Order Book DEX Standardは、注文板を使って資産を売買する分散型取引所(DEX)を実装するための共通インターフェース仕様です。 ユーザーが資産を預け入れる処理、引き出す処理、取引を行うために必要な基本機能がまとめられており、異なる開発者やプロジェクト間でも同じ仕組みで動かせるようにすることが目的です。

特徴として、ユーザーと取引所の双方の資産を守るために「二段階の強制出金方式」が提案されています。 これは、ユーザーが取引所を信用できない場合でも、自分の資産を安全に引き出せるようする仕組みです。 同時に、強制出金を悪用して損失を逃れるような行為を防ぎ、取引所側の資産も保護する狙いがあります。

この仕様は、Layer2上の注文板方式のDEXを標準化することで、開発者が相互運用性の高い取引所を構築しやすくし、ネットワーク全体として流動性や利便性の向上につながることを期待しています。

動機

Layer2上の注文板DEXは、オンチェーン処理のコストを抑えながら高速に売買できる仕組みとして注目されています。 しかし、従来は共通のインターフェースがなかったため、プロジェクトごとの作りがバラバラで、資産管理や出金方式に統一性がなく、ユーザーにとって安全性の判断が難しい状況がありました。

Order Book DEX Standardの動機は、まずユーザーの資産を確実に守るための基本機能を標準化することにあります。 預け入れ、出金、強制出金といった資産管理を担う重要な処理が統一されることで、開発者は安全なDEXを一貫した方法で構築できます。

さらに、ERC6787では二段階の強制出金方式が導入されています。 背景には、ユーザー保護の観点と取引所保護の観点の両立があります。 Layer2のDEXでは、資産は 1:1 の準備金で管理される前提で、清算と決済も分散化する仕組みを採用しています。 通常の強制出金はユーザー保護のために必要ですが、無制限に認めてしまうと、ユーザーが先物取引(特に無期限契約)で負った損失から逃れる目的で強制出金を行うリスクが発生します。

そこで二段階方式を採用し、まずユーザーの強制出金申請を確認する段階を設け、その後一定の検証期間を経て、問題がなければ最終的な強制出金を実行できるようにします。 この仕組みにより、ユーザーの資産保全と、取引所が本来受け取れるはずの差損回収の両方が守られるようになります。

また、この二段階方式は、分散システムでデータの整合性を保つための「二相コミットプロトコル」という仕組みを応用した考え方です。 取引の途中状態で不整合が発生しないようにするための考え方を、Layer2 DEXの資産管理に応用することで、安全性と堅牢性を高めています。

最終的に、Order Book DEX Standardは、ユーザーと取引所双方の安全性を高めながら、既存の課題である流動性不足や価格発見の効率性にも貢献できる設計を目指しています。 開発者が同じ土台の上にDEXを作れるようになることで、全体としての信頼性や利便性が向上し、より多くのユーザーが安心して利用できる環境が整います。

仕様

イベント

PrepareForceWithdraw
javascript
event PrepareForceWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);

ユーザーが強制出金の準備処理を正常に呼び出した時に発行されるイベント。 ユーザーが prepareForceWithdraw を実行し、取引所側が強制出金要求を受理した際に出力されます。 これにより、外部システムやフロントエンドは強制出金要求の発生を検知できます。 イベントにはユーザーアドレス、対象となるトークンのアドレス、そして要求された出金量が含まれます。 強制出金は二段階制で行われるため、このイベントは「第一段階の受付」を示す重要な情報となります。

パラメータ

  • user
    • 強制出金を発行したユーザーのアドレス。
  • tokenAddress
    • 出金対象となるトークンコントラクトのアドレス。
  • amount
    • 強制出金を要求したトークン量。

関数

deposit
javascript
function deposit(address token, uint256 amount) external;

指定したトークンを取引所に預け入れるための関数。 ユーザーが取引所で取引を行うためには、あらかじめ対象トークンをコントラクトへ預け入れる必要があります。 この関数ではトークンのコントラクトアドレスと金額を指定し、取引所が管理するアカウントに資産を移動します。 預け入れ後、取引所はユーザー残高を内部的に更新し、注文や取引に利用できるようにします。

引数

  • token
    • 預け入れるトークンのコントラクトアドレス。
  • amount
    • 預け入れるトークンの量。
withdraw
javascript
function withdraw(address token, uint256 amount) external;

指定したトークンを取引所から引き出す関数。 ユーザーが取引所から自身のウォレットへ資産を戻したい場合に利用します。 指定したトークンと数量を元に、取引所の内部残高からユーザーのウォレットへ実際にトークンを返却します。 通常の引き出し処理はユーザーが自由に行えるもので、強制出金ではありません。

引数

  • token
    • 引き出すトークンのコントラクトアドレス。
  • amount
    • 引き出すトークンの量。
prepareForceWithdraw
javascript
function prepareForceWithdraw(address token, uint256 amount) external returns (uint256 requestID);

強制出金の第一段階を開始するための関数。 ユーザーが取引所を信用できない状況に備えて、Layer2の注文板DEXでは強制出金の仕組みを備えています。 この関数は「強制出金の予告」を行うもので、ユーザーが指定したトークンと数量を出金したい意図を示します。 強制出金は二段階方式のため、まずこの関数で「申請」を行い、取引所はその後のタイムアウト期間内にユーザーの注文状況を確認し、必要であれば注文の強制キャンセルや決済処理を行います。 また、複数の強制出金が同時に処理される可能性があるため、各申請には固有の requestID が付与されます。

引数

  • token
    • 強制出金の対象となるトークンのコントラクトアドレス。
  • amount
    • 強制出金を希望する数量。

戻り値

  • requestID
    • 強制出金申請を一意に識別する ID。
commitForceWithdraw
javascript
function commitForceWithdraw(uint256 requestID) external;

二段階強制出金の最終実行を行う関数。 prepareForceWithdraw によって発行された requestID を指定し、強制出金を最終的に完了させます。 取引所側がタイムアウト期間内に注文確認・決済などを行い、問題がない状態であればこの関数を呼ぶことで資産がユーザーへ返却されます。 これにより、ユーザーは取引所の協力を必要とせずに資産を取り戻すことができ、Layer2環境における資産の安全性が確保されます。

引数

  • requestID
    • 強制出金申請を識別するID。

補足

このフローは、ユーザーがLayer2ベースのOrder Book DEXを利用する時に、二段階で強制出金を行う仕組みを示しています。 強制出金は、取引所側のバックエンドが応答しない状況や、ユーザーが資産を即座に保護したい場合に重要な役割を持ちます。

フローは Alice → DEX Front → Wallet → Alice の Account Abstraction (AA) → DEX の Account Abstraction (DEX AA) の順で通信しながら進みます。

1. ユーザーがDEXに接続する

AliceはまずDEXフロントエンドにアクセスします。 ここでWalletと接続し、アカウントがDEXの関連処理を受け取れるように購読(Subscribe)を行います。

2. 通常の預け入れ(deposit)

AliceはDEXに資産を預け入れます。

  1. DEXフロントは Alice の操作(UserOp)を Wallet に送信します。
  2. Wallet は Alice の AA に処理を渡します。
  3. AliceAA が deposit を DEX AA に送信し、資産を預け入れます。
  4. DEX AA が結果を返し、預け入れ処理が完了します。

この時点で Alice は通常の取引ができる状態です。

3. 強制出金の申請(prepareForceWithdraw)

次に Alice は強制出金の準備を始めます。

  1. Alice がフロントエンドを通して強制出金の開始を要求します。
  2. Wallet → Alice AA と流れ、Alice AA が prepareForceWithdraw を DEX AA に送信します。
  3. DEX AA はリクエストを受理し、ユニークな requestID を発行して返します。

この requestID が、後で実際の強制出金を行う際に必要となります。

4. 取引所によるチェック(注文状態の確認と決済)

prepareForceWithdraw が受理された後、DEX側はユーザーが不正な強制出金を行っていないか確認します。

代表的な確認内容。

  • ユーザーに未決済の注文が残っていないか
  • 未反映の損失がないか(特に無期限先物など)
  • 準備金との差し引き後に引き出し可能な資産があるか

必要があれば注文キャンセルや残高調整が行われます。 チェック完了後、DEXはフロント側に通知します。

5. タイムアウトまで待機

強制出金は「二段階方式」なので、prepareForceWithdraw の後すぐには資産を引き出せません。

一定時間のタイムアウト期間を設ける理由は以下です。

  • 取引所がユーザーの注文状態を確認・反映する時間を確保するため
  • 利用者が強制出金機能を悪用し、損失を回避しようとする行為を防ぐため
  • 二相コミット(Two-Phase Commit)と同じ発想で整合性を確保するため

この時間が経過すると、強制出金の実行フェーズに進めます。

6. 強制出金の実行(commitForceWithdraw)

タイムアウト後、Alice は commitForceWithdraw を実行します。

  1. フロント → Wallet → Alice AA と処理が渡されます。
  2. Alice AA は commitForceWithdraw(requestID) を DEX AA に送信します。
  3. DEX AA は該当する強制出金リクエストを処理し、最終的に Alice のウォレットに資産が戻されます。

これで二段階強制出金が完了します。

引用

Jessica (@qizheng09), Roy (@royshang), Jun (@SniperUsopp), "ERC-6787: Order Book DEX with Two Phase Withdrawal [DRAFT]," Ethereum Improvement Proposals, no. 6787, March 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6787.

最後に

今回は「注文板を使うDEXで出金処理を二段階に分けることで、ユーザーが自分の資産を確実に引き出せるように設計した仕組みを提案しているERC6787」についてまとめてきました! いかがだったでしょうか?

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!

他の媒体でも情報発信しているのでぜひ他も見ていってください!