Skip to content

test_create_opcode_initcode()

Documentation for tests/shanghai/eip3860_initcode/test_initcode.py::TestCreateInitcode::test_create_opcode_initcode@83970623.

Generate fixtures for these test cases for Prague with:

fill -v tests/shanghai/eip3860_initcode/test_initcode.py::TestCreateInitcode::test_create_opcode_initcode --fork Prague

Test contract creation via the CREATE/CREATE2 opcodes that have an initcode that is on/over the max allowed limit.

Source code in tests/shanghai/eip3860_initcode/test_initcode.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
@pytest.mark.parametrize(
    "initcode",
    [
        INITCODE_ZEROS_MAX_LIMIT,
        INITCODE_ONES_MAX_LIMIT,
        INITCODE_ZEROS_OVER_LIMIT,
        INITCODE_ONES_OVER_LIMIT,
        EMPTY_INITCODE,
        SINGLE_BYTE_INITCODE,
        INITCODE_ZEROS_32_BYTES,
        INITCODE_ZEROS_33_BYTES,
        INITCODE_ZEROS_49120_BYTES,
        INITCODE_ZEROS_49121_BYTES,
    ],
    ids=get_initcode_name,
)
@pytest.mark.parametrize("opcode", [Op.CREATE, Op.CREATE2], ids=get_create_id)
class TestCreateInitcode:
    """
    Test contract creation via the CREATE/CREATE2 opcodes that have an initcode
    that is on/over the max allowed limit.
    """

    @pytest.fixture
    def create2_salt(self) -> int:
        """Salt value used for CREATE2 contract creation."""
        return 0xDEADBEEF

    @pytest.fixture
    def creator_code(self, opcode: Op, create2_salt: int) -> Bytecode:
        """Generate code for the creator contract which performs the CREATE/CREATE2 operation."""
        return (
            Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
            + Op.GAS
            + opcode(size=Op.CALLDATASIZE, salt=create2_salt)
            + Op.GAS
            # stack: [Gas 2, Call Result, Gas 1]
            + Op.SWAP1
            # stack: [Call Result, Gas 2, Gas 1]
            + Op.SSTORE(0, unchecked=True)
            # stack: [Gas 2, Gas 1]
            + Op.SWAP1
            # stack: [Gas 1, Gas 2]
            + Op.SUB
            # stack: [Gas 1 - Gas 2]
            + Op.SSTORE(1, unchecked=True)
        )

    @pytest.fixture
    def creator_contract_address(self, pre: Alloc, creator_code: Bytecode) -> Address:
        """Return address of creator contract."""
        return pre.deploy_contract(creator_code)

    @pytest.fixture
    def created_contract_address(  # noqa: D103
        self,
        opcode: Op,
        create2_salt: int,
        initcode: Initcode,
        creator_contract_address: Address,
    ) -> Address:
        """Calculate address of the contract created by the creator contract."""
        return compute_create_address(
            address=creator_contract_address,
            nonce=1,
            salt=create2_salt,
            initcode=initcode,
            opcode=opcode,
        )

    @pytest.fixture
    def caller_code(self, creator_contract_address: Address) -> Bytecode:
        """Generate code for the caller contract that calls the creator contract."""
        return Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.SSTORE(
            Op.CALL(5000000, creator_contract_address, 0, 0, Op.CALLDATASIZE, 0, 0), 1
        )

    @pytest.fixture
    def caller_contract_address(self, pre: Alloc, caller_code: Bytecode) -> Address:
        """Return address of the caller contract."""
        return pre.deploy_contract(caller_code)

    @pytest.fixture
    def tx(self, caller_contract_address: Address, initcode: Initcode, sender: EOA) -> Transaction:
        """Generate transaction that executes the caller contract."""
        return Transaction(
            nonce=0,
            to=caller_contract_address,
            data=initcode,
            gas_limit=10000000,
            gas_price=10,
            sender=sender,
        )

    @pytest.fixture
    def contract_creation_gas_cost(self, fork: Fork, opcode: Op) -> int:
        """Calculate gas cost of the contract creation operation."""
        gas_costs = fork.gas_costs()

        create_contract_base_gas = gas_costs.G_CREATE
        gas_opcode_gas = gas_costs.G_BASE
        push_dup_opcode_gas = gas_costs.G_VERY_LOW
        calldatasize_opcode_gas = gas_costs.G_BASE
        contract_creation_gas_usage = (
            create_contract_base_gas
            + gas_opcode_gas
            + (2 * push_dup_opcode_gas)
            + calldatasize_opcode_gas
        )
        if opcode == Op.CREATE2:  # Extra push operation
            contract_creation_gas_usage += push_dup_opcode_gas
        return contract_creation_gas_usage

    @pytest.fixture
    def initcode_word_cost(self, fork: Fork, initcode: Initcode) -> int:
        """Calculate gas cost charged for the initcode length."""
        gas_costs = fork.gas_costs()
        return ceiling_division(len(initcode), 32) * gas_costs.G_INITCODE_WORD

    @pytest.fixture
    def create2_word_cost(self, opcode: Op, fork: Fork, initcode: Initcode) -> int:
        """Calculate gas cost charged for the initcode length."""
        if opcode == Op.CREATE:
            return 0

        gas_costs = fork.gas_costs()
        return ceiling_division(len(initcode), 32) * gas_costs.G_KECCAK_256_WORD

    def test_create_opcode_initcode(
        self,
        state_test: StateTestFiller,
        env: Environment,
        pre: Alloc,
        post: Alloc,
        tx: Transaction,
        initcode: Initcode,
        caller_contract_address: Address,
        creator_contract_address: Address,
        created_contract_address: Address,
        contract_creation_gas_cost: int,
        initcode_word_cost: int,
        create2_word_cost: int,
    ):
        """
        Test contract creation via the CREATE/CREATE2 opcodes that have an
        initcode that is on/over the max allowed limit.
        """
        if len(initcode) > Spec.MAX_INITCODE_SIZE:
            # Call returns 0 as out of gas s[0]==1
            post[caller_contract_address] = Account(
                nonce=1,
                storage={
                    0: 1,
                    1: 0,
                },
            )

            post[created_contract_address] = Account.NONEXISTENT
            post[creator_contract_address] = Account(
                nonce=1,
                storage={
                    0: 0,
                    1: 0,
                },
            )

        else:
            expected_gas_usage = contract_creation_gas_cost
            # The initcode is only executed if the length check succeeds
            expected_gas_usage += initcode.execution_gas
            # The code is only deployed if the length check succeeds
            expected_gas_usage += initcode.deployment_gas

            # CREATE2 hashing cost should only be deducted if the initcode
            # does not exceed the max length
            expected_gas_usage += create2_word_cost

            # Initcode word cost is only deducted if the length check
            # succeeds
            expected_gas_usage += initcode_word_cost

            # Call returns 1 as valid initcode length s[0]==1 && s[1]==1
            post[caller_contract_address] = Account(
                nonce=1,
                storage={
                    0: 0,
                    1: 1,
                },
            )

            post[created_contract_address] = Account(code=initcode.deploy_code)
            post[creator_contract_address] = Account(
                nonce=2,
                storage={
                    0: created_contract_address,
                    1: expected_gas_usage,
                },
            )

        state_test(
            env=env,
            pre=pre,
            post=post,
            tx=tx,
        )

