forked from OpenZeppelin/openzeppelin-contracts
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathCrosschainRemoteExecutor.sol
More file actions
75 lines (60 loc) · 2.67 KB
/
CrosschainRemoteExecutor.sol
File metadata and controls
75 lines (60 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {IERC7786GatewaySource} from "../interfaces/draft-IERC7786.sol";
import {ERC7786Recipient} from "./ERC7786Recipient.sol";
import {ERC7579Utils, Mode, CallType, ExecType} from "../account/utils/draft-ERC7579Utils.sol";
import {Bytes} from "../utils/Bytes.sol";
contract CrosschainRemoteExecutor is ERC7786Recipient {
using Bytes for bytes;
using ERC7579Utils for *;
address private _gateway;
bytes private _controller;
event CrosschainControllerSet(address gateway, bytes controller);
error AccessRestricted();
constructor(address initialGateway, bytes memory initialController) {
_setup(initialGateway, initialController);
}
function gateway() public view virtual returns (address) {
return _gateway;
}
function controller() public view virtual returns (bytes memory) {
return _controller;
}
function reconfigure(address newGateway, bytes memory newController) public virtual {
require(msg.sender == address(this), AccessRestricted());
_setup(newGateway, newController);
}
function _setup(address gateway_, bytes memory controller_) internal virtual {
// Sanity check, this should revert if gateway is not an ERC-7786 implementation. Note that since
// supportsAttribute returns data, an EOA would fail that test (nothing returned).
IERC7786GatewaySource(gateway_).supportsAttribute(bytes4(0));
_gateway = gateway_;
_controller = controller_;
emit CrosschainControllerSet(gateway_, controller_);
}
/// @inheritdoc ERC7786Recipient
function _isAuthorizedGateway(
address instance,
bytes calldata sender
) internal view virtual override returns (bool) {
return gateway() == instance && controller().equal(sender);
}
/// @inheritdoc ERC7786Recipient
function _processMessage(
address /*gateway*/,
bytes32 /*receiveId*/,
bytes calldata /*sender*/,
bytes calldata payload
) internal virtual override {
// split payload
(CallType callType, ExecType execType, , ) = Mode.wrap(bytes32(payload[0x00:0x20])).decodeMode();
bytes calldata executionCalldata = payload[0x20:];
if (callType == ERC7579Utils.CALLTYPE_SINGLE) {
executionCalldata.execSingle(execType);
} else if (callType == ERC7579Utils.CALLTYPE_BATCH) {
executionCalldata.execBatch(execType);
} else if (callType == ERC7579Utils.CALLTYPE_DELEGATECALL) {
executionCalldata.execDelegateCall(execType);
} else revert ERC7579Utils.ERC7579UnsupportedCallType(callType);
}
}