11//! Implementations of [`Scripting`](spec::Group::Scripting) cheatcodes. 
22
33use  crate :: { Cheatcode ,  CheatsCtxt ,  Result ,  Vm :: * } ; 
4- use  alloy_primitives:: { Address ,  PrimitiveSignature ,  B256 ,  U256 } ; 
4+ use  alloy_primitives:: { Address ,  Uint ,  B256 ,  U256 } ; 
55use  alloy_rpc_types:: Authorization ; 
66use  alloy_signer:: SignerSync ; 
77use  alloy_signer_local:: PrivateKeySigner ; 
@@ -54,46 +54,71 @@ impl Cheatcode for attachDelegationCall {
5454    } 
5555} 
5656
57- impl  Cheatcode  for  signDelegationCall  { 
57+ impl  Cheatcode  for  signDelegation_0Call  { 
5858    fn  apply_stateful ( & self ,  ccx :  & mut  CheatsCtxt )  -> Result  { 
59-         let  Self  {  implementation,  privateKey }  = self ; 
60-         let  signer = PrivateKeySigner :: from_bytes ( & B256 :: from ( * privateKey) ) ?; 
61-         let  authority = signer. address ( ) ; 
62-         let  ( auth,  nonce)  = create_auth ( ccx,  * implementation,  authority) ?; 
63-         let  sig = signer. sign_hash_sync ( & auth. signature_hash ( ) ) ?; 
64-         Ok ( sig_to_delegation ( sig,  nonce,  * implementation) . abi_encode ( ) ) 
59+         let  Self  {  implementation,  privateKey }  = * self ; 
60+         sign_delegation ( ccx,  privateKey,  implementation,  None ,  false ) 
6561    } 
6662} 
6763
68- impl  Cheatcode  for  signAndAttachDelegationCall  { 
64+ impl  Cheatcode  for  signDelegation_1Call  { 
6965    fn  apply_stateful ( & self ,  ccx :  & mut  CheatsCtxt )  -> Result  { 
70-         let  Self  {  implementation,  privateKey }  = self ; 
71-         let  signer = PrivateKeySigner :: from_bytes ( & B256 :: from ( * privateKey) ) ?; 
72-         let  authority = signer. address ( ) ; 
73-         let  ( auth,  nonce)  = create_auth ( ccx,  * implementation,  authority) ?; 
74-         let  sig = signer. sign_hash_sync ( & auth. signature_hash ( ) ) ?; 
75-         let  signed_auth = sig_to_auth ( sig,  auth) ; 
76-         write_delegation ( ccx,  signed_auth. clone ( ) ) ?; 
77-         ccx. state . active_delegation  = Some ( signed_auth) ; 
78-         Ok ( sig_to_delegation ( sig,  nonce,  * implementation) . abi_encode ( ) ) 
66+         let  Self  {  implementation,  privateKey,  nonce }  = * self ; 
67+         sign_delegation ( ccx,  privateKey,  implementation,  Some ( nonce) ,  false ) 
7968    } 
8069} 
8170
82- fn  create_auth ( 
71+ impl  Cheatcode  for  signAndAttachDelegation_0Call  { 
72+     fn  apply_stateful ( & self ,  ccx :  & mut  CheatsCtxt )  -> Result  { 
73+         let  Self  {  implementation,  privateKey }  = * self ; 
74+         sign_delegation ( ccx,  privateKey,  implementation,  None ,  true ) 
75+     } 
76+ } 
77+ 
78+ impl  Cheatcode  for  signAndAttachDelegation_1Call  { 
79+     fn  apply_stateful ( & self ,  ccx :  & mut  CheatsCtxt )  -> Result  { 
80+         let  Self  {  implementation,  privateKey,  nonce }  = * self ; 
81+         sign_delegation ( ccx,  privateKey,  implementation,  Some ( nonce) ,  true ) 
82+     } 
83+ } 
84+ 
85+ /// Helper function to sign and attach (if needed) an EIP-7702 delegation. 
86+ /// Uses the provided nonce, otherwise retrieves and increments the nonce of the EOA. 
87+ fn  sign_delegation ( 
8388    ccx :  & mut  CheatsCtxt , 
89+     private_key :  Uint < 256 ,  4 > , 
8490    implementation :  Address , 
85-     authority :  Address , 
86- )  -> Result < ( Authorization ,  u64 ) >  { 
87-     let  authority_acc = ccx. ecx . journaled_state . load_account ( authority,  & mut  ccx. ecx . db ) ?; 
88-     let  nonce = authority_acc. data . info . nonce ; 
89-     Ok ( ( 
90-         Authorization  { 
91-             address :  implementation, 
92-             nonce, 
93-             chain_id :  U256 :: from ( ccx. ecx . env . cfg . chain_id ) , 
94-         } , 
91+     nonce :  Option < u64 > , 
92+     attach :  bool , 
93+ )  -> Result < Vec < u8 > >  { 
94+     let  signer = PrivateKeySigner :: from_bytes ( & B256 :: from ( private_key) ) ?; 
95+     let  nonce = if  let  Some ( nonce)  = nonce { 
96+         nonce
97+     }  else  { 
98+         let  authority_acc =
99+             ccx. ecx . journaled_state . load_account ( signer. address ( ) ,  & mut  ccx. ecx . db ) ?; 
100+         authority_acc. data . info . nonce 
101+     } ; 
102+     let  auth = Authorization  { 
103+         address :  implementation, 
104+         nonce, 
105+         chain_id :  U256 :: from ( ccx. ecx . env . cfg . chain_id ) , 
106+     } ; 
107+     let  sig = signer. sign_hash_sync ( & auth. signature_hash ( ) ) ?; 
108+     // Attach delegation. 
109+     if  attach { 
110+         let  signed_auth = SignedAuthorization :: new_unchecked ( auth,  sig. v ( )  as  u8 ,  sig. r ( ) ,  sig. s ( ) ) ; 
111+         write_delegation ( ccx,  signed_auth. clone ( ) ) ?; 
112+         ccx. state . active_delegation  = Some ( signed_auth) ; 
113+     } 
114+     Ok ( SignedDelegation  { 
115+         v :  sig. v ( )  as  u8 , 
116+         r :  sig. r ( ) . into ( ) , 
117+         s :  sig. s ( ) . into ( ) , 
95118        nonce, 
96-     ) ) 
119+         implementation, 
120+     } 
121+     . abi_encode ( ) ) 
97122} 
98123
99124fn  write_delegation ( ccx :  & mut  CheatsCtxt ,  auth :  SignedAuthorization )  -> Result < ( ) >  { 
@@ -108,24 +133,6 @@ fn write_delegation(ccx: &mut CheatsCtxt, auth: SignedAuthorization) -> Result<(
108133    Ok ( ( ) ) 
109134} 
110135
111- fn  sig_to_delegation ( 
112-     sig :  PrimitiveSignature , 
113-     nonce :  u64 , 
114-     implementation :  Address , 
115- )  -> SignedDelegation  { 
116-     SignedDelegation  { 
117-         v :  sig. v ( )  as  u8 , 
118-         r :  sig. r ( ) . into ( ) , 
119-         s :  sig. s ( ) . into ( ) , 
120-         nonce, 
121-         implementation, 
122-     } 
123- } 
124- 
125- fn  sig_to_auth ( sig :  PrimitiveSignature ,  auth :  Authorization )  -> SignedAuthorization  { 
126-     SignedAuthorization :: new_unchecked ( auth,  sig. v ( )  as  u8 ,  sig. r ( ) ,  sig. s ( ) ) 
127- } 
128- 
129136impl  Cheatcode  for  startBroadcast_0Call  { 
130137    fn  apply_stateful ( & self ,  ccx :  & mut  CheatsCtxt )  -> Result  { 
131138        let  Self  { }  = self ; 
0 commit comments