test_create_opcode_initcode(state_test, env, pre, post, tx, initcode, caller_contract_address, creator_contract_address, created_contract_address, contract_creation_gas_cost, initcode_word_cost, create2_word_cost)

Test contract creation via the CREATE/CREATE2 opcodes that have an initcode that is on/over the max allowed limit.

Source code in tests/shanghai/eip3860_initcode/test_initcode.py
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
def test_create_opcode_initcode(
    self,
    state_test: StateTestFiller,
    env: Environment,
    pre: Alloc,
    post: Alloc,
    tx: Transaction,
    initcode: Initcode,
    caller_contract_address: Address,
    creator_contract_address: Address,
    created_contract_address: Address,
    contract_creation_gas_cost: int,
    initcode_word_cost: int,
    create2_word_cost: int,
):
    """
    Test contract creation via the CREATE/CREATE2 opcodes that have an
    initcode that is on/over the max allowed limit.
    """
    if len(initcode) > Spec.MAX_INITCODE_SIZE:
        # Call returns 0 as out of gas s[0]==1
        post[caller_contract_address] = Account(
            nonce=1,
            storage={
                0: 1,
                1: 0,
            },
        )

        post[created_contract_address] = Account.NONEXISTENT
        post[creator_contract_address] = Account(
            nonce=1,
            storage={
                0: 0,
                1: 0,
            },
        )

    else:
        expected_gas_usage = contract_creation_gas_cost
        # The initcode is only executed if the length check succeeds
        expected_gas_usage += initcode.execution_gas
        # The code is only deployed if the length check succeeds
        expected_gas_usage += initcode.deployment_gas

        # CREATE2 hashing cost should only be deducted if the initcode
        # does not exceed the max length
        expected_gas_usage += create2_word_cost

        # Initcode word cost is only deducted if the length check
        # succeeds
        expected_gas_usage += initcode_word_cost

        # Call returns 1 as valid initcode length s[0]==1 && s[1]==1
        post[caller_contract_address] = Account(
            nonce=1,
            storage={
                0: 0,
                1: 1,
            },
        )

        post[created_contract_address] = Account(code=initcode.deploy_code)
        post[creator_contract_address] = Account(
            nonce=2,
            storage={
                0: created_contract_address,
                1: expected_gas_usage,
            },
        )

    state_test(
        env=env,
        pre=pre,
        post=post,
        tx=tx,
    )

