Skip to content
On this page

CTF: Selfie チャレンジ ― DVT 資金を奪取する技術

「これは新しい貸付プールだ!DVT トークンのフラッシュローンを提供している。さらに、おしゃれなガバナンス機能まである。一体何が問題になるんだろう?…(心の声略)」

DeFi プロジェクトにフラッシュローンとガバナンス機能が組み合わさると、何が起こるでしょうか? Damn Vulnerable DeFi の Selfie チャレンジは、この興味深く(そして危険でもある)シナリオを深く理解するための絶好の機会です。


チャレンジ目標

あなたの任務は:

  • プール内の すべての DVT トークンを回収
  • 指定された recovery アカウントへ送金

しかし注意:

  • 初期状態では DVT を1枚も持っていない
  • プールには 150万 DVT が存在

脆弱性の根源

■ SelfiePool

  • フラッシュローン機能を提供
  • 手数料 0
  • 任意の量の DVT を一時的に借りられる

ただし:

  • emergencyExitonlyGovernance により制限

■ SimpleGovernance

  • 提案と実行が可能なガバナンス機構
  • queueAction 実行には:

👉 総供給量の過半数以上の投票権が必要

通常は:

  • 大量の DamnValuableVotes トークン保有が必要

攻撃戦略

1. フラッシュローンで DVT を取得

  • プールから 全 DVT を借入
  • 一時的に巨大な残高を持つ

2. コールバック内で操作

onFlashLoan 内で:

■ 投票権の確保

  • delegate を実行
  • 自分に投票権を集中

■ 悪意ある提案

solidity
abi.encodeWithSignature("emergencyExit(address)", recovery);
  • プールから資金を引き出す提案を作成

■ 提案登録

solidity
governance.queueAction(...)

👉 過半数の投票権を一時的に満たしているため成功


■ フラッシュローン返済準備

  • approve により返済可能にする

3. 時間経過を待つ

  • ガバナンスには 遅延(約2日) がある

4. 提案の実行

solidity
governance.executeAction(actionId);

5. 結果

👉 SelfiePool の全 DVT が:

👉 recovery アドレスへ送金


コード構成(MyContract)

■ exploit

solidity
pool.flashLoan(...)

■ onFlashLoan

solidity
token.delegate(address(this));
actionId = governance.queueAction(...);
token.approve(address(pool), amount);

■ execute

solidity
governance.executeAction(actionId);

このチャレンジの本質

🔹 フラッシュローンの悪用

  • 一時的な資産でも影響力を持てる

🔹 ガバナンスの欠陥

  • 「スナップショットなし」の投票設計
  • 一瞬の残高で支配可能

🔹 時間遅延の利用

  • 即時ではなく「遅延実行」
  • 攻撃者に準備時間を与える

まとめ

Selfie チャレンジは以下を融合しています:

  • フラッシュローン
  • ガバナンス
  • 投票権委任
  • 時間遅延

そして示しているのは:

👉 「一時的な資産でも、ガバナンスを乗っ取れる」


DeFi において重要なのは:

「誰がどれだけ持っているか」ではなく、 「いつ持っているか」


準備はいいですか? 次に資金を“救う”のはあなたです。

Built with AiAda