@@ -581,6 +581,21 @@ Finally, the original sender of the transaction, `ACCTFROM` is changed to the ne
581
581
[priority(40)]
582
582
```
583
583
584
+ We define a new rule for the ` #halt ~> #return _ _ ` production that will trigger the ` #endPrank ` rules if the prank was set only for a single call and if the current call depth is equal to the depth at which ` prank ` was invoked plus one.
585
+
586
+
587
+ ``` {.k .bytes}
588
+ rule <k> (. => #endPrank) ~> #halt ~> #return _RETSTART _RETWIDTH ... </k>
589
+ <callDepth> CD </callDepth>
590
+ <prank>
591
+ <singleCall> true </singleCall>
592
+ <depth> PD </depth>
593
+ ...
594
+ </prank>
595
+ requires CD ==Int PD +Int 1
596
+ [priority(40)]
597
+ ```
598
+
584
599
#### ` startPrank ` - Sets ` msg.sender ` and ` tx.origin ` for all subsequent calls until ` stopPrank ` is called.
585
600
586
601
```
@@ -594,14 +609,31 @@ The `#loadAccount` production is used to load accounts into the state if they ar
594
609
595
610
``` {.k .bytes}
596
611
rule [foundry.call.startPrank]:
597
- <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(ARGS) ~> #setPrank #asWord(ARGS) .Account ... </k>
612
+ <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(ARGS) ~> #setPrank #asWord(ARGS) .Account false ... </k>
598
613
requires SELECTOR ==Int selector ( "startPrank(address)" )
599
614
600
615
rule [foundry.call.startPrankWithOrigin]:
601
- <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(#range(ARGS, 0, 32)) ~> #loadAccount #asWord(#range(ARGS, 32, 32)) ~> #setPrank #asWord(#range(ARGS, 0, 32)) #asWord(#range(ARGS, 32, 32)) ... </k>
616
+ <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(#range(ARGS, 0, 32)) ~> #loadAccount #asWord(#range(ARGS, 32, 32)) ~> #setPrank #asWord(#range(ARGS, 0, 32)) #asWord(#range(ARGS, 32, 32)) false ... </k>
602
617
requires SELECTOR ==Int selector ( "startPrank(address,address)" )
603
618
```
604
619
620
+ #### ` prank ` - Impersonate ` msg.sender ` and ` tx.origin ` for only for the next call.
621
+
622
+ ```
623
+ function prank(address) external;
624
+ function prank(address sender, address origin) external;
625
+ ```
626
+
627
+ ``` {.k .bytes}
628
+ rule [foundry.call.prank]:
629
+ <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(ARGS) ~> #setPrank #asWord(ARGS) .Account true ... </k>
630
+ requires SELECTOR ==Int selector ( "prank(address)" )
631
+
632
+ rule [foundry.call.prankWithOrigin]:
633
+ <k> #call_foundry SELECTOR ARGS => #loadAccount #asWord(#range(ARGS, 0, 32)) ~> #loadAccount #asWord(#range(ARGS, 32, 32)) ~> #setPrank #asWord(#range(ARGS, 0, 32)) #asWord(#range(ARGS, 32, 32)) true ... </k>
634
+ requires SELECTOR ==Int selector ( "prank(address,address)" )
635
+ ```
636
+
605
637
#### ` stopPrank ` - Stops impersonating ` msg.sender ` and ` tx.origin ` .
606
638
607
639
```
@@ -736,12 +768,12 @@ Utils
736
768
</expected>
737
769
```
738
770
739
- - ` #setPrank NEWCALLER NEWORIGIN ` will set the ` <prank/> ` subconfiguration for the given accounts.
771
+ - ` #setPrank NEWCALLER NEWORIGIN SINGLEPRANK ` will set the ` <prank/> ` subconfiguration for the given accounts.
740
772
741
773
``` k
742
- syntax KItem ::= "#setPrank" Int Account [klabel(foundry_setPrank)]
743
- // -------------------------------------------------------------------
744
- rule <k> #setPrank NEWCALLER NEWORIGIN => . ... </k>
774
+ syntax KItem ::= "#setPrank" Int Account Bool [klabel(foundry_setPrank)]
775
+ // ------------------------------------------------------------------------
776
+ rule <k> #setPrank NEWCALLER NEWORIGIN SINGLEPRANK => . ... </k>
745
777
<callDepth> CD </callDepth>
746
778
<caller> CL </caller>
747
779
<origin> OG </origin>
@@ -752,7 +784,7 @@ Utils
752
784
<newOrigin> _ => NEWORIGIN </newOrigin>
753
785
<active> false => true </active>
754
786
<depth> _ => CD </depth>
755
- <singleCall> _ => false </singleCall>
787
+ <singleCall> _ => SINGLEPRANK </singleCall>
756
788
</prank>
757
789
```
758
790
0 commit comments