3
3
pragma solidity ^ 0.8.20 ;
4
4
5
5
import {Address} from "./Address.sol " ;
6
+ import {Create2} from "./Create2.sol " ;
6
7
7
8
/**
8
9
* @dev Helper contract for performing potentially dangerous calls through a relay the hide the address of the
@@ -14,34 +15,33 @@ import {Address} from "./Address.sol";
14
15
* "senderCreator" when calling account factories. Similarly ERC-6942 does factory calls that could be dangerous if
15
16
* performed directly.
16
17
*
17
- * This contract provides a `_relayedCall ` that can be used to perform dangerous calls. These calls are relayed
18
- * through a minimal relayer. This relayer is deployed at construction and its address is stored in immutable storage.
18
+ * This contract provides a `indirectCall ` that can be used to perform dangerous calls. These calls are indirect
19
+ * through a minimal relayer.
19
20
*/
20
- abstract contract RelayedCall {
21
- /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
22
- /// TODO: should be internal, but hardhat-exposed doesn't expose that correctly in 0.3.19
23
- address public immutable _relayer = _deployRelayer ();
24
-
25
- function _relayedCallStrict (address target , bytes memory data ) internal returns (bytes memory ) {
26
- return _relayedCallStrict (target, 0 , data);
21
+ library IndirectCall {
22
+ function indirectCall (address target , bytes memory data ) internal returns (bool , bytes memory ) {
23
+ return indirectCall (target, 0 , data);
27
24
}
28
25
29
- function _relayedCallStrict (address target , uint256 value , bytes memory data ) internal returns (bytes memory ) {
30
- (bool success , bytes memory returndata ) = _relayedCall (target, value, data);
31
- return Address.verifyCallResult (success, returndata);
26
+ function indirectCall (address target , uint256 value , bytes memory data ) internal returns (bool , bytes memory ) {
27
+ return getRelayer ().call {value: value}(abi.encodePacked (target, data));
32
28
}
33
29
34
- function _relayedCall (address target , bytes memory data ) internal returns (bool , bytes memory ) {
35
- return _relayedCall (target, 0 , data);
30
+ function indirectCallStrict (address target , bytes memory data ) internal returns (bytes memory ) {
31
+ return indirectCallStrict (target, 0 , data);
36
32
}
37
33
38
- function _relayedCall (address target , uint256 value , bytes memory data ) internal returns (bool , bytes memory ) {
39
- return _relayer.call {value: value}(abi.encodePacked (target, data));
34
+ function indirectCallStrict (address target , uint256 value , bytes memory data ) internal returns (bytes memory ) {
35
+ (bool success , bytes memory returndata ) = indirectCall (target, value, data);
36
+ return Address.verifyCallResult (success, returndata);
40
37
}
41
38
42
- function _deployRelayer () private returns (address addr ) {
39
+ function getRelayer () internal returns (address ) {
40
+ // [Relayer details]
41
+ //
43
42
// deployment prefix: 3d602f80600a3d3981f3
44
43
// deployed bytecode: 60133611600a575f5ffd5b6014360360145f375f5f601436035f345f3560601c5af13d5f5f3e5f3d91602d57fd5bf3
44
+ // bytecode hash: 7bc0ea09c689dc0a6de3865d8789dae51a081efcf6569589ddae4b677df5dd3f
45
45
//
46
46
// offset | bytecode | opcode | stack
47
47
// -------|----------|----------------|--------
@@ -85,15 +85,23 @@ abstract contract RelayedCall {
85
85
// 0x002c | fd | revert |
86
86
// 0x002d | 5b | jumpdest | 0 rds
87
87
// 0x002e | f3 | return |
88
- assembly ("memory-safe" ) {
89
- mstore (0x19 , 0x1436035f345f3560601c5af13d5f5f3e5f3d91602d57fd5bf3 )
90
- mstore (0x00 , 0x3d602f80600a3d3981f360133611600a575f5ffd5b6014360360145f375f5f60 )
91
- addr := create2 (0 , 0 , 0x39 , 0 )
92
- if iszero (addr) {
93
- let ptr := mload (0x40 )
94
- returndatacopy (ptr, 0 , returndatasize ())
95
- revert (ptr, returndatasize ())
88
+
89
+ // Create2 address computation, and deploy it if not yet available
90
+ address relayer = Create2.computeAddress (
91
+ bytes32 (0 ),
92
+ 0x7bc0ea09c689dc0a6de3865d8789dae51a081efcf6569589ddae4b677df5dd3f
93
+ );
94
+ if (relayer.code.length == 0 ) {
95
+ assembly ("memory-safe" ) {
96
+ mstore (0x19 , 0x1436035f345f3560601c5af13d5f5f3e5f3d91602d57fd5bf3 )
97
+ mstore (0x00 , 0x3d602f80600a3d3981f360133611600a575f5ffd5b6014360360145f375f5f60 )
98
+ if iszero (create2 (0 , 0 , 0x39 , 0 )) {
99
+ let ptr := mload (0x40 )
100
+ returndatacopy (ptr, 0 , returndatasize ())
101
+ revert (ptr, returndatasize ())
102
+ }
96
103
}
97
104
}
105
+ return relayer;
98
106
}
99
107
}
0 commit comments