@wormhole-foundation/wormhole-solidity-sdk 1.0.1 → 1.1.0

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.
@@ -1,18 +1,32 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.19;
3
3
 
4
- import {ICoreBridge} from "../interfaces/ICoreBridge.sol";
5
- import {IExecutor, IVaaV1Receiver} from "../interfaces/IExecutor.sol";
6
- import {CoreBridgeLib} from "../libraries/CoreBridge.sol";
7
- import {RequestLib} from "./Request.sol";
8
- import {RelayInstructionLib} from "./RelayInstruction.sol";
9
- import {toUniversalAddress} from "../Utils.sol";
4
+ import {ICoreBridge} from "../interfaces/ICoreBridge.sol";
5
+ import {IExecutor,
6
+ IExecutorQuoterRouter,
7
+ IVaaV1Receiver} from "../interfaces/IExecutor.sol";
8
+ import {CoreBridgeLib} from "../libraries/CoreBridge.sol";
9
+ import {RequestLib} from "./Request.sol";
10
+ import {RelayInstructionLib} from "./RelayInstruction.sol";
11
+ import {toUniversalAddress} from "../Utils.sol";
10
12
 
11
13
  //abstract base contracts for typical Executor integrations
12
- //integrators should inherit from exactly one of:
13
- // * ExecutorSend
14
+ //
15
+ //executor supports off-chain and on-chain quoting so there are two flavors of send contracts.
16
+ //
17
+ //send-only contracts should inherit from exactly one of:
18
+ // * ExecutorSendQuoteOffChain
19
+ // * ExecutorSendQuoteOnChain
20
+ // * ExecutorSendQuoteBoth
21
+ //
22
+ //receive-only contracts should inherit from:
14
23
  // * ExecutorReceive
15
- // * ExecutorSendReceive
24
+ //
25
+ //send-and-receive contracts should inherit from exactly one of:
26
+ // * ExecutorSendReceiveQuoteOffChain
27
+ // * ExecutorSendReceiveQuoteOnChain
28
+ // * ExecutorSendReceiveQuoteBoth
29
+ //
16
30
  //note: The Impl contracts are a nuisance to deal with the diamond inheritance pattern and
17
31
  // the "Base constructor arguments given twice" error that comes with it.
18
32
 
@@ -51,7 +65,40 @@ abstract contract ExecutorSharedBase {
51
65
  }
52
66
  }
53
67
 
