@layerzerolabs/utils-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,39 @@
1
+
2
+ > @layerzerolabs/utils-evm-contracts@0.0.0 lint /home/runner/work/monorepo-internal/monorepo-internal/contracts/common/utils/evm/non-upgradeable
3
+ > solhint --config solhint.config.js 'contracts/**/*.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/IAllowlist.sol
9
+ 44:5 warning GC: [isBlacklisted] on Event [BlacklistUpdated] could be Indexed gas-indexed-events
10
+ 51:5 warning GC: [isWhitelisted] on Event [WhitelistUpdated] could be Indexed gas-indexed-events
11
+
12
+ contracts/interfaces/IBurnableMintable.sol
13
+ 5:1 warning Missing @author tag in contract 'IBurnableMintable' use-natspec
14
+ 5:1 warning Missing @notice tag in contract 'IBurnableMintable' use-natspec
15
+
16
+ contracts/interfaces/IFeeConfig.sol
17
+ 27:5 warning GC: [id] on Event [FeeBpsSet] could be Indexed gas-indexed-events
18
+ 27:5 warning GC: [feeBps] on Event [FeeBpsSet] could be Indexed gas-indexed-events
19
+ 27:5 warning GC: [enabled] on Event [FeeBpsSet] could be Indexed gas-indexed-events
20
+ 33:5 warning GC: [feeBps] on Event [DefaultFeeBpsSet] could be Indexed gas-indexed-events
21
+
22
+ contracts/interfaces/IPause.sol
23
+ 15:5 warning GC: [paused] on Event [PauseSet] could be Indexed gas-indexed-events
24
+
25
+ contracts/interfaces/IPauseByID.sol
26
+ 39:5 warning GC: [id] on Event [PauseSet] could be Indexed gas-indexed-events
27
+ 39:5 warning GC: [paused] on Event [PauseSet] could be Indexed gas-indexed-events
28
+ 39:5 warning GC: [enabled] on Event [PauseSet] could be Indexed gas-indexed-events
29
+ 45:5 warning GC: [paused] on Event [DefaultPauseSet] could be Indexed gas-indexed-events
30
+
31
+ contracts/interfaces/IRateLimiter.sol
32
+ 134:5 warning GC: [isExempt] on Event [RateLimitAddressExemptionUpdated] could be Indexed gas-indexed-events
33
+
34
+ ✖ 14 problems (0 errors, 14 warnings)
35
+
36
+ --------------------------------------------------------------------------
37
+ ===> Join SOLHINT Community at: https://discord.com/invite/4TYGq3zpjs <===
38
+ --------------------------------------------------------------------------
39
+
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,63 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ import { IAccessControlEnumerable } from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
5
+
6
+ /**
7
+ * @title IAccessControl2Step
8
+ * @author LayerZero Labs (tinom.eth)
9
+ * @custom:version 1.0.0
10
+ * @notice Interface for the `AccessControl2Step` contract.
11
+ */
12
+ interface IAccessControl2Step is IAccessControlEnumerable {
13
+ /**
14
+ * @notice Thrown when the intended default admin is invalid.
15
+ * @param defaultAdmin Invalid default admin address
16
+ */
17
+ error InvalidDefaultAdmin(address defaultAdmin);
18
+
19
+ /**
20
+ * @notice Thrown when one of the following rules is violated:
21
+ * - The `DEFAULT_ADMIN_ROLE` must only be managed by itself.
22
+ * - The `DEFAULT_ADMIN_ROLE` must only be held by one account at the time.
23
+ * - Any `DEFAULT_ADMIN_ROLE` transfer must be in two steps.
24
+ */
25
+ error AccessControlEnforcedDefaultAdminRules();
26
+
27
+ /**
28
+ * @notice Thrown when the caller is not the pending admin.
29
+ * @param pendingAdmin Address of the pending admin
30
+ */
31
+ error CallerNotPendingAdmin(address pendingAdmin);
32
+
33
+ /**
34
+ * @notice Emitted when a `DEFAULT_ADMIN_ROLE` transfer is started.
35
+ * @param newAdmin Address of the new pending default admin
36
+ */
37
+ event DefaultAdminTransferStarted(address indexed newAdmin);
38
+
39
+ /**
40
+ * @notice Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.
41
+ * @return defaultAdminAddress Address of the current `DEFAULT_ADMIN_ROLE` holder
42
+ */
43
+ function defaultAdmin() external view returns (address defaultAdminAddress);
44
+
45
+ /**
46
+ * @notice Returns the address of the account that can claim the `DEFAULT_ADMIN_ROLE` by calling
47
+ * `acceptDefaultAdminTransfer`.
48
+ * @return pendingDefaultAdminAddress Address of the pending `DEFAULT_ADMIN_ROLE` account
49
+ */
50
+ function pendingDefaultAdmin() external view returns (address pendingDefaultAdminAddress);
51
+
52
+ /**
53
+ * @notice Starts a `DEFAULT_ADMIN_ROLE` transfer by setting a `pendingDefaultAdmin`.
54
+ * @dev It can cancel an existing pending transfer by setting the `newAdmin` to `address(0)`.
55
+ * @param newAdmin Address of the new pending default admin
56
+ */
57
+ function beginDefaultAdminTransfer(address newAdmin) external;
58
+
59
+ /**
60
+ * @notice Completes a `DEFAULT_ADMIN_ROLE` transfer previously started with `beginDefaultAdminTransfer`.
61
+ */
62
+ function acceptDefaultAdminTransfer() external;
63
+ }
@@ -0,0 +1,145 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IAllowlist
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `Allowlist` contract.
9
+ */
10
+ interface IAllowlist {
11
+ /**
12
+ * @notice Available allowlist modes.
13
+ * - `Open`: No restrictions.
14
+ * - `Blacklist`: Users in the blacklist are not allowed.
15
+ * - `Whitelist`: Only users in the whitelist are allowed.
16
+ */
17
+ enum AllowlistMode {
18
+ Open,
19
+ Blacklist,
20
+ Whitelist
21
+ }
22
+
23
+ /**
24
+ * @notice Parameters for setting the allowlist state for a user.
25
+ * @param user User address
26
+ * @param isEnabled Whether the user is whitelisted or blacklisted, depends on function context
27
+ */
28
+ struct SetAllowlistParam {
29
+ address user;
30
+ bool isEnabled;
31
+ }
32
+
33
+ /**
34
+ * @notice Emitted when the allowlist mode is updated.
35
+ * @param newMode New mode
36
+ */
37
+ event AllowlistModeUpdated(AllowlistMode newMode);
38
+
39
+ /**
40
+ * @notice Emitted when a user's blacklist state is updated.
41
+ * @param user User address
42
+ * @param isBlacklisted Whether the user is now blacklisted
43
+ */
44
+ event BlacklistUpdated(address indexed user, bool isBlacklisted);
45
+
46
+ /**
47
+ * @notice Emitted when a user's whitelist state is updated.
48
+ * @param user User address
49
+ * @param isWhitelisted Whether the user is now whitelisted
50
+ */
51
+ event WhitelistUpdated(address indexed user, bool isWhitelisted);
52
+
53
+ /**
54
+ * @notice Thrown when the intended allowlist mode is already set.
55
+ * @param mode Current mode
56
+ */
57
+ error ModeAlreadySet(AllowlistMode mode);
58
+
59
+ /**
60
+ * @notice Thrown when a user is already in the desired state (blacklist or whitelist).
61
+ * @param user User address
62
+ * @param isEnabled The desired state that the user is already in
63
+ */
64
+ error AllowlistStateIdempotent(address user, bool isEnabled);
65
+
66
+ /**
67
+ * @notice Thrown when a user is not allowlisted.
68
+ * @param user User address
69
+ * @param mode Current mode
70
+ */
71
+ error NotAllowlisted(address user, AllowlistMode mode);
72
+
73
+ /**
74
+ * @notice Returns the current allowlist mode.
75
+ * @return mode Current mode
76
+ */
77
+ function allowlistMode() external view returns (AllowlistMode mode);
78
+
79
+ /**
80
+ * @notice Returns the blacklist state for a user.
81
+ * @param _user User address
82
+ * @return isUserBlacklisted Whether the user is blacklisted
83
+ */
84
+ function isBlacklisted(address _user) external view returns (bool isUserBlacklisted);
85
+
86
+ /**
87
+ * @notice Returns the whitelist state for a user.
88
+ * @param _user User address
89
+ * @return isUserWhitelisted Whether the user is whitelisted
90
+ */
91
+ function isWhitelisted(address _user) external view returns (bool isUserWhitelisted);
92
+
93
+ /**
94
+ * @notice Checks if a user is allowlisted under the current mode.
95
+ * @param _user User address
96
+ * @return isUserAllowlisted Whether the user is allowlisted
97
+ */
98
+ function isAllowlisted(address _user) external view returns (bool isUserAllowlisted);
99
+
100
+ /**
101
+ * @notice Returns the total count of blacklisted addresses.
102
+ * @return count Total number of blacklisted addresses
103
+ */
104
+ function blacklistedCount() external view returns (uint256 count);
105
+
106
+ /**
107
+ * @notice Returns the total count of whitelisted addresses.
108
+ * @return count Total number of whitelisted addresses
109
+ */
110
+ function whitelistedCount() external view returns (uint256 count);
111
+
112
+ /**
113
+ * @notice Returns a paginated list of blacklisted addresses.
114
+ * @param _offset Starting index
115
+ * @param _limit Maximum number of addresses to return
116
+ * @return addresses Array of blacklisted addresses
117
+ */
118
+ function getBlacklist(uint256 _offset, uint256 _limit) external view returns (address[] memory addresses);
119
+
120
+ /**
121
+ * @notice Returns a paginated list of whitelisted addresses.
122
+ * @param _offset Starting index
123
+ * @param _limit Maximum number of addresses to return
124
+ * @return addresses Array of whitelisted addresses
125
+ */
126
+ function getWhitelist(uint256 _offset, uint256 _limit) external view returns (address[] memory addresses);
127
+
128
+ /**
129
+ * @notice Sets the allowlist mode.
130
+ * @param _mode New allowlist mode
131
+ */
132
+ function setAllowlistMode(AllowlistMode _mode) external;
133
+
134
+ /**
135
+ * @notice Sets the blacklist state for an array of users.
136
+ * @param _params Array of users and blacklist states
137
+ */
138
+ function setBlacklisted(SetAllowlistParam[] calldata _params) external;
139
+
140
+ /**
141
+ * @notice Sets the whitelist state for an array of users.
142
+ * @param _params Array of users and whitelist states
143
+ */
144
+ function setWhitelisted(SetAllowlistParam[] calldata _params) external;
145
+ }
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /// @title Interface for burnable and mintable tokens
5
+ interface IBurnableMintable {
6
+ /**
7
+ * @notice Burns tokens from a specified account
8
+ * @param _from Address from which tokens will be burned
9
+ * @param _amount Amount of tokens to be burned
10
+ * @return success Indicates whether the operation was successful
11
+ */
12
+ function burn(address _from, uint256 _amount) external returns (bool success);
13
+
14
+ /**
15
+ * @notice Mints tokens to a specified account
16
+ * @param _to Address to which tokens will be minted
17
+ * @param _amount Amount of tokens to be minted
18
+ * @return success Indicates whether the operation was successful
19
+ */
20
+ function mint(address _to, uint256 _amount) external returns (bool success);
21
+ }
@@ -0,0 +1,83 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IFeeConfig
6
+ * @author LayerZero Labs (@TRileySchwarz, tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `FeeConfig` contract.
9
+ */
10
+ interface IFeeConfig {
11
+ /**
12
+ * @notice Configuration for a fee.
13
+ * @param feeBps Fee basis points (BPS)
14
+ * @param enabled False to fallback to the default fee basis points (BPS)
15
+ */
16
+ struct FeeConfig {
17
+ uint16 feeBps;
18
+ bool enabled;
19
+ }
20
+
21
+ /**
22
+ * @notice Emitted when the fee basis points (BPS) are set for a specific destination ID.
23
+ * @param id Destination ID
24
+ * @param feeBps Fee basis points (BPS)
25
+ * @param enabled Whether the fee is enabled for the destination
26
+ */
27
+ event FeeBpsSet(uint256 id, uint16 feeBps, bool enabled);
28
+
29
+ /**
30
+ * @notice Emitted when the default fee basis points (BPS) are set.
31
+ * @param feeBps Default fee basis points (BPS)
32
+ */
33
+ event DefaultFeeBpsSet(uint16 feeBps);
34
+
35
+ /**
36
+ * @notice Thrown when the fee basis points (BPS) are invalid.
37
+ * @param feeBps Invalid fee basis points (BPS)
38
+ */
39
+ error InvalidBps(uint16 feeBps);
40
+
41
+ /**
42
+ * @notice Retrieves the fee for a destination ID and amount.
43
+ * @param _id Destination ID
44
+ * @param _amount Amount to calculate the fee for
45
+ * @return fee Fee amount
46
+ */
47
+ function getFee(uint256 _id, uint256 _amount) external view returns (uint256 fee);
48
+
49
+ /**
50
+ * @notice Retrieves the pre-fee amount required to yield a given post-fee amount.
51
+ * @param _id Destination ID
52
+ * @param _amountAfterFee Desired amount after fees
53
+ * @return amountBeforeFee Required amount before fees
54
+ */
55
+ function getAmountBeforeFee(uint256 _id, uint256 _amountAfterFee) external view returns (uint256 amountBeforeFee);
56
+
57
+ /**
58
+ * @notice Retrieves default fee basis points (BPS) used if no fee is configured for the destination ID.
59
+ * @return fee Default fee basis points (BPS)
60
+ */
61
+ function defaultFeeBps() external view returns (uint16 fee);
62
+
63
+ /**
64
+ * @notice Retrieves the configured fee for a given ID.
65
+ * @param _id Destination ID
66
+ * @return config Configured fee for the destination ID
67
+ */
68
+ function feeBps(uint256 _id) external view returns (FeeConfig memory config);
69
+
70
+ /**
71
+ * @notice Set the default fee basis points (BPS) for all destinations.
72
+ * @param _feeBps New default fee basis points (BPS)
73
+ */
74
+ function setDefaultFeeBps(uint16 _feeBps) external;
75
+
76
+ /**
77
+ * @notice Sets the fee basis points for a specific destination ID.
78
+ * @param _id Destination ID
79
+ * @param _feeBps Fee basis points to set
80
+ * @param _enabled Whether the fee is enabled for the destination
81
+ */
82
+ function setFeeBps(uint256 _id, uint16 _feeBps, bool _enabled) external;
83
+ }
@@ -0,0 +1,33 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IFeeHandler
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `FeeHandler` contract.
9
+ */
10
+ interface IFeeHandler {
11
+ /**
12
+ * @notice Thrown when the fee deposit address is invalid.
13
+ */
14
+ error InvalidFeeDeposit();
15
+
16
+ /**
17
+ * @notice Emitted when the fee deposit is updated.
18
+ * @param feeDeposit New fee deposit address
19
+ */
20
+ event FeeDepositSet(address indexed feeDeposit);
21
+
22
+ /**
23
+ * @notice Returns the address to which fees are forwarded.
24
+ * @return deposit Address that will receive any accrued fees
25
+ */
26
+ function feeDeposit() external view returns (address deposit);
27
+
28
+ /**
29
+ * @notice Sets the fee deposit address.
30
+ * @param _feeDeposit Address that will receive any accrued fees
31
+ */
32
+ function setFeeDeposit(address _feeDeposit) external;
33
+ }
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IFundRecovery
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for ERC20 contracts implementing fund recovery functionality.
9
+ */
10
+ interface IFundRecovery {
11
+ /**
12
+ * @notice Recovers funds from a non-allowlisted address.
13
+ * @dev Only recovers from non-allowlisted `_from` address.
14
+ * @param _from Address to recover funds from
15
+ * @param _to Address to send the recovered funds to
16
+ * @param _amount Amount of funds to recover
17
+ */
18
+ function recoverFunds(address _from, address _to, uint256 _amount) external;
19
+ }
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IPause
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `Pause` contract.
9
+ */
10
+ interface IPause {
11
+ /**
12
+ * @notice Emitted when the pause status is set.
13
+ * @param paused Pause status
14
+ */
15
+ event PauseSet(bool paused);
16
+
17
+ /**
18
+ * @notice Thrown when attempting to perform an action while paused.
19
+ */
20
+ error Paused();
21
+
22
+ /**
23
+ * @notice Thrown when setting pause state is idempotent (no change).
24
+ * @param isPaused Whether system is paused
25
+ */
26
+ error PauseStateIdempotent(bool isPaused);
27
+
28
+ /**
29
+ * @notice Checks if the system is paused.
30
+ * @return paused Whether the system is paused
31
+ */
32
+ function isPaused() external view returns (bool paused);
33
+
34
+ /**
35
+ * @notice Pauses the system.
36
+ */
37
+ function pause() external;
38
+
39
+ /**
40
+ * @notice Unpauses the system.
41
+ */
42
+ function unpause() external;
43
+ }
@@ -0,0 +1,90 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IPauseByID
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `PauseByID` contract.
9
+ */
10
+ interface IPauseByID {
11
+ /**
12
+ * @notice Configuration for a pause setting.
13
+ * @param paused Whether transfers are paused for this ID
14
+ * @param enabled False to fallback to the default pause setting
15
+ */
16
+ struct PauseConfig {
17
+ bool paused;
18
+ bool enabled;
19
+ }
20
+
21
+ /**
22
+ * @notice Parameter for setting pause state.
23
+ * @param id Destination ID
24
+ * @param paused Whether transfers are paused for this ID
25
+ * @param enabled Whether the pause config is enabled for the destination
26
+ */
27
+ struct SetPausedParam {
28
+ uint256 id;
29
+ bool paused;
30
+ bool enabled;
31
+ }
32
+
33
+ /**
34
+ * @notice Emitted when the pause status is set for a specific destination ID.
35
+ * @param id Destination ID
36
+ * @param paused Whether transfers are paused for this ID
37
+ * @param enabled Whether the pause config is enabled for the destination
38
+ */
39
+ event PauseSet(uint256 id, bool paused, bool enabled);
40
+
41
+ /**
42
+ * @notice Emitted when the default pause status is set.
43
+ * @param paused Default pause status
44
+ */
45
+ event DefaultPauseSet(bool paused);
46
+
47
+ /**
48
+ * @notice Thrown when attempting to transfer while paused.
49
+ * @param id Destination ID that is paused
50
+ */
51
+ error Paused(uint256 id);
52
+
53
+ /**
54
+ * @notice Thrown when setting pause state is idempotent (no change).
55
+ * @param isPaused Whether transfers are paused
56
+ */
57
+ error PauseStateIdempotent(bool isPaused);
58
+
59
+ /**
60
+ * @notice Checks if transfers to a destination ID are paused.
61
+ * @param _id Destination ID
62
+ * @return paused Whether transfers are paused
63
+ */
64
+ function isPaused(uint256 _id) external view returns (bool paused);
65
+
66
+ /**
67
+ * @notice Retrieves default pause status used if no pause config is set for the destination ID.
68
+ * @return paused Default pause status
69
+ */
70
+ function defaultPaused() external view returns (bool paused);
71
+
72
+ /**
73
+ * @notice Retrieves the configured pause setting for a given ID.
74
+ * @param _id Destination ID
75
+ * @return config Configured pause setting for the destination ID
76
+ */
77
+ function pauseConfig(uint256 _id) external view returns (PauseConfig memory config);
78
+
79
+ /**
80
+ * @notice Set the default pause status for all destinations.
81
+ * @param _paused New default pause status
82
+ */
83
+ function setDefaultPaused(bool _paused) external;
84
+
85
+ /**
86
+ * @notice Sets the pause status for an array of destination IDs.
87
+ * @param _params Array of pause configurations
88
+ */
89
+ function setPaused(SetPausedParam[] calldata _params) external;
90
+ }
@@ -0,0 +1,244 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.22;
3
+
4
+ /**
5
+ * @title IRateLimiter
6
+ * @author LayerZero Labs (tinom.eth)
7
+ * @custom:version 1.0.0
8
+ * @notice Interface for the `RateLimiter` contract.
9
+ */
10
+ interface IRateLimiter {
11
+ /**
12
+ * @notice Global configuration for the rate limiter.
13
+ * @param useGlobalState Whether to use global state for the rate limiter, instead of per-ID rules
14
+ * @param isGloballyDisabled Whether the rate limiter is globally disabled
15
+ */
16
+ struct RateLimitGlobalConfig {
17
+ bool useGlobalState;
18
+ bool isGloballyDisabled;
19
+ }
20
+
21
+ /**
22
+ * @notice Rate limit state for a given ID.
23
+ * @param outboundUsage Current usage of the outbound rate limit
24
+ * @param inboundUsage Current usage of the inbound rate limit
25
+ * @param lastUpdated Last updated timestamp
26
+ * @param configBitmap Bitmap of the rate limit configuration
27
+ * @param outboundLimit Limit of the outbound rate limit
28
+ * @param outboundWindow Window of the outbound rate limit
29
+ * @param inboundLimit Limit of the inbound rate limit
30
+ * @param inboundWindow Window of the inbound rate limit
31
+ */
32
+ struct RateLimit {
33
+ uint96 outboundUsage;
34
+ uint96 inboundUsage;
35
+ uint40 lastUpdated;
36
+ uint24 configBitmap;
37
+ uint96 outboundLimit;
38
+ uint32 outboundWindow;
39
+ uint96 inboundLimit;
40
+ uint32 inboundWindow;
41
+ }
42
+
43
+ /**
44
+ * @notice Rate limit configuration.
45
+ * @param overrideDefaultConfig Whether to override the default configuration
46
+ * @param outboundEnabled Whether the outbound rate limit is enabled
47
+ * @param inboundEnabled Whether the inbound rate limit is enabled
48
+ * @param netAccountingEnabled Whether net accounting is enabled
49
+ * @param addressExemptionEnabled Whether address exemption is enabled
50
+ * @param outboundLimit Limit of the outbound rate limit
51
+ * @param inboundLimit Limit of the inbound rate limit
52
+ * @param outboundWindow Window of the outbound rate limit
53
+ * @param inboundWindow Window of the inbound rate limit
54
+ */
55
+ struct RateLimitConfig {
56
+ bool overrideDefaultConfig;
57
+ bool outboundEnabled;
58
+ bool inboundEnabled;
59
+ bool netAccountingEnabled;
60
+ bool addressExemptionEnabled;
61
+ uint96 outboundLimit;
62
+ uint96 inboundLimit;
63
+ uint32 outboundWindow;
64
+ uint32 inboundWindow;
65
+ }
66
+
67
+ /**
68
+ * @notice Parameters for setting a rate limit configuration.
69
+ * @param id ID of the rate limit configuration
70
+ * @param config Configuration to set
71
+ */
72
+ struct SetRateLimitConfigParam {
73
+ uint256 id;
74
+ RateLimitConfig config;
75
+ }
76
+
77
+ /**
78
+ * @notice Rate limit state.
79
+ * @param outboundUsage Current usage of the outbound rate limit
80
+ * @param inboundUsage Current usage of the inbound rate limit
81
+ * @param lastUpdated Last updated timestamp
82
+ */
83
+ struct RateLimitState {
84
+ uint96 outboundUsage;
85
+ uint96 inboundUsage;
86
+ uint40 lastUpdated;
87
+ }
88
+
89
+ /**
90
+ * @notice Parameters for setting a rate limit state.
91
+ * @param id ID of the rate limit state
92
+ * @param state State to set
93
+ */
94
+ struct SetRateLimitStateParam {
95
+ uint256 id;
96
+ RateLimitState state;
97
+ }
98
+
99
+ /**
100
+ * @notice Parameter for setting a rate limit address exemption.
101
+ * @param user Address of the user
102
+ * @param isExempt Whether the address should be exempt from the rate limit
103
+ */
104
+ struct SetRateLimitAddressExemptionParam {
105
+ address user;
106
+ bool isExempt;
107
+ }
108
+
109
+ /**
110
+ * @notice Emitted when the global rate limiter configuration is updated.
111
+ * @param globalConfig Updated global configuration
112
+ */
113
+ event RateLimitGlobalConfigUpdated(RateLimitGlobalConfig globalConfig);
114
+
115
+ /**
116
+ * @notice Emitted when a rate limit configuration is updated.
117
+ * @param id ID of the rate limit configuration
118
+ * @param config Parameters for the updated rate limit configuration
119
+ */
120
+ event RateLimitConfigUpdated(uint256 indexed id, RateLimitConfig config);
121
+
122
+ /**
123
+ * @notice Emitted when a rate limit state is updated.
124
+ * @param id ID of the rate limit state
125
+ * @param state Parameters for the updated rate limit state
126
+ */
127
+ event RateLimitStateUpdated(uint256 indexed id, RateLimitState state);
128
+
129
+ /**
130
+ * @notice Emitted when a rate limit address exemption is updated.
131
+ * @param user Address of the user
132
+ * @param isExempt Whether the address is exempt
133
+ */
134
+ event RateLimitAddressExemptionUpdated(address indexed user, bool isExempt);
135
+
136
+ /**
137
+ * @notice Thrown when the scaled decimals are invalid.
138
+ * @param scaledDecimals Scaled decimals
139
+ */
140
+ error InvalidScaledDecimals(uint8 scaledDecimals);
141
+
142
+ /**
143
+ * @notice Thrown when a rate limit state is set to a timestamp in the future.
144
+ * @param lastUpdated Last updated timestamp
145
+ * @param currentTimestamp Current block timestamp
146
+ */
147
+ error LastUpdatedInFuture(uint40 lastUpdated, uint40 currentTimestamp);
148
+
149
+ /**
150
+ * @notice Thrown when a rate limit is exceeded.
151
+ * @param availableAmount Remaining capacity of the rate limit
152
+ * @param requestedAmount Amount requested
153
+ */
154
+ error RateLimitExceeded(uint256 availableAmount, uint256 requestedAmount);
155
+
156
+ /**
157
+ * @notice Thrown when a user is already in the desired state (exempt or not exempt).
158
+ * @param user User address
159
+ * @param isExempt Whether the address is exempt
160
+ */
161
+ error ExemptionStateIdempotent(address user, bool isExempt);
162
+
163
+ /**
164
+ * @notice Returns the global configuration for the rate limiter.
165
+ * @return globalConfig Global configuration
166
+ */
167
+ function getRateLimitGlobalConfig() external view returns (RateLimitGlobalConfig memory globalConfig);
168
+
169
+ /**
170
+ * @notice Returns the rate limit state and configuration for a given ID.
171
+ * @dev May return unscaled state if `SCALE_DECIMALS` is set, use `getRateLimitUsages` for scaled values.
172
+ * @dev Reads the rate limit state from storage without checking defaults.
173
+ * @param _id ID of the rate limit
174
+ * @return rateLimit Rate limit state and configuration
175
+ */
176
+ function rateLimits(uint256 _id) external view returns (RateLimit memory rateLimit);
177
+
178
+ /**
179
+ * @notice Returns the address exemption status for a given user.
180
+ * @param _user Address of the user
181
+ * @return isExempt Whether the address is exempt
182
+ */
183
+ function isRateLimitAddressExempt(address _user) external view returns (bool isExempt);
184
+
185
+ /**
186
+ * @notice Calculates decayed usages and capacities for a rate limit.
187
+ * @dev Potentially scaled up by `SCALE_DECIMALS`.
188
+ * @dev Checks config and falls back to default if necessary.
189
+ * @dev If a rate limit is disabled in a given direction, the available amount is `type(uint256).max`.
190
+ * @param _id ID of the rate limit
191
+ * @return outboundUsage Scaled current usage of the outbound rate limit
192
+ * @return outboundAvailableAmount Scaled capacity of the outbound rate limit
193
+ * @return inboundUsage Scaled current usage of the inbound rate limit
194
+ * @return inboundAvailableAmount Scaled capacity of the inbound rate limit
195
+ */
196
+ function getRateLimitUsages(
197
+ uint256 _id
198
+ )
199
+ external
200
+ view
201
+ returns (
202
+ uint256 outboundUsage,
203
+ uint256 outboundAvailableAmount,
204
+ uint256 inboundUsage,
205
+ uint256 inboundAvailableAmount
206
+ );
207
+
208
+ /**
209
+ * @notice Sets the global configuration for the rate limiter.
210
+ * @param _globalConfig Global configuration to set
211
+ */
212
+ function setRateLimitGlobalConfig(RateLimitGlobalConfig memory _globalConfig) external;
213
+
214
+ /**
215
+ * @notice Sets ID-specific configurations for the rate limiter.
216
+ * @dev Configurations must be significantly larger than windows to avoid precision loss when calculating decays.
217
+ * @dev It does not checkpoint rate limits for the configured IDs.
218
+ * @param _params Array of configurations to set
219
+ */
220
+ function setRateLimitConfigs(SetRateLimitConfigParam[] calldata _params) external;
221
+
222
+ /**
223
+ * @notice Sets ID-specific states for the rate limiter.
224
+ * @dev States cannot be set to a timestamp in the future.
225
+ * @param _params Array of states to set
226
+ */
227
+ function setRateLimitStates(SetRateLimitStateParam[] calldata _params) external;
228
+
229
+ /**
230
+ * @notice Sets address exemptions for the rate limiter.
231
+ * @dev Only in effect if `addressExemptionEnabled` is true for an ID.
232
+ * @param _exemptions Array of exemptions to set
233
+ */
234
+ function setRateLimitAddressExemptions(SetRateLimitAddressExemptionParam[] calldata _exemptions) external;
235
+
236
+ /**
237
+ * @notice Checkpoints rate limits for multiple IDs, updating decayed usages to storage.
238
+ * @dev Recommended to be called atomically before setting new limits or windows through `setRateLimitConfigs`, to
239
+ * avoid retroactively applying decays. Alternatively, `setRateLimitStates` can be called to explicitly set
240
+ * the desired usages.
241
+ * @param _ids Array of rate limit IDs to checkpoint
242
+ */
243
+ function checkpointRateLimits(uint256[] calldata _ids) external;
244
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@layerzerolabs/utils-evm-contracts",
3
+ "version": "0.2.74",
4
+ "private": false,
5
+ "description": "LayerZero Labs reference EVM utility implementations",
6
+ "license": "MIT",
7
+ "devDependencies": {
8
+ "@layerzerolabs/test-devtools-evm-foundry": "8.0.1",
9
+ "@layerzerolabs/toolbox-foundry": "^0.1.13",
10
+ "@openzeppelin/contracts": "^5.0.2",
11
+ "solhint": "^6.0.1",
12
+ "@layerzerolabs/solhint-configuration": "0.2.74",
13
+ "@layerzerolabs/typescript-configuration": "0.2.74",
14
+ "@layerzerolabs/vm-tooling-evm": "0.2.74",
15
+ "@layerzerolabs/tsup-configuration": "0.2.74"
16
+ },
17
+ "publishConfig": {
18
+ "access": "restricted",
19
+ "registry": "https://registry.npmjs.org/"
20
+ },
21
+ "externalRepoConfig": {
22
+ "targets": [
23
+ "audit-external",
24
+ "monorepo-external"
25
+ ]
26
+ },
27
+ "scripts": {
28
+ "clean-artifacts": "rm -rf artifacts* cache hh-cache*",
29
+ "lint": "solhint --config solhint.config.js 'contracts/**/*.sol' --fix --noPrompt"
30
+ }
31
+ }
@@ -0,0 +1,3 @@
1
+ const baseConfig = require('@layerzerolabs/solhint-configuration');
2
+
3
+ module.exports = baseConfig;