@layerzerolabs/lz-evm-protocol-v2 2.0.2

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 (51) hide show
  1. package/artifacts/contracts/EndpointV2.sol/EndpointV2.json +2364 -0
  2. package/artifacts/contracts/EndpointV2Alt.sol/EndpointV2Alt.json +2379 -0
  3. package/artifacts/contracts/MessageLibManager.sol/MessageLibManager.json +783 -0
  4. package/artifacts/contracts/MessagingChannel.sol/MessagingChannel.json +426 -0
  5. package/artifacts/contracts/MessagingComposer.sol/MessagingComposer.json +320 -0
  6. package/artifacts/contracts/MessagingContext.sol/MessagingContext.json +42 -0
  7. package/artifacts/contracts/interfaces/ILayerZeroComposer.sol/ILayerZeroComposer.json +44 -0
  8. package/artifacts/contracts/interfaces/ILayerZeroEndpointV2.sol/ILayerZeroEndpointV2.json +1844 -0
  9. package/artifacts/contracts/interfaces/ILayerZeroReceiver.sol/ILayerZeroReceiver.json +121 -0
  10. package/artifacts/contracts/interfaces/IMessageLib.sol/IMessageLib.json +149 -0
  11. package/artifacts/contracts/interfaces/IMessageLibManager.sol/IMessageLibManager.json +629 -0
  12. package/artifacts/contracts/interfaces/IMessagingChannel.sol/IMessagingChannel.json +344 -0
  13. package/artifacts/contracts/interfaces/IMessagingComposer.sol/IMessagingComposer.json +246 -0
  14. package/artifacts/contracts/interfaces/IMessagingContext.sol/IMessagingContext.json +42 -0
  15. package/artifacts/contracts/interfaces/ISendLib.sol/ISendLib.json +364 -0
  16. package/artifacts/contracts/libs/AddressCast.sol/AddressCast.json +10 -0
  17. package/artifacts/contracts/libs/CalldataBytesLib.sol/CalldataBytesLib.json +10 -0
  18. package/artifacts/contracts/libs/Errors.sol/Errors.json +226 -0
  19. package/artifacts/contracts/libs/GUID.sol/GUID.json +10 -0
  20. package/artifacts/contracts/libs/Transfer.sol/Transfer.json +32 -0
  21. package/artifacts/contracts/messagelib/BlockedMessageLib.sol/BlockedMessageLib.json +94 -0
  22. package/artifacts/contracts/messagelib/SimpleMessageLib.sol/SimpleMessageLib.json +591 -0
  23. package/artifacts/contracts/messagelib/libs/BitMaps.sol/BitMaps.json +10 -0
  24. package/artifacts/contracts/messagelib/libs/ExecutorOptions.sol/ExecutorOptions.json +26 -0
  25. package/artifacts/contracts/messagelib/libs/PacketV1Codec.sol/PacketV1Codec.json +10 -0
  26. package/contracts/EndpointV2.sol +403 -0
  27. package/contracts/EndpointV2Alt.sol +50 -0
  28. package/contracts/MessageLibManager.sol +326 -0
  29. package/contracts/MessagingChannel.sol +161 -0
  30. package/contracts/MessagingComposer.sol +80 -0
  31. package/contracts/MessagingContext.sol +36 -0
  32. package/contracts/interfaces/ILayerZeroComposer.sol +24 -0
  33. package/contracts/interfaces/ILayerZeroEndpointV2.sol +98 -0
  34. package/contracts/interfaces/ILayerZeroReceiver.sol +20 -0
  35. package/contracts/interfaces/IMessageLib.sol +26 -0
  36. package/contracts/interfaces/IMessageLibManager.sol +68 -0
  37. package/contracts/interfaces/IMessagingChannel.sol +32 -0
  38. package/contracts/interfaces/IMessagingComposer.sol +38 -0
  39. package/contracts/interfaces/IMessagingContext.sol +9 -0
  40. package/contracts/interfaces/ISendLib.sol +36 -0
  41. package/contracts/libs/AddressCast.sol +40 -0
  42. package/contracts/libs/CalldataBytesLib.sol +58 -0
  43. package/contracts/libs/Errors.sol +42 -0
  44. package/contracts/libs/GUID.sol +19 -0
  45. package/contracts/libs/Transfer.sol +34 -0
  46. package/contracts/messagelib/BlockedMessageLib.sol +30 -0
  47. package/contracts/messagelib/SimpleMessageLib.sol +149 -0
  48. package/contracts/messagelib/libs/BitMaps.sol +26 -0
  49. package/contracts/messagelib/libs/ExecutorOptions.sol +85 -0
  50. package/contracts/messagelib/libs/PacketV1Codec.sol +108 -0
  51. package/package.json +27 -0
