@@ -528,3 +528,58 @@ def test_bal_7702_invalid_chain_id_authorization(
528528 blocks = [block ],
529529 post = post ,
530530 )
531+
532+
533+ @pytest .mark .with_all_call_opcodes
534+ def test_bal_7702_delegated_via_call_opcode (
535+ pre : Alloc ,
536+ blockchain_test : BlockchainTestFiller ,
537+ call_opcode : Op ,
538+ ):
539+ """
540+ Ensure BAL captures delegation target when a contract uses *CALL
541+ opcodes to call a delegated account.
542+ """
543+ # `oracle` contract that just returns successfully
544+ oracle = pre .deploy_contract (code = Op .STOP )
545+
546+ # `alice` is a delegated account pointing to oracle
547+ alice = pre .deploy_contract (
548+ nonce = 1 ,
549+ code = Spec7702 .delegation_designation (oracle ),
550+ balance = 0 ,
551+ )
552+
553+ # caller contract that uses `call_opcode` to call `alice`
554+ caller = pre .deploy_contract (code = (call_opcode (address = alice ) + Op .STOP ))
555+
556+ bob = pre .fund_eoa ()
557+ tx = Transaction (
558+ sender = bob ,
559+ to = caller , # `bob` calls caller contract
560+ gas_limit = 10_000_000 ,
561+ gas_price = 0xA ,
562+ )
563+
564+ block = Block (
565+ txs = [tx ],
566+ expected_block_access_list = BlockAccessListExpectation (
567+ account_expectations = {
568+ bob : BalAccountExpectation (
569+ nonce_changes = [BalNonceChange (tx_index = 1 , post_nonce = 1 )],
570+ ),
571+ caller : BalAccountExpectation .empty (),
572+ # `alice` is accessed due to being the call target
573+ alice : BalAccountExpectation .empty (),
574+ # `oracle` appears in BAL due to delegation target access
575+ oracle : BalAccountExpectation .empty (),
576+ }
577+ ),
578+ )
579+
580+ post = {bob : Account (nonce = 1 )}
581+ blockchain_test (
582+ pre = pre ,
583+ blocks = [block ],
584+ post = post ,
585+ )
0 commit comments