54
- abstract contract ExecutorSendImpl is ExecutorSharedBase {
68
+ abstract contract ExecutorSendBase is ExecutorSharedBase {
69
+ function _publishAndCompose(
70
+ bytes memory payload,
71
+ uint8 consistencyLevel,
72
+ uint256 totalCost, //must equal execution cost + Wormhole message fee for publishing!
73
+ uint16 peerChain,
74
+ uint128 gasLimit,
75
+ uint128 msgVal,
76
+ bytes memory extraRelayInstructions
77
+ ) internal returns (
78
+ uint64 sequence,
79
+ bytes32 peerAddress,
80
+ bytes memory relayInstructions,
81
+ bytes memory requestBytes,
82
+ uint256 executorFee
83
+ ) {
84
+ uint messageFee = _coreBridge.messageFee();
85
+ uint32 nonce = 0; //unused
86
+ sequence = _coreBridge.publishMessage{value: messageFee}(nonce, payload, consistencyLevel);
87
+
88
+ relayInstructions = RelayInstructionLib.encodeGas(gasLimit, msgVal);
89
+ if (extraRelayInstructions.length > 0)
90
+ relayInstructions = abi.encodePacked(relayInstructions, extraRelayInstructions);
91
+
92
+ peerAddress = _getExistingPeer(peerChain);
93
+ requestBytes =
94
+ RequestLib.encodeVaaMultiSigRequest(_chainId, toUniversalAddress(address(this)), sequence);
95
+
96
+ //value calculation is unchecked because executor call will fail on underflow anyway
97
+ unchecked { executorFee = totalCost - messageFee; }
98
+ }
99
+ }
100
+
101
+ abstract contract ExecutorSendQuoteOffChainImpl is ExecutorSendBase {
55
102
  IExecutor internal immutable _executor;
56
103
 
57
104
  constructor(address executor) {
@@ -69,31 +116,81 @@ abstract contract ExecutorSendImpl is ExecutorSharedBase {
69
116
  uint128 msgVal,
70
117
  bytes memory extraRelayInstructions
71
118
  ) internal returns (uint64 sequence) { unchecked {
72
- uint messageFee = _coreBridge.messageFee();
73
- uint32 nonce = 0; //unused
74
- sequence = _coreBridge.publishMessage{value: messageFee}(nonce, payload, consistencyLevel);
119
+ ( uint64 sequence_,
120
+ bytes32 peerAddress,
121
+ bytes memory relayInstructions,
122
+ bytes memory requestBytes,
123
+ uint256 executorFee
124
+ ) = _publishAndCompose(
125
+ payload,
126
+ consistencyLevel,
127
+ totalCost,
128
+ peerChain,
129
+ gasLimit,
130
+ msgVal,
131
+ extraRelayInstructions
132
+ );
75
133
 
76
- bytes memory relayInstructions = RelayInstructionLib.encodeGas(gasLimit, msgVal);
77
- if (extraRelayInstructions.length > 0)
78
- relayInstructions = abi.encodePacked(relayInstructions, extraRelayInstructions);
134
+ _executor.requestExecution{value: executorFee}(
135
+ peerChain,
136
+ peerAddress,
137
+ refundAddress,
138
+ signedQuote,
139
+ requestBytes,
140
+ relayInstructions
141
+ );
79
142
 
80
- bytes32 peerAddress = _getExistingPeer(peerChain);
143
+ sequence = sequence_;
144
+ }}
145
+ }
146
+
147
+ abstract contract ExecutorSendQuoteOnChainImpl is ExecutorSendBase {
148
+ IExecutorQuoterRouter internal immutable _executorQuoterRouter;
149
+
150
+ constructor(address executorQuoterRouter) {
151
+ _executorQuoterRouter = IExecutorQuoterRouter(executorQuoterRouter);
152
+ }
81
153
 
82
- //value calculation is unchecked because call will fail on underflow anyway
83
- _executor.requestExecution{value: totalCost - messageFee}(
154
+ function _publishAndRelay(
155
+ bytes memory payload,
156
+ uint8 consistencyLevel,
157
+ uint256 totalCost, //must equal execution cost + Wormhole message fee for publishing!
158
+ uint16 peerChain,
159
+ address refundAddress,
160
+ address quoterAddress,
161
+ uint128 gasLimit,
162
+ uint128 msgVal,
163
+ bytes memory extraRelayInstructions
164
+ ) internal returns (uint64 sequence) { unchecked {
165
+ ( uint64 sequence_,
166
+ bytes32 peerAddress,
167
+ bytes memory relayInstructions,
168
+ bytes memory requestBytes,
169
+ uint256 executorFee
170
+ ) = _publishAndCompose(
171
+ payload,
172
+ consistencyLevel,
173
+ totalCost,
174
+ peerChain,
175
+ gasLimit,
176
+ msgVal,
177
+ extraRelayInstructions
178
+ );
179
+
180
+ _executorQuoterRouter.requestExecution{value: executorFee}(
84
181
  peerChain,
85
182
  peerAddress,
86
183
  refundAddress,
87
- signedQuote,
88
- RequestLib.encodeVaaMultiSigRequest(_chainId, toUniversalAddress(address(this)), sequence),
184
+ quoterAddress,
185
+ requestBytes,
89
186
  relayInstructions
90
187
  );
188
+
189
+ sequence = sequence_;
91
190
  }}
92
191
  }
93
192
 
94
193
  abstract contract ExecutorReceiveImpl is ExecutorSharedBase, IVaaV1Receiver {
95
- constructor(address coreBridge) {}
96
-
97
194
  //default impl as safeguard - integrators should override this with an empty impl and perform
98
195
  // appropriate check in their impl of _executeVaa instead, if they allow for non-zero msg.value
99
196
  function _executeVaaDefaultMsgValueCheck() internal virtual {
@@ -158,23 +255,46 @@ abstract contract ExecutorReceiveImpl is ExecutorSharedBase, IVaaV1Receiver {
158
255
  }
159
256
  }
160
257
 
161
- abstract contract ExecutorSend is ExecutorSharedBase, ExecutorSendImpl {
258
+ abstract contract ExecutorSendQuoteOffChain is ExecutorSharedBase, ExecutorSendQuoteOffChainImpl {
162
259
  constructor(address coreBridge, address executor)
163
260
  ExecutorSharedBase(coreBridge)
164
- ExecutorSendImpl(executor)
165
- {}
261
+ ExecutorSendQuoteOffChainImpl(executor) {}
262
+ }
263
+
264
+ abstract contract ExecutorSendQuoteOnChain is ExecutorSharedBase, ExecutorSendQuoteOnChainImpl {
265
+ constructor(address coreBridge, address executorQuoterRouter)
266
+ ExecutorSharedBase(coreBridge)
267
+ ExecutorSendQuoteOnChainImpl(executorQuoterRouter) {}
268
+ }
269
+
270
+ abstract contract ExecutorSendQuoteBoth is
271
+ ExecutorSharedBase, ExecutorSendQuoteOffChainImpl, ExecutorSendQuoteOnChainImpl {
272
+ constructor(address coreBridge, address executor, address executorQuoterRouter)
273
+ ExecutorSharedBase(coreBridge)
274
+ ExecutorSendQuoteOffChainImpl(executor)
275
+ ExecutorSendQuoteOnChainImpl(executorQuoterRouter) {}
166
276
  }
167
277
 
168
278
  abstract contract ExecutorReceive is ExecutorSharedBase, ExecutorReceiveImpl {
169
279
  constructor(address coreBridge)
170
- ExecutorSharedBase(coreBridge)
171
- ExecutorReceiveImpl(coreBridge)
172
- {}
280
+ ExecutorSharedBase(coreBridge) {}
173
281
  }
174
282
 
175
- abstract contract ExecutorSendReceive is ExecutorSharedBase, ExecutorSendImpl, ExecutorReceiveImpl {
283
+ abstract contract ExecutorSendReceiveQuoteOffChain is
284
+ ExecutorSharedBase, ExecutorSendQuoteOffChainImpl, ExecutorReceiveImpl {
176
285
  constructor(address coreBridge, address executor)
177
- ExecutorSendImpl(executor)
178
- ExecutorReceiveImpl(coreBridge)
179
- ExecutorSharedBase(coreBridge) {}
286
+ ExecutorSharedBase(coreBridge)
287
+ ExecutorSendQuoteOffChainImpl(executor) {}
288
+ }
289
+
290
+ abstract contract ExecutorSendReceiveQuoteOnChain is
291
+ ExecutorSharedBase, ExecutorSendQuoteOnChainImpl, ExecutorReceiveImpl {
292
+ constructor(address coreBridge, address executorQuoterRouter)
293
+ ExecutorSharedBase(coreBridge)
294
+ ExecutorSendQuoteOnChainImpl(executorQuoterRouter) {}
295
+ }
296
+
297
+ abstract contract ExecutorSendReceiveQuoteBoth is ExecutorReceiveImpl, ExecutorSendQuoteBoth {
298
+ constructor(address coreBridge, address executor, address executorQuoterRouter)
299
+ ExecutorSendQuoteBoth(coreBridge, executor, executorQuoterRouter) {}
180
300
  }
@@ -49,7 +49,7 @@ library RelayInstructionLib {
49
49
  gasDropOffInstructionCount * GAS_DROP_OFF_INSTRUCTION_SIZE;
50
50
  }}
51
51
 
52
- function encodeGasDropOffInstructionUnchecked(
52
+ function encodeGasInstructionUnchecked(
53
53
  uint128 gasLimit,
54
54
  uint128 msgVal,
55
55
  bytes memory buffer,
@@ -46,6 +46,8 @@ uint16 constant CHAIN_ID_XRPLEVM = 57;
46
46
  uint16 constant CHAIN_ID_PLASMA = 58;
47
47
  uint16 constant CHAIN_ID_CREDIT_COIN = 59;
48
48
  uint16 constant CHAIN_ID_STACKS = 60;
49
+ uint16 constant CHAIN_ID_MOCA = 63;
50
+ uint16 constant CHAIN_ID_MEGA_ETH = 64;
49
51
  uint16 constant CHAIN_ID_WORMCHAIN = 3104;
50
52
  uint16 constant CHAIN_ID_COSMOSHUB = 4000;
51
53
  uint16 constant CHAIN_ID_EVMOS = 4001;
@@ -63,4 +65,5 @@ uint16 constant CHAIN_ID_BASE_SEPOLIA = 10004;
63
65
  uint16 constant CHAIN_ID_OPTIMISM_SEPOLIA = 10005;
64
66
  uint16 constant CHAIN_ID_HOLESKY = 10006;
65
67
  uint16 constant CHAIN_ID_POLYGON_SEPOLIA = 10007;
68
+ uint16 constant CHAIN_ID_MONAD_TESTNET = 10009;
66
69
  uint16 constant CHAIN_ID_HYPER_CORE = 65000;
@@ -27,6 +27,59 @@ interface IExecutor {
27
27
 
28
28
  //from https://github.com/wormholelabs-xyz/example-messaging-executor/blob/ec5daea3c03f8860a62c23e28db5c6dc8771a9ce/evm/src/interfaces/IVaaV1Receiver.sol
29
29
  //required interface for receiving MultiSig (=V1) VAAs from the executor
30
+
30
31
  interface IVaaV1Receiver {
31
32
  function executeVAAv1(bytes memory multiSigVaa) external payable;
32
33
  }
34
+
35
+ // ---- On-chain Quoting ----
36
+
37
+ //see https://github.com/wormholelabs-xyz/example-messaging-executor/blob/main/design/02_On_Chain_Quotes.md
38
+
39
+ //from https://github.com/wormholelabs-xyz/example-messaging-executor/blob/main/evm/src/interfaces/IExecutorQuoter.sol
40
+
41
+ interface IExecutorQuoter {
42
+ function requestQuote(
43
+ uint16 dstChain,
44
+ bytes32 dstAddr,
45
+ address refundAddr,
46
+ bytes calldata requestBytes,
47
+ bytes calldata relayInstructions
48
+ ) external view returns (uint256 requiredMsgValue);
49
+
50
+ function requestExecutionQuote(
51
+ uint16 dstChain,
52
+ bytes32 dstAddr,
53
+ address refundAddr,
54
+ bytes calldata requestBytes,
55
+ bytes calldata relayInstructions
56
+ ) external returns (
57
+ uint256 requiredMsgValue,
58
+ bytes32 payee,
59
+ bytes32 quoteBody //= packed(baseFee, dstGasPrice, srcPrice, dstPrice)
60
+ );
61
+ }
62
+
63
+ //from https://github.com/wormholelabs-xyz/example-messaging-executor/blob/main/evm/src/interfaces/IExecutorQuoterRouter.sol
64
+
65
+ event OnChainQuote(address quoterContract); //emitted by IExecutorQuoterRouter.requestExecution()
66
+
67
+ interface IExecutorQuoterRouter {
68
+ function quoteExecution(
69
+ uint16 dstChain,
70
+ bytes32 dstAddr,
71
+ address refundAddr,
72
+ address quoterAddr,
73
+ bytes calldata requestBytes,
74
+ bytes calldata relayInstructions
75
+ ) external view returns (uint256);
76
+
77
+ function requestExecution(
78
+ uint16 dstChain,
79
+ bytes32 dstAddr,
80
+ address refundAddr,
81
+ address quoterAddr,
82
+ bytes calldata requestBytes,
83
+ bytes calldata relayInstructions
84
+ ) external payable;
85
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wormhole-foundation/wormhole-solidity-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Wormhole Solidity SDK",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {