Skip to content

Commit

Permalink
new(tests): EIP-7702: More delegation clearing tests (#983)
Browse files Browse the repository at this point in the history
* new(tests): EIP-7702: More delegation clearing tests

* add post check

* new(tests): EIP-7702: Max call depth for delegated accounts
  • Loading branch information
marioevz authored Dec 2, 2024
1 parent 5cf1f24 commit 1ea34d8
Showing 1 changed file with 181 additions and 0 deletions.
181 changes: 181 additions & 0 deletions tests/prague/eip7702_set_code_tx/test_set_code_txs.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,54 @@ def test_set_code_to_self_caller(
)


@pytest.mark.execute(pytest.mark.skip(reason="excessive gas"))
def test_set_code_max_depth_call_stack(
state_test: StateTestFiller,
pre: Alloc,
):
"""
Test re-entry to delegated account until the max call stack depth is reached.
"""
storage = Storage()
auth_signer = pre.fund_eoa(auth_account_start_balance)
set_code = Conditional(
condition=Op.ISZERO(Op.TLOAD(0)),
if_true=Op.TSTORE(0, 1)
+ Op.CALL(address=auth_signer)
+ Op.SSTORE(storage.store_next(1025), Op.TLOAD(0)),
if_false=Op.TSTORE(0, Op.ADD(1, Op.TLOAD(0))) + Op.CALL(address=auth_signer),
)
set_code_to_address = pre.deploy_contract(set_code)

tx = Transaction(
gas_limit=100_000_000_000_000,
to=auth_signer,
authorization_list=[
AuthorizationTuple(
address=set_code_to_address,
nonce=0,
signer=auth_signer,
),
],
sender=pre.fund_eoa(),
)

state_test(
env=Environment(),
pre=pre,
tx=tx,
post={
set_code_to_address: Account(storage={}),
auth_signer: Account(
nonce=1,
code=Spec.delegation_designation(set_code_to_address),
storage=storage,
balance=auth_account_start_balance,
),
},
)


@pytest.mark.with_all_call_opcodes
@pytest.mark.parametrize(
"value",
Expand Down Expand Up @@ -3164,6 +3212,139 @@ def test_delegation_clearing(
)


@pytest.mark.parametrize(
"self_sponsored",
[
pytest.param(False, id="not_self_sponsored"),
pytest.param(True, id="self_sponsored"),
],
)
@pytest.mark.parametrize(
"pre_set_delegation_code",
[
pytest.param(Op.RETURN(0, 1), id="delegated_account"),
pytest.param(None, id="undelegated_account"),
],
)
def test_delegation_clearing_tx_to(
state_test: StateTestFiller,
pre: Alloc,
pre_set_delegation_code: Bytecode | None,
self_sponsored: bool,
):
"""
Tests directly calling the account which delegation is being cleared.
Args:
pre_set_delegation_code: The code to set on the account before clearing delegation, or None
if the account should not have any code set.
self_sponsored: Whether the delegation clearing transaction is self-sponsored.
""" # noqa: D417
pre_set_delegation_address: Address | None = None
if pre_set_delegation_code is not None:
pre_set_delegation_address = pre.deploy_contract(pre_set_delegation_code)

if self_sponsored:
auth_signer = pre.fund_eoa(delegation=pre_set_delegation_address)
else:
auth_signer = pre.fund_eoa(0, delegation=pre_set_delegation_address)

sender = pre.fund_eoa() if not self_sponsored else auth_signer

tx = Transaction(
gas_limit=200_000,
to=auth_signer,
value=0,
authorization_list=[
AuthorizationTuple(
address=Spec.RESET_DELEGATION_ADDRESS, # Reset
nonce=auth_signer.nonce + (1 if self_sponsored else 0),
signer=auth_signer,
),
],
sender=sender,
)

state_test(
env=Environment(),
pre=pre,
tx=tx,
post={
auth_signer: Account(
nonce=auth_signer.nonce + 1,
code=b"",
storage={},
),
},
)


@pytest.mark.parametrize(
"pre_set_delegation_code",
[
pytest.param(Op.RETURN(0, 1), id="delegated_account"),
pytest.param(None, id="undelegated_account"),
],
)
def test_delegation_clearing_and_set(
state_test: StateTestFiller,
pre: Alloc,
pre_set_delegation_code: Bytecode | None,
):
"""
Tests clearing and setting the delegation again in the same authorization list.
Args:
pre_set_delegation_code: The code to set on the account before clearing delegation, or None
if the account should not have any code set.
""" # noqa: D417
pre_set_delegation_address: Address | None = None
if pre_set_delegation_code is not None:
pre_set_delegation_address = pre.deploy_contract(pre_set_delegation_code)

auth_signer = pre.fund_eoa(0, delegation=pre_set_delegation_address)

reset_code_address = pre.deploy_contract(
Op.CALL(address=Spec.RESET_DELEGATION_ADDRESS) + Op.SSTORE(0, 1) + Op.STOP
)

sender = pre.fund_eoa()

tx = Transaction(
gas_limit=200_000,
to=auth_signer,
value=0,
authorization_list=[
AuthorizationTuple(
address=Spec.RESET_DELEGATION_ADDRESS, # Reset
nonce=auth_signer.nonce,
signer=auth_signer,
),
AuthorizationTuple(
address=reset_code_address,
nonce=auth_signer.nonce + 1,
signer=auth_signer,
),
],
sender=sender,
)

state_test(
env=Environment(),
pre=pre,
tx=tx,
post={
auth_signer: Account(
nonce=auth_signer.nonce + 2,
code=Spec.delegation_designation(reset_code_address),
storage={
0: 1,
},
),
},
)


@pytest.mark.parametrize(
"entry_code",
[
Expand Down

0 comments on commit 1ea34d8

Please sign in to comment.