@layerzerolabs/lz-evm-v1-0.7 2.1.19 → 2.1.21
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/contracts/RelayerV2.sol
CHANGED
|
@@ -13,6 +13,7 @@ import "hardhat-deploy/solc_0.7/proxy/Proxied.sol";
|
|
|
13
13
|
import "./interfaces/ILayerZeroRelayerV2.sol";
|
|
14
14
|
import "./interfaces/ILayerZeroUltraLightNodeV2.sol";
|
|
15
15
|
import "./interfaces/ILayerZeroPriceFeedV2.sol";
|
|
16
|
+
import "./libs/RateLimiter.sol";
|
|
16
17
|
|
|
17
18
|
interface IStargateComposer {
|
|
18
19
|
function isSending() external view returns (bool);
|
|
@@ -23,6 +24,7 @@ contract RelayerV2 is ReentrancyGuard, OwnableUpgradeable, Proxied, ILayerZeroRe
|
|
|
23
24
|
using SafeMath for uint;
|
|
24
25
|
using SafeMath for uint128;
|
|
25
26
|
using SafeMath for uint64;
|
|
27
|
+
using RateLimiter for RateLimiter.Info;
|
|
26
28
|
|
|
27
29
|
ILayerZeroUltraLightNodeV2 public uln;
|
|
28
30
|
address public stargateBridgeAddress;
|
|
@@ -95,6 +97,10 @@ contract RelayerV2 is ReentrancyGuard, OwnableUpgradeable, Proxied, ILayerZeroRe
|
|
|
95
97
|
|
|
96
98
|
uint256 public nativeDecimalsRate;
|
|
97
99
|
|
|
100
|
+
RateLimiter.Info public limiter;
|
|
101
|
+
|
|
102
|
+
event RateLimiterSet(uint64 capacity, uint64 rate);
|
|
103
|
+
|
|
98
104
|
// owner is always approved
|
|
99
105
|
modifier onlyApproved() {
|
|
100
106
|
if (owner() != msg.sender) {
|
|
@@ -186,6 +192,11 @@ contract RelayerV2 is ReentrancyGuard, OwnableUpgradeable, Proxied, ILayerZeroRe
|
|
|
186
192
|
|
|
187
193
|
//----------------------------------------------------------------------------------
|
|
188
194
|
// onlyOwner
|
|
195
|
+
function configRateLimiter(uint64 _capacity, uint64 _rate) external onlyOwner {
|
|
196
|
+
limiter.setCapacity(_capacity);
|
|
197
|
+
limiter.setRate(_rate);
|
|
198
|
+
emit RateLimiterSet(_capacity, _rate);
|
|
199
|
+
}
|
|
189
200
|
|
|
190
201
|
function setApprovedAddress(address _relayerAddress, bool _approve) public onlyOwner {
|
|
191
202
|
approvedAddresses[_relayerAddress] = _approve;
|
|
@@ -302,6 +313,11 @@ contract RelayerV2 is ReentrancyGuard, OwnableUpgradeable, Proxied, ILayerZeroRe
|
|
|
302
313
|
uint _payloadSize,
|
|
303
314
|
bytes calldata _adapterParams
|
|
304
315
|
) external override returns (uint fee) {
|
|
316
|
+
if (_dstChainId >= 10000 && limiter.capacity > 0) {
|
|
317
|
+
// sandbox or testnet
|
|
318
|
+
limiter.tryConsume(10000);
|
|
319
|
+
}
|
|
320
|
+
|
|
305
321
|
require(msg.sender == address(uln), "Relayer: invalid uln");
|
|
306
322
|
require(_payloadSize <= 10000, "Relayer: _payloadSize > 10000");
|
|
307
323
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
// Copyright 2023 LayerZero Labs Ltd.
|
|
3
|
+
// You may obtain a copy of the License at
|
|
4
|
+
// https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1
|
|
5
|
+
|
|
6
|
+
pragma solidity ^0.7.6;
|
|
7
|
+
|
|
8
|
+
library RateLimiter {
|
|
9
|
+
struct Info {
|
|
10
|
+
// capacity of the token bucket. This is the maximum number of tokens that the bucket can hold at any given time
|
|
11
|
+
uint64 capacity;
|
|
12
|
+
// current number of tokens in the bucket
|
|
13
|
+
uint64 tokens;
|
|
14
|
+
// number of tokens refilled per second
|
|
15
|
+
uint64 rate;
|
|
16
|
+
// timestamp of last refill
|
|
17
|
+
uint64 lastRefillTime;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function setCapacity(Info storage _self, uint64 _capacity) internal {
|
|
21
|
+
_self.capacity = _capacity;
|
|
22
|
+
_self.tokens = _capacity;
|
|
23
|
+
_self.lastRefillTime = uint64(block.timestamp);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function setRate(Info storage _self, uint64 _rate) internal {
|
|
27
|
+
refill(_self, 0);
|
|
28
|
+
_self.rate = _rate;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function tryConsume(Info storage _self, uint64 _amount) internal returns (uint64) {
|
|
32
|
+
refill(_self, 0);
|
|
33
|
+
|
|
34
|
+
uint64 tokens = _self.tokens;
|
|
35
|
+
require(tokens >= _amount, "RelayerV2: out of counters - try again later!");
|
|
36
|
+
|
|
37
|
+
uint64 newTokens = tokens - _amount;
|
|
38
|
+
_self.tokens = newTokens;
|
|
39
|
+
return newTokens;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function refill(Info storage _self, uint64 _extraTokens) internal {
|
|
43
|
+
uint newTokens = _extraTokens;
|
|
44
|
+
|
|
45
|
+
uint64 currentTime = uint64(block.timestamp);
|
|
46
|
+
if (currentTime > _self.lastRefillTime) {
|
|
47
|
+
uint timeElapsedInSeconds = currentTime - _self.lastRefillTime;
|
|
48
|
+
newTokens += timeElapsedInSeconds * _self.rate;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (newTokens > 0) {
|
|
52
|
+
newTokens += _self.tokens;
|
|
53
|
+
_self.tokens = newTokens > _self.capacity ? _self.capacity : uint64(newTokens);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_self.lastRefillTime = currentTime;
|
|
57
|
+
}
|
|
58
|
+
}
|