@@ -16,6 +16,8 @@ pub struct Prank {
1616 pub depth : u64 ,
1717 /// Whether the prank stops by itself after the next call
1818 pub single_call : bool ,
19+ /// Whether the prank should be be applied to delegate call
20+ pub delegate_call : bool ,
1921 /// Whether the prank has been used yet (false if unused)
2022 pub used : bool ,
2123}
@@ -29,8 +31,18 @@ impl Prank {
2931 new_origin : Option < Address > ,
3032 depth : u64 ,
3133 single_call : bool ,
34+ delegate_call : bool ,
3235 ) -> Self {
33- Self { prank_caller, prank_origin, new_caller, new_origin, depth, single_call, used : false }
36+ Self {
37+ prank_caller,
38+ prank_origin,
39+ new_caller,
40+ new_origin,
41+ depth,
42+ single_call,
43+ delegate_call,
44+ used : false ,
45+ }
3446 }
3547
3648 /// Apply the prank by setting `used` to true iff it is false
@@ -47,28 +59,56 @@ impl Prank {
4759impl Cheatcode for prank_0Call {
4860 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
4961 let Self { msgSender } = self ;
50- prank ( ccx, msgSender, None , true )
62+ prank ( ccx, msgSender, None , true , false )
5163 }
5264}
5365
5466impl Cheatcode for startPrank_0Call {
5567 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
5668 let Self { msgSender } = self ;
57- prank ( ccx, msgSender, None , false )
69+ prank ( ccx, msgSender, None , false , false )
5870 }
5971}
6072
6173impl Cheatcode for prank_1Call {
6274 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
6375 let Self { msgSender, txOrigin } = self ;
64- prank ( ccx, msgSender, Some ( txOrigin) , true )
76+ prank ( ccx, msgSender, Some ( txOrigin) , true , false )
6577 }
6678}
6779
6880impl Cheatcode for startPrank_1Call {
6981 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
7082 let Self { msgSender, txOrigin } = self ;
71- prank ( ccx, msgSender, Some ( txOrigin) , false )
83+ prank ( ccx, msgSender, Some ( txOrigin) , false , false )
84+ }
85+ }
86+
87+ impl Cheatcode for prank_2Call {
88+ fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
89+ let Self { msgSender, delegateCall } = self ;
90+ prank ( ccx, msgSender, None , true , * delegateCall)
91+ }
92+ }
93+
94+ impl Cheatcode for startPrank_2Call {
95+ fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
96+ let Self { msgSender, delegateCall } = self ;
97+ prank ( ccx, msgSender, None , false , * delegateCall)
98+ }
99+ }
100+
101+ impl Cheatcode for prank_3Call {
102+ fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
103+ let Self { msgSender, txOrigin, delegateCall } = self ;
104+ prank ( ccx, msgSender, Some ( txOrigin) , true , * delegateCall)
105+ }
106+ }
107+
108+ impl Cheatcode for startPrank_3Call {
109+ fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
110+ let Self { msgSender, txOrigin, delegateCall } = self ;
111+ prank ( ccx, msgSender, Some ( txOrigin) , false , * delegateCall)
72112 }
73113}
74114
@@ -85,6 +125,7 @@ fn prank(
85125 new_caller : & Address ,
86126 new_origin : Option < & Address > ,
87127 single_call : bool ,
128+ delegate_call : bool ,
88129) -> Result {
89130 let prank = Prank :: new (
90131 ccx. caller ,
@@ -93,8 +134,15 @@ fn prank(
93134 new_origin. copied ( ) ,
94135 ccx. ecx . journaled_state . depth ( ) ,
95136 single_call,
137+ delegate_call,
96138 ) ;
97139
140+ // Ensure that code exists at `msg.sender` if delegate calling.
141+ if delegate_call {
142+ let code = ccx. code ( * new_caller) ?;
143+ ensure ! ( !code. is_empty( ) , "cannot `prank` delegate call from an EOA" ) ;
144+ }
145+
98146 if let Some ( Prank { used, single_call : current_single_call, .. } ) = ccx. state . prank {
99147 ensure ! ( used, "cannot overwrite a prank until it is applied at least once" ) ;
100148 // This case can only fail if the user calls `vm.startPrank` and then `vm.prank` later on.
0 commit comments