@layerzerolabs/oapp-evm-contracts 0.2.74

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.
@@ -0,0 +1,56 @@
1
+
2
+ > @layerzerolabs/oapp-evm-contracts@0.0.0 lint /home/runner/work/monorepo-internal/monorepo-internal/apps/oapp-app/contracts/evm/non-upgradeable
3
+ > solhint --config solhint.config.js 'contracts/**/*.sol' 'test/**/*.sol' --fix --noPrompt
4
+
5
+ A new version of Solhint is available: 6.2.1
6
+ Please consider updating your Solhint package.
7
+
8
+ contracts/interfaces/IOAppComposer.sol
9
+ 11:1 warning Missing @title tag in contract 'IOAppComposer' use-natspec
10
+ 11:1 warning Missing @author tag in contract 'IOAppComposer' use-natspec
11
+ 11:1 warning Missing @notice tag in contract 'IOAppComposer' use-natspec
12
+
13
+ contracts/interfaces/IOAppCore.sol
14
+ 9:1 warning Missing @author tag in contract 'IOAppCore' use-natspec
15
+ 9:1 warning Missing @notice tag in contract 'IOAppCore' use-natspec
16
+ 17:5 warning Missing @notice tag in event 'PeerSet' use-natspec
17
+ 17:5 warning Missing @param tag in event 'PeerSet' use-natspec
18
+ 17:5 warning Mismatch in @param names for event 'PeerSet'. Expected: [eid, peer], Found: [] use-natspec
19
+ 17:5 warning GC: [eid] on Event [PeerSet] could be Indexed gas-indexed-events
20
+
21
+ contracts/interfaces/IOAppExtended.sol
22
+ 17:1 warning Code contains empty blocks no-empty-blocks
23
+
24
+ contracts/interfaces/IOAppMsgInspection.sol
25
+ 15:5 warning GC: [msgInspector] on Event [MsgInspectorSet] could be Indexed gas-indexed-events
26
+
27
+ contracts/interfaces/IOAppReceiver.sol
28
+ 9:1 warning Missing @title tag in contract 'IOAppReceiver' use-natspec
29
+ 9:1 warning Missing @author tag in contract 'IOAppReceiver' use-natspec
30
+ 9:1 warning Missing @notice tag in contract 'IOAppReceiver' use-natspec
31
+
32
+ contracts/oapp/libs/OptionsBuilder.sol
33
+ 13:1 warning Missing @author tag in contract 'OptionsBuilder' use-natspec
34
+ 13:1 warning Missing @notice tag in contract 'OptionsBuilder' use-natspec
35
+ 36:5 warning Missing @notice tag in function 'newOptions' use-natspec
36
+ 51:5 warning Missing @notice tag in function 'addExecutorLzReceiveOption' use-natspec
37
+ 69:5 warning Missing @notice tag in function 'addExecutorNativeDropOption' use-natspec
38
+ 87:5 warning Missing @notice tag in function 'addExecutorLzReadOption' use-natspec
39
+ 87:5 warning Missing @param tag in function 'addExecutorLzReadOption' use-natspec
40
+ 87:5 warning Mismatch in @param names for function 'addExecutorLzReadOption'. Expected: [_options, _gas, _size, _value], Found: [] use-natspec
41
+ 87:5 warning Missing @return tag in function 'addExecutorLzReadOption' use-natspec
42
+ 87:5 warning Mismatch in @return count for function 'addExecutorLzReadOption'. Expected: 1, Found: 0 use-natspec
43
+ 109:5 warning Missing @notice tag in function 'addExecutorLzComposeOption' use-natspec
44
+ 124:5 warning Missing @notice tag in function 'addExecutorOrderedExecutionOption' use-natspec
45
+ 136:5 warning Missing @notice tag in function 'addDVNPreCrimeOption' use-natspec
46
+ 150:5 warning Missing @notice tag in function 'addExecutorOption' use-natspec
47
+ 173:5 warning Missing @notice tag in function 'addDVNOption' use-natspec
48
+ 195:5 warning Missing @notice tag in function 'encodeLegacyOptionsType1' use-natspec
49
+ 207:5 warning Missing @notice tag in function 'encodeLegacyOptionsType2' use-natspec
50
+
51
+ ✖ 31 problems (0 errors, 31 warnings)
52
+
53
+ --------------------------------------------------------------------------
54
+ ===> Join SOLHINT Community at: https://discord.com/invite/4TYGq3zpjs <===
55
+ --------------------------------------------------------------------------
56
+
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2026 - LayerZero Labs Ltd.
2
+
3
+ Permission is hereby granted, free of charge, to any
4
+ person obtaining a copy of this software and associated
5
+ documentation files (the "Software"), to deal in the
6
+ Software without restriction, including without
7
+ limitation the rights to use, copy, modify, merge,
8
+ publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software
10
+ is furnished to do so, subject to the following
11
+ conditions:
12
+ The above copyright notice and this permission notice
13
+ shall be included in all copies or substantial portions
14
+ of the Software.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
17
+ TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
22
+ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IOAppAlt
6
+ * @author LayerZero Labs (@TRileySchwarz, tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `OAppAlt` contract.
9
+ */
10
+ interface IOAppAlt {
11
+ /**
12
+ * @dev Thrown when the native token is not set, possibly due to the endpoint not being an `EndpointV2Alt`.
13
+ */
14
+ error InvalidNativeToken();
15
+
16
+ /**
17
+ * @dev Thrown when the native fee is paid with `msg.value`.
18
+ */
19
+ error OnlyAltToken();
20
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import { ILayerZeroComposer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroComposer.sol";
5
+
6
+ /**
7
+ * @title IOAppComposer
8
+ * @dev This interface defines the OApp Composer, allowing developers to inherit only the OApp package without the protocol.
9
+ */
10
+ // solhint-disable-next-line no-empty-blocks
11
+ interface IOAppComposer is ILayerZeroComposer {}
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
5
+
6
+ /**
7
+ * @title IOAppCore
8
+ */
9
+ interface IOAppCore {
10
+ // Custom error messages
11
+ error OnlyPeer(uint32 eid, bytes32 sender);
12
+ error NoPeer(uint32 eid);
13
+ error InvalidEndpointCall();
14
+ error InvalidDelegate();
15
+
16
+ // Event emitted when a peer (OApp) is set for a corresponding endpoint
17
+ event PeerSet(uint32 eid, bytes32 peer);
18
+
19
+ /**
20
+ * @notice Retrieves the OApp version information.
21
+ * @return senderVersion The version of the OAppSender.sol contract.
22
+ * @return receiverVersion The version of the OAppReceiver.sol contract.
23
+ */
24
+ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);
25
+
26
+ /**
27
+ * @notice Retrieves the LayerZero endpoint associated with the OApp.
28
+ * @return iEndpoint The LayerZero endpoint as an interface.
29
+ */
30
+ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);
31
+
32
+ /**
33
+ * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.
34
+ * @param _eid The endpoint ID.
35
+ * @return peer The peer address (OApp instance) associated with the corresponding endpoint.
36
+ */
37
+ function peers(uint32 _eid) external view returns (bytes32 peer);
38
+
39
+ /**
40
+ * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
41
+ * @param _eid The endpoint ID.
42
+ * @param _peer The address of the peer to be associated with the corresponding endpoint.
43
+ */
44
+ function setPeer(uint32 _eid, bytes32 _peer) external;
45
+
46
+ /**
47
+ * @notice Sets the delegate address for the OApp Core.
48
+ * @param _delegate The address of the delegate to be set.
49
+ */
50
+ function setDelegate(address _delegate) external;
51
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import { IOAppCore } from "./IOAppCore.sol";
5
+ import { IOAppMsgInspection } from "./IOAppMsgInspection.sol";
6
+ import { IOAppOptionsType3 } from "./IOAppOptionsType3.sol";
7
+ import { IOAppReceiver } from "./IOAppReceiver.sol";
8
+
9
+ /**
10
+ * @title IOAppExtended
11
+ * @author LayerZero Labs (@TRileySchwarz, tinom.eth)
12
+ * @custom:version 1.0.0
13
+ * @notice Aggregate interface for extended OApp contracts.
14
+ * @dev `IOAppReceiver` must precede `IOAppCore` for C3 linearization compatibility with `OApp`,
15
+ * where `OAppReceiver`'s linearization places `IOAppReceiver` before `IOAppCore`.
16
+ */
17
+ interface IOAppExtended is IOAppReceiver, IOAppCore, IOAppOptionsType3, IOAppMsgInspection {}
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IOAppMsgInspection
6
+ * @author LayerZero Labs (@TRileySchwarz, tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `OAppMsgInspection` contract.
9
+ */
10
+ interface IOAppMsgInspection {
11
+ /**
12
+ * @notice Emitted when a new message inspector is set.
13
+ * @param msgInspector Address of the new message inspector
14
+ */
15
+ event MsgInspectorSet(address msgInspector);
16
+
17
+ /**
18
+ * @notice Retrieves the message inspector address.
19
+ * @return inspector Address of the message inspector
20
+ */
21
+ function msgInspector() external view returns (address inspector);
22
+
23
+ /**
24
+ * @notice Sets the message inspector address.
25
+ * @param _msgInspector Address of the new message inspector
26
+ */
27
+ function setMsgInspector(address _msgInspector) external;
28
+ }
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IOAppMsgInspector
6
+ * @author LayerZero Labs (@TRileySchwarz, tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for OApp message inspector contracts.
9
+ */
10
+ interface IOAppMsgInspector {
11
+ /**
12
+ * @notice Emitted when the inspection fails.
13
+ * @param sender Address of the sender of the message
14
+ * @param message LayerZero message payload that failed inspection
15
+ * @param options LayerZero message options that failed inspection
16
+ */
17
+ error InspectionFailed(address sender, bytes message, bytes options);
18
+
19
+ /**
20
+ * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid.
21
+ * @dev It may either revert or return a boolean.
22
+ * @param _sender Address of the sender of the message
23
+ * @param _message LayerZero message payload to be inspected
24
+ * @param _options LayerZero message options to be inspected
25
+ * @return valid A boolean indicating whether the inspection passed (true) or failed (false)
26
+ */
27
+ function inspect(
28
+ address _sender,
29
+ bytes calldata _message,
30
+ bytes calldata _options
31
+ ) external view returns (bool valid);
32
+ }
@@ -0,0 +1,65 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IOAppOptionsType3
6
+ * @author LayerZero Labs
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `IOAppOptionsType3` contract.
9
+ */
10
+ interface IOAppOptionsType3 {
11
+ /**
12
+ * @notice Struct representing enforced option parameters.
13
+ * @param eid Endpoint ID
14
+ * @param msgType OApp message type
15
+ * @param options Additional options
16
+ */
17
+ struct EnforcedOptionParam {
18
+ uint32 eid;
19
+ uint16 msgType;
20
+ bytes options;
21
+ }
22
+
23
+ /**
24
+ * @notice Thrown when invalid options are provided.
25
+ * @param options Invalid options
26
+ */
27
+ error InvalidOptions(bytes options);
28
+
29
+ /**
30
+ * @notice Emitted when enforced options are set.
31
+ * @param _enforcedOptions Array of enforced options
32
+ */
33
+ event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions);
34
+
35
+ /**
36
+ * @notice Returns the enforced options for a given endpoint ID and message type.
37
+ * @param _eid Endpoint ID
38
+ * @param _msgType Message type, as defined by the OApp
39
+ * @return options Enforced options
40
+ */
41
+ function enforcedOptions(uint32 _eid, uint16 _msgType) external view returns (bytes memory options);
42
+
43
+ /**
44
+ * @notice Combines options for a given endpoint and message type.
45
+ * @param _eid Endpoint ID
46
+ * @param _msgType Message type, as defined by the OApp
47
+ * @param _extraOptions Additional options passed by the caller
48
+ * @return options Combination of caller specified options AND enforced options
49
+ */
50
+ function combineOptions(
51
+ uint32 _eid,
52
+ uint16 _msgType,
53
+ bytes calldata _extraOptions
54
+ ) external view returns (bytes memory options);
55
+
56
+ /**
57
+ * @notice Sets enforced options for specific endpoint and message type combinations.
58
+ * @dev Provides a way for the OApp to enforce things like paying for minimum destination `lzReceive` gas amounts.
59
+ * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the
60
+ * `msgType`. E.g., the amount of `lzReceive` gas necessary to deliver a `lzCompose` message adds overhead you
61
+ * don't want to pay if you are only sending a standard message such as `lzReceive` WITHOUT `sendCompose`.
62
+ * @param _enforcedOptions Array of enforced options
63
+ */
64
+ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external;
65
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import {
5
+ ILayerZeroReceiver,
6
+ Origin
7
+ } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol";
8
+
9
+ interface IOAppReceiver is ILayerZeroReceiver {
10
+ /**
11
+ * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint.
12
+ * @param _origin The origin information containing the source endpoint and sender address.
13
+ * - srcEid: The source chain endpoint ID.
14
+ * - sender: The sender address on the src chain.
15
+ * - nonce: The nonce of the message.
16
+ * @param _message The lzReceive payload.
17
+ * @param _sender The sender address.
18
+ * @return isSender Is a valid sender.
19
+ *
20
+ * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
21
+ * @dev The default sender IS the OAppReceiver implementer.
22
+ */
23
+ function isComposeMsgSender(
24
+ Origin calldata _origin,
25
+ bytes calldata _message,
26
+ address _sender
27
+ ) external view returns (bool isSender);
28
+ }
@@ -0,0 +1,217 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import { ExecutorOptions } from "@layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol";
5
+ import { DVNOptions } from "@layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol";
6
+ import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
7
+ import { BytesLib } from "solidity-bytes-utils/contracts/BytesLib.sol";
8
+
9
+ /**
10
+ * @title OptionsBuilder
11
+ * @dev Library for building and encoding various message options.
12
+ */
13
+ library OptionsBuilder {
14
+ using SafeCast for uint256;
15
+ using BytesLib for bytes;
16
+
17
+ // Constants for options types
18
+ uint16 internal constant TYPE_1 = 1; // legacy options type 1
19
+ uint16 internal constant TYPE_2 = 2; // legacy options type 2
20
+ uint16 internal constant TYPE_3 = 3;
21
+
22
+ // Custom error message
23
+ error InvalidSize(uint256 max, uint256 actual);
24
+ error InvalidOptionType(uint16 optionType);
25
+
26
+ // Modifier to ensure only options of type 3 are used
27
+ modifier onlyType3(bytes memory _options) {
28
+ if (_options.toUint16(0) != TYPE_3) revert InvalidOptionType(_options.toUint16(0));
29
+ _;
30
+ }
31
+
32
+ /**
33
+ * @dev Creates a new options container with type 3.
34
+ * @return options The newly created options container.
35
+ */
36
+ function newOptions() internal pure returns (bytes memory) {
37
+ return abi.encodePacked(TYPE_3);
38
+ }
39
+
40
+ /**
41
+ * @dev Adds an executor LZ receive option to the existing options.
42
+ * @param _options The existing options container.
43
+ * @param _gas The gasLimit used on the lzReceive() function in the OApp.
44
+ * @param _value The msg.value passed to the lzReceive() function in the OApp.
45
+ * @return options The updated options container.
46
+ *
47
+ * @dev When multiples of this option are added, they are summed by the executor
48
+ * eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint,
49
+ * that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function.
50
+ */
51
+ function addExecutorLzReceiveOption(
52
+ bytes memory _options,
53
+ uint128 _gas,
54
+ uint128 _value
55
+ ) internal pure onlyType3(_options) returns (bytes memory) {
56
+ bytes memory option = ExecutorOptions.encodeLzReceiveOption(_gas, _value);
57
+ return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZRECEIVE, option);
58
+ }
59
+
60
+ /**
61
+ * @dev Adds an executor native drop option to the existing options.
62
+ * @param _options The existing options container.
63
+ * @param _amount The amount for the native value that is airdropped to the 'receiver'.
64
+ * @param _receiver The receiver address for the native drop option.
65
+ * @return options The updated options container.
66
+ *
67
+ * @dev When multiples of this option are added, they are summed by the executor on the remote chain.
68
+ */
69
+ function addExecutorNativeDropOption(
70
+ bytes memory _options,
71
+ uint128 _amount,
72
+ bytes32 _receiver
73
+ ) internal pure onlyType3(_options) returns (bytes memory) {
74
+ bytes memory option = ExecutorOptions.encodeNativeDropOption(_amount, _receiver);
75
+ return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_NATIVE_DROP, option);
76
+ }
77
+
78
+ // /**
79
+ // * @dev Adds an executor native drop option to the existing options.
80
+ // * @param _options The existing options container.
81
+ // * @param _amount The amount for the native value that is airdropped to the 'receiver'.
82
+ // * @param _receiver The receiver address for the native drop option.
83
+ // * @return options The updated options container.
84
+ // *
85
+ // * @dev When multiples of this option are added, they are summed by the executor on the remote chain.
86
+ // */
87
+ function addExecutorLzReadOption(
88
+ bytes memory _options,
89
+ uint128 _gas,
90
+ uint32 _size,
91
+ uint128 _value
92
+ ) internal pure onlyType3(_options) returns (bytes memory) {
93
+ bytes memory option = ExecutorOptions.encodeLzReadOption(_gas, _size, _value);
94
+ return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZREAD, option);
95
+ }
96
+
97
+ /**
98
+ * @dev Adds an executor LZ compose option to the existing options.
99
+ * @param _options The existing options container.
100
+ * @param _index The index for the lzCompose() function call.
101
+ * @param _gas The gasLimit for the lzCompose() function call.
102
+ * @param _value The msg.value for the lzCompose() function call.
103
+ * @return options The updated options container.
104
+ *
105
+ * @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain.
106
+ * @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0.
107
+ * ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2
108
+ */
109
+ function addExecutorLzComposeOption(
110
+ bytes memory _options,
111
+ uint16 _index,
112
+ uint128 _gas,
113
+ uint128 _value
114
+ ) internal pure onlyType3(_options) returns (bytes memory) {
115
+ bytes memory option = ExecutorOptions.encodeLzComposeOption(_index, _gas, _value);
116
+ return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZCOMPOSE, option);
117
+ }
118
+
119
+ /**
120
+ * @dev Adds an executor ordered execution option to the existing options.
121
+ * @param _options The existing options container.
122
+ * @return options The updated options container.
123
+ */
124
+ function addExecutorOrderedExecutionOption(
125
+ bytes memory _options
126
+ ) internal pure onlyType3(_options) returns (bytes memory) {
127
+ return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_ORDERED_EXECUTION, bytes(""));
128
+ }
129
+
130
+ /**
131
+ * @dev Adds a DVN pre-crime option to the existing options.
132
+ * @param _options The existing options container.
133
+ * @param _dvnIdx The DVN index for the pre-crime option.
134
+ * @return options The updated options container.
135
+ */
136
+ function addDVNPreCrimeOption(
137
+ bytes memory _options,
138
+ uint8 _dvnIdx
139
+ ) internal pure onlyType3(_options) returns (bytes memory) {
140
+ return addDVNOption(_options, _dvnIdx, DVNOptions.OPTION_TYPE_PRECRIME, bytes(""));
141
+ }
142
+
143
+ /**
144
+ * @dev Adds an executor option to the existing options.
145
+ * @param _options The existing options container.
146
+ * @param _optionType The type of the executor option.
147
+ * @param _option The encoded data for the executor option.
148
+ * @return options The updated options container.
149
+ */
150
+ function addExecutorOption(
151
+ bytes memory _options,
152
+ uint8 _optionType,
153
+ bytes memory _option
154
+ ) internal pure onlyType3(_options) returns (bytes memory) {
155
+ return
156
+ abi.encodePacked(
157
+ _options,
158
+ ExecutorOptions.WORKER_ID,
159
+ _option.length.toUint16() + 1, // +1 for optionType
160
+ _optionType,
161
+ _option
162
+ );
163
+ }
164
+
165
+ /**
166
+ * @dev Adds a DVN option to the existing options.
167
+ * @param _options The existing options container.
168
+ * @param _dvnIdx The DVN index for the DVN option.
169
+ * @param _optionType The type of the DVN option.
170
+ * @param _option The encoded data for the DVN option.
171
+ * @return options The updated options container.
172
+ */
173
+ function addDVNOption(
174
+ bytes memory _options,
175
+ uint8 _dvnIdx,
176
+ uint8 _optionType,
177
+ bytes memory _option
178
+ ) internal pure onlyType3(_options) returns (bytes memory) {
179
+ return
180
+ abi.encodePacked(
181
+ _options,
182
+ DVNOptions.WORKER_ID,
183
+ _option.length.toUint16() + 2, // +2 for optionType and dvnIdx
184
+ _dvnIdx,
185
+ _optionType,
186
+ _option
187
+ );
188
+ }
189
+
190
+ /**
191
+ * @dev Encodes legacy options of type 1.
192
+ * @param _executionGas The gasLimit value passed to lzReceive().
193
+ * @return legacyOptions The encoded legacy options.
194
+ */
195
+ function encodeLegacyOptionsType1(uint256 _executionGas) internal pure returns (bytes memory) {
196
+ if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);
197
+ return abi.encodePacked(TYPE_1, _executionGas);
198
+ }
199
+
200
+ /**
201
+ * @dev Encodes legacy options of type 2.
202
+ * @param _executionGas The gasLimit value passed to lzReceive().
203
+ * @param _nativeForDst The amount of native air dropped to the receiver.
204
+ * @param _receiver The _nativeForDst receiver address.
205
+ * @return legacyOptions The encoded legacy options of type 2.
206
+ */
207
+ function encodeLegacyOptionsType2(
208
+ uint256 _executionGas,
209
+ uint256 _nativeForDst,
210
+ bytes memory _receiver // @dev Use bytes instead of bytes32 in legacy type 2 for _receiver.
211
+ ) internal pure returns (bytes memory) {
212
+ if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);
213
+ if (_nativeForDst > type(uint128).max) revert InvalidSize(type(uint128).max, _nativeForDst);
214
+ if (_receiver.length > 32) revert InvalidSize(32, _receiver.length);
215
+ return abi.encodePacked(TYPE_2, _executionGas, _nativeForDst, _receiver);
216
+ }
217
+ }
package/foundry.toml ADDED
@@ -0,0 +1,20 @@
1
+ [profile.default]
2
+ solc = '0.8.22'
3
+ verbosity = 3
4
+ src = "contracts"
5
+ test = "test"
6
+ out = "artifacts"
7
+ cache_path = "cache"
8
+ libs = ['node_modules', 'node_modules/@layerzerolabs/toolbox-foundry/lib']
9
+ optimizer = true
10
+ optimizer_runs = 200
11
+
12
+ remappings = [
13
+ 'ds-test/=node_modules/@layerzerolabs/toolbox-foundry/lib/ds-test/',
14
+ 'forge-std/=node_modules/@layerzerolabs/toolbox-foundry/lib/forge-std/',
15
+ '@openzeppelin/=node_modules/@openzeppelin/',
16
+ '@layerzerolabs/=node_modules/@layerzerolabs/',
17
+ ]
18
+
19
+ [fuzz]
20
+ runs = 1000
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@layerzerolabs/oapp-evm-contracts",
3
+ "version": "0.2.74",
4
+ "private": false,
5
+ "description": "LayerZero Labs reference EVM OApp implementation",
6
+ "license": "MIT",
7
+ "devDependencies": {
8
+ "@layerzerolabs/lz-evm-messagelib-v2": "3.0.167",
9
+ "@layerzerolabs/lz-evm-protocol-v2": "3.0.167",
10
+ "@layerzerolabs/lz-evm-v1-0.7": "3.0.167",
11
+ "@layerzerolabs/test-devtools-evm-foundry": "8.0.1",
12
+ "@layerzerolabs/toolbox-foundry": "^0.1.13",
13
+ "@openzeppelin/contracts": "^5.0.2",
14
+ "@openzeppelin/contracts-upgradeable": "^5.0.2",
15
+ "ethers": "^5.8.0",
16
+ "solhint": "^6.0.1",
17
+ "solidity-bytes-utils": "^0.8.4",
18
+ "@layerzerolabs/solhint-configuration": "0.2.74",
19
+ "@layerzerolabs/tsup-configuration": "0.2.74",
20
+ "@layerzerolabs/vm-tooling-evm": "0.2.74",
21
+ "@layerzerolabs/typescript-configuration": "0.2.74"
22
+ },
23
+ "publishConfig": {
24
+ "access": "restricted",
25
+ "registry": "https://registry.npmjs.org/"
26
+ },
27
+ "externalRepoConfig": {
28
+ "targets": [
29
+ "audit-external",
30
+ "monorepo-external"
31
+ ]
32
+ },
33
+ "scripts": {
34
+ "clean-artifacts": "rm -rf artifacts* cache hh-cache*",
35
+ "lint": "solhint --config solhint.config.js 'contracts/**/*.sol' 'test/**/*.sol' --fix --noPrompt"
36
+ }
37
+ }
@@ -0,0 +1,3 @@
1
+ const baseConfig = require('@layerzerolabs/solhint-configuration');
2
+
3
+ module.exports = baseConfig;