Skip to content

Test Recreate

Documentation for tests/constantinople/eip1014_create2/test_recreate.py.

Generate fixtures for these test cases with:

fill -v tests/constantinople/eip1014_create2/test_recreate.py

Test Account Self-destruction and Re-creation

test_recreate(blockchain_test, pre, fork, recreate_on_separate_block)

Test that the storage is cleared when a contract is first destructed then re-created using CREATE2.

Source code in tests/constantinople/eip1014_create2/test_recreate.py
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
@pytest.mark.parametrize("recreate_on_separate_block", [True, False])
@pytest.mark.valid_from("Constantinople")
@pytest.mark.valid_until("Shanghai")
def test_recreate(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: Fork,
    recreate_on_separate_block: bool,
):
    """
    Test that the storage is cleared when a contract is first destructed then re-created using
    CREATE2.
    """
    env = Environment()

    creator_contract_code = Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.CREATE2(
        0, 0, Op.CALLDATASIZE, 0
    )
    creator_address = pre.deploy_contract(creator_contract_code)
    sender = pre.fund_eoa()

    deploy_code = Yul(
        """
        {
            switch callvalue()
            case 0 {
                selfdestruct(0)
            }
            default {
                sstore(0, callvalue())
            }
        }
        """,
        fork=fork,
    )

    initcode = Initcode(deploy_code=deploy_code)

    create_tx = Transaction(
        gas_limit=100000000,
        to=creator_address,
        data=initcode,
        sender=sender,
    )

    created_contract_address = compute_create2_address(
        address=creator_address, salt=0, initcode=initcode
    )

    set_storage_tx = Transaction(
        gas_limit=100000000,
        to=created_contract_address,
        value=1,
        sender=sender,
    )

    blocks = [Block(txs=[create_tx, set_storage_tx])]

    destruct_tx = Transaction(
        gas_limit=100000000,
        to=created_contract_address,
        value=0,
        sender=sender,
    )

    balance = 1
    send_funds_tx = Transaction(
        gas_limit=100000000,
        to=created_contract_address,
        value=balance,
        sender=sender,
    )

    re_create_tx = Transaction(
        gas_limit=100000000,
        to=creator_address,
        data=initcode,
        sender=sender,
    )

    if recreate_on_separate_block:
        blocks.append(Block(txs=[destruct_tx, send_funds_tx]))
        blocks.append(Block(txs=[re_create_tx]))
    else:
        blocks.append(Block(txs=[destruct_tx, send_funds_tx, re_create_tx]))

    post = {
        created_contract_address: Account(
            nonce=1,
            balance=balance,
            code=deploy_code,
            storage={},
        ),
    }

    blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=blocks)