Parametrized Test Cases

The interactive table below is also available as a standalone page.

Test ID (Abbreviated) opcode initcode
...fork_Shanghai-blockchain_test-create-max_size_zeros CREATE max_size_zeros
...fork_Shanghai-blockchain_test-create-max_size_ones CREATE max_size_ones
...fork_Shanghai-blockchain_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Shanghai-blockchain_test-create-over_limit_ones CREATE over_limit_ones
...fork_Shanghai-blockchain_test-create-empty CREATE empty
...fork_Shanghai-blockchain_test-create-single_byte CREATE single_byte
...fork_Shanghai-blockchain_test-create-32_bytes CREATE 32_bytes
...fork_Shanghai-blockchain_test-create-33_bytes CREATE 33_bytes
...fork_Shanghai-blockchain_test-create-49120_bytes CREATE 49120_bytes
...fork_Shanghai-blockchain_test-create-49121_bytes CREATE 49121_bytes
...fork_Shanghai-blockchain_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Shanghai-blockchain_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Shanghai-blockchain_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Shanghai-blockchain_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Shanghai-blockchain_test-create2-empty CREATE2 empty
...fork_Shanghai-blockchain_test-create2-single_byte CREATE2 single_byte
...fork_Shanghai-blockchain_test-create2-32_bytes CREATE2 32_bytes
...fork_Shanghai-blockchain_test-create2-33_bytes CREATE2 33_bytes
...fork_Shanghai-blockchain_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Shanghai-blockchain_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Shanghai-state_test-create-max_size_zeros CREATE max_size_zeros
...fork_Shanghai-state_test-create-max_size_ones CREATE max_size_ones
...fork_Shanghai-state_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Shanghai-state_test-create-over_limit_ones CREATE over_limit_ones
...fork_Shanghai-state_test-create-empty CREATE empty
...fork_Shanghai-state_test-create-single_byte CREATE single_byte
...fork_Shanghai-state_test-create-32_bytes CREATE 32_bytes
...fork_Shanghai-state_test-create-33_bytes CREATE 33_bytes
...fork_Shanghai-state_test-create-49120_bytes CREATE 49120_bytes
...fork_Shanghai-state_test-create-49121_bytes CREATE 49121_bytes
...fork_Shanghai-state_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Shanghai-state_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Shanghai-state_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Shanghai-state_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Shanghai-state_test-create2-empty CREATE2 empty
...fork_Shanghai-state_test-create2-single_byte CREATE2 single_byte
...fork_Shanghai-state_test-create2-32_bytes CREATE2 32_bytes
...fork_Shanghai-state_test-create2-33_bytes CREATE2 33_bytes
...fork_Shanghai-state_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Shanghai-state_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Cancun-blockchain_test-create-max_size_zeros CREATE max_size_zeros
...fork_Cancun-blockchain_test-create-max_size_ones CREATE max_size_ones
...fork_Cancun-blockchain_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Cancun-blockchain_test-create-over_limit_ones CREATE over_limit_ones
...fork_Cancun-blockchain_test-create-empty CREATE empty
...fork_Cancun-blockchain_test-create-single_byte CREATE single_byte
...fork_Cancun-blockchain_test-create-32_bytes CREATE 32_bytes
...fork_Cancun-blockchain_test-create-33_bytes CREATE 33_bytes
...fork_Cancun-blockchain_test-create-49120_bytes CREATE 49120_bytes
...fork_Cancun-blockchain_test-create-49121_bytes CREATE 49121_bytes
...fork_Cancun-blockchain_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Cancun-blockchain_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Cancun-blockchain_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Cancun-blockchain_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Cancun-blockchain_test-create2-empty CREATE2 empty
...fork_Cancun-blockchain_test-create2-single_byte CREATE2 single_byte
...fork_Cancun-blockchain_test-create2-32_bytes CREATE2 32_bytes
...fork_Cancun-blockchain_test-create2-33_bytes CREATE2 33_bytes
...fork_Cancun-blockchain_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Cancun-blockchain_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Cancun-state_test-create-max_size_zeros CREATE max_size_zeros
...fork_Cancun-state_test-create-max_size_ones CREATE max_size_ones
...fork_Cancun-state_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Cancun-state_test-create-over_limit_ones CREATE over_limit_ones
...fork_Cancun-state_test-create-empty CREATE empty
...fork_Cancun-state_test-create-single_byte CREATE single_byte
...fork_Cancun-state_test-create-32_bytes CREATE 32_bytes
...fork_Cancun-state_test-create-33_bytes CREATE 33_bytes
...fork_Cancun-state_test-create-49120_bytes CREATE 49120_bytes
...fork_Cancun-state_test-create-49121_bytes CREATE 49121_bytes
...fork_Cancun-state_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Cancun-state_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Cancun-state_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Cancun-state_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Cancun-state_test-create2-empty CREATE2 empty
...fork_Cancun-state_test-create2-single_byte CREATE2 single_byte
...fork_Cancun-state_test-create2-32_bytes CREATE2 32_bytes
...fork_Cancun-state_test-create2-33_bytes CREATE2 33_bytes
...fork_Cancun-state_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Cancun-state_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Prague-blockchain_test-create-max_size_zeros CREATE max_size_zeros
...fork_Prague-blockchain_test-create-max_size_ones CREATE max_size_ones
...fork_Prague-blockchain_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Prague-blockchain_test-create-over_limit_ones CREATE over_limit_ones
...fork_Prague-blockchain_test-create-empty CREATE empty
...fork_Prague-blockchain_test-create-single_byte CREATE single_byte
...fork_Prague-blockchain_test-create-32_bytes CREATE 32_bytes
...fork_Prague-blockchain_test-create-33_bytes CREATE 33_bytes
...fork_Prague-blockchain_test-create-49120_bytes CREATE 49120_bytes
...fork_Prague-blockchain_test-create-49121_bytes CREATE 49121_bytes
...fork_Prague-blockchain_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Prague-blockchain_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Prague-blockchain_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Prague-blockchain_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Prague-blockchain_test-create2-empty CREATE2 empty
...fork_Prague-blockchain_test-create2-single_byte CREATE2 single_byte
...fork_Prague-blockchain_test-create2-32_bytes CREATE2 32_bytes
...fork_Prague-blockchain_test-create2-33_bytes CREATE2 33_bytes
...fork_Prague-blockchain_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Prague-blockchain_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Prague-state_test-create-max_size_zeros CREATE max_size_zeros
...fork_Prague-state_test-create-max_size_ones CREATE max_size_ones
...fork_Prague-state_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Prague-state_test-create-over_limit_ones CREATE over_limit_ones
...fork_Prague-state_test-create-empty CREATE empty
...fork_Prague-state_test-create-single_byte CREATE single_byte
...fork_Prague-state_test-create-32_bytes CREATE 32_bytes
...fork_Prague-state_test-create-33_bytes CREATE 33_bytes
...fork_Prague-state_test-create-49120_bytes CREATE 49120_bytes
...fork_Prague-state_test-create-49121_bytes CREATE 49121_bytes
...fork_Prague-state_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Prague-state_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Prague-state_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Prague-state_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Prague-state_test-create2-empty CREATE2 empty
...fork_Prague-state_test-create2-single_byte CREATE2 single_byte
...fork_Prague-state_test-create2-32_bytes CREATE2 32_bytes
...fork_Prague-state_test-create2-33_bytes CREATE2 33_bytes
...fork_Prague-state_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Prague-state_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Osaka-blockchain_test-create-max_size_zeros CREATE max_size_zeros
...fork_Osaka-blockchain_test-create-max_size_ones CREATE max_size_ones
...fork_Osaka-blockchain_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Osaka-blockchain_test-create-over_limit_ones CREATE over_limit_ones
...fork_Osaka-blockchain_test-create-empty CREATE empty
...fork_Osaka-blockchain_test-create-single_byte CREATE single_byte
...fork_Osaka-blockchain_test-create-32_bytes CREATE 32_bytes
...fork_Osaka-blockchain_test-create-33_bytes CREATE 33_bytes
...fork_Osaka-blockchain_test-create-49120_bytes CREATE 49120_bytes
...fork_Osaka-blockchain_test-create-49121_bytes CREATE 49121_bytes
...fork_Osaka-blockchain_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Osaka-blockchain_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Osaka-blockchain_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Osaka-blockchain_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Osaka-blockchain_test-create2-empty CREATE2 empty
...fork_Osaka-blockchain_test-create2-single_byte CREATE2 single_byte
...fork_Osaka-blockchain_test-create2-32_bytes CREATE2 32_bytes
...fork_Osaka-blockchain_test-create2-33_bytes CREATE2 33_bytes
...fork_Osaka-blockchain_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Osaka-blockchain_test-create2-49121_bytes CREATE2 49121_bytes
...fork_Osaka-state_test-create-max_size_zeros CREATE max_size_zeros
...fork_Osaka-state_test-create-max_size_ones CREATE max_size_ones
...fork_Osaka-state_test-create-over_limit_zeros CREATE over_limit_zeros
...fork_Osaka-state_test-create-over_limit_ones CREATE over_limit_ones
...fork_Osaka-state_test-create-empty CREATE empty
...fork_Osaka-state_test-create-single_byte CREATE single_byte
...fork_Osaka-state_test-create-32_bytes CREATE 32_bytes
...fork_Osaka-state_test-create-33_bytes CREATE 33_bytes
...fork_Osaka-state_test-create-49120_bytes CREATE 49120_bytes
...fork_Osaka-state_test-create-49121_bytes CREATE 49121_bytes
...fork_Osaka-state_test-create2-max_size_zeros CREATE2 max_size_zeros
...fork_Osaka-state_test-create2-max_size_ones CREATE2 max_size_ones
...fork_Osaka-state_test-create2-over_limit_zeros CREATE2 over_limit_zeros
...fork_Osaka-state_test-create2-over_limit_ones CREATE2 over_limit_ones
...fork_Osaka-state_test-create2-empty CREATE2 empty
...fork_Osaka-state_test-create2-single_byte CREATE2 single_byte
...fork_Osaka-state_test-create2-32_bytes CREATE2 32_bytes
...fork_Osaka-state_test-create2-33_bytes CREATE2 33_bytes
...fork_Osaka-state_test-create2-49120_bytes CREATE2 49120_bytes
...fork_Osaka-state_test-create2-49121_bytes CREATE2 49121_bytes