@hyperlane-xyz/core 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/GasRouter.sol +103 -0
- package/contracts/OwnableMulticall.sol +5 -4
- package/contracts/PausableReentrancyGuard.sol +2 -2
- package/contracts/igps/InterchainGasPaymaster.sol +2 -1
- package/contracts/libs/Call.sol +108 -19
- package/contracts/middleware/InterchainAccountRouter.sol +47 -34
- package/contracts/middleware/InterchainCallMessage.sol +112 -0
- package/contracts/middleware/InterchainQueryRouter.sol +36 -80
- package/contracts/mock/MockHyperlaneEnvironment.sol +4 -4
- package/contracts/test/TestGasRouter.sol +28 -0
- package/contracts/test/TestInterchainGasPaymaster.sol +8 -17
- package/contracts/test/TestQuery.sol +11 -6
- package/contracts/test/TestQuerySender.sol +22 -11
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit.d.ts +75 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit.d.ts.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit.js +4 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit.js.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.d.ts +2 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.d.ts.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.js +3 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.js.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/index.d.ts +3 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/index.d.ts.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/index.js +4 -0
- package/dist/@openzeppelin/contracts/token/ERC20/extensions/index.js.map +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/index.d.ts +2 -0
- package/dist/@openzeppelin/contracts/token/ERC20/index.d.ts.map +1 -1
- package/dist/@openzeppelin/contracts/token/ERC20/index.js +1 -0
- package/dist/@openzeppelin/contracts/token/ERC20/index.js.map +1 -1
- package/dist/contracts/GasRouter.d.ts +336 -0
- package/dist/contracts/GasRouter.d.ts.map +1 -0
- package/dist/contracts/GasRouter.js +4 -0
- package/dist/contracts/GasRouter.js.map +1 -0
- package/dist/contracts/InterchainGasPaymaster.d.ts +162 -0
- package/dist/contracts/InterchainGasPaymaster.d.ts.map +1 -0
- package/dist/contracts/InterchainGasPaymaster.js +4 -0
- package/dist/contracts/InterchainGasPaymaster.js.map +1 -0
- package/dist/contracts/OwnableMulticall.d.ts +13 -5
- package/dist/contracts/OwnableMulticall.d.ts.map +1 -1
- package/dist/contracts/igps/GasOverheadIgp.d.ts +194 -0
- package/dist/contracts/igps/GasOverheadIgp.d.ts.map +1 -0
- package/dist/contracts/igps/GasOverheadIgp.js +4 -0
- package/dist/contracts/igps/GasOverheadIgp.js.map +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/middleware/InterchainAccountRouter.d.ts +60 -44
- package/dist/contracts/middleware/InterchainAccountRouter.d.ts.map +1 -1
- package/dist/contracts/middleware/InterchainQueryRouter.d.ts +36 -57
- package/dist/contracts/middleware/InterchainQueryRouter.d.ts.map +1 -1
- package/dist/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge.d.ts +78 -0
- package/dist/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge.d.ts.map +1 -0
- package/dist/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge.js +4 -0
- package/dist/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge.js.map +1 -0
- package/dist/contracts/mock/MockCircleBridge.d.ts +86 -0
- package/dist/contracts/mock/MockCircleBridge.d.ts.map +1 -0
- package/dist/contracts/mock/MockCircleBridge.js +4 -0
- package/dist/contracts/mock/MockCircleBridge.js.map +1 -0
- package/dist/contracts/mock/MockInterchainAccountRouter.d.ts +422 -0
- package/dist/contracts/mock/MockInterchainAccountRouter.d.ts.map +1 -0
- package/dist/contracts/mock/MockInterchainAccountRouter.js +4 -0
- package/dist/contracts/mock/MockInterchainAccountRouter.js.map +1 -0
- package/dist/contracts/test/TestGasRouter.d.ts +441 -0
- package/dist/contracts/test/TestGasRouter.d.ts.map +1 -0
- package/dist/contracts/test/TestGasRouter.js +4 -0
- package/dist/contracts/test/TestGasRouter.js.map +1 -0
- package/dist/contracts/test/TestInterchainGasPaymaster.d.ts +122 -12
- package/dist/contracts/test/TestInterchainGasPaymaster.d.ts.map +1 -1
- package/dist/contracts/test/TestQuery.d.ts +9 -9
- package/dist/contracts/test/TestQuery.d.ts.map +1 -1
- package/dist/contracts/test/index.d.ts +1 -0
- package/dist/contracts/test/index.d.ts.map +1 -1
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit__factory.d.ts +23 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit__factory.d.ts.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit__factory.js +93 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/IERC20Permit__factory.js.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.d.ts +2 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.d.ts.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.js +9 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol/index.js.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/index.d.ts +2 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/index.d.ts.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/index.js +31 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/extensions/index.js.map +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/index.d.ts +1 -0
- package/dist/factories/@openzeppelin/contracts/token/ERC20/index.d.ts.map +1 -1
- package/dist/factories/@openzeppelin/contracts/token/ERC20/index.js +25 -1
- package/dist/factories/@openzeppelin/contracts/token/ERC20/index.js.map +1 -1
- package/dist/factories/contracts/GasRouter__factory.d.ts +52 -0
- package/dist/factories/contracts/GasRouter__factory.d.ts.map +1 -0
- package/dist/factories/contracts/GasRouter__factory.js +392 -0
- package/dist/factories/contracts/GasRouter__factory.js.map +1 -0
- package/dist/factories/contracts/InterchainGasPaymaster__factory.d.ts +62 -0
- package/dist/factories/contracts/InterchainGasPaymaster__factory.d.ts.map +1 -0
- package/dist/factories/contracts/InterchainGasPaymaster__factory.js +178 -0
- package/dist/factories/contracts/InterchainGasPaymaster__factory.js.map +1 -0
- package/dist/factories/contracts/Mailbox__factory.d.ts +1 -1
- package/dist/factories/contracts/Mailbox__factory.js +1 -1
- package/dist/factories/contracts/OwnableMulticall__factory.d.ts +20 -3
- package/dist/factories/contracts/OwnableMulticall__factory.d.ts.map +1 -1
- package/dist/factories/contracts/OwnableMulticall__factory.js +23 -7
- package/dist/factories/contracts/OwnableMulticall__factory.js.map +1 -1
- package/dist/factories/contracts/igps/GasOverheadIgp__factory.d.ts +75 -0
- package/dist/factories/contracts/igps/GasOverheadIgp__factory.d.ts.map +1 -0
- package/dist/factories/contracts/igps/GasOverheadIgp__factory.js +263 -0
- package/dist/factories/contracts/igps/GasOverheadIgp__factory.js.map +1 -0
- package/dist/factories/contracts/igps/InterchainGasPaymaster__factory.d.ts +1 -1
- package/dist/factories/contracts/igps/InterchainGasPaymaster__factory.js +2 -2
- package/dist/factories/contracts/index.d.ts +1 -0
- package/dist/factories/contracts/index.d.ts.map +1 -1
- package/dist/factories/contracts/index.js +3 -1
- package/dist/factories/contracts/index.js.map +1 -1
- package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.d.ts +13 -3
- package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.d.ts.map +1 -1
- package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.js +70 -39
- package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.js.map +1 -1
- package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.d.ts +13 -3
- package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.d.ts.map +1 -1
- package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.js +24 -92
- package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.js.map +1 -1
- package/dist/factories/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge__factory.d.ts +36 -0
- package/dist/factories/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge__factory.d.ts.map +1 -0
- package/dist/factories/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge__factory.js +104 -0
- package/dist/factories/contracts/middleware/liquidity-layer/interfaces/circle/ICircleBridge__factory.js.map +1 -0
- package/dist/factories/contracts/mock/MockCircleBridge__factory.d.ts +59 -0
- package/dist/factories/contracts/mock/MockCircleBridge__factory.d.ts.map +1 -0
- package/dist/factories/contracts/mock/MockCircleBridge__factory.js +151 -0
- package/dist/factories/contracts/mock/MockCircleBridge__factory.js.map +1 -0
- package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.d.ts +1 -1
- package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.d.ts.map +1 -1
- package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.js +2 -2
- package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.js.map +1 -1
- package/dist/factories/contracts/mock/MockInterchainAccountRouter__factory.d.ts +69 -0
- package/dist/factories/contracts/mock/MockInterchainAccountRouter__factory.d.ts.map +1 -0
- package/dist/factories/contracts/mock/MockInterchainAccountRouter__factory.js +556 -0
- package/dist/factories/contracts/mock/MockInterchainAccountRouter__factory.js.map +1 -0
- package/dist/factories/contracts/test/TestGasRouter__factory.d.ts +64 -0
- package/dist/factories/contracts/test/TestGasRouter__factory.d.ts.map +1 -0
- package/dist/factories/contracts/test/TestGasRouter__factory.js +579 -0
- package/dist/factories/contracts/test/TestGasRouter__factory.js.map +1 -0
- package/dist/factories/contracts/test/TestInterchainGasPaymaster__factory.d.ts +1 -1
- package/dist/factories/contracts/test/TestInterchainGasPaymaster__factory.d.ts.map +1 -1
- package/dist/factories/contracts/test/TestInterchainGasPaymaster__factory.js +97 -5
- package/dist/factories/contracts/test/TestInterchainGasPaymaster__factory.js.map +1 -1
- package/dist/factories/contracts/test/TestMailbox__factory.d.ts +1 -1
- package/dist/factories/contracts/test/TestMailbox__factory.js +1 -1
- package/dist/factories/contracts/test/TestQuerySender__factory.d.ts +1 -1
- package/dist/factories/contracts/test/TestQuerySender__factory.d.ts.map +1 -1
- package/dist/factories/contracts/test/TestQuerySender__factory.js +1 -1
- package/dist/factories/contracts/test/TestQuerySender__factory.js.map +1 -1
- package/dist/factories/contracts/test/TestQuery__factory.d.ts +1 -1
- package/dist/factories/contracts/test/TestQuery__factory.d.ts.map +1 -1
- package/dist/factories/contracts/test/TestQuery__factory.js +2 -2
- package/dist/factories/contracts/test/TestQuery__factory.js.map +1 -1
- package/dist/factories/contracts/test/index.d.ts +1 -0
- package/dist/factories/contracts/test/index.d.ts.map +1 -1
- package/dist/factories/contracts/test/index.js +3 -1
- package/dist/factories/contracts/test/index.js.map +1 -1
- package/dist/factories/interfaces/IInterchainAccountRouter__factory.d.ts +12 -2
- package/dist/factories/interfaces/IInterchainAccountRouter__factory.d.ts.map +1 -1
- package/dist/factories/interfaces/IInterchainAccountRouter__factory.js +27 -20
- package/dist/factories/interfaces/IInterchainAccountRouter__factory.js.map +1 -1
- package/dist/factories/interfaces/IInterchainQueryRouter__factory.d.ts +12 -2
- package/dist/factories/interfaces/IInterchainQueryRouter__factory.d.ts.map +1 -1
- package/dist/factories/interfaces/IInterchainQueryRouter__factory.js +17 -85
- package/dist/factories/interfaces/IInterchainQueryRouter__factory.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IInterchainAccountRouter.d.ts +35 -35
- package/dist/interfaces/IInterchainAccountRouter.d.ts.map +1 -1
- package/dist/interfaces/IInterchainQueryRouter.d.ts +23 -44
- package/dist/interfaces/IInterchainQueryRouter.d.ts.map +1 -1
- package/interfaces/IInterchainAccountRouter.sol +5 -6
- package/interfaces/IInterchainQueryRouter.sol +1 -15
- package/package.json +5 -4
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
2
|
+
pragma solidity >=0.6.11;
|
|
3
|
+
|
|
4
|
+
import {Router} from "./Router.sol";
|
|
5
|
+
|
|
6
|
+
abstract contract GasRouter is Router {
|
|
7
|
+
// ============ Mutable Storage ============
|
|
8
|
+
mapping(uint32 => uint256) public destinationGas;
|
|
9
|
+
|
|
10
|
+
// ============ Events ============
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @notice Emitted when a domain's destination gas is set.
|
|
14
|
+
* @param domain The domain of the router.
|
|
15
|
+
* @param gas The gas amount used by the handle function of the domain's router.
|
|
16
|
+
*/
|
|
17
|
+
event DestinationGasSet(uint32 indexed domain, uint256 gas);
|
|
18
|
+
|
|
19
|
+
struct GasRouterConfig {
|
|
20
|
+
uint32 domain;
|
|
21
|
+
uint256 gas;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @notice Sets the gas amount dispatched for each configured domain.
|
|
26
|
+
* @param gasConfigs The array of GasRouterConfig structs
|
|
27
|
+
*/
|
|
28
|
+
function setDestinationGas(GasRouterConfig[] calldata gasConfigs)
|
|
29
|
+
external
|
|
30
|
+
onlyOwner
|
|
31
|
+
{
|
|
32
|
+
for (uint256 i = 0; i < gasConfigs.length; i += 1) {
|
|
33
|
+
_setDestinationGas(gasConfigs[i].domain, gasConfigs[i].gas);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @notice Returns the gas payment required to dispatch a message to the given domain's router.
|
|
39
|
+
* @param _destinationDomain The domain of the router.
|
|
40
|
+
* @return _gasPayment Payment computed by the registered InterchainGasPaymaster.
|
|
41
|
+
*/
|
|
42
|
+
function quoteGasPayment(uint32 _destinationDomain)
|
|
43
|
+
external
|
|
44
|
+
view
|
|
45
|
+
returns (uint256 _gasPayment)
|
|
46
|
+
{
|
|
47
|
+
return
|
|
48
|
+
interchainGasPaymaster.quoteGasPayment(
|
|
49
|
+
_destinationDomain,
|
|
50
|
+
destinationGas[_destinationDomain]
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _setDestinationGas(uint32 domain, uint256 gas) internal {
|
|
55
|
+
destinationGas[domain] = gas;
|
|
56
|
+
emit DestinationGasSet(domain, gas);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @dev Uses the destinationGas mapping to populate the gas amount for the message.
|
|
61
|
+
* @notice Dispatches a message to an enrolled router via the local router's Mailbox
|
|
62
|
+
* and pays for it to be relayed to the destination.
|
|
63
|
+
* @dev Reverts if there is no enrolled router for _destinationDomain.
|
|
64
|
+
* @param _destinationDomain The domain of the chain to which to send the message.
|
|
65
|
+
* @param _messageBody Raw bytes content of message.
|
|
66
|
+
* @param _gasPayment The amount of native tokens to pay for the message to be relayed.
|
|
67
|
+
* @param _gasPaymentRefundAddress The address to refund any gas overpayment to.
|
|
68
|
+
*/
|
|
69
|
+
function _dispatchWithGas(
|
|
70
|
+
uint32 _destinationDomain,
|
|
71
|
+
bytes memory _messageBody,
|
|
72
|
+
uint256 _gasPayment,
|
|
73
|
+
address _gasPaymentRefundAddress
|
|
74
|
+
) internal returns (bytes32 _messageId) {
|
|
75
|
+
return
|
|
76
|
+
_dispatchWithGas(
|
|
77
|
+
_destinationDomain,
|
|
78
|
+
_messageBody,
|
|
79
|
+
destinationGas[_destinationDomain],
|
|
80
|
+
_gasPayment,
|
|
81
|
+
_gasPaymentRefundAddress
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @dev Passes `msg.value` as gas payment and `msg.sender` as gas payment refund address.
|
|
87
|
+
* @dev Uses the destinationGas mapping to populate the gas amount for the message.
|
|
88
|
+
* @param _destinationDomain The domain of the chain to send the message.
|
|
89
|
+
* @param _messageBody Raw bytes content of message.
|
|
90
|
+
*/
|
|
91
|
+
function _dispatchWithGas(
|
|
92
|
+
uint32 _destinationDomain,
|
|
93
|
+
bytes memory _messageBody
|
|
94
|
+
) internal returns (bytes32 _messageId) {
|
|
95
|
+
return
|
|
96
|
+
_dispatchWithGas(
|
|
97
|
+
_destinationDomain,
|
|
98
|
+
_messageBody,
|
|
99
|
+
msg.value,
|
|
100
|
+
msg.sender
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -9,11 +9,9 @@ import {CallLib} from "./libs/Call.sol";
|
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
* @title OwnableMulticall
|
|
12
|
-
* @dev
|
|
12
|
+
* @dev Permits owner address to execute state mutating calls with value to other contracts
|
|
13
13
|
*/
|
|
14
14
|
contract OwnableMulticall is OwnableUpgradeable {
|
|
15
|
-
using CallLib for CallLib.Call[];
|
|
16
|
-
|
|
17
15
|
constructor() {
|
|
18
16
|
_transferOwnership(msg.sender);
|
|
19
17
|
}
|
|
@@ -23,6 +21,9 @@ contract OwnableMulticall is OwnableUpgradeable {
|
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
function proxyCalls(CallLib.Call[] calldata calls) external onlyOwner {
|
|
26
|
-
|
|
24
|
+
return CallLib.multicall(calls);
|
|
27
25
|
}
|
|
26
|
+
|
|
27
|
+
// solhint-disable-next-line no-empty-blocks
|
|
28
|
+
receive() external payable {}
|
|
28
29
|
}
|
|
@@ -5,9 +5,9 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
|
5
5
|
|
|
6
6
|
// adapted from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
|
|
7
7
|
abstract contract PausableReentrancyGuardUpgradeable is Initializable {
|
|
8
|
+
uint256 private constant _ENTERED = 0;
|
|
8
9
|
uint256 private constant _NOT_ENTERED = 1;
|
|
9
|
-
uint256 private constant
|
|
10
|
-
uint256 private constant _PAUSED = 3;
|
|
10
|
+
uint256 private constant _PAUSED = 2;
|
|
11
11
|
|
|
12
12
|
uint256 private _status;
|
|
13
13
|
|
package/contracts/libs/Call.sol
CHANGED
|
@@ -3,52 +3,141 @@ pragma solidity ^0.8.13;
|
|
|
3
3
|
|
|
4
4
|
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
|
|
5
5
|
|
|
6
|
+
import {TypeCasts} from "./TypeCasts.sol";
|
|
7
|
+
|
|
6
8
|
library CallLib {
|
|
7
|
-
struct
|
|
8
|
-
|
|
9
|
+
struct StaticCall {
|
|
10
|
+
// supporting non EVM targets
|
|
11
|
+
bytes32 to;
|
|
9
12
|
bytes data;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
struct Call {
|
|
16
|
+
uint256 value;
|
|
17
|
+
StaticCall _call;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
struct StaticCallWithCallback {
|
|
21
|
+
StaticCall _call;
|
|
22
|
+
bytes callback;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function target(StaticCall memory _call) internal pure returns (address) {
|
|
26
|
+
return TypeCasts.bytes32ToAddress(_call.to);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function call(Call memory _call)
|
|
30
|
+
internal
|
|
31
|
+
returns (bytes memory returnData)
|
|
32
|
+
{
|
|
33
|
+
return
|
|
34
|
+
Address.functionCallWithValue(
|
|
35
|
+
target(_call._call),
|
|
36
|
+
_call._call.data,
|
|
37
|
+
_call.value
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function staticcall(StaticCall memory _call)
|
|
42
|
+
private
|
|
43
|
+
view
|
|
44
|
+
returns (bytes memory)
|
|
45
|
+
{
|
|
46
|
+
return Address.functionStaticCall(target(_call), _call.data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function staticcall(StaticCallWithCallback memory _call)
|
|
50
|
+
internal
|
|
51
|
+
view
|
|
52
|
+
returns (bytes memory callback)
|
|
53
|
+
{
|
|
54
|
+
return bytes.concat(_call.callback, staticcall(_call._call));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function multicall(Call[] memory calls) internal {
|
|
13
58
|
uint256 i = 0;
|
|
14
59
|
uint256 len = calls.length;
|
|
15
60
|
while (i < len) {
|
|
16
|
-
|
|
61
|
+
call(calls[i]);
|
|
17
62
|
unchecked {
|
|
18
63
|
++i;
|
|
19
64
|
}
|
|
20
65
|
}
|
|
21
66
|
}
|
|
22
67
|
|
|
23
|
-
function
|
|
68
|
+
function multistaticcall(StaticCallWithCallback[] memory _calls)
|
|
69
|
+
internal
|
|
70
|
+
view
|
|
71
|
+
returns (bytes[] memory)
|
|
72
|
+
{
|
|
24
73
|
uint256 i = 0;
|
|
25
|
-
uint256 len =
|
|
74
|
+
uint256 len = _calls.length;
|
|
75
|
+
bytes[] memory callbacks = new bytes[](len);
|
|
26
76
|
while (i < len) {
|
|
27
|
-
|
|
77
|
+
callbacks[i] = staticcall(_calls[i]);
|
|
28
78
|
unchecked {
|
|
29
79
|
++i;
|
|
30
80
|
}
|
|
31
81
|
}
|
|
82
|
+
return callbacks;
|
|
32
83
|
}
|
|
33
84
|
|
|
34
|
-
function
|
|
35
|
-
internal
|
|
36
|
-
returns (bytes[] memory resolveCalls)
|
|
37
|
-
{
|
|
38
|
-
// reuse memory
|
|
39
|
-
resolveCalls = callbacks;
|
|
40
|
-
|
|
85
|
+
function multicallto(address to, bytes[] memory calls) internal {
|
|
41
86
|
uint256 i = 0;
|
|
42
87
|
uint256 len = calls.length;
|
|
43
88
|
while (i < len) {
|
|
44
|
-
|
|
45
|
-
calls[i].to,
|
|
46
|
-
calls[i].data
|
|
47
|
-
);
|
|
48
|
-
resolveCalls[i] = bytes.concat(callbacks[i], returnData);
|
|
89
|
+
Address.functionCall(to, calls[i]);
|
|
49
90
|
unchecked {
|
|
50
91
|
++i;
|
|
51
92
|
}
|
|
52
93
|
}
|
|
53
94
|
}
|
|
95
|
+
|
|
96
|
+
function build(bytes32 to, bytes memory data)
|
|
97
|
+
internal
|
|
98
|
+
pure
|
|
99
|
+
returns (StaticCall memory)
|
|
100
|
+
{
|
|
101
|
+
return StaticCall(to, data);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function build(address to, bytes memory data)
|
|
105
|
+
internal
|
|
106
|
+
pure
|
|
107
|
+
returns (StaticCall memory)
|
|
108
|
+
{
|
|
109
|
+
return build(TypeCasts.addressToBytes32(to), data);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function build(
|
|
113
|
+
bytes32 to,
|
|
114
|
+
uint256 value,
|
|
115
|
+
bytes memory data
|
|
116
|
+
) internal pure returns (Call memory) {
|
|
117
|
+
return Call(value, build(to, data));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function build(
|
|
121
|
+
address to,
|
|
122
|
+
uint256 value,
|
|
123
|
+
bytes memory data
|
|
124
|
+
) internal pure returns (Call memory) {
|
|
125
|
+
return Call(value, build(to, data));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function build(
|
|
129
|
+
bytes32 to,
|
|
130
|
+
bytes memory data,
|
|
131
|
+
bytes memory callback
|
|
132
|
+
) internal pure returns (StaticCallWithCallback memory) {
|
|
133
|
+
return StaticCallWithCallback(build(to, data), callback);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function build(
|
|
137
|
+
address to,
|
|
138
|
+
bytes memory data,
|
|
139
|
+
bytes memory callback
|
|
140
|
+
) internal pure returns (StaticCallWithCallback memory) {
|
|
141
|
+
return StaticCallWithCallback(build(to, data), callback);
|
|
142
|
+
}
|
|
54
143
|
}
|
|
@@ -5,8 +5,10 @@ pragma solidity ^0.8.13;
|
|
|
5
5
|
import {OwnableMulticall} from "../OwnableMulticall.sol";
|
|
6
6
|
import {Router} from "../Router.sol";
|
|
7
7
|
import {IInterchainAccountRouter} from "../../interfaces/IInterchainAccountRouter.sol";
|
|
8
|
+
import {InterchainCallMessage} from "./InterchainCallMessage.sol";
|
|
8
9
|
import {MinimalProxy} from "../libs/MinimalProxy.sol";
|
|
9
10
|
import {CallLib} from "../libs/Call.sol";
|
|
11
|
+
import {TypeCasts} from "../libs/TypeCasts.sol";
|
|
10
12
|
|
|
11
13
|
// ============ External Imports ============
|
|
12
14
|
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
|
|
@@ -18,8 +20,11 @@ import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Ini
|
|
|
18
20
|
* @dev Currently does not support Sovereign Consensus (user specified Interchain Security Modules).
|
|
19
21
|
*/
|
|
20
22
|
contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
using TypeCasts for address;
|
|
24
|
+
using TypeCasts for bytes32;
|
|
25
|
+
|
|
26
|
+
address internal immutable implementation;
|
|
27
|
+
bytes32 internal immutable bytecodeHash;
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
30
|
* @notice Emitted when an interchain account is created (first time message is sent from a given `origin`/`sender` pair)
|
|
@@ -29,7 +34,7 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
|
29
34
|
*/
|
|
30
35
|
event InterchainAccountCreated(
|
|
31
36
|
uint32 indexed origin,
|
|
32
|
-
|
|
37
|
+
bytes32 sender,
|
|
33
38
|
address account
|
|
34
39
|
);
|
|
35
40
|
|
|
@@ -68,29 +73,20 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
|
68
73
|
* @notice Dispatches a sequence of calls to be relayed by the sender's interchain account on the destination domain.
|
|
69
74
|
* @param _destinationDomain The domain of the chain where the message will be sent to.
|
|
70
75
|
* @param calls The sequence of calls to be relayed.
|
|
76
|
+
* @dev Recommend using CallLib.build to format the interchain calls.
|
|
71
77
|
*/
|
|
72
78
|
function dispatch(uint32 _destinationDomain, CallLib.Call[] calldata calls)
|
|
73
79
|
external
|
|
74
80
|
returns (bytes32)
|
|
75
81
|
{
|
|
76
|
-
return
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
* @return The message ID of the dispatched message.
|
|
85
|
-
*/
|
|
86
|
-
function dispatch(
|
|
87
|
-
uint32 _destinationDomain,
|
|
88
|
-
address target,
|
|
89
|
-
bytes calldata data
|
|
90
|
-
) external returns (bytes32) {
|
|
91
|
-
CallLib.Call[] memory calls = new CallLib.Call[](1);
|
|
92
|
-
calls[0] = CallLib.Call({to: target, data: data});
|
|
93
|
-
return _dispatch(_destinationDomain, abi.encode(msg.sender, calls));
|
|
82
|
+
return
|
|
83
|
+
_dispatch(
|
|
84
|
+
_destinationDomain,
|
|
85
|
+
InterchainCallMessage.format(
|
|
86
|
+
calls,
|
|
87
|
+
msg.sender.addressToBytes32()
|
|
88
|
+
)
|
|
89
|
+
);
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
/**
|
|
@@ -99,42 +95,59 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
|
99
95
|
* @param _sender The parent account address on the origin domain.
|
|
100
96
|
* @return The address of the interchain account.
|
|
101
97
|
*/
|
|
102
|
-
function getInterchainAccount(uint32 _origin,
|
|
98
|
+
function getInterchainAccount(uint32 _origin, bytes32 _sender)
|
|
103
99
|
public
|
|
104
100
|
view
|
|
105
|
-
returns (address)
|
|
101
|
+
returns (address payable)
|
|
106
102
|
{
|
|
107
103
|
return _getInterchainAccount(_salt(_origin, _sender));
|
|
108
104
|
}
|
|
109
105
|
|
|
106
|
+
function getInterchainAccount(uint32 _origin, address _sender)
|
|
107
|
+
external
|
|
108
|
+
view
|
|
109
|
+
returns (address payable)
|
|
110
|
+
{
|
|
111
|
+
return getInterchainAccount(_origin, _sender.addressToBytes32());
|
|
112
|
+
}
|
|
113
|
+
|
|
110
114
|
/**
|
|
111
115
|
* @notice Returns and deploys (if not already) the interchain account for a given `origin`/`sender` pair.
|
|
112
116
|
* @param _origin The origin domain of the interchain account.
|
|
113
117
|
* @param _sender The parent account address on the origin domain.
|
|
114
118
|
* @return The address of the interchain account.
|
|
115
119
|
*/
|
|
116
|
-
function getDeployedInterchainAccount(uint32 _origin,
|
|
120
|
+
function getDeployedInterchainAccount(uint32 _origin, bytes32 _sender)
|
|
117
121
|
public
|
|
118
122
|
returns (OwnableMulticall)
|
|
119
123
|
{
|
|
120
124
|
bytes32 salt = _salt(_origin, _sender);
|
|
121
|
-
address interchainAccount = _getInterchainAccount(salt);
|
|
125
|
+
address payable interchainAccount = _getInterchainAccount(salt);
|
|
122
126
|
if (!Address.isContract(interchainAccount)) {
|
|
123
127
|
bytes memory bytecode = MinimalProxy.bytecode(implementation);
|
|
124
|
-
interchainAccount = Create2.deploy(0, salt, bytecode);
|
|
125
|
-
OwnableMulticall(interchainAccount).initialize();
|
|
128
|
+
interchainAccount = payable(Create2.deploy(0, salt, bytecode));
|
|
126
129
|
emit InterchainAccountCreated(_origin, _sender, interchainAccount);
|
|
130
|
+
// transfers ownership to this contract
|
|
131
|
+
OwnableMulticall(interchainAccount).initialize();
|
|
127
132
|
}
|
|
128
133
|
return OwnableMulticall(interchainAccount);
|
|
129
134
|
}
|
|
130
135
|
|
|
136
|
+
function getDeployedInterchainAccount(uint32 _origin, address _sender)
|
|
137
|
+
public
|
|
138
|
+
returns (OwnableMulticall)
|
|
139
|
+
{
|
|
140
|
+
return
|
|
141
|
+
getDeployedInterchainAccount(_origin, _sender.addressToBytes32());
|
|
142
|
+
}
|
|
143
|
+
|
|
131
144
|
/**
|
|
132
145
|
* @notice Returns the salt used to deploy the interchain account for a given `origin`/`sender` pair.
|
|
133
146
|
* @param _origin The origin domain of the interchain account.
|
|
134
147
|
* @param _sender The parent account address on the origin domain.
|
|
135
148
|
* @return The CREATE2 salt used for deploying the interchain account.
|
|
136
149
|
*/
|
|
137
|
-
function _salt(uint32 _origin,
|
|
150
|
+
function _salt(uint32 _origin, bytes32 _sender)
|
|
138
151
|
internal
|
|
139
152
|
pure
|
|
140
153
|
returns (bytes32)
|
|
@@ -150,9 +163,9 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
|
150
163
|
function _getInterchainAccount(bytes32 salt)
|
|
151
164
|
internal
|
|
152
165
|
view
|
|
153
|
-
returns (address)
|
|
166
|
+
returns (address payable)
|
|
154
167
|
{
|
|
155
|
-
return Create2.computeAddress(salt, bytecodeHash);
|
|
168
|
+
return payable(Create2.computeAddress(salt, bytecodeHash));
|
|
156
169
|
}
|
|
157
170
|
|
|
158
171
|
/**
|
|
@@ -165,10 +178,10 @@ contract InterchainAccountRouter is Router, IInterchainAccountRouter {
|
|
|
165
178
|
bytes32, // router sender
|
|
166
179
|
bytes calldata _message
|
|
167
180
|
) internal override {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
(
|
|
181
|
+
OwnableMulticall interchainAccount = getDeployedInterchainAccount(
|
|
182
|
+
_origin,
|
|
183
|
+
InterchainCallMessage.sender(_message)
|
|
171
184
|
);
|
|
172
|
-
|
|
185
|
+
interchainAccount.proxyCalls(InterchainCallMessage.calls(_message));
|
|
173
186
|
}
|
|
174
187
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.13;
|
|
3
|
+
|
|
4
|
+
import {CallLib} from "../libs/Call.sol";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Format of metadata:
|
|
8
|
+
* [ 0: 32] Sender address
|
|
9
|
+
* [ 32:64] Call type (left padded with zeroes)
|
|
10
|
+
* [ 64:???] Encoded call array
|
|
11
|
+
*/
|
|
12
|
+
library InterchainCallMessage {
|
|
13
|
+
uint256 private constant SENDER_OFFSET = 0;
|
|
14
|
+
uint256 private constant TYPE_OFFSET = 32;
|
|
15
|
+
uint256 private constant CALLS_OFFSET = 64;
|
|
16
|
+
|
|
17
|
+
enum CallType {
|
|
18
|
+
CALL,
|
|
19
|
+
STATIC_CALL,
|
|
20
|
+
STATIC_CALL_WITH_CALLBACK,
|
|
21
|
+
RAW_CALLDATA
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function sender(bytes calldata _message) internal pure returns (bytes32) {
|
|
25
|
+
return bytes32(_message[SENDER_OFFSET:TYPE_OFFSET]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function calltype(bytes calldata _message)
|
|
29
|
+
internal
|
|
30
|
+
pure
|
|
31
|
+
returns (CallType)
|
|
32
|
+
{
|
|
33
|
+
// left padded with zeroes
|
|
34
|
+
return CallType(uint8(bytes1(_message[CALLS_OFFSET - 1])));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function format(CallLib.Call[] calldata _calls, bytes32 _sender)
|
|
38
|
+
internal
|
|
39
|
+
pure
|
|
40
|
+
returns (bytes memory)
|
|
41
|
+
{
|
|
42
|
+
return abi.encode(_sender, CallType.CALL, _calls);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function calls(bytes calldata _message)
|
|
46
|
+
internal
|
|
47
|
+
pure
|
|
48
|
+
returns (CallLib.Call[] memory _calls)
|
|
49
|
+
{
|
|
50
|
+
assert(calltype(_message) == CallType.CALL);
|
|
51
|
+
(, , _calls) = abi.decode(
|
|
52
|
+
_message,
|
|
53
|
+
(bytes32, CallType, CallLib.Call[])
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function format(CallLib.StaticCall[] calldata _calls, bytes32 _sender)
|
|
58
|
+
internal
|
|
59
|
+
pure
|
|
60
|
+
returns (bytes memory)
|
|
61
|
+
{
|
|
62
|
+
return abi.encode(_sender, CallType.STATIC_CALL, _calls);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function staticCalls(bytes calldata _message)
|
|
66
|
+
internal
|
|
67
|
+
pure
|
|
68
|
+
returns (CallLib.StaticCall[] memory _calls)
|
|
69
|
+
{
|
|
70
|
+
assert(calltype(_message) == CallType.STATIC_CALL);
|
|
71
|
+
(, , _calls) = abi.decode(
|
|
72
|
+
_message,
|
|
73
|
+
(bytes32, CallType, CallLib.StaticCall[])
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function format(
|
|
78
|
+
CallLib.StaticCallWithCallback[] calldata _calls,
|
|
79
|
+
bytes32 _sender
|
|
80
|
+
) internal pure returns (bytes memory) {
|
|
81
|
+
return abi.encode(_sender, CallType.STATIC_CALL_WITH_CALLBACK, _calls);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function callsWithCallbacks(bytes calldata _message)
|
|
85
|
+
internal
|
|
86
|
+
pure
|
|
87
|
+
returns (CallLib.StaticCallWithCallback[] memory _calls)
|
|
88
|
+
{
|
|
89
|
+
assert(calltype(_message) == CallType.STATIC_CALL_WITH_CALLBACK);
|
|
90
|
+
(, , _calls) = abi.decode(
|
|
91
|
+
_message,
|
|
92
|
+
(bytes32, CallType, CallLib.StaticCallWithCallback[])
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function format(bytes[] memory _calls, bytes32 _sender)
|
|
97
|
+
internal
|
|
98
|
+
pure
|
|
99
|
+
returns (bytes memory)
|
|
100
|
+
{
|
|
101
|
+
return abi.encode(_sender, CallType.RAW_CALLDATA, _calls);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function rawCalls(bytes calldata _message)
|
|
105
|
+
internal
|
|
106
|
+
pure
|
|
107
|
+
returns (bytes[] memory _calls)
|
|
108
|
+
{
|
|
109
|
+
assert(calltype(_message) == CallType.RAW_CALLDATA);
|
|
110
|
+
(, , _calls) = abi.decode(_message, (bytes32, CallType, bytes[]));
|
|
111
|
+
}
|
|
112
|
+
}
|