@pytest.mark.parametrize("target_account_type", TargetAccountType)
@pytest.mark.parametrize("delegate", [True, False])
@pytest.mark.parametrize("sender_delegated", [True, False])
@pytest.mark.parametrize("call_from_initcode", [True, False])
def test_delegate_call_targets(
state_test: StateTestFiller,
pre: Alloc,
target_account_type: TargetAccountType,
target_address: Address,
delegate: bool,
sender_delegated: bool,
call_from_initcode: bool,
) -> None:
"""
Test contracts doing delegatecall to various targets resolved via 7702
delegation.
"""
env = Environment()
if delegate:
target_address = pre.fund_eoa(0, delegation=target_address)
if sender_delegated:
sender_delegation_target = pre.deploy_contract(Op.STOP)
sender_address = pre.fund_eoa(delegation=sender_delegation_target)
else:
sender_address = pre.fund_eoa()
delegate_call_code = Op.SSTORE(
slot_call_result, Op.DELEGATECALL(address=target_address)
) + Op.SSTORE(slot_code_worked, value_code_worked)
if call_from_initcode:
# Call from initcode
caller_contract = delegate_call_code + Op.RETURN(0, 0)
tx = Transaction(
sender=sender_address,
to=None,
data=caller_contract,
gas_limit=4_000_000,
)
calling_contract_address = tx.created_contract
else:
# Normal call from existing contract
caller_contract = delegate_call_code + Op.STOP
calling_contract_address = pre.deploy_contract(caller_contract)
tx = Transaction(
sender=sender_address,
to=calling_contract_address,
gas_limit=4_000_000,
)
calling_storage = {
slot_code_worked: value_code_worked,
slot_call_result: LEGACY_CALL_FAILURE
if target_account_type
in [
TargetAccountType.LEGACY_CONTRACT_INVALID,
TargetAccountType.LEGACY_CONTRACT_REVERT,
]
else LEGACY_CALL_SUCCESS,
}
post = {
calling_contract_address: Account(storage=calling_storage),
}
state_test(
env=env,
pre=pre,
post=post,
tx=tx,
)