Skip to content

Commit 10bf57e

Browse files
authored
new(tests): EIP-7702: More delegation clearing tests (ethereum#983)
* new(tests): EIP-7702: More delegation clearing tests * add post check * new(tests): EIP-7702: Max call depth for delegated accounts
1 parent d4b8661 commit 10bf57e

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

prague/eip7702_set_code_tx/test_set_code_txs.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,54 @@ def test_set_code_to_self_caller(
686686
)
687687

688688

689+
@pytest.mark.execute(pytest.mark.skip(reason="excessive gas"))
690+
def test_set_code_max_depth_call_stack(
691+
state_test: StateTestFiller,
692+
pre: Alloc,
693+
):
694+
"""
695+
Test re-entry to delegated account until the max call stack depth is reached.
696+
"""
697+
storage = Storage()
698+
auth_signer = pre.fund_eoa(auth_account_start_balance)
699+
set_code = Conditional(
700+
condition=Op.ISZERO(Op.TLOAD(0)),
701+
if_true=Op.TSTORE(0, 1)
702+
+ Op.CALL(address=auth_signer)
703+
+ Op.SSTORE(storage.store_next(1025), Op.TLOAD(0)),
704+
if_false=Op.TSTORE(0, Op.ADD(1, Op.TLOAD(0))) + Op.CALL(address=auth_signer),
705+
)
706+
set_code_to_address = pre.deploy_contract(set_code)
707+
708+
tx = Transaction(
709+
gas_limit=100_000_000_000_000,
710+
to=auth_signer,
711+
authorization_list=[
712+
AuthorizationTuple(
713+
address=set_code_to_address,
714+
nonce=0,
715+
signer=auth_signer,
716+
),
717+
],
718+
sender=pre.fund_eoa(),
719+
)
720+
721+
state_test(
722+
env=Environment(),
723+
pre=pre,
724+
tx=tx,
725+
post={
726+
set_code_to_address: Account(storage={}),
727+
auth_signer: Account(
728+
nonce=1,
729+
code=Spec.delegation_designation(set_code_to_address),
730+
storage=storage,
731+
balance=auth_account_start_balance,
732+
),
733+
},
734+
)
735+
736+
689737
@pytest.mark.with_all_call_opcodes
690738
@pytest.mark.parametrize(
691739
"value",
@@ -3164,6 +3212,139 @@ def test_delegation_clearing(
31643212
)
31653213

31663214

3215+
@pytest.mark.parametrize(
3216+
"self_sponsored",
3217+
[
3218+
pytest.param(False, id="not_self_sponsored"),
3219+
pytest.param(True, id="self_sponsored"),
3220+
],
3221+
)
3222+
@pytest.mark.parametrize(
3223+
"pre_set_delegation_code",
3224+
[
3225+
pytest.param(Op.RETURN(0, 1), id="delegated_account"),
3226+
pytest.param(None, id="undelegated_account"),
3227+
],
3228+
)
3229+
def test_delegation_clearing_tx_to(
3230+
state_test: StateTestFiller,
3231+
pre: Alloc,
3232+
pre_set_delegation_code: Bytecode | None,
3233+
self_sponsored: bool,
3234+
):
3235+
"""
3236+
Tests directly calling the account which delegation is being cleared.
3237+
3238+
Args:
3239+
pre_set_delegation_code: The code to set on the account before clearing delegation, or None
3240+
if the account should not have any code set.
3241+
self_sponsored: Whether the delegation clearing transaction is self-sponsored.
3242+
""" # noqa: D417
3243+
pre_set_delegation_address: Address | None = None
3244+
if pre_set_delegation_code is not None:
3245+
pre_set_delegation_address = pre.deploy_contract(pre_set_delegation_code)
3246+
3247+
if self_sponsored:
3248+
auth_signer = pre.fund_eoa(delegation=pre_set_delegation_address)
3249+
else:
3250+
auth_signer = pre.fund_eoa(0, delegation=pre_set_delegation_address)
3251+
3252+
sender = pre.fund_eoa() if not self_sponsored else auth_signer
3253+
3254+
tx = Transaction(
3255+
gas_limit=200_000,
3256+
to=auth_signer,
3257+
value=0,
3258+
authorization_list=[
3259+
AuthorizationTuple(
3260+
address=Spec.RESET_DELEGATION_ADDRESS, # Reset
3261+
nonce=auth_signer.nonce + (1 if self_sponsored else 0),
3262+
signer=auth_signer,
3263+
),
3264+
],
3265+
sender=sender,
3266+
)
3267+
3268+
state_test(
3269+
env=Environment(),
3270+
pre=pre,
3271+
tx=tx,
3272+
post={
3273+
auth_signer: Account(
3274+
nonce=auth_signer.nonce + 1,
3275+
code=b"",
3276+
storage={},
3277+
),
3278+
},
3279+
)
3280+
3281+
3282+
@pytest.mark.parametrize(
3283+
"pre_set_delegation_code",
3284+
[
3285+
pytest.param(Op.RETURN(0, 1), id="delegated_account"),
3286+
pytest.param(None, id="undelegated_account"),
3287+
],
3288+
)
3289+
def test_delegation_clearing_and_set(
3290+
state_test: StateTestFiller,
3291+
pre: Alloc,
3292+
pre_set_delegation_code: Bytecode | None,
3293+
):
3294+
"""
3295+
Tests clearing and setting the delegation again in the same authorization list.
3296+
3297+
Args:
3298+
pre_set_delegation_code: The code to set on the account before clearing delegation, or None
3299+
if the account should not have any code set.
3300+
""" # noqa: D417
3301+
pre_set_delegation_address: Address | None = None
3302+
if pre_set_delegation_code is not None:
3303+
pre_set_delegation_address = pre.deploy_contract(pre_set_delegation_code)
3304+
3305+
auth_signer = pre.fund_eoa(0, delegation=pre_set_delegation_address)
3306+
3307+
reset_code_address = pre.deploy_contract(
3308+
Op.CALL(address=Spec.RESET_DELEGATION_ADDRESS) + Op.SSTORE(0, 1) + Op.STOP
3309+
)
3310+
3311+
sender = pre.fund_eoa()
3312+
3313+
tx = Transaction(
3314+
gas_limit=200_000,
3315+
to=auth_signer,
3316+
value=0,
3317+
authorization_list=[
3318+
AuthorizationTuple(
3319+
address=Spec.RESET_DELEGATION_ADDRESS, # Reset
3320+
nonce=auth_signer.nonce,
3321+
signer=auth_signer,
3322+
),
3323+
AuthorizationTuple(
3324+
address=reset_code_address,
3325+
nonce=auth_signer.nonce + 1,
3326+
signer=auth_signer,
3327+
),
3328+
],
3329+
sender=sender,
3330+
)
3331+
3332+
state_test(
3333+
env=Environment(),
3334+
pre=pre,
3335+
tx=tx,
3336+
post={
3337+
auth_signer: Account(
3338+
nonce=auth_signer.nonce + 2,
3339+
code=Spec.delegation_designation(reset_code_address),
3340+
storage={
3341+
0: 1,
3342+
},
3343+
),
3344+
},
3345+
)
3346+
3347+
31673348
@pytest.mark.parametrize(
31683349
"entry_code",
31693350
[

0 commit comments

Comments
 (0)