@wormhole-foundation/wormhole-solidity-sdk 1.0.1

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.
Files changed (56) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +78 -0
  3. package/contracts/Executor/Integration.sol +180 -0
  4. package/contracts/Executor/RelayInstruction.sol +108 -0
  5. package/contracts/Executor/Request.sol +43 -0
  6. package/contracts/RawDispatcher.sol +29 -0
  7. package/contracts/Utils.sol +27 -0
  8. package/contracts/WormholeRelayer/AdditionalMessages.sol +37 -0
  9. package/contracts/WormholeRelayer/Keys.sol +198 -0
  10. package/contracts/WormholeRelayer/Receiver.sol +44 -0
  11. package/contracts/WormholeRelayer/Sender.sol +264 -0
  12. package/contracts/WormholeRelayer.sol +7 -0
  13. package/contracts/constants/CctpDomainMapping.sol +72 -0
  14. package/contracts/constants/CctpDomains.sol +21 -0
  15. package/contracts/constants/Chains.sol +66 -0
  16. package/contracts/constants/Common.sol +17 -0
  17. package/contracts/constants/ConsistencyLevel.sol +9 -0
  18. package/contracts/interfaces/ICoreBridge.sol +80 -0
  19. package/contracts/interfaces/ICustomConsistencyLevel.sol +12 -0
  20. package/contracts/interfaces/IDeliveryProvider.sol +84 -0
  21. package/contracts/interfaces/IExecutor.sol +32 -0
  22. package/contracts/interfaces/ITokenBridge.sol +81 -0
  23. package/contracts/interfaces/IWormholeRelayer.sol +658 -0
  24. package/contracts/interfaces/cctp/IMessageTransmitter.sol +76 -0
  25. package/contracts/interfaces/cctp/ITokenMessenger.sol +72 -0
  26. package/contracts/interfaces/cctp/ITokenMinter.sol +40 -0
  27. package/contracts/interfaces/cctp/shared/IOwnable2Step.sol +18 -0
  28. package/contracts/interfaces/cctp/shared/IPausable.sol +20 -0
  29. package/contracts/interfaces/token/IERC20.sol +16 -0
  30. package/contracts/interfaces/token/IERC20Metadata.sol +11 -0
  31. package/contracts/interfaces/token/IERC20Permit.sol +19 -0
  32. package/contracts/interfaces/token/IWETH.sol +12 -0
  33. package/contracts/libraries/BytesParsing.sol +2848 -0
  34. package/contracts/libraries/CctpMessages.sol +755 -0
  35. package/contracts/libraries/CoreBridge.sol +365 -0
  36. package/contracts/libraries/CustomConsistency.sol +60 -0
  37. package/contracts/libraries/Percentage.sol +99 -0
  38. package/contracts/libraries/PermitParsing.sol +580 -0
  39. package/contracts/libraries/QueryResponse.sol +741 -0
  40. package/contracts/libraries/ReplayProtection.sol +106 -0
  41. package/contracts/libraries/SafeERC20.sol +67 -0
  42. package/contracts/libraries/TokenBridgeMessages.sol +742 -0
  43. package/contracts/libraries/TypedUnits.sol +304 -0
  44. package/contracts/libraries/UncheckedIndexing.sol +99 -0
  45. package/contracts/libraries/VaaLib.sol +1385 -0
  46. package/contracts/proxy/Eip1967Admin.sol +20 -0
  47. package/contracts/proxy/Eip1967Implementation.sol +15 -0
  48. package/contracts/proxy/Proxy.sol +43 -0
  49. package/contracts/proxy/ProxyBase.sol +80 -0
  50. package/contracts/utils/DecimalNormalization.sol +18 -0
  51. package/contracts/utils/EagerOps.sol +18 -0
  52. package/contracts/utils/Keccak.sol +39 -0
  53. package/contracts/utils/Revert.sol +11 -0
  54. package/contracts/utils/Transfer.sol +23 -0
  55. package/contracts/utils/UniversalAddress.sol +17 -0
  56. package/package.json +23 -0
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2022 Wormhole Project Contributors
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # Wormhole Solidity SDK
2
+
3
+ The purpose of this SDK is to make on-chain integrations with Wormhole on EVM compatible chains as smooth as possible by providing all necessary Solidity interfaces along with useful libraries and tools for testing.
4
+
5
+ For off-chain code, please refer to the [TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts) and in particular the [EVM platform implementation](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms/evm).
6
+
7
+ ## Releases
8
+
9
+ > License Reminder
10
+ >
11
+ > The code is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ >
13
+ > So make sure you check / audit any code you use before deploying to mainnet.
14
+
15
+ The `main` branch is considered the nightly version of the SDK. Stick to tagged releases for a stable experience.
16
+
17
+ **Note: The SDK is currently on its way to a version 1.0 . Proceed with extra caution until then.**
18
+
19
+ ## Installation
20
+
21
+ **Foundry and Forge**
22
+
23
+ ```bash
24
+ forge install wormhole-foundation/wormhole-solidity-sdk@v1.0.0
25
+ ```
26
+
27
+ **EVM Version**
28
+
29
+ One hazard of developing EVM contracts in a cross-chain environment is that different chains have varying levels of "EVM-equivalence". This means you have to ensure that all chains that you are planning to deploy to support all EIPs/opcodes that you rely on.
30
+
31
+ For example, if you are using a solc version newer than `0.8.19` and are planning to deploy to a chain that does not support [PUSH0 opcode](https://eips.ethereum.org/EIPS/eip-3855) (introduced as part of the Shanghai hardfork), you should set `evm_version = "paris"` in your `foundry.toml`, since the default EVM version of solc was advanced from Paris to Shanghai as part of solc's `0.8.20` release.
32
+
33
+ **Via-IR Support**
34
+
35
+ Some of the components of this SDK require the use of intermediate representation to enable more powerful optimization passes that span across functions. This also resolves `stack-too-deep` issues that the standard compiler cannot resolve currently. The tradeoff for enabling this feature is slightly longer compilation times (up to 15 seconds). This functionality is not to be considered experimental (read [comments](https://forum.soliditylang.org/t/can-someone-explain-how-via-ir-works/1898/5) from the Solidity Development Team) but a tradeoff until there is a better handling of the stack by the solidity compiler.
36
+
37
+ **Testing**
38
+
39
+ It is strongly recommended that you run the forge test suite of this SDK with your own compiler version to catch potential errors that stem from differences in compiler versions early. Yes, strictly speaking the Solidity version pragma should prevent these issues, but better to be safe than sorry, especially given that some components make extensive use of inline assembly.
40
+
41
+ **IERC20 and SafeERC20 Remapping**
42
+
43
+ This SDK comes with its own IERC20 interface and SafeERC20 implementation. Given that projects tend to combine different SDKs, there's often this annoying issue of clashes of IERC20 interfaces, even though they are effectively the same. We handle this issue by importing `IERC20/IERC20.sol` which allows remapping the `IERC20/` prefix to whatever directory contains `IERC20.sol` in your project, thus providing an override mechanism that should allow dealing with this problem seamlessly until forge allows remapping of individual files. The same approach is used for SafeERC20.
44
+
45
+ ## Components & Testing
46
+
47
+ For additional documentation of components and how to test integrations, see the docs directory.
48
+
49
+ ## Security
50
+
51
+ This repository has been thoroughly reviewed by Wormhole Contributors and key files have been audited by a 3rd party. To ensure you are using production-ready code, always use tagged releases. If you need to use newer code from `main`, please contact the team for any security concerns.
52
+
53
+ ## Style
54
+
55
+ This SDK largely follows [the Solidity style guide](https://docs.soliditylang.org/en/latest/style-guide.html) with some exceptions/modifications:
56
+
57
+ - indentation uses 2 instead of 4 spaces
58
+ - maximum line length where feasible is 100 characters (urls in comments are an exception)
59
+ - [order of functions](https://docs.soliditylang.org/en/latest/style-guide.html) is roughly followed but more important functions might be sorted to the top.
60
+ - additional whitespace is at times added to create more compelling visual blocks (e.g. for a block of related assignments)
61
+ - function modifiers do not get a separate line each once line length is exceeded
62
+ - NatSpec is avoided because it favors a "box-checking" approach towards documentation rather than focusing on essentials and rationales
63
+
64
+ ## Philosophy/Creeds
65
+
66
+ In This House We Believe:
67
+
68
+ - clarity breeds security
69
+ - Do NOT trust in the Lord (i.e. the community, auditors, fellow devs, FOSS, ...) with any of your heart (i.e. with your or your users' security), but lean _hard_ on your own understanding.
70
+ - _Nothing_ is considered safe unless you have _personally_ verified it as such.
71
+ - git gud
72
+ - shut up and suffer
73
+
74
+ ## Notable Solidity Repos
75
+
76
+ - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)
77
+ - [Solmate](https://github.com/transmissions11/solmate) / [Solady](https://github.com/Vectorized/solady)
78
+ - [Uniswap Permit2](https://github.com/Uniswap/permit2) + [explanation](https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/permit2)
@@ -0,0 +1,180 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.19;
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";
10
+
11
+ //abstract base contracts for typical Executor integrations
12
+ //integrators should inherit from exactly one of:
13
+ // * ExecutorSend
14
+ // * ExecutorReceive
15
+ // * ExecutorSendReceive
16
+ //note: The Impl contracts are a nuisance to deal with the diamond inheritance pattern and
17
+ // the "Base constructor arguments given twice" error that comes with it.
18
+
19
+ // ╭─────────────────────────────╮
20
+ // │ WARNING: Receiving VAAs │
21
+ // ╰─────────────────────────────╯
22
+ //
23
+ // When reciving a VAA, you must ensure:
24
+ // 1. The VAA was emitted by a known peer to prevent spoofing - see _checkPeer
25
+ // 2. The VAA was intended for this chain - see _checkDestination
26
+ //
27
+ // Emitter information is part of the VAA itself, but due to Wormhole's design as an attestion
28
+ // mechanism, there is no destination chain in the VAA header itself.
29
+ // It is therefore up to the integrator to include such a field in message payloads of messages
30
+ // with an intended target.
31
+
32
+ error InvalidPeer();
33
+ error DestinationMismatch();
34
+
35
+ abstract contract ExecutorSharedBase {
36
+ ICoreBridge internal immutable _coreBridge;
37
+ uint16 internal immutable _chainId;
38
+
39
+ constructor(address coreBridge) {
40
+ _coreBridge = ICoreBridge(coreBridge);
41
+ _chainId = _coreBridge.chainId();
42
+ }
43
+
44
+ //should return bytes32(0) if there is no peer on the given chain
45
+ function _getPeer(uint16 chainId) internal view virtual returns (bytes32);
46
+
47
+ function _getExistingPeer(uint16 chainId) internal view virtual returns (bytes32 peer) {
48
+ peer = _getPeer(chainId);
49
+ if (peer == bytes32(0))
50
+ revert InvalidPeer();
51
+ }
52
+ }
53
+
54
+ abstract contract ExecutorSendImpl is ExecutorSharedBase {
55
+ IExecutor internal immutable _executor;
56
+
57
+ constructor(address executor) {
58
+ _executor = IExecutor(executor);
59
+ }
60
+
61
+ function _publishAndRelay(
62
+ bytes memory payload,
63
+ uint8 consistencyLevel,
64
+ uint256 totalCost, //must equal execution cost + Wormhole message fee for publishing!
65
+ uint16 peerChain,
66
+ address refundAddress,
67
+ bytes calldata signedQuote,
68
+ uint128 gasLimit,
69
+ uint128 msgVal,
70
+ bytes memory extraRelayInstructions
71
+ ) internal returns (uint64 sequence) { unchecked {
72
+ uint messageFee = _coreBridge.messageFee();
73
+ uint32 nonce = 0; //unused
74
+ sequence = _coreBridge.publishMessage{value: messageFee}(nonce, payload, consistencyLevel);
75
+
76
+ bytes memory relayInstructions = RelayInstructionLib.encodeGas(gasLimit, msgVal);
77
+ if (extraRelayInstructions.length > 0)
78
+ relayInstructions = abi.encodePacked(relayInstructions, extraRelayInstructions);
79
+
80
+ bytes32 peerAddress = _getExistingPeer(peerChain);
81
+
82
+ //value calculation is unchecked because call will fail on underflow anyway
83
+ _executor.requestExecution{value: totalCost - messageFee}(
84
+ peerChain,
85
+ peerAddress,
86
+ refundAddress,
87
+ signedQuote,
88
+ RequestLib.encodeVaaMultiSigRequest(_chainId, toUniversalAddress(address(this)), sequence),
89
+ relayInstructions
90
+ );
91
+ }}
92
+ }
93
+
94
+ abstract contract ExecutorReceiveImpl is ExecutorSharedBase, IVaaV1Receiver {
95
+ constructor(address coreBridge) {}
96
+
97
+ //default impl as safeguard - integrators should override this with an empty impl and perform
98
+ // appropriate check in their impl of _executeVaa instead, if they allow for non-zero msg.value
99
+ function _executeVaaDefaultMsgValueCheck() internal virtual {
100
+ require(msg.value == 0);
101
+ }
102
+
103
+ //impl via the appropriate replay protection library from ReplayProtectionLib.sol
104
+ function _replayProtect(
105
+ uint16 emitterChainId,
106
+ bytes32 emitterAddress,
107
+ uint64 sequence,
108
+ bytes calldata encodedVaa
109
+ ) internal virtual;
110
+
111
+ //WARNING: must correctly handle non-zero msg.value (since invoking function is payable)
112
+ function _executeVaa(
113
+ bytes calldata payload,
114
+ uint32 timestamp,
115
+ uint16 peerChain,
116
+ bytes32 peerAddress,
117
+ uint64 sequence,
118
+ uint8 consistencyLevel
119
+ ) internal virtual;
120
+
121
+ //ATTENTION: You typically want to ensure that a VAA is intended for this chain
122
+ // to protect against VAA submission on other chains.
123
+ function _checkDestination(uint16 destinationChainId) internal view virtual {
124
+ if (destinationChainId != _chainId)
125
+ revert DestinationMismatch();
126
+ }
127
+
128
+ //ATTENTION: You must ensure that the emitter of the VAA does indeed match a known
129
+ // peer to prevent spoofing.
130
+ function _checkPeer(uint16 chainId, bytes32 peerAddress) internal view virtual {
131
+ if (_getPeer(chainId) != peerAddress)
132
+ revert InvalidPeer();
133
+ }
134
+
135
+ function executeVAAv1(bytes calldata multiSigVaa) external payable virtual {
136
+ _executeVaaDefaultMsgValueCheck();
137
+
138
+ ( uint32 timestamp,
139
+ , //nonce is ignored
140
+ uint16 emitterChainId,
141
+ bytes32 emitterAddress,
142
+ uint64 sequence,
143
+ uint8 consistencyLevel,
144
+ bytes calldata payload
145
+ ) = CoreBridgeLib.decodeAndVerifyVaaCd(address(_coreBridge), multiSigVaa);
146
+
147
+ _checkPeer(emitterChainId, emitterAddress);
148
+ _replayProtect(emitterChainId, emitterAddress, sequence, multiSigVaa);
149
+
150
+ _executeVaa(
151
+ payload,
152
+ timestamp,
153
+ emitterChainId,
154
+ emitterAddress,
155
+ sequence,
156
+ consistencyLevel
157
+ );
158
+ }
159
+ }
160
+
161
+ abstract contract ExecutorSend is ExecutorSharedBase, ExecutorSendImpl {
162
+ constructor(address coreBridge, address executor)
163
+ ExecutorSharedBase(coreBridge)
164
+ ExecutorSendImpl(executor)
165
+ {}
166
+ }
167
+
168
+ abstract contract ExecutorReceive is ExecutorSharedBase, ExecutorReceiveImpl {
169
+ constructor(address coreBridge)
170
+ ExecutorSharedBase(coreBridge)
171
+ ExecutorReceiveImpl(coreBridge)
172
+ {}
173
+ }
174
+
175
+ abstract contract ExecutorSendReceive is ExecutorSharedBase, ExecutorSendImpl, ExecutorReceiveImpl {
176
+ constructor(address coreBridge, address executor)
177
+ ExecutorSendImpl(executor)
178
+ ExecutorReceiveImpl(coreBridge)
179
+ ExecutorSharedBase(coreBridge) {}
180
+ }
@@ -0,0 +1,108 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.19;
3
+
4
+ import {UncheckedIndexing} from "../libraries/UncheckedIndexing.sol";
5
+
6
+ //RelayInstructions are concatenated as tightly packed bytes.
7
+ //If the same type of instruction exists multiple times, its values are summed.
8
+ //see https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/executor/relayInstruction.ts
9
+ //and also: https://github.com/wormholelabs-xyz/example-executor-ci-test/blob/6bf0e7156bf81d54f3ded707e53815a2ff62555e/src/utils.ts#L37-L71
10
+
11
+ library RelayInstructionLib {
12
+ uint8 internal constant RECV_INST_TYPE_GAS = 1;
13
+ uint8 internal constant RECV_INST_TYPE_DROP_OFF = 2;
14
+
15
+ function encodeGas(uint128 gasLimit, uint128 msgVal) internal pure returns (bytes memory) {
16
+ return abi.encodePacked(RECV_INST_TYPE_GAS, gasLimit, msgVal);
17
+ }
18
+
19
+ function encodeGasDropOffInstruction(
20
+ uint128 dropOff,
21
+ bytes32 recipient
22
+ ) internal pure returns (bytes memory) {
23
+ return abi.encodePacked(RECV_INST_TYPE_DROP_OFF, dropOff, recipient);
24
+ }
25
+
26
+ function encodeGasDropOffInstructions(
27
+ uint128[] memory dropOffs,
28
+ bytes32[] memory recipients
29
+ ) internal pure returns (bytes memory instructions) { unchecked {
30
+ uint instructionCount = dropOffs.length;
31
+ assert(instructionCount == recipients.length);
32
+
33
+ instructions = new bytes(instructionCount * GAS_DROP_OFF_INSTRUCTION_SIZE);
34
+ encodeGasDropOffInstructionsUnchecked(dropOffs, recipients, instructions, 0);
35
+ }}
36
+
37
+ //more complex implementations for higher gas efficiency below:
38
+ using UncheckedIndexing for uint128[];
39
+ using UncheckedIndexing for bytes32[];
40
+
41
+ uint256 internal constant GAS_INSTRUCTION_SIZE = 33;
42
+ uint256 internal constant GAS_DROP_OFF_INSTRUCTION_SIZE = 49;
43
+
44
+ function calcBytesSize(
45
+ uint gasInstructionCount,
46
+ uint gasDropOffInstructionCount
47
+ ) internal pure returns (uint) { unchecked {
48
+ return gasInstructionCount * GAS_INSTRUCTION_SIZE +
49
+ gasDropOffInstructionCount * GAS_DROP_OFF_INSTRUCTION_SIZE;
50
+ }}
51
+
52
+ function encodeGasDropOffInstructionUnchecked(
53
+ uint128 gasLimit,
54
+ uint128 msgVal,
55
+ bytes memory buffer,
56
+ uint offset
57
+ ) internal pure returns (uint newOffset) {
58
+ assembly ("memory-safe") {
59
+ let ptr := add(buffer, offset)
60
+ let word := mload(ptr)
61
+ //store type while keeping higher order bits intact
62
+ word := or(shl(8, word), RECV_INST_TYPE_GAS)
63
+ mstore(add(ptr, 1), word)
64
+
65
+ //store gas limit and msg val
66
+ word := or(shl(128, gasLimit), msgVal)
67
+ newOffset := add(offset, GAS_INSTRUCTION_SIZE) //equal to add(ptr, 32)
68
+ mstore(add(buffer, newOffset), word)
69
+ }
70
+ }
71
+
72
+ function encodeGasDropOffInstructionUnchecked(
73
+ uint128 dropOff,
74
+ bytes32 recipient,
75
+ bytes memory buffer,
76
+ uint offset
77
+ ) internal pure returns (uint newOffset) {
78
+ assembly ("memory-safe") {
79
+ //store type and amount while keeping higher order bits intact
80
+ let ptr := add(buffer, offset)
81
+ let word := mload(ptr)
82
+ word := or(shl(8, word), RECV_INST_TYPE_DROP_OFF)
83
+ word := or(shl(128, word), dropOff)
84
+ mstore(add(ptr, 17), word)
85
+
86
+ //store recipient
87
+ newOffset := add(offset, GAS_DROP_OFF_INSTRUCTION_SIZE) //equal to add(ptr, 32)
88
+ mstore(add(buffer, newOffset), recipient)
89
+ }
90
+ }
91
+
92
+ function encodeGasDropOffInstructionsUnchecked(
93
+ uint128[] memory dropOffs,
94
+ bytes32[] memory recipients,
95
+ bytes memory buffer,
96
+ uint offset
97
+ ) internal pure returns (uint newOffset) { unchecked {
98
+ uint instructionCount = dropOffs.length;
99
+ newOffset = offset;
100
+ for (uint i = 0; i < instructionCount; ++i)
101
+ newOffset = encodeGasDropOffInstructionUnchecked(
102
+ dropOffs.readUnchecked(i),
103
+ recipients.readUnchecked(i),
104
+ buffer,
105
+ newOffset
106
+ );
107
+ }}
108
+ }
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.19;
3
+
4
+ //see: https://github.com/wormholelabs-xyz/example-messaging-executor/blob/ec5daea3c03f8860a62c23e28db5c6dc8771a9ce/evm/src/libraries/ExecutorMessages.sol
5
+ //and also: https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0379af2b0562c832bf4d2ff3d866ffca2ac92aae/core/definitions/src/protocols/executor/api.ts#L46
6
+
7
+ library RequestLib {
8
+ bytes4 internal constant REQ_VAA_V1 = "ERV1";
9
+ bytes4 internal constant REQ_NTT_V1 = "ERN1";
10
+ bytes4 internal constant REQ_CCTP_V1 = "ERC1";
11
+ bytes4 internal constant REQ_CCTP_V2 = "ERC2";
12
+
13
+ function encodeVaaMultiSigRequest(
14
+ uint16 emitterChain,
15
+ bytes32 emitterAddress,
16
+ uint64 sequence
17
+ ) internal pure returns (bytes memory) {
18
+ return abi.encodePacked(REQ_VAA_V1, emitterChain, emitterAddress, sequence);
19
+ }
20
+
21
+ //messageId specifies the manager message id for the NTT transfer
22
+ //for VAAs that's just the sequence number
23
+ function encodeNttRequest(
24
+ uint16 srcChain,
25
+ bytes32 srcManager,
26
+ bytes32 messageId
27
+ ) internal pure returns (bytes memory) {
28
+ return abi.encodePacked(REQ_NTT_V1, srcChain, srcManager, messageId);
29
+ }
30
+
31
+ function encodeCctpV1Request(
32
+ uint32 srcDomain,
33
+ uint64 nonce
34
+ ) internal pure returns (bytes memory) {
35
+ return abi.encodePacked(REQ_CCTP_V1, srcDomain, nonce);
36
+ }
37
+
38
+ //this request currently assumes the Executor will auto detect the event off chain.
39
+ //that may change in the future, in which case this interface would change.
40
+ function encodeCctpV2Request() internal pure returns (bytes memory) {
41
+ return abi.encodePacked(REQ_CCTP_V2, uint8(1));
42
+ }
43
+ }
@@ -0,0 +1,29 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.0;
3
+
4
+ //TL;DR:
5
+ // Allows implementing custom call dispatching logic that is more efficient both in terms
6
+ // of gas (only when using the via-IR pipeline!) and calldata size than Solidity's default
7
+ // encoding and dispatching.
8
+ //
9
+ // The numbers in the function names of this contract are meaningless and only serve the
10
+ // purpose of yielding a low selector that will guarantee that these functions will come
11
+ // first in Solidity's default function sorting _when using the via-IR pipeline_.
12
+ //
13
+ //See docs/RawDispatcher.md for details.
14
+ abstract contract RawDispatcher {
15
+
16
+ //selector: 00000eb6
17
+ function exec768() external payable returns (bytes memory) {
18
+ return _exec(msg.data[4:]);
19
+ }
20
+
21
+ //selector: 0008a112
22
+ function get1959() external view returns (bytes memory) {
23
+ return _get(msg.data[4:]);
24
+ }
25
+
26
+ function _exec(bytes calldata data) internal virtual returns (bytes memory);
27
+
28
+ function _get(bytes calldata data) internal view virtual returns (bytes memory);
29
+ }
@@ -0,0 +1,27 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.4;
3
+
4
+ import {
5
+ tokenOrNativeTransfer
6
+ } from "./utils/Transfer.sol";
7
+ import {
8
+ reRevert
9
+ } from "./utils/Revert.sol";
10
+ import {
11
+ NotAnEvmAddress,
12
+ toUniversalAddress,
13
+ fromUniversalAddress
14
+ } from "./utils/UniversalAddress.sol";
15
+ import {
16
+ keccak256Word,
17
+ keccak256SliceUnchecked,
18
+ keccak256Cd
19
+ } from "./utils/Keccak.sol";
20
+ import {
21
+ eagerAnd,
22
+ eagerOr
23
+ } from "./utils/EagerOps.sol";
24
+ import {
25
+ normalizeAmount,
26
+ deNormalizeAmount
27
+ } from "./utils/DecimalNormalization.sol";
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.19;
3
+
4
+ import {WORD_SIZE} from "../constants/Common.sol";
5
+
6
+ // The `additionalMessages` parameter of `receiveWormholeMessages` contains the list of
7
+ // VAAs, CCTP messages, and potentially other messages that were requested for delivery in
8
+ // their speficied order.
9
+ //
10
+ // VAAs requested via VaaKey are delivered as normally encoded VAAs, just as one would expect.
11
+ //
12
+ // CCTP messages on the other hand do not include the associated attestation in their format but
13
+ // instead expect the attestation to be provided separately.
14
+ // So the message associated with a CctpKey is a tuple of (CCTP message, attestation) and
15
+ // `unpackAdditionalCctpMessage` can be used to extract them.
16
+ //
17
+ // To further decode VAAs or CctpMessages, check out the `VaaLib` and `CctpLib` libraries.
18
+ // To verify VAAs more efficiently, check out the `CoreBridge` library.
19
+
20
+ function unpackAdditionalCctpMessage(
21
+ bytes calldata message
22
+ ) pure returns (bytes calldata cctpMessage, bytes calldata attestation) {
23
+ assembly ("memory-safe") {
24
+ // message.offset points to ABI-encoded struct {bytes cctpMessage, bytes attestation}
25
+ // First word is offset to cctpMessage bytes (always 0x40)
26
+ // Second word is offset to attestation bytes
27
+ let attestationRelativeOffset := calldataload(add(message.offset, WORD_SIZE))
28
+
29
+ let cctpMessageLengthOffset := add(message.offset, 0x40)
30
+ cctpMessage.offset := add(cctpMessageLengthOffset, WORD_SIZE)
31
+ cctpMessage.length := calldataload(cctpMessageLengthOffset)
32
+
33
+ let attestationLengthOffset := add(message.offset, attestationRelativeOffset)
34
+ attestation.offset := add(attestationLengthOffset, WORD_SIZE)
35
+ attestation.length := calldataload(attestationLengthOffset)
36
+ }
37
+ }