@@ -0,0 +1,149 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity 0.8.22;
4
+
5
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
6
+ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
7
+ import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
8
+ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
9
+
10
+ import { IMessageLib, MessageLibType } from "../interfaces/IMessageLib.sol";
11
+ import { Packet } from "../interfaces/ISendLib.sol";
12
+ import { ILayerZeroEndpointV2, MessagingFee, Origin } from "../interfaces/ILayerZeroEndpointV2.sol";
13
+ import { Errors } from "../libs/Errors.sol";
14
+ import { PacketV1Codec } from "./libs/PacketV1Codec.sol";
15
+ import { Transfer } from "../libs/Transfer.sol";
16
+
17
+ contract SimpleMessageLib is Ownable, ERC165 {
18
+ using SafeERC20 for IERC20;
19
+ using PacketV1Codec for bytes;
20
+
21
+ address public immutable endpoint;
22
+ address public immutable treasury;
23
+ uint32 public immutable localEid;
24
+ uint8 public constant PACKET_VERSION = 1;
25
+
26
+ address public whitelistCaller;
27
+
28
+ uint256 public lzTokenFee;
29
+ uint256 public nativeFee;
30
+
31
+ bytes public defaultOption;
32
+
33
+ error OnlyEndpoint();
34
+ error OnlyWhitelistCaller();
35
+ error InvalidEndpoint(address expected, address actual);
36
+ error ToIsAddressZero();
37
+ error LzTokenIsAddressZero();
38
+ error TransferFailed();
39
+
40
+ // only the endpoint can call SEND() and setConfig()
41
+ modifier onlyEndpoint() {
42
+ if (endpoint != msg.sender) {
43
+ revert OnlyEndpoint();
44
+ }
45
+ _;
46
+ }
47
+
48
+ constructor(address _endpoint, address _treasury) {
49
+ endpoint = _endpoint;
50
+ treasury = _treasury;
51
+ localEid = ILayerZeroEndpointV2(_endpoint).eid();
52
+ lzTokenFee = 99;
53
+ nativeFee = 100;
54
+ // defaultOption = Options.encodeLegacyOptionsType1(200000);
55
+ }
56
+
57
+ function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
58
+ return interfaceId == type(IMessageLib).interfaceId || super.supportsInterface(interfaceId);
59
+ }
60
+
61
+ // no validation logic at all
62
+ function validatePacket(bytes calldata packetBytes) external {
63
+ if (whitelistCaller != address(0x0) && msg.sender != whitelistCaller) {
64
+ revert OnlyWhitelistCaller();
65
+ }
66
+ Origin memory origin = Origin(packetBytes.srcEid(), packetBytes.sender(), packetBytes.nonce());
67
+ ILayerZeroEndpointV2(endpoint).verify(origin, packetBytes.receiverB20(), keccak256(packetBytes.payload()));
68
+ }
69
+
70
+ // ------------------ onlyEndpoint ------------------
71
+ function send(
72
+ Packet calldata _packet,
73
+ bytes memory _options,
74
+ bool _payInLzToken
75
+ ) external onlyEndpoint returns (MessagingFee memory fee, bytes memory encodedPacket, bytes memory options) {
76
+ encodedPacket = PacketV1Codec.encode(_packet);
77
+
78
+ options = _options.length == 0 ? defaultOption : _options;
79
+ _handleMessagingParamsHook(encodedPacket, options);
80
+
81
+ fee = MessagingFee(nativeFee, _payInLzToken ? lzTokenFee : 0);
82
+ }
83
+
84
+ // ------------------ onlyOwner ------------------
85
+ function setDefaultOption(bytes memory _defaultOption) external onlyOwner {
86
+ defaultOption = _defaultOption;
87
+ }
88
+
89
+ function setMessagingFee(uint256 _nativeFee, uint256 _lzTokenFee) external onlyOwner {
90
+ nativeFee = _nativeFee;
91
+ lzTokenFee = _lzTokenFee;
92
+ }
93
+
94
+ function setWhitelistCaller(address _whitelistCaller) external onlyOwner {
95
+ whitelistCaller = _whitelistCaller;
96
+ }
97
+
98
+ function withdrawFee(address _to, uint256 _amount) external onlyOwner {
99
+ if (_to == address(0x0)) {
100
+ revert ToIsAddressZero();
101
+ }
102
+
103
+ address altTokenAddr = ILayerZeroEndpointV2(endpoint).nativeToken();
104
+
105
+ // transfers native if altTokenAddr == address(0x0)
106
+ Transfer.nativeOrToken(altTokenAddr, _to, _amount);
107
+ }
108
+
109
+ function withdrawLzTokenFee(address _to, uint256 _amount) external onlyOwner {
110
+ if (_to == address(0x0)) {
111
+ revert ToIsAddressZero();
112
+ }
113
+ address lzToken = ILayerZeroEndpointV2(endpoint).lzToken();
114
+ if (lzToken == address(0x0)) {
115
+ revert LzTokenIsAddressZero();
116
+ }
117
+ IERC20(lzToken).safeTransfer(_to, _amount);
118
+ }
119
+
120
+ // ------------------ View ------------------
121
+ function quote(
122
+ Packet calldata /*_packet*/,
123
+ bytes calldata /*_options*/,
124
+ bool _payInLzToken
125
+ ) external view returns (MessagingFee memory) {
126
+ return MessagingFee(nativeFee, _payInLzToken ? lzTokenFee : 0);
127
+ }
128
+
129
+ function isSupportedEid(uint32) external pure returns (bool) {
130
+ return true;
131
+ }
132
+
133
+ function version() external pure returns (uint64 major, uint8 minor, uint8 endpointVersion) {
134
+ return (0, 0, 2);
135
+ }
136
+
137
+ function messageLibType() external pure returns (MessageLibType) {
138
+ return MessageLibType.SendAndReceive;
139
+ }
140
+
141
+ // ------------------ Internal ------------------
142
+ function _handleMessagingParamsHook(bytes memory _encodedPacket, bytes memory _options) internal virtual {}
143
+
144
+ fallback() external payable {
145
+ revert Errors.NotImplemented();
146
+ }
147
+
148
+ receive() external payable {}
149
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ // modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol
4
+ pragma solidity ^0.8.22;
5
+
6
+ type BitMap256 is uint256;
7
+
8
+ using BitMaps for BitMap256 global;
9
+
10
+ library BitMaps {
11
+ /**
12
+ * @dev Returns whether the bit at `index` is set.
13
+ */
14
+ function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {
15
+ uint256 mask = 1 << index;
16
+ return BitMap256.unwrap(bitmap) & mask != 0;
17
+ }
18
+
19
+ /**
20
+ * @dev Sets the bit at `index`.
21
+ */
22
+ function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {
23
+ uint256 mask = 1 << index;
24
+ return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);
25
+ }
26
+ }
@@ -0,0 +1,85 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.22;
4
+
5
+ import { CalldataBytesLib } from "../../libs/CalldataBytesLib.sol";
6
+
7
+ library ExecutorOptions {
8
+ using CalldataBytesLib for bytes;
9
+
10
+ uint8 internal constant WORKER_ID = 1;
11
+
12
+ uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
13
+ uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;
14
+ uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;
15
+ uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;
16
+
17
+ error InvalidLzReceiveOption();
18
+ error InvalidNativeDropOption();
19
+ error InvalidLzComposeOption();
20
+
21
+ /// @dev decode the next executor option from the options starting from the specified cursor
22
+ /// @param _options [executor_id][executor_option][executor_id][executor_option]...
23
+ /// executor_option = [option_size][option_type][option]
24
+ /// option_size = len(option_type) + len(option)
25
+ /// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes
26
+ /// @param _cursor the cursor to start decoding from
27
+ /// @return optionType the type of the option
28
+ /// @return option the option of the executor
29
+ /// @return cursor the cursor to start decoding the next executor option
30
+ function nextExecutorOption(
31
+ bytes calldata _options,
32
+ uint256 _cursor
33
+ ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {
34
+ unchecked {
35
+ // skip worker id
36
+ cursor = _cursor + 1;
37
+
38
+ // read option size
39
+ uint16 size = _options.toU16(cursor);
40
+ cursor += 2;
41
+
42
+ // read option type
43
+ optionType = _options.toU8(cursor);
44
+
45
+ // startCursor and endCursor are used to slice the option from _options
46
+ uint256 startCursor = cursor + 1; // skip option type
47
+ uint256 endCursor = cursor + size;
48
+ option = _options[startCursor:endCursor];
49
+ cursor += size;
50
+ }
51
+ }
52
+
53
+ function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {
54
+ if (_option.length != 16 && _option.length != 32) revert InvalidLzReceiveOption();
55
+ gas = _option.toU128(0);
56
+ value = _option.length == 32 ? _option.toU128(16) : 0;
57
+ }
58
+
59
+ function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {
60
+ if (_option.length != 48) revert InvalidNativeDropOption();
61
+ amount = _option.toU128(0);
62
+ receiver = _option.toB32(16);
63
+ }
64
+
65
+ function decodeLzComposeOption(
66
+ bytes calldata _option
67
+ ) internal pure returns (uint16 index, uint128 gas, uint128 value) {
68
+ if (_option.length != 18 && _option.length != 34) revert InvalidLzComposeOption();
69
+ index = _option.toU16(0);
70
+ gas = _option.toU128(2);
71
+ value = _option.length == 34 ? _option.toU128(18) : 0;
72
+ }
73
+
74
+ function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
75
+ return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);
76
+ }
77
+
78
+ function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {
79
+ return abi.encodePacked(_amount, _receiver);
80
+ }
81
+
82
+ function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
83
+ return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);
84
+ }
85
+ }
@@ -0,0 +1,108 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.22;
4
+
5
+ import { Packet } from "../../interfaces/ISendLib.sol";
6
+ import { AddressCast } from "../../libs/AddressCast.sol";
7
+
8
+ library PacketV1Codec {
9
+ using AddressCast for address;
10
+ using AddressCast for bytes32;
11
+
12
+ uint8 internal constant PACKET_VERSION = 1;
13
+
14
+ // header (version + nonce + path)
15
+ // version
16
+ uint256 private constant PACKET_VERSION_OFFSET = 0;
17
+ // nonce
18
+ uint256 private constant NONCE_OFFSET = 1;
19
+ // path
20
+ uint256 private constant SRC_EID_OFFSET = 9;
21
+ uint256 private constant SENDER_OFFSET = 13;
22
+ uint256 private constant DST_EID_OFFSET = 45;
23
+ uint256 private constant RECEIVER_OFFSET = 49;
24
+ // payload (guid + message)
25
+ uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path)
26
+ uint256 private constant MESSAGE_OFFSET = 113;
27
+
28
+ function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) {
29
+ encodedPacket = abi.encodePacked(
30
+ PACKET_VERSION,
31
+ _packet.nonce,
32
+ _packet.srcEid,
33
+ _packet.sender.toBytes32(),
34
+ _packet.dstEid,
35
+ _packet.receiver,
36
+ _packet.guid,
37
+ _packet.message
38
+ );
39
+ }
40
+
41
+ function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) {
42
+ return
43
+ abi.encodePacked(
44
+ PACKET_VERSION,
45
+ _packet.nonce,
46
+ _packet.srcEid,
47
+ _packet.sender.toBytes32(),
48
+ _packet.dstEid,
49
+ _packet.receiver
50
+ );
51
+ }
52
+
53
+ function encodePayload(Packet memory _packet) internal pure returns (bytes memory) {
54
+ return abi.encodePacked(_packet.guid, _packet.message);
55
+ }
56
+
57
+ function header(bytes calldata _packet) internal pure returns (bytes calldata) {
58
+ return _packet[0:GUID_OFFSET];
59
+ }
60
+
61
+ function version(bytes calldata _packet) internal pure returns (uint8) {
62
+ return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET]));
63
+ }
64
+
65
+ function nonce(bytes calldata _packet) internal pure returns (uint64) {
66
+ return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET]));
67
+ }
68
+
69
+ function srcEid(bytes calldata _packet) internal pure returns (uint32) {
70
+ return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET]));
71
+ }
72
+
73
+ function sender(bytes calldata _packet) internal pure returns (bytes32) {
74
+ return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]);
75
+ }
76
+
77
+ function senderAddressB20(bytes calldata _packet) internal pure returns (address) {
78
+ return sender(_packet).toAddress();
79
+ }
80
+
81
+ function dstEid(bytes calldata _packet) internal pure returns (uint32) {
82
+ return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET]));
83
+ }
84
+
85
+ function receiver(bytes calldata _packet) internal pure returns (bytes32) {
86
+ return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]);
87
+ }
88
+
89
+ function receiverB20(bytes calldata _packet) internal pure returns (address) {
90
+ return receiver(_packet).toAddress();
91
+ }
92
+
93
+ function guid(bytes calldata _packet) internal pure returns (bytes32) {
94
+ return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]);
95
+ }
96
+
97
+ function message(bytes calldata _packet) internal pure returns (bytes calldata) {
98
+ return bytes(_packet[MESSAGE_OFFSET:]);
99
+ }
100
+
101
+ function payload(bytes calldata _packet) internal pure returns (bytes calldata) {
102
+ return bytes(_packet[GUID_OFFSET:]);
103
+ }
104
+
105
+ function payloadHash(bytes calldata _packet) internal pure returns (bytes32) {
106
+ return keccak256(payload(_packet));
107
+ }
108
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@layerzerolabs/lz-evm-protocol-v2",
3
+ "version": "2.0.2",
4
+ "license": "LZBL-1.2",
5
+ "files": [
6
+ "artifacts/contracts/**/!(*.dbg).json",
7
+ "contracts/**/*"
8
+ ],
9
+ "scripts": {
10
+ "postpack": "node ./scripts/pack.mjs --postpack"
11
+ },
12
+ "dependencies": {},
13
+ "devDependencies": {
14
+ "@openzeppelin/contracts": "^4.8.1",
15
+ "hardhat-deploy": "^0.11.44",
16
+ "hardhat-deploy-ethers": "^0.3.0-beta.13",
17
+ "solidity-bytes-utils": "^0.8.0"
18
+ },
19
+ "publishConfig": {
20
+ "access": "restricted"
21
+ },
22
+ "lzVersions": {
23
+ "default": [
24
+ "v2"
25
+ ]
26
+ }
27
+ }