@layerzerolabs/lz-evm-oapp-v2 2.1.21 → 2.1.23
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/CHANGELOG.md +12 -0
- package/artifacts/contracts/oapp/OApp.sol/OApp.json +40 -7
- package/artifacts/contracts/oapp/OAppReceiver.sol/OAppReceiver.json +40 -7
- package/artifacts/contracts/oapp/examples/OmniCounter.sol/OmniCounter.json +48 -15
- package/artifacts/contracts/oapp/examples/OmniCounterAbstract.sol/MsgCodec.json +2 -2
- package/artifacts/contracts/oapp/examples/OmniCounterAbstract.sol/OmniCounterAbstract.json +46 -13
- package/artifacts/contracts/oapp/examples/OmniCounterPreCrime.sol/OmniCounterPreCrime.json +2 -2
- package/artifacts/contracts/oapp/interfaces/IOAppReceiver.sol/IOAppReceiver.json +37 -4
- package/artifacts/contracts/oapp/utils/RateLimiter.sol/RateLimiter.json +104 -0
- package/artifacts/contracts/oft/OFT.sol/OFT.json +46 -13
- package/artifacts/contracts/oft/OFTAdapter.sol/OFTAdapter.json +46 -13
- package/artifacts/contracts/oft/OFTCore.sol/OFTCore.json +46 -13
- package/contracts/oapp/OAppReceiver.sol +17 -7
- package/contracts/oapp/examples/OmniCounterAbstract.sol +1 -0
- package/contracts/oapp/interfaces/IOAppReceiver.sol +14 -4
- package/contracts/oapp/utils/RateLimiter.sol +229 -0
- package/contracts/oft/OFT.sol +4 -2
- package/contracts/oft/OFTAdapter.sol +4 -2
- package/contracts/oft/OFTCore.sol +3 -0
- package/package.json +7 -7
|
@@ -5,11 +5,21 @@ import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/co
|
|
|
5
5
|
|
|
6
6
|
interface IOAppReceiver is ILayerZeroReceiver {
|
|
7
7
|
/**
|
|
8
|
-
* @notice
|
|
9
|
-
* @
|
|
8
|
+
* @notice Indicates whether an address is an approved composeMsg sender to the Endpoint.
|
|
9
|
+
* @param _origin The origin information containing the source endpoint and sender address.
|
|
10
|
+
* - srcEid: The source chain endpoint ID.
|
|
11
|
+
* - sender: The sender address on the src chain.
|
|
12
|
+
* - nonce: The nonce of the message.
|
|
13
|
+
* @param _message The lzReceive payload.
|
|
14
|
+
* @param _sender The sender address.
|
|
15
|
+
* @return isSender Is a valid sender.
|
|
10
16
|
*
|
|
11
17
|
* @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
|
|
12
|
-
* @dev The default sender IS the
|
|
18
|
+
* @dev The default sender IS the OAppReceiver implementer.
|
|
13
19
|
*/
|
|
14
|
-
function
|
|
20
|
+
function isComposeMsgSender(
|
|
21
|
+
Origin calldata _origin,
|
|
22
|
+
bytes calldata _message,
|
|
23
|
+
address _sender
|
|
24
|
+
) external view returns (bool isSender);
|
|
15
25
|
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @title RateLimiter
|
|
6
|
+
* @dev Abstract contract for implementing rate limiting functionality. This contract provides a basic framework for
|
|
7
|
+
* rate limiting how often a function can be executed. It is designed to be inherited by other contracts requiring rate
|
|
8
|
+
* limiting capabilities to protect resources or services from excessive use.
|
|
9
|
+
*
|
|
10
|
+
* Example 1: Max rate limit reached at beginning of window. As time continues the amount of in flights comes down.
|
|
11
|
+
*
|
|
12
|
+
* Rate Limit Config:
|
|
13
|
+
* limit: 100 units
|
|
14
|
+
* window: 60 seconds
|
|
15
|
+
*
|
|
16
|
+
* Amount in Flight (units) vs. Time Graph (seconds)
|
|
17
|
+
*
|
|
18
|
+
* 100 | * - (Max limit reached at beginning of window)
|
|
19
|
+
* | *
|
|
20
|
+
* | *
|
|
21
|
+
* | *
|
|
22
|
+
* 50 | * (After 30 seconds only 50 units in flight)
|
|
23
|
+
* | *
|
|
24
|
+
* | *
|
|
25
|
+
* | *
|
|
26
|
+
* 0 +--|---|---|---|---|-->(After 60 seconds 0 units are in flight)
|
|
27
|
+
* 0 15 30 45 60 (seconds)
|
|
28
|
+
*
|
|
29
|
+
* Example 2: Max rate limit reached at beginning of window. As time continues the amount of in flights comes down
|
|
30
|
+
* allowing for more to be sent. At the 90 second mark, more in flights come in.
|
|
31
|
+
*
|
|
32
|
+
* Rate Limit Config:
|
|
33
|
+
* limit: 100 units
|
|
34
|
+
* window: 60 seconds
|
|
35
|
+
*
|
|
36
|
+
* Amount in Flight (units) vs. Time Graph (seconds)
|
|
37
|
+
*
|
|
38
|
+
* 100 | * - (Max limit reached at beginning of window)
|
|
39
|
+
* | *
|
|
40
|
+
* | *
|
|
41
|
+
* | *
|
|
42
|
+
* 50 | * * (50 inflight)
|
|
43
|
+
* | * *
|
|
44
|
+
* | * *
|
|
45
|
+
* | * *
|
|
46
|
+
* 0 +--|--|--|--|--|--|--|--|--|--> Time
|
|
47
|
+
* 0 15 30 45 60 75 90 105 120 (seconds)
|
|
48
|
+
*
|
|
49
|
+
* Example 3: Max rate limit reached at beginning of window. At the 15 second mark, the window gets updated to 60
|
|
50
|
+
* seconds and the limit gets updated to 50 units. This scenario shows the direct depiction of "in flight" from the
|
|
51
|
+
* previous window affecting the current window.
|
|
52
|
+
*
|
|
53
|
+
* Initial Rate Limit Config: For first 15 seconds
|
|
54
|
+
* limit: 100 units
|
|
55
|
+
* window: 30 seconds
|
|
56
|
+
*
|
|
57
|
+
* Updated Rate Limit Config: Updated at 15 second mark
|
|
58
|
+
* limit: 50 units
|
|
59
|
+
* window: 60 seconds
|
|
60
|
+
*
|
|
61
|
+
* Amount in Flight (units) vs. Time Graph (seconds)
|
|
62
|
+
* 100 - *
|
|
63
|
+
* |*
|
|
64
|
+
* | *
|
|
65
|
+
* | *
|
|
66
|
+
* | *
|
|
67
|
+
* | *
|
|
68
|
+
* | *
|
|
69
|
+
* 75 - | *
|
|
70
|
+
* | *
|
|
71
|
+
* | *
|
|
72
|
+
* | *
|
|
73
|
+
* | *
|
|
74
|
+
* | *
|
|
75
|
+
* | *
|
|
76
|
+
* | *
|
|
77
|
+
* 50 - | 𐫰 <--(Slope changes at the 15 second mark because of the update.
|
|
78
|
+
* | ✧ * Window extended to 60 seconds and limit reduced to 50 units.
|
|
79
|
+
* | ✧ ︎ * Because amountInFlight/lastUpdated do not reset, 50 units are
|
|
80
|
+
* | ✧ * considered in flight from the previous window and the corresponding
|
|
81
|
+
* | ✧ ︎ * decay from the previous rate.)
|
|
82
|
+
* | ✧ *
|
|
83
|
+
* 25 - | ✧ *
|
|
84
|
+
* | ✧ *
|
|
85
|
+
* | ✧ *
|
|
86
|
+
* | ✧ *
|
|
87
|
+
* | ✧ *
|
|
88
|
+
* | ✧ *
|
|
89
|
+
* | ✧ *
|
|
90
|
+
* | ✧ *
|
|
91
|
+
* 0 - +---|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----> Time
|
|
92
|
+
* 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 (seconds)
|
|
93
|
+
* [ Initial 30 Second Window ]
|
|
94
|
+
* [ --------------- Extended 60 Second Window --------------- ]
|
|
95
|
+
*/
|
|
96
|
+
abstract contract RateLimiter {
|
|
97
|
+
/**
|
|
98
|
+
* @notice Rate Limit struct.
|
|
99
|
+
* @param amountInFlight The amount in the current window.
|
|
100
|
+
* @param lastUpdated Timestamp representing the last time the rate limit was checked or updated.
|
|
101
|
+
* @param limit This represents the maximum allowed amount within a given window.
|
|
102
|
+
* @param window Defines the duration of the rate limiting window.
|
|
103
|
+
*/
|
|
104
|
+
struct RateLimit {
|
|
105
|
+
uint256 amountInFlight;
|
|
106
|
+
uint256 lastUpdated;
|
|
107
|
+
uint256 limit;
|
|
108
|
+
uint256 window;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @notice Rate Limit Configuration struct.
|
|
113
|
+
* @param dstEid The destination endpoint id.
|
|
114
|
+
* @param limit This represents the maximum allowed amount within a given window.
|
|
115
|
+
* @param window Defines the duration of the rate limiting window.
|
|
116
|
+
*/
|
|
117
|
+
struct RateLimitConfig {
|
|
118
|
+
uint32 dstEid;
|
|
119
|
+
uint256 limit;
|
|
120
|
+
uint256 window;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @dev Mapping from destination endpoint id to RateLimit Configurations.
|
|
125
|
+
*/
|
|
126
|
+
mapping(uint32 dstEid => RateLimit limit) public rateLimits;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @notice Emitted when _setRateLimits occurs.
|
|
130
|
+
* @param rateLimitConfigs An array of `RateLimitConfig` structs representing the rate limit configurations set.
|
|
131
|
+
* - `dstEid`: The destination endpoint id.
|
|
132
|
+
* - `limit`: This represents the maximum allowed amount within a given window.
|
|
133
|
+
* - `window`: Defines the duration of the rate limiting window.
|
|
134
|
+
*/
|
|
135
|
+
event RateLimitsChanged(RateLimitConfig[] rateLimitConfigs);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @notice Error that is thrown when an amount exceeds the rate_limit.
|
|
139
|
+
*/
|
|
140
|
+
error RateLimitExceeded();
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @notice Get the current amount that can be sent to this destination endpoint id for the given rate limit window.
|
|
144
|
+
* @param _dstEid The destination endpoint id.
|
|
145
|
+
* @return currentAmountInFlight The current amount that was sent.
|
|
146
|
+
* @return amountCanBeSent The amount that can be sent.
|
|
147
|
+
*/
|
|
148
|
+
function getAmountCanBeSent(
|
|
149
|
+
uint32 _dstEid
|
|
150
|
+
) external view virtual returns (uint256 currentAmountInFlight, uint256 amountCanBeSent) {
|
|
151
|
+
RateLimit memory rl = rateLimits[_dstEid];
|
|
152
|
+
return _amountCanBeSent(rl.amountInFlight, rl.lastUpdated, rl.limit, rl.window);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @notice Sets the Rate Limit.
|
|
157
|
+
* @param _rateLimitConfigs A `RateLimitConfig` struct representing the rate limit configuration.
|
|
158
|
+
* - `dstEid`: The destination endpoint id.
|
|
159
|
+
* - `limit`: This represents the maximum allowed amount within a given window.
|
|
160
|
+
* - `window`: Defines the duration of the rate limiting window.
|
|
161
|
+
*/
|
|
162
|
+
function _setRateLimits(RateLimitConfig[] memory _rateLimitConfigs) internal virtual {
|
|
163
|
+
unchecked {
|
|
164
|
+
for (uint256 i = 0; i < _rateLimitConfigs.length; i++) {
|
|
165
|
+
RateLimit storage rl = rateLimits[_rateLimitConfigs[i].dstEid];
|
|
166
|
+
|
|
167
|
+
// @dev Ensure we checkpoint the existing rate limit as to not retroactively apply the new decay rate.
|
|
168
|
+
_checkAndUpdateRateLimit(_rateLimitConfigs[i].dstEid, 0);
|
|
169
|
+
|
|
170
|
+
// @dev Does NOT reset the amountInFlight/lastUpdated of an existing rate limit.
|
|
171
|
+
rl.limit = _rateLimitConfigs[i].limit;
|
|
172
|
+
rl.window = _rateLimitConfigs[i].window;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
emit RateLimitsChanged(_rateLimitConfigs);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @notice Checks current amount in flight and amount that can be sent for a given rate limit window.
|
|
180
|
+
* @param _amountInFlight The amount in the current window.
|
|
181
|
+
* @param _lastUpdated Timestamp representing the last time the rate limit was checked or updated.
|
|
182
|
+
* @param _limit This represents the maximum allowed amount within a given window.
|
|
183
|
+
* @param _window Defines the duration of the rate limiting window.
|
|
184
|
+
* @return currentAmountInFlight The amount in the current window.
|
|
185
|
+
* @return amountCanBeSent The amount that can be sent.
|
|
186
|
+
*/
|
|
187
|
+
function _amountCanBeSent(
|
|
188
|
+
uint256 _amountInFlight,
|
|
189
|
+
uint256 _lastUpdated,
|
|
190
|
+
uint256 _limit,
|
|
191
|
+
uint256 _window
|
|
192
|
+
) internal view virtual returns (uint256 currentAmountInFlight, uint256 amountCanBeSent) {
|
|
193
|
+
uint256 timeSinceLastDeposit = block.timestamp - _lastUpdated;
|
|
194
|
+
if (timeSinceLastDeposit >= _window) {
|
|
195
|
+
currentAmountInFlight = 0;
|
|
196
|
+
amountCanBeSent = _limit;
|
|
197
|
+
} else {
|
|
198
|
+
// @dev Presumes linear decay.
|
|
199
|
+
uint256 decay = (_limit * timeSinceLastDeposit) / _window;
|
|
200
|
+
currentAmountInFlight = _amountInFlight <= decay ? 0 : _amountInFlight - decay;
|
|
201
|
+
// @dev In the event the _limit is lowered, and the 'in-flight' amount is higher than the _limit, set to 0.
|
|
202
|
+
amountCanBeSent = _limit <= currentAmountInFlight ? 0 : _limit - currentAmountInFlight;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @notice Verifies whether the specified amount falls within the rate limit constraints for the targeted
|
|
208
|
+
* endpoint ID. On successful verification, it updates amountInFlight and lastUpdated. If the amount exceeds
|
|
209
|
+
* the rate limit, the operation reverts.
|
|
210
|
+
* @param _dstEid The destination endpoint id.
|
|
211
|
+
* @param _amount The amount to check for rate limit constraints.
|
|
212
|
+
*/
|
|
213
|
+
function _checkAndUpdateRateLimit(uint32 _dstEid, uint256 _amount) internal virtual {
|
|
214
|
+
// @dev By default dstEid that have not been explicitly set will return amountCanBeSent == 0.
|
|
215
|
+
RateLimit storage rl = rateLimits[_dstEid];
|
|
216
|
+
|
|
217
|
+
(uint256 currentAmountInFlight, uint256 amountCanBeSent) = _amountCanBeSent(
|
|
218
|
+
rl.amountInFlight,
|
|
219
|
+
rl.lastUpdated,
|
|
220
|
+
rl.limit,
|
|
221
|
+
rl.window
|
|
222
|
+
);
|
|
223
|
+
if (_amount > amountCanBeSent) revert RateLimitExceeded();
|
|
224
|
+
|
|
225
|
+
// @dev Update the storage to contain the new amount and current timestamp.
|
|
226
|
+
rl.amountInFlight = currentAmountInFlight + _amount;
|
|
227
|
+
rl.lastUpdated = block.timestamp;
|
|
228
|
+
}
|
|
229
|
+
}
|
package/contracts/oft/OFT.sol
CHANGED
|
@@ -30,7 +30,7 @@ abstract contract OFT is OFTCore, ERC20 {
|
|
|
30
30
|
*
|
|
31
31
|
* @dev In the case of OFT, address(this) and erc20 are the same contract.
|
|
32
32
|
*/
|
|
33
|
-
function token()
|
|
33
|
+
function token() public view returns (address) {
|
|
34
34
|
return address(this);
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -46,6 +46,7 @@ abstract contract OFT is OFTCore, ERC20 {
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* @dev Burns tokens from the sender's specified balance.
|
|
49
|
+
* @param _from The address to debit the tokens from.
|
|
49
50
|
* @param _amountLD The amount of tokens to send in local decimals.
|
|
50
51
|
* @param _minAmountLD The minimum amount to send in local decimals.
|
|
51
52
|
* @param _dstEid The destination chain ID.
|
|
@@ -53,6 +54,7 @@ abstract contract OFT is OFTCore, ERC20 {
|
|
|
53
54
|
* @return amountReceivedLD The amount received in local decimals on the remote.
|
|
54
55
|
*/
|
|
55
56
|
function _debit(
|
|
57
|
+
address _from,
|
|
56
58
|
uint256 _amountLD,
|
|
57
59
|
uint256 _minAmountLD,
|
|
58
60
|
uint32 _dstEid
|
|
@@ -63,7 +65,7 @@ abstract contract OFT is OFTCore, ERC20 {
|
|
|
63
65
|
// therefore amountSentLD CAN differ from amountReceivedLD.
|
|
64
66
|
|
|
65
67
|
// @dev Default OFT burns on src.
|
|
66
|
-
_burn(
|
|
68
|
+
_burn(_from, amountSentLD);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/**
|
|
@@ -42,7 +42,7 @@ abstract contract OFTAdapter is OFTCore {
|
|
|
42
42
|
*
|
|
43
43
|
* @dev In the case of OFTAdapter, address(this) and erc20 are NOT the same contract.
|
|
44
44
|
*/
|
|
45
|
-
function token()
|
|
45
|
+
function token() public view returns (address) {
|
|
46
46
|
return address(innerToken);
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -59,6 +59,7 @@ abstract contract OFTAdapter is OFTCore {
|
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* @dev Burns tokens from the sender's specified balance, ie. pull method.
|
|
62
|
+
* @param _from The address to debit from.
|
|
62
63
|
* @param _amountLD The amount of tokens to send in local decimals.
|
|
63
64
|
* @param _minAmountLD The minimum amount to send in local decimals.
|
|
64
65
|
* @param _dstEid The destination chain ID.
|
|
@@ -71,13 +72,14 @@ abstract contract OFTAdapter is OFTCore {
|
|
|
71
72
|
* a pre/post balance check will need to be done to calculate the amountReceivedLD.
|
|
72
73
|
*/
|
|
73
74
|
function _debit(
|
|
75
|
+
address _from,
|
|
74
76
|
uint256 _amountLD,
|
|
75
77
|
uint256 _minAmountLD,
|
|
76
78
|
uint32 _dstEid
|
|
77
79
|
) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) {
|
|
78
80
|
(amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid);
|
|
79
81
|
// @dev Lock tokens by moving them into this contract from the caller.
|
|
80
|
-
innerToken.safeTransferFrom(
|
|
82
|
+
innerToken.safeTransferFrom(_from, address(this), amountSentLD);
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/**
|
|
@@ -179,6 +179,7 @@ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3
|
|
|
179
179
|
// - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender.
|
|
180
180
|
// - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance.
|
|
181
181
|
(uint256 amountSentLD, uint256 amountReceivedLD) = _debit(
|
|
182
|
+
msg.sender,
|
|
182
183
|
_sendParam.amountLD,
|
|
183
184
|
_sendParam.minAmountLD,
|
|
184
185
|
_sendParam.dstEid
|
|
@@ -363,6 +364,7 @@ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3
|
|
|
363
364
|
|
|
364
365
|
/**
|
|
365
366
|
* @dev Internal function to perform a debit operation.
|
|
367
|
+
* @param _from The address to debit.
|
|
366
368
|
* @param _amountLD The amount to send in local decimals.
|
|
367
369
|
* @param _minAmountLD The minimum amount to send in local decimals.
|
|
368
370
|
* @param _dstEid The destination endpoint ID.
|
|
@@ -373,6 +375,7 @@ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3
|
|
|
373
375
|
* @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD.
|
|
374
376
|
*/
|
|
375
377
|
function _debit(
|
|
378
|
+
address _from,
|
|
376
379
|
uint256 _amountLD,
|
|
377
380
|
uint256 _minAmountLD,
|
|
378
381
|
uint32 _dstEid
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/lz-evm-oapp-v2",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"artifacts/contracts/**/!(*.dbg).json",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@layerzerolabs/lz-evm-messagelib-v2": "^2.1.
|
|
15
|
-
"@layerzerolabs/lz-evm-protocol-v2": "^2.1.
|
|
16
|
-
"@layerzerolabs/lz-evm-v1-0.7": "^2.1.
|
|
14
|
+
"@layerzerolabs/lz-evm-messagelib-v2": "^2.1.23",
|
|
15
|
+
"@layerzerolabs/lz-evm-protocol-v2": "^2.1.23",
|
|
16
|
+
"@layerzerolabs/lz-evm-v1-0.7": "^2.1.23",
|
|
17
17
|
"@openzeppelin/contracts": "^4.8.1",
|
|
18
18
|
"@openzeppelin/contracts-upgradeable": "^4.8.1",
|
|
19
19
|
"hardhat-deploy": "^0.11.44",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"solidity-bytes-utils": "^0.8.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@layerzerolabs/lz-evm-messagelib-v2": "^2.1.
|
|
25
|
-
"@layerzerolabs/lz-evm-protocol-v2": "^2.1.
|
|
26
|
-
"@layerzerolabs/lz-evm-v1-0.7": "^2.1.
|
|
24
|
+
"@layerzerolabs/lz-evm-messagelib-v2": "^2.1.23",
|
|
25
|
+
"@layerzerolabs/lz-evm-protocol-v2": "^2.1.23",
|
|
26
|
+
"@layerzerolabs/lz-evm-v1-0.7": "^2.1.23",
|
|
27
27
|
"@openzeppelin/contracts": "^4.8.1 || ^5.0.0",
|
|
28
28
|
"@openzeppelin/contracts-upgradeable": "^4.8.1 || ^5.0.0",
|
|
29
29
|
"hardhat-deploy": "^0.11.44",
|