T24 · MEV
あなたの取引はブロックに入る前に誰に見られているか?
- 練習する能力
- BuilderProtocol Literacy
- 実践
- フォーク環境で自分の取引にサンドイッチ攻撃を仕掛け、ユーザーの損失を定量化する。
- AI Lab
- AI にユーザー側の防御策を列挙させ、自分のプロダクトで実現可能か一つずつ評価する。
現実の問題
交換画面を公開して二か月。利用者が同じ不満を言い始めた。「約定価格がいつも見積価格より少し悪い。」
T20に沿って確認すると、現在の準備金で見積もり、経路は最適で、最低受取量は署名に含まれ、有効期限もある。何より 取引はrevertしていない。スリッページ保護は動き、署名した下限以上を受け取っている。
そこで一件をブロックエクスプローラーで見る。
ブロック内の47番目だ。46番目と48番目を見ると、同じ送信元、同じプールで、一つは買い、一つは売り。利用者の取引を挟んでいる。
三件を順にローカルで再実行し、利用者が少なく受け取った量を計算する。見覚えのある数字だ。フロントエンドの既定スリッページ許容幅とほぼ一致していた。
利用者がだまされたわけでも、契約にバグがあるわけでもない。検査はすべて通った。ただ 真ん中に置かれたのだ。
本当の問いは この三件の順番を誰が決め、何に基づいてそうしたか? だ。
思考実験
ブロックチェーンを一つの村に縮めよう。
入口に 掲示板があり、用事のある人が紙を貼る。十二秒ごとに 処理担当者が来て、紙を選び、好きな順番でまとめて処理する。
この二規則だけで三つのことが分かる。
第一、掲示板は公開され、処理前から読める。 何をどれだけ買い、どんな価格まで許すかが紙に書かれ、処理前に全員が読める。漏えいではなく掲示板の仕組みだ。公開しなければ担当者の処理を他人が検証できない。
第二、担当者は順番を決め、自分の紙も差し込める。 あなたを47番目に置き、その前に自分の紙を置ける。
第三、自分で実行する必要さえない。 「次の回は最も高く払う人を先頭にする」と公表できる。
第三が転換点だ。誰より先に並ぶかは技術的詳細を超え、価格を付け、競売にかけ、金を払って買う対象になる。
そこから三つの商売が生まれる。まだ名前は付けない。
甲:同じ商品の価格が違う二つの店で、安く買い高く売る。後には価格が揃い、誰も損をしなかったように見えるが、差額は本来商品を提供した人のものだった。
乙:掲示板であなたの大量購入を見て先に買い、あなたが価格を上げた後に売る。あなたの意図自体が利益の源泉になる。
丙:担保が回収可能な水準を割ったのを見て、T22の清算を誰より早く行い、報酬を取る。
三つに共通する重要な点がある。どれも脆弱性を使っていない。 全操作が規則に従い、すべての検査に通る。
利用するのはコードの誤りではなく、システムの構造そのものだ。
あなたが決める
利用者は署名済みで、この取引をあなたのコードから送るところだ。
どこへ送るか?
結果を観察する
四つは同じ問いに答えている。意図が何人にどれほどの時間見え、その可視性から誰が利益を得られるか。
| 方法 | 意図を見る人 | 信頼する相手 | 主な代償 | 失敗形態 |
|---|---|---|---|---|
| 公開メンプール+狭い許容幅 | 全員 | 新たな相手なし | 高い失敗率 | 反復失敗で拡大を迫られる |
| 公開メンプール+広い許容幅 | 全員 | 新たな相手なし | 搾取分が見えない | 長期間、気づかず損をする |
| 私設経路 | 一運営者 | 運営者の約束 | 新たな相手方 | 約束違反を検証できない |
| インテント+競争実行 | 実行者群 | 競争の強さ | 遅延、実行者の集中 | 競争不足で価格が静かに悪化 |
第三列が本章で最も覚えるべき点だ。
MEVは消去ではなく移転される。防護策は取引順序から利益を得る権利の持ち主を変えるのであり、その額をゼロにはしない。
特定サービスで安全になるという主張は、ここで新たな信頼先を説明していない。
二つ目は、取引が狙われるかを決める計算可能な閾値だ。
攻撃者の粗利益 ≈ 取引額 × 押し込めるスリッページ余地
攻撃者の費用 ≈ 二回の交換手数料 + 二回のGas + 順位獲得の入札額
純利益が正なら実行し、ゼロ以下なら狙わない逆から読めばT20の定量版になる。スリッページ許容幅は自分で掲げた懸賞額だ。許容幅と取引額の積が攻撃費用を超えたとき、対象範囲に入る。
つまり 取引順序自体が売れる資源である。
バグではなく、改版でも消えない。誰かが順序を決める必要から生じる。できるのは 額と現在の受取人を知ることだ。
モデルを作る
一、取引を誰が見たか
- フロントエンド
- ウォレット
- RPC提供者
- 公開メンプール
- サーチャー
- ブロックビルダー
- ブロック提案者
- ブロックへ収録
| 段階 | 見えるもの | できること | 検証可能か |
|---|---|---|---|
| RPC提供者 | 全取引内容 | 転送遅延、他者への転送 | できない |
| 公開メンプール | 全取引内容 | 全ネットワークで読む | できる。公開が目的 |
| サーチャー | 全取引内容 | サンドイッチ、先回り、裁定 | できない |
| ブロックビルダー | 全内容と全入札 | 最終順序を決める | 事後は可能、事前は不可 |
| ブロック提案者 | 組み立てたブロック | 採用または置換 | 事後は可能 |
一行目は忘れられがちだ。 公開メンプールを避ければ安全だと考えても、その前にRPC提供者を通る。コードで直接設定するのにほとんど調べない、取引を最初に見る相手だ。
二、四形態、二つの性質
| 形態 | 利益の負担者 | 誰も行わない場合 | 利用者が損をするか |
|---|---|---|---|
| 裁定 | 流動性提供者 | 市場間の価格差が残る | しないがLPは損をする |
| 清算 | 清算される利用者 | T22の不良債権 | 追加損ではない。元々支払う必要がある |
| フロントラン | 取引の発信者 | 何も起きない | はい |
| サンドイッチ | 取引の発信者 | 何も起きない | はい |
第三列が四形態を二つに分ける。
上二行は誰かがしなければならないこと。裁定がなければ価格差が残り、清算がなければ不良債権が増える。抽出される価値は元からあり、その受取人が決まる。
下二行はこの取引を送ったからこそ生じること。誰もしなければその費用は発生しない。価値の移転ではなく 作り出された費用で、全額を利用者が負担する。
この区別でMEV対策を評価する。裁定利益をAからBへ移すだけでは利用者は改善せず、下二行を減らして初めて改善になる。
三、サンドイッチの数学:許容幅が最適攻撃規模を決める
T19の定積プールなら計算できる。外部ライブラリ不要の二関数を、そのままテストへ入れられる。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// 定積見積もり:入力からfeeBps万分率の手数料を差し引く。典型値30
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut,
uint256 feeBps
) pure returns (uint256) {
uint256 inAfterFee = amountIn * (10_000 - feeBps);
return reserveOut * inAfterFee / (reserveIn * 10_000 + inAfterFee);
}
/// サンドイッチのない場合とある場合の利用者受取額の差
/// この引き算が本章で自分で測る数字になる
function sandwichLoss(
uint256 userIn,
uint256 attackerIn, // 攻撃者が先回りして投入する額
uint256 reserveIn,
uint256 reserveOut,
uint256 feeBps
) pure returns (uint256) {
uint256 clean = getAmountOut(userIn, reserveIn, reserveOut, feeBps);
// 攻撃者が先に買い、準備金を動かす
uint256 got = getAmountOut(attackerIn, reserveIn, reserveOut, feeBps);
uint256 newIn = reserveIn + attackerIn;
uint256 newOut = reserveOut - got;
// 利用者は押し上げられた曲線で約定する
uint256 sandwiched = getAmountOut(userIn, newIn, newOut, feeBps);
return clean - sandwiched;
}攻撃者が attackerIn を選ぶときの制約は 署名された最低受取量だ。押しすぎると利用者の取引が全部戻り、攻撃の二操作は無駄になり手数料も失う。
したがって最適解は明確だ。
最適なattackerIn = sandwichedが利用者のamountOutMinと一致する投入額
つまり:
利用者の損失上限 = 取引額 × スリッページ許容幅
攻撃者はちょうどその上限まで取るここで立ち止まろう。 推測も欲張りも不要で、許容幅が投入すべき額を教える。0.5%を5%に変えると目標利益が十倍になる。
実行するかは粗利益が費用を上回るかで決まる。
粗利益 ≈ 利用者の損失 − 攻撃者自身の二交換の手数料
費用 ≈ 二回のGas + 利用者の前後へ並ぶための入札
純利益が正のときだけ実行する。
そのため最小攻撃対象額があり、それ未満は狙われない。Labではその最小額を求める。一般的な防護助言以上に有用で、リスクが始まる取引規模を教えてくれる。
四、三つの防護策は誰へ権力を渡すか
| 方法 | 減らすもの | 権力の移転先 | 検証できない点 |
|---|---|---|---|
| 許容幅を狭める | 抽出可能価値 | 移転なし | なし。新たな信頼を必要としない |
| 私設取引経路 | 露出範囲 | 経路運営者 | 覗き見や第三者への引渡し |
| インテントと競争実行 | 露出範囲と利益の一部返還 | 実行者群 | 競争の十分さ |
抽出可能価値の削減は金額そのものを減らし、露出範囲の削減はそれを見られる人数を減らす。前者は新たな相手を信頼しなくてよいが、後者は新たな相手方を必ず導入する。
実務では三択ではなく組み合わせる。 取引額と深度に応じて許容幅を動的計算し、大口は私設経路や競争実行へ回し、画面で 推定価格影響を明示する。最後は費用がかからないのに、多くの製品で欠けている。
何と呼ぶか
ブロックへ含める取引、除外する取引、実行順序を決めることで追加抽出できる価値。
要点は脆弱性ではなく 順序。誰かが順序を決めるという構造から生じ、改版では消えない。額と現在の受取人を把握する必要がある。
二市場間の価格差で利益を得ること。
四形態で明確な正の外部性があり、分散市場の価格を揃える。ただし 利益は流動性提供者から来る。LPのインパーマネントロスのかなりの部分がこの形で持ち出される。
利用者の前後へ一件ずつ入れ、価格を許容幅の端まで動かして差額を実現すること。
裁定との違いは 損失が移転ではなく作られる点。誰もしなければ存在しない。取れる額は利用者自身の許容幅で決まる。
取引群の実行順を決める権力。
本章の主役だ。売買可能になると、サーチャーが機会を探し、ビルダーが組み立て、提案者が位置を売る供給網が生まれる。順序は資源で、有価資源には市場ができる。
公開放送を経ず、ブロック生産側へ直接届く取引経路。
全員に見える状態を一主体に見える状態へ変える。信頼の再配分であり、リスクの消去ではない。 運営者、約束、保証方法、違反を発見できるかを確認する。
インテント方式で最適な実現経路を探し、実行する競争参加者。
順序権の利益を競争対象にし、一部を良い約定価格として利用者に戻す。代償は 実行者が集中しやすいこと。資金、基盤、アルゴリズムが要る。使う前に 実行者の収入源は何か? と問おう。答えは必ずあるが文書にあるとは限らない。
実践
成果物は理解したという感想ではなく 自分で測った数値だ。既定設定で一万の交換からいくら取られるかを答えられるようにする。
環境を準備し、見積もりを一致させる。
チェーンをローカルForkし、定積プールの両準備金と料率を記録する。getAmountOut をテストへ入れ、計算結果とチェーン呼出しの返り値を比較する。一単位も違ってはいけない。違えば丸め方向や手数料の位置を誤っている。T19の丸め表を確認する。以後の損失計算はこの一致が土台だ。
基準を測ってから一回挟む。 テスト用アドレスだけで10000単位を交換し、実受取量を clean とする。以後の比較の分母になる。
同じブロックで三取引を順に実行する。
第1取引 攻撃者がa買う ← 価格を上げる
第2取引 利用者が交換 ← 上げた曲線で約定
第3取引 攻撃者が第1取引で買った全量を売る利用者受取量 sandwiched、攻撃者の最終受取額、投入額との差を記録する。利用者の損失は clean から sandwiched を引いた量だ。百分率にして既定許容幅と並べて見る。
最適な攻撃規模を走査する。
利用者取引と許容幅を固定し、a を小から大へ変え、各点の利用者損失と攻撃者純利益を記録する。利用者損失は a とともに増え、下限を割ると戻る。攻撃者利益は増えてから下がる。押しすぎれば利用者取引が成立せず、費用を失う。
純利益最大の a を見つけ、この a のとき利用者の受取量が署名した最低量とほぼ一致するか確かめる。一致すれば 許容幅が攻撃者の目標利益を決める結論を自分で確認したことになる。
二次元表を埋める。
横軸を許容幅、縦軸を取引額にし、各セルに利用者損失率と攻撃者純利益を書く。
0.1% 0.5% 1% 5%
1,000 ... ... ... ...
10,000 ... ... ... ...
100,000 ... ... ... ...攻撃者純利益が正の領域を線で囲む。 左下の安全領域は特別な防護のおかげではなく、攻撃する価値がないからだ。
費用から最小攻撃対象額を求める。本章の定量演習だ。
既知:片側の深さD、手数料率f、許容幅s、現在Gas価格g
第1段階:走査した最適aで粗利益を求める
粗利益 ≈ 利用者損失 − 攻撃者の二交換の手数料
(二回fを払う点を見落とさない)
第2段階:費用を計算する
二回のGas = 2 × 一交換のGas × g
順位入札 = 前後に並ぶために譲る粗利益
(保守的に粗利益の半分とする)
第3段階:純利益 = 第1段階 − 第2段階
第4段階:純利益を0として取引額Vを逆算する
Vはこのプールと許容幅での最小攻撃対象額になるVを求めて三つ行う。
- Gas価格を十倍にして再計算する。混雑時はVが大きくなり、小口はかえって狙われにくい。
- 許容幅を5%から0.5%へ変え、Vが何倍になるか計算する。
- 自分の製品で 実取引の何割がVを超えるか集計する。
第三が真の成果物だ。抽象的リスクが週報に書ける割合になる。
別の防護経路で測り直し、代償を書く。
Forkで私設経路を模擬するには 第1・第3取引を実行せず、利用者取引だけ実行する。損失はゼロになるが、重要なのは次の記録だ。
| 問い | 答え |
|---|---|
| 経路の運営者は誰か | |
| 何を約束し、どこに書いてあるか | |
| 約束は何で保証されるか | |
| 違反したら発見できるか | |
| 停止したらどう縮退するか |
五欄を埋められなければ防護として数えない。 スイッチ一つではなく、新たな相手方の導入だ。
すべてローカルForkで行い、実資金を接続せず、攻撃スクリプトは自分のテスト用アドレスだけに実行する。 実資金は卒業制作でのみ扱い、先に第五段階の安全検査を通過する。
AI Lab
三段階で問う。第二と第三に価値がある。
第一段階:
オンチェーン交換製品が使える利用者側MEV対策を列挙してください。
各項目に、減らすのが抽出可能価値か露出範囲か、
実装費用、利用体験への影響、信頼の移転先を書いてください。
まず結論を出さず、一覧を完成させてください。
第二段階:
私の製品条件は(自分で記入):利用者規模、典型的取引額の分布、
チェーン、既定許容幅、接続しているRPCの出所です。
各策がここで実行可能か一つずつ評価し、
定量化できる期待効果と代償を示してください。
第三段階:
推奨する上位二策についてそれぞれ、
失敗条件、失敗時に観測できる兆候、
提供者停止時の縮退経路を書いてください。第一段階は多くのモデルが網羅できるが、私設経路を使えば解決と書きがちだ。運営者と保証を追問し、答えられなければ未評価とする。第二は「大幅に減らす」と曖昧になりやすい。取引額分布の何割をカバーし、損失をいくら減らすか数値を求める。数字のない評価は本章では評価にならない。
第三が成果物で、汎用の追問にもなる。どんな防護も、いつ失敗し、どう失敗を知るかに答える必要がある。 正常時だけ働き、失敗を発見できない防護は、他の警戒を緩めさせるので、防護なしより危険になり得る。
一覧を得たら各評価をLabの二次元表と照合する。推奨策は実際の取引額が入るセルをカバーしているか?
AI の回答後、自分で必ず検証すること
- 各策で権力が誰に移るかを説明したか。新たな信頼先を言えなければ評価は未完了
- 抽出可能価値の削減と露出範囲の削減を区別したか
- 許容幅の提案は固定百分率か、取引額と深度に応じる式か
- 私設経路や特定サービスを完成した解決策ではなく信頼の再配分として扱ったか
- インテントと競争実行で実行者の収入源を答えたか
- RPC提供者も取引を見られる段階だと説明したか
- 具体的サービス名、インターフェース、設定を記憶に頼らず自分で確認したか
実例
公開メンプールの攻撃は偶発ではなく産業だ。対象を探す走査、ブロック内順位への入札最適化、資金提供をそれぞれ専業者が行う。
規模は集計できる。この業界で完全公開検証できる数少ない事柄で、誰でもチェーン上から各攻撃を復元できる。
製品開発者への結論は具体的だ。既定許容幅は体験の設定であると同時に、誰かがリアルタイムで読み、価格付けする公開変数でもある。
提案者群はサーチャーの提出内容を規則どおり組み込むはずだったが、ブロックを受け取った後に取引を置き換え、用意された機会を自分で取った。大きな額が関わった。
価値は金額ではなく、私設経路の防護が暗号学的保証ではなく約束だと示したことにある。特定の主体が規則を守ることに依存し、違反利益が十分大きければ規則は規則にすぎない。
Lab最後の表の第三行、保証方法の本当の答えは多くの策で「評判」だ。十分大きな機会なら、その評判を一度で換金できる。
一部のL2は単一シーケンサーが順序を決める。公開メンプールがなく、公開のサンドイッチ機会もなく、露出範囲は減る。
だが権力は消えず、一プロセスに完全に集中する。全取引を見て全順序を決め、利用者はその行為をほとんど検証できない。
移転の典型例だ。見知らぬ集団の攻撃リスクが、一運営者を信頼するリスクに変わる。 どちらを選ぶかは受け入れられる失敗形態次第で、明示的な判断が必要だ。
T22の最後に戻ろう。一機会を十人が発見し、勝つのは一人で、九人は手数料だけ払う。
その失敗費用は消えず、清算者の採算判断に入る。期待失敗費用を差し引いても利益を出させるには報酬を上げる必要があり、その報酬は清算対象者が払う。
つまり 順序権の競争費用が高い清算ペナルティとして利用者に落ちる。サンドイッチより見えにくいMEVの間接経路だ。
変数を一つ変える
サンドイッチが減り、約定価格は改善し、問い合わせも減る。
同時に三つをリスク一覧に加える。新しい単一障害点ができ、停止時は製品が止まるか、公開メンプールへ黙って戻る。後者は防護消失を利用者が知らず危険だ。運営者には全取引が見え、行動を検証できない。さらに 裁定者も取引を見られず、場合によって価格発見が遅くなる。
縮退経路は明示し、観測でき、利用者に見える必要がある。 無防護へ静かに戻るより、明確に失敗する方がよい。
直感では露出時間が三十分の一になり、安全そうに見える。
実際には二つ変わる。攻撃者の反応時間は短くなり、高速基盤が必要で参加者は減る。一方 残った者の競争は激化し、一ブロックに入る取引も減り、先頭の位置は希少で高価になる。
さらに 秒数やブロック数で固定した仮定をすべて再計算する。有効期限、許容幅計算、収録までの時間見積もりは特定の間隔に依存する。T21、T22と同じく、チェーン変更時は時間関係の全設定を導き直す必要がある。
利用者側ではなく仕組みを変える。同じバッチ内で先後がなくなり、サンドイッチの前提が消える。
代償は三つ。遅延があり、終了を待つ。価格発見が遅くなり、急変時は統一価格が古くなる。そして バッチ境界が新たな競争点になる。どの注文を今回に含め、どれを次回へ送るかが価値ある判断になる。
仕組み設計では ある抽出価値を消すと別の希少位置を作りやすい。新しい価値が古いものより十分小さいかで判断する。
四策で唯一 新たな信頼を必要としない方法で、フロントエンド計算だけなので安い。
小口は粗利益が費用に届かないため広め、大口は自動で狭め、閾値を超えたら分割や実行経路変更を提案する。
難しいのは式ではなく リアルタイムのプール深度だ。T17、T18に戻り、自分の索引とリアルタイム経路から取り、古いキャッシュを避ける。古い深度で計算した許容幅は固定値より危険になり得る。賢く見えるからだ。
持ち帰る問い
最も明らかにすべき金は、利用者が順序に払う費用で、請求書には載らない。少し悪い約定価格として現れ、書類も通知もなく、多くは気づかない。
手数料ゼロやGas無料を見たら順序権の持ち主を問う習慣を付けよう。表の費用がなくても、場所が変わっただけのことが多い。
供給網の各層に収入がある。サーチャーは価格差、ビルダーは組立料、提案者は位置、私設経路はサービス料や分配、実行者は競争後の残余を得る。
図にして各段階へ収入源を書くのが対策評価の第一歩。収入を説明できない段階は、まだ理解していない段階だ。
リスクは三か所で可視性が違う。利用者は見えない約定悪化、LP は一部見える裁定損失、プロトコルは遅れて見える評判低下と離脱を負う。
特に 損失の特徴が成功した取引であることを覚えよう。失敗なら問い合わせが来るが、5%抜かれても来ない。苦情だけで発見するチームはこの損失を見つけられない。
インセンティブは明白だ。順序に価値があれば必ず買う人がいる。 悪意がなくても合理的行動から生じる。
全員が規則を守ることに依存する策には、一回の違反利益が長期の遵守利益を超えたら何が起きるか? と問う。2023年の例が答えを示した。
章末チェック
価値の移転か、新しい費用の発生かが違う。
裁定は存在している市場間価格差から利益を取り、LPが負担するが価格も揃える。裁定者がいなければ差が残る。
サンドイッチは 誰もしなければ損失自体が存在しない。何かを訂正するのではなく、可視の取引を送ったことで追加費用が作られる。
評価基準は 裁定利益をAからBへ移すだけでは利用者を助けず、先回りとサンドイッチを減らしてこそ改善になることだ。
曖昧な相関ではなく、上限を決める関係だ。
押しすぎれば最低受取量を割って取引が戻り、Gasを無駄にするため、最適策は 許容幅の端でちょうど約定させることだ。
したがって 損失上限は取引額と許容幅の積で、攻撃者はそこを狙う。0.5%を5%へ変えれば目標利益は十倍になる。
実行は粗利益が二回の手数料、Gas、順位入札を超えるか次第で、Labの最小攻撃対象額につながる。
信頼の再配分を リスクの消去と呼ぶ点だ。
全員には見えなくなるが、運営者には全内容が見える。収録可否と時刻を決め、他者へ機会を渡せる。公開市場から一相手方への信頼へ変わる。
運営者、約束、記載場所、保証、違反を発見できるかの五点が必要だ。多くの保証は評判で、2023年の例は十分大きな機会で一度に換金され得ると示した。
さらに どのメンプールへ届くより前にRPC提供者が見ていることも忘れてはいけない。
消さない。順序権の利益を競争対象にし、一部を良い価格として戻す。
改善ではあるが、実行者は価値を取る。返還率は競争次第で チェーン上から検証できない。資金、基盤、アルゴリズムの必要から集中もしやすい。
問うべきは 実行者の収入源、競争の十分さ、不足時に観測できる兆候だ。
唯一の正解はないが、次を確認する。
- 全取引経路で 署名から収録まで誰が見るか。調べたことのないRPC提供者も含める。
- 許容幅が固定か動的か、典型的取引額との積がいくらか。
- 最小攻撃対象額と、それを超える実取引の割合。
- 各防護が 誰へ信頼を渡し、失敗時に何を観測できるか。
- 私設経路停止、実行者撤退、深度データ遅延の各縮退経路と利用者への表示。
- 約定価格と見積価格の偏差分布を監視しているか。苦情が来ないため、能動的発見のための信号になる。
第六は最も実施されにくく、最も有用な実装行動だ。取引は成功しているため、専用に見なければ警告は出ない。
第四段階はここで終わる。T19の曲線、T20の交換経路、T21の価格源、T22の清算速度、T23の台帳整合性、そして順序権へ進んだ。これらが示すのは、DeFiの実際のリスクが契約論理だけではなく、外部世界に触れる境界にあることだ。 第五段階ではその境界を一つずつ検査項目にする。
要点
取引の順序自体が売れる資源だ。