@@ -4,6 +4,33 @@ pragma solidity ^0.8.23;
44import "forge-std/Test.sol " ;
55
66import { CallUtils } from "../../../contracts/libs/CallUtils.sol " ;
7+ import { delegateCallChecked } from "../../../contracts/libs/CallUtils.sol " ;
8+
9+ // Helper contract to test delegateCallChecked
10+ contract DelegateCallTarget {
11+ uint256 public value;
12+
13+ function setValue (uint256 _value ) external {
14+ value = _value;
15+ }
16+
17+ function revertAlways () external pure {
18+ revert ("Target revert " );
19+ }
20+ }
21+
22+ // Contract that uses delegateCallChecked
23+ contract DelegateCallChecker {
24+ uint256 public value;
25+
26+ function delegateCallSetValue (address target , uint256 _value ) external {
27+ delegateCallChecked (target, abi.encodeWithSelector (DelegateCallTarget.setValue.selector , _value));
28+ }
29+
30+ function delegateCallRevert (address target ) external {
31+ delegateCallChecked (target, abi.encodeWithSelector (DelegateCallTarget.revertAlways.selector ));
32+ }
33+ }
734
835contract CallUtilsAnvil is Test {
936 function testPadLength32 (uint256 len ) public pure {
@@ -16,6 +43,26 @@ contract CallUtilsAnvil is Test {
1643 assertTrue (CallUtils.isValidAbiEncodedBytes (abi.encode (data)));
1744 }
1845
46+ function testDelegateCallChecked_Success () public {
47+ DelegateCallTarget target = new DelegateCallTarget ();
48+ DelegateCallChecker checker = new DelegateCallChecker ();
49+
50+ uint256 testValue = 42 ;
51+ checker.delegateCallSetValue (address (target), testValue);
52+
53+ // The value should be set in the checker contract (not the target) due to delegatecall
54+ assertEq (checker.value (), testValue);
55+ assertEq (target.value (), 0 );
56+ }
57+
58+ function testDelegateCallChecked_Revert () public {
59+ DelegateCallTarget target = new DelegateCallTarget ();
60+ DelegateCallChecker checker = new DelegateCallChecker ();
61+
62+ vm.expectRevert ("CallUtils: delegatecall failed " );
63+ checker.delegateCallRevert (address (target));
64+ }
65+
1966 // TODO this is a hard fuzzing case, because we need to know if there is a case that:
2067 // 1. CallUtils.isValidAbiEncodedBytes returns true
2168 // 2. and abi.decode reverts
0 commit comments