/
MessageReceiverAdapter.sol
76 lines (67 loc) · 3.16 KB
/
MessageReceiverAdapter.sol
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
76
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.9;
import "../../framework/MessageApp.sol";
import "../../safeguard/MessageAppPauser.sol";
import "../../safeguard/DelayedMessage.sol";
import "../../../libraries/Utils.sol";
contract MessageReceiverAdapter is MessageApp, MessageAppPauser, DelayedMessage {
event ExternalCall(address srcContract, uint64 srcChainId, address dstContract, bytes callData);
event AllowedSenderUpdated(address dstContract, uint64 srcChainId, address srcContract, bool allowed);
// dstContract => srcChainId => srcContract => allowed or not
mapping(address => mapping(uint64 => mapping(address => bool))) public allowedSender;
constructor(address _messageBus) MessageApp(_messageBus) {}
// Called by MessageBus on destination chain to receive cross-chain messages.
// The message is abi.encode of (dst_contract_address, dst_contract_calldata).
// If a delayed period is configured, the message would be put in a delayed message queue,
// otherwise, the external call to the dst contract will be executed immediately
function executeMessage(
address _srcContract,
uint64 _srcChainId,
bytes calldata _message,
address // executor
) external payable override onlyMessageBus whenNotMsgPaused returns (ExecutionStatus) {
(address dstContract, bytes memory callData) = abi.decode(_message, (address, bytes));
require(allowedSender[dstContract][_srcChainId][_srcContract], "not allowed sender");
if (delayPeriod > 0) {
_addDelayedMessage(_srcContract, _srcChainId, dstContract, callData);
} else {
_externalCall(_srcContract, _srcChainId, dstContract, callData);
}
return ExecutionStatus.Success;
}
// execute external call to the dst contract after the message delay period is passed.
function executeDelayedMessage(
address _srcContract,
uint64 _srcChainId,
address _dstContract,
bytes calldata _callData,
uint32 _nonce
) external payable whenNotPaused {
_executeDelayedMessage(_srcContract, _srcChainId, _dstContract, _callData, _nonce);
_externalCall(_srcContract, _srcChainId, _dstContract, _callData);
}
function _externalCall(
address _srcContract,
uint64 _srcChainId,
address _dstContract,
bytes memory _callData
) internal {
(bool ok, bytes memory returnData) = _dstContract.call{value: msg.value}(_callData);
if (!ok) {
revert(Utils.getRevertMsg(returnData));
}
emit ExternalCall(_srcContract, _srcChainId, _dstContract, _callData);
}
function setAllowedSender(
address _dstContract,
uint64 _srcChainId,
address[] calldata _srcContracts,
bool[] calldata _alloweds
) external onlyOwner {
require(_srcContracts.length == _alloweds.length, "length mismatch");
for (uint256 i = 0; i < _srcContracts.length; i++) {
allowedSender[_dstContract][_srcChainId][_srcContracts[i]] = _alloweds[i];
emit AllowedSenderUpdated(_dstContract, _srcChainId, _srcContracts[i], _alloweds[i]);
}
}
}