generated from gnosisguild/zodiac-mod-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathConnextModule.sol
142 lines (126 loc) · 5.65 KB
/
ConnextModule.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.15;
import "@gnosis.pm/zodiac/contracts/core/Module.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IXReceiver} from "./interfaces/IXReceiver.sol";
contract ConnextModule is Module, IXReceiver {
using SafeERC20 for IERC20;
event ModuleSetUp(
address owner,
address avatar,
address target,
address originSender,
uint32 origin,
address connext
);
event OriginSenderSet(address originSender);
event OriginSet(uint32 origin);
event ConnextSet(address connext);
error ConnextOnly();
error ModuleTransactionFailed();
error OriginSenderOnly();
error OriginOnly();
/// The ConnextHandler contract on this domain.
address public connext;
/// Address of the sender from origin.
address public originSender;
/// Origin Domain ID.
uint32 public origin;
/// @param _owner Address that will be able to call functions protected onlyGovernance() functions.
/// @param _avatar Address that will receive all token transfered along with xReceive calls and that will ultimately execute messages passed.
/// @param _target Address on which this contract will call `execTransactionFromModule()`.
/// @param _originSender Address which is allowed to send calls to this contract from `origin` via `connext`.
/// @param _origin Identifier for the foreign chain form which this module sould receive messages.
/// @param _connext Address of the connext contract.
constructor(
address _owner,
address _avatar,
address _target,
address _originSender,
uint32 _origin,
address _connext
) {
bytes memory initializeParams = abi.encode(_owner, _avatar, _target, _originSender, _origin, _connext);
setUp(initializeParams);
}
/// @dev Initialize function, will be triggered when a new proxy is deployed
/// @param initializeParams ABI encoded initialization params, in the same order as the parameters for this contract's constructor.
/// @notice Only callable once.
function setUp(bytes memory initializeParams) public override initializer {
__Ownable_init();
(
address _owner,
address _avatar,
address _target,
address _originSender,
uint32 _origin,
address _connext
) = abi.decode(initializeParams, (address, address, address, address, uint32, address));
setAvatar(_avatar);
setTarget(_target);
setOriginSender(_originSender);
setOrigin(_origin);
setConnext(_connext);
transferOwnership(_owner);
emit ModuleSetUp(owner(), avatar, target, originSender, origin, connext);
}
/// @dev Validates calls to ensure they were sent by the correct `connext` contract and that the `origin` and `originSender` are correct.
/// @param _originSender Address which is allowed to send calls to this contract from `origin` via `connext`.
/// @param _origin Identifier for the foreign chain form which this module sould receive messages.
modifier onlyConnext(address _originSender, uint32 _origin) {
if (msg.sender != connext) revert ConnextOnly();
if (_originSender != originSender) revert OriginSenderOnly();
if (_origin != origin) revert OriginOnly();
_;
}
/// @dev Receives xCalls from Connext.
/// @param _amount The ammount of `_asset` to be transferred to `avatar` with this call.
/// @param _asset Address of the asset to be transferred with this call.
/// @param _originSender The foreign address which sent this message.
/// @param _origin The identifier for the foreign chain where this message originated.
/// @notice Only callable by `connext` address.
function xReceive(
bytes32,
uint256 _amount,
address _asset,
address _originSender,
uint32 _origin,
bytes memory _callData
)
external override onlyConnext(_originSender, _origin)
returns (bytes memory returnData) {
// Decode message
(address _to, uint256 _value, bytes memory _data, Enum.Operation _operation) = abi.decode(
_callData,
(address, uint256, bytes, Enum.Operation)
);
// Approve token transfer if tokens were passed in
IERC20 _token = IERC20(_asset);
if(_amount > 0) _token.safeTransfer(avatar, _amount);
// Execute transaction against target
if (!exec(_to, _value, _data, _operation)) revert ModuleTransactionFailed();
return returnData;
}
/// @dev Sets `originSender` address.
/// @param _originSender Address that will be allowed to send calls to this contract from `origin` via `connext`.
/// @notice Only callable by `owner`.
function setOriginSender(address _originSender) public onlyOwner {
require(_originSender != address(0), "Sender should not be address(0)");
originSender = _originSender;
emit OriginSenderSet(originSender);
}
/// @dev Sets `connext` address.
/// @param _connext Address that will be allowed to call `xReceive()` on this contract.
/// @notice Only callable by `owner`.
function setConnext(address _connext) public onlyOwner {
connext = _connext;
emit ConnextSet(connext);
}
/// @dev Sets `origin`.
/// @param _origin Uint32 identifier of the foreign chain where `originSender` will be able to initiate messages to this contract.
/// @notice Only callable by `owner`.
function setOrigin(uint32 _origin) public onlyOwner {
origin = _origin;
emit OriginSet(origin);
}
}