@@ -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