@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.
- package/.turbo/turbo-lint.log +56 -0
- package/LICENSE +23 -0
- package/contracts/interfaces/IOAppAlt.sol +20 -0
- package/contracts/interfaces/IOAppComposer.sol +11 -0
- package/contracts/interfaces/IOAppCore.sol +51 -0
- package/contracts/interfaces/IOAppExtended.sol +17 -0
- package/contracts/interfaces/IOAppMsgInspection.sol +28 -0
- package/contracts/interfaces/IOAppMsgInspector.sol +32 -0
- package/contracts/interfaces/IOAppOptionsType3.sol +65 -0
- package/contracts/interfaces/IOAppReceiver.sol +28 -0
- package/contracts/oapp/libs/OptionsBuilder.sol +217 -0
- package/foundry.toml +20 -0
- package/package.json +37 -0
- package/solhint.config.js +3 -0
|
@@ -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
|
+
}
|