DAOの資金をガバナンス攻撃から守る|投票力の確定・タイムロック・支出権限
約14分で読めます
約14分
目次(タップで折りたたみ)
2022年4月、DeFiプロトコルのBeanstalkで、ガバナンスを使った攻撃が起きました。攻撃者はフラッシュローン(同じ取引の中で借りて返す、担保のいらない借入)で、一時的に大きな投票力を手に入れます。その投票力で悪意ある提案を通して実行し、BEAN以外の資産約7,700万米ドルが失われました(Beanstalk公式「Governance Exploit」)。
提案は、ルールどおりに定足数を満たして可決されています。つまり、定足数を満たしたという事実だけでは、決定が正当だとも、安全だとも言えないのです。
もうひとつ見落とされやすい点があります。投票で可決されても、実際に資金やコントラクトを動かすのは、タイムロックやSafeといった別の仕組みです。資金や権限も、そちらの側に置かれます。そのため、投票の設定だけを整えても、実行する側に抜け道が残っていれば守れません。
では、DAOを安全に動かすには何を決めればよいか。短く言えば3つです。投票力をいつの時点で確定させるか。何を提案できるようにするか。どこまで支出を任せるか。そのうえで、可決した提案が実際に何を実行するのかを、投票の前に確かめられる形にします。以下では、DAOや財団の運営責任者がこれを決めていく順に見ていきます。
この記事でわかること
- 誰がどこまで資金を動かせるかの洗い出し方と、提案から実行までの流れ
- 投票のやり方の選び方、待機時間と緊急停止の決め方、資金の分け方
- 本番前に試す攻撃、見るべき指標、規模ごとの始め方と受け入れチェック
この記事で使う言葉
- Governor:オンチェーン投票を行うコントラクトの部品
- タイムロック:可決した内容を、決めた待ち時間が過ぎてから実行する仕組み
- Safe:複数人の署名で動かす金庫(マルチシグ)
- モジュール:Safeに後から足して機能を加える部品(支出の上限や役割ごとの権限など)
- フォーク環境:本番のチェーンの状態を写した試験用の環境
誰が、どの資金やコントラクトを、どこまで動かせるかを一覧にする
OpenZeppelin Contracts 5.xでタイムロックを組み込むと、提案を実行するのは外部のTimelockControllerになります。管理する資産と権限も、タイムロックの側に置く設計です(OpenZeppelin「How to set up on-chain governance」)。つまり、ガバナンスの画面で提案が可決されても、実際に資金やコントラクトを動かすのは別の仕組みです。
ですから、Governorの設定だけを監査しても足りません。Safeの所有者、タイムロックの役割(ロール)、アップグレードの管理者、ブリッジの管理者のどこかに抜け道があれば、守りは完成しません。
そこでまず、「誰が、どの資金やコントラクトを、どこまで動かせるか」の一覧表を作ります。表には次の項目を並べます。
- 対象のチェーンと、資産またはコントラクト
- 今の所有者・管理者、ふだんの経路と緊急時の経路
- 1回あたり・期間あたりに失いうる上限と、この仕組みを変えられる人
とくに、「守りの仕組みそのものを変える権限」を別に書き出します。支出の上限を決めていても、同じ2-of-3のSafeがその上限を外せるなら、実際に動かせる額は全残高です。
対象ごとに、ふだん動かす人と、守られているべき約束をまとめると次のようになります。
| 対象 | ふだん動かす人 | 守られているべき約束 |
|---|---|---|
| 運営費用の金庫(vault) | 運営担当の役割 | 自由に送金したり、任意の処理を実行させたりできない |
| 長期の資金(treasury) | Governor→タイムロック | 緊急停止の権限を持つ人が、自分へ送金できない |
| プロトコルのアップグレード | タイムロック | 別の管理者が、すぐにアップグレードできない |
| オラクル・リスクの設定値 | 限られた役割か、ガバナンス | 一度に清算の条件を反転できない |
| ブリッジ・チェーン間の実行コントラクト | 各チェーンの受け取り側のコントラクト | 片側が止まったとき、二重に実行しない |
それぞれにかける制約と、緊急時の権限は、後半の「実装する人向けの詳細」の表にまとめています。
提案から実行まで、どう進め、何を確かめるか
人が読む説明と、実際に実行されるデータが違う提案は、画面を見るだけでは防げません。ですから、提案は文書だけでは足りず、実行する取引と1対1で対応させます。そのうえで、提案をシミュレーションした結果と、実行するデータを読み解いた結果を、レビューの対象にします。提案ごとに残す記録の一覧は後半にまとめています。
提案は次の6段階で進みます。
- 起案(Draft):何を実行し、状態がどう変わるはずかと、失敗したときの戻し方を書く。
- 提案(Proposed):提案に必要な投票力の下限、提案した人、投票力を数える時点(スナップショット)を決める。
- 投票中(Active):過去の時点の投票力で数える。後から残高を移して、同じ投票力を二重に使えないようにする。
- 可決(Succeeded):定足数と賛成の条件を、別々に判定する。棄権票を定足数に入れるかも、仕様として決める。
- 待機登録(Queued):同じ呼出先・送金額・実行データをタイムロックに登録し、待ち時間が終わるまで変えられないようにする。
- 実行済み(Executed):取引の結果と、対象の状態の変化を突き合わせる。取引が成功しただけでは、目的を果たしたとは見なさない。
フラッシュローンで借りた投票力は、借りたその取引の中でしか持っていられません。投票力を過去の時点で数えれば、その分は数に入らないことになります。3の段階は、冒頭のような攻撃を防ぐためのものです。
OpenZeppelinのTimelockControllerは、操作を「待機中・実行可・完了」で管理し、提案する人、実行する人、取り消す人、管理者の役割を分けています。管理者の権限は、設定が済んだらタイムロック自身だけに絞る構成が示されています。提案する人や取り消す人を後から足すと、承認済みの操作が取り消されたり、決まりを迂回されたりしうる、という警告もあります(OpenZeppelin Governance API)。役割の設定は、デプロイしたときだけでなく、定期的にチェーンから読み直します。
投票のやり方は、「誰の意思か」と「いつ確定するか」で選ぶ
Snapshotなどのチェーンの外での投票は、手数料(ガス)の負担が軽く、方向性の確認や署名者への指示に向きます。ただし、投票の結果とSafeでの実行のあいだに、人の裁量が残ります。
オンチェーン投票なら、可決の条件と実行を、チェーンの上で直接つなげられます。ただし、悪意ある実行データも、ルールどおりに実行されてしまいます。参加を自動にすることと、安全であることは同じではありません。
このように、どのやり方にも得手不得手があり、万能なものはありません。要点は次のとおりです。
| 方式 | 向く用途 | 主な失敗 |
|---|---|---|
| チェーンの外での投票+マルチシグ | 方針の確認、初期のDAO | 結果と実行の食い違い、署名者が動けない |
| オンチェーンのGovernor | 決まった形のプロトコル変更 | 投票力の集中、悪意ある提案 |
| 役割(ロール)への委任 | 定期的な支払い、リスク管理の操作 | 権限の積み上がり、許可した送り先の悪用 |
それぞれを補う手当ては、次のとおりです。
- チェーンの外での投票+マルチシグ:実行する取引を事前に示す。実行までにかかる時間を約束する。食い違いがあれば公表する。
- オンチェーンのGovernor:スナップショット、提案の下限、シミュレーション、タイムロック。
- 役割への委任:許可リスト、金額・回数の上限、期限、権限の取り消し。
投票の委任(delegation)は参加率を上げます。ただし、代理人への永久の白紙委任にはしません。委任先、期間、対象の提案の範囲、さらに委任できるか、解除がいつ反映されるかをはっきりさせます。実際に使われた投票力が、どれだけ集中しているかも追います。
待機時間は、監視して止めるまでにかかる時間から逆算する
タイムロックの待ち時間は、おかしな提案を見つけて止めるための時間です。監視の担当が提案を読み解いてシミュレーションし、関係者に知らせ、利用者が抜けるか、提案を取り消せるようになるまでの時間が要ります。ですから長さは、一律に「48時間」とはせず、この時間から決めます。
誰も見ていない7日間より、24時間の監視と自動のシミュレーションが付いた短い待機のほうが効く場合があります。待機時間は操作の種類ごとに分けます。待機時間を短くする提案そのものには、いちばん長い待機を当てます。
緊急停止の権限を持つ人(guardian)は、DAOでは特に、「投票の結果を上書きできる裏口」にならないようにします。できることは、安全な方向の操作に絞ります。提案の取り消し、モジュールの停止、支出の上限を下げること、特定の操作の一時停止などです。停止の解除、資金の回収、コントラクトの入れ替えは、別の人数の承認とタイムロックを通します。
操作の種類ごとの待機時間の決め方、緊急権限の絞り方、署名者の独立性と交代・失効の訓練は、マルチシグ・タイムロックの本番権限設計で詳しく扱います。
資金を、日常の運用・予算・準備の資産に分ける
全資産を1つのSafeに置き、すべての支払いに同じ人数の署名を求めたとします。すると、少額の支払いが滞るか、署名者が中身を読まずに承認するようになります。
そこで資産を、置き場所か方針の上で分けます。日常の運用は、送り先・トークン・期間の上限の範囲で任せます。大口や、いつもと違う移動は、ガバナンスに戻します。
SafeのSpending Limitsは、受け取る人と、期間あたりのトークンの額を制限できます。Zodiac Roles Modifierの許容量(allowance)は、呼び出すデータの中の数値、送るETHの額、関数を呼ぶ回数に上限を付けられます(Zodiac Roles Modifier「Allowances」)。
ただし、次のものを別に制限しないと、表向きの送金の上限をすり抜けられます。
- モジュールを有効にしたり入れ替えたりできる、所有者の権限
- 任意の呼び出しや、任意の処理を代わりに実行させる呼び出し
- トークンの使用の承認と、DEX(分散型取引所)での価格の許容幅
予算の記録には、次のものを持たせます。予算のID、期間、資産、上限、許可した送り先か関数、執行する役割、承認した提案、使った額、支払い予定として押さえた額です。残高だけでなく、承認済みでまだ送っていない分を差し引いた、使える額を出します。
値動きのある資産の上限を円やドルに換算して管理するなら、次の扱いも決めます。価格を届けるオラクルが止まったり急に動いたりしたとき、どうするか。想定と実際の価格の差(スリッページ)を、どこまで許すかです。
本番の前に、攻撃を試して守りが効くか確かめる
冒頭のBeanstalkのような攻撃が通らないかを、本番の前にフォーク環境で試します。少なくとも次の5つです。
- 同じブロックか短い期間で手に入れた投票力で、提案の作成・投票・実行まで行けてしまわないか。
- 悪意ある呼出先、プロキシ(中身を差し替えられるコントラクト)のアップグレード、トークンの使用の承認、モジュールの追加を提案に入れたとき、監視と待機で見つけられるか。
- 提案する人、取り消す人、実行する人、Safeの所有者のどれか1つが乗っ取られたとき、最大でいくら失うか。
- 緊急停止の後、攻撃者だけで再開できてしまわないか。正規の復旧にかかる時間は許せる長さか。
- チェーン間のメッセージの重複、順番の入れ替わり、片側の停止で、同じ提案が二重に実行されないか。
何を測れば、守りが効いていると分かるか
投票の参加率だけでは、見えないものがあります。少数の委任先への集中、署名者の裁量、タイムロックの監視が形だけになっていることです。月ごとか四半期ごとに、次を記録します。
- 上位の委任先が持つ投票力の割合
- 役割ごとに動かせる最大の額
- タイムロック中の警告に対応するまでの時間
あわせて、次も記録します。
- 提案の作成から実行までの時間の中央値、期限切れ・取り消しの割合
- シミュレーションの成功率、予算超過で断った件数
- 使われていない所有者とモジュール
守りの仕組みを変えるときは、2人でレビューし、変更の差を残します。チェーン上の設定は、期待する値のファイルと続けて突き合わせます。文書の署名者一覧ではなく、実際の値をチェーンから取ります。所有者、必要な署名の人数、役割、許容量、プロキシの管理者、実行されるコードです。食い違いを見つけたら、自動で直す前に、新旧の取引と正当な提案を突き合わせます。
規模ごとに、どこから始めるか
最初の構成は、最大でいくら失うかと、操作の頻度で決めます。規模ごとの目安は次のとおりです。
| 規模 | 始める構成 |
|---|---|
| 小規模・初期 | チェーンの外での投票、独立したメンバーのマルチシグ、取引内容の公開、運営費の上限 |
| 中規模 | 日常の支出を役割と許容量に切り出し、長期の資産とアップグレードをGovernor+タイムロックへ移す |
| 大規模・複数チェーン | 操作の種類ごとのタイムロック、チェーン間の実行コントラクト、常時の監視、フォーク環境でのシミュレーション、緊急時の訓練 |
小規模で始める場合も、「後で分散化する」条件を先に決めておきます。残高、参加者の数、プロトコルが預かる資産などを、移る目安にします。
使わないほうがよい構成も、はっきりさせます。すばやい判断が毎日必要なのに投票する人が少ない段階では、すべての操作をオンチェーン投票にすると運用が止まります。逆に、全残高を失いかねないアップグレードや任意の呼び出しを、速さだけを理由に1人の署名者に任せるのも向きません。投票のやり方ではなく、操作の頻度、元に戻せるか、最大の損失、見つけるまでの時間で、通り道を選びます。
実装の前に確かめる10のこと
- すべての資産、コントラクト、チェーンについて、所有者・管理者と抜け道を洗い出した。
- 提案の説明、実行データ、シミュレーション、実行後の状態の変化を、同じIDで追える。
- 投票力のスナップショット、提案の下限、定足数、賛成の条件を、ぎりぎりの値で確かめた。
- 操作の種類ごとのタイムロックの長さを、監視・対応の時間から説明できる。
- 日常の支出に、送り先、資産、関数、金額・回数・期間の上限がある。
- 守りの仕組みを変える権限も含めて、役割ごとの最大の損失を計算した。
- 緊急停止の権限は安全な方向の操作に限られ、解除の通り道が分かれている。
- 署名者の端末、組織、復旧の手段が互いに独立していて、交代・失効の訓練をした。
- フラッシュローン、悪意あるアップグレード、モジュールの追加、チェーン間の重複を、フォーク環境で試した。
- チェーン上の実際の値を期待値と続けて突き合わせ、異常のときの連絡・停止・復旧の対応時間を決めている。
DAOを作る工程の全体はDAOの作り方とビジネスモデル設計、工程と費用の目安はDAOプロジェクト開発の工程一覧と費用目安、日本で法人を併用するときの運用の論点はDAO合同会社の設立・運営ガイドで補足しています。プロトコルそのもののアップグレード方式を決めるならスマートコントラクトのアップグレード設計、外部のプロトコルのガバナンス変更を監視する側の設計はDeFiガバナンス変更の監視と影響分析をご覧ください。
実装する人向けの詳細
ここからは、スマートコントラクトの設計者向けの詳しい話です。
権限と資産の一覧(全体)
| 対象 | 通常の実行者 | 制約 | 緊急権限 | 確認する不変条件 |
|---|---|---|---|---|
| 運営費用の金庫(vault) | 運営担当ロール | 許可先・トークン・期間上限 | 緊急停止権限者(guardian)が停止 | 任意送金やdelegatecallができない |
| 長期の資金(treasury) | Governor→タイムロック | 長い待機、提案単位の上限 | 取消のみ | 緊急停止権限者は自分へ送金できない |
| プロトコルのアップグレード | タイムロック | バイトコードの検証、長い待機 | 一時停止、切り戻し手順 | 別の管理者が即時アップグレードできない |
| オラクル・リスク設定値 | 限定ロールまたはガバナンス | 変更幅・頻度の上限 | 安全側へ限定変更 | 一度に清算条件を反転できない |
| ブリッジ・チェーン間の実行コントラクト | 各チェーンの受信コントラクト | 送信元・チェーン・メッセージの検証 | 経路(レーン)ごとの停止 | 片側停止時に二重実行しない |
delegatecallは、別のコントラクトのコードを、呼び出し元の権限と資産のまま実行させる呼び出しです。前半で「任意の処理を代わりに実行させる呼び出し」と書いたものに当たります。
提案ごとに残す記録
proposal_id、説明文のハッシュ- 呼出先(target)、送金額(value)、calldata(実行する呼出データ)、チェーンID
- 投票力を確定する時点(スナップショット)、投票期間、定足数(quorum)
- キュー登録時刻、実行可能時刻、実行トランザクションのハッシュ
投票方式ごとの実行との接続
| 方式 | 適する用途 | 実行との接続 | 主な失敗 | 補う統制 |
|---|---|---|---|---|
| オフチェーン投票+マルチシグ | 方針確認、初期のDAO | 署名者が別途実行 | 結果と実行の不一致、署名者の停止 | トランザクションハッシュの事前提示、実行までの対応時間の約束、差異の開示 |
| オンチェーンのGovernor | 定型的なプロトコル変更 | 可決後に自動で待機登録 | 投票力の集中、悪意ある提案 | スナップショット、提案の下限、シミュレーション、タイムロック |
| ロールへの委任 | 定常支払、リスク管理の操作 | 方針の範囲内で即時実行 | 権限の積み上がり、許可先の悪用 | 許可リスト、金額・回数上限、期限、権限の取消 |
XTELAができること
私たちは、DAOの権限・資産統制マップを作り、提案から実行後の照合までの流れ、Governorとタイムロック、Safeとモジュール、予算の許容量、監視とシミュレーションを設計・実装します。フラッシュローンや悪意ある提案をフォーク環境で再現するPoC(概念実証)から始め、貴社のDAOの規模に合った構成に仕上げます。法的な判断は弁護士と連携して進めます。ご相談はお問い合わせからどうぞ。
主要参考資料
- OpenZeppelin「How to set up on-chain governance」(2026年8月12日確認)
- OpenZeppelin Contracts 5.x Governance API(2026年8月12日確認)
- Zodiac Roles Modifier「Allowances」(2026年9月24日確認)
- Safe「Set up and use Spending Limits」(2026年8月12日確認)
- Beanstalk「Governance Exploit」
資料の確認日と注意
仕様と資料は2026年8月12日に確認しました。Zodiac Rolesの記述は、2026年9月24日に確認し直しています。内容は一般的な技術・運用設計の解説です。プロトコルの仕様、組織の形、適用される法令は変わりえます。法人の責任、契約、会計、税務、金融規制の個別の判断は、実装の時点の一次資料をもとに専門家へご確認ください。