@layerzerolabs/protocol-v2-messagelib-evm-contracts 1.2.95

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 (88) hide show
  1. package/README.md +15 -0
  2. package/contracts/Executor.sol +339 -0
  3. package/contracts/ExecutorFeeLib.sol +241 -0
  4. package/contracts/MessageLibBase.sol +21 -0
  5. package/contracts/PriceFeed.sol +304 -0
  6. package/contracts/ReceiveLibBaseE2.sol +28 -0
  7. package/contracts/SendLibBase.sol +258 -0
  8. package/contracts/SendLibBaseE2.sol +140 -0
  9. package/contracts/SimpleReadExecutor.sol +110 -0
  10. package/contracts/Treasury.sol +74 -0
  11. package/contracts/Worker.sol +167 -0
  12. package/contracts/decompressor/DVNDecoder.sol +52 -0
  13. package/contracts/decompressor/DVNDecompressor.sol +70 -0
  14. package/contracts/decompressor/DecompressorExtension.sol +204 -0
  15. package/contracts/decompressor/ExecutorDecoder.sol +147 -0
  16. package/contracts/decompressor/ExecutorDecompressor.sol +58 -0
  17. package/contracts/interfaces/IExecutor.sol +47 -0
  18. package/contracts/interfaces/IExecutorFeeLib.sol +56 -0
  19. package/contracts/interfaces/ILayerZeroExecutor.sol +29 -0
  20. package/contracts/interfaces/ILayerZeroPriceFeed.sol +61 -0
  21. package/contracts/interfaces/ILayerZeroReadExecutor.sol +15 -0
  22. package/contracts/interfaces/ILayerZeroTreasury.sol +19 -0
  23. package/contracts/interfaces/IWorker.sol +29 -0
  24. package/contracts/libs/ExecutorOptions.sol +104 -0
  25. package/contracts/libs/SafeCall.sol +123 -0
  26. package/contracts/lowlat/EssenceDVNWrapper.sol +77 -0
  27. package/contracts/lowlat/MultiCall.sol +42 -0
  28. package/contracts/mocks/DVNMock.sol +28 -0
  29. package/contracts/mocks/ExecutorMock.sol +95 -0
  30. package/contracts/uln/LzExecutor.sol +129 -0
  31. package/contracts/uln/ReceiveUlnBase.sol +125 -0
  32. package/contracts/uln/SendUlnBase.sol +129 -0
  33. package/contracts/uln/UlnBase.sol +195 -0
  34. package/contracts/uln/dvn/DVN.sol +393 -0
  35. package/contracts/uln/dvn/DVNFeeLib.sol +288 -0
  36. package/contracts/uln/dvn/DeadDVN.sol +30 -0
  37. package/contracts/uln/dvn/MultiSig.sol +135 -0
  38. package/contracts/uln/dvn/SimpleReadDVN.sol +112 -0
  39. package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapter.sol +151 -0
  40. package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapterFeeLib.sol +71 -0
  41. package/contracts/uln/dvn/adapters/DVNAdapterBase.sol +114 -0
  42. package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL1.sol +126 -0
  43. package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL2.sol +50 -0
  44. package/contracts/uln/dvn/adapters/avalanche/NOTES.md +4 -0
  45. package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapter.sol +152 -0
  46. package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapterFeeLib.sol +127 -0
  47. package/contracts/uln/dvn/adapters/libs/DVNAdapterMessageCodec.sol +41 -0
  48. package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL1.sol +86 -0
  49. package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL2.sol +58 -0
  50. package/contracts/uln/interfaces/IDVN.sol +26 -0
  51. package/contracts/uln/interfaces/IDVNFeeLib.sol +56 -0
  52. package/contracts/uln/interfaces/ILayerZeroDVN.sol +34 -0
  53. package/contracts/uln/interfaces/ILayerZeroReadDVN.sol +27 -0
  54. package/contracts/uln/interfaces/IReceiveUlnE2.sol +13 -0
  55. package/contracts/uln/interfaces/adapters/IAxelarDVNAdapter.sol +50 -0
  56. package/contracts/uln/interfaces/adapters/IAxelarDVNAdapterFeeLib.sol +49 -0
  57. package/contracts/uln/interfaces/adapters/ICCIPDVNAdapter.sol +34 -0
  58. package/contracts/uln/interfaces/adapters/ICCIPDVNAdapterFeeLib.sol +46 -0
  59. package/contracts/uln/libs/DVNOptions.sol +181 -0
  60. package/contracts/uln/libs/ReadCmdCodecV1.sol +136 -0
  61. package/contracts/uln/libs/SupportedCmdTypes.sol +29 -0
  62. package/contracts/uln/libs/UlnOptions.sol +176 -0
  63. package/contracts/uln/readlib/ReadLib1002.sol +518 -0
  64. package/contracts/uln/readlib/ReadLib1002View.sol +98 -0
  65. package/contracts/uln/readlib/ReadLibBase.sol +187 -0
  66. package/contracts/uln/uln301/AddressSizeConfig.sol +22 -0
  67. package/contracts/uln/uln301/ReceiveLibBaseE1.sol +103 -0
  68. package/contracts/uln/uln301/ReceiveUln301.sol +83 -0
  69. package/contracts/uln/uln301/ReceiveUln301View.sol +89 -0
  70. package/contracts/uln/uln301/SendLibBaseE1.sol +194 -0
  71. package/contracts/uln/uln301/SendUln301.sol +99 -0
  72. package/contracts/uln/uln301/TreasuryFeeHandler.sol +41 -0
  73. package/contracts/uln/uln301/interfaces/IMessageLibE1.sol +22 -0
  74. package/contracts/uln/uln301/interfaces/INonceContract.sol +7 -0
  75. package/contracts/uln/uln301/interfaces/ITreasuryFeeHandler.sol +13 -0
  76. package/contracts/uln/uln301/interfaces/IUltraLightNode301.sol +7 -0
  77. package/contracts/uln/uln301/mocks/NonceContractMock.sol +23 -0
  78. package/contracts/uln/uln302/ReceiveUln302.sol +85 -0
  79. package/contracts/uln/uln302/ReceiveUln302View.sol +89 -0
  80. package/contracts/uln/uln302/SendUln302.sol +86 -0
  81. package/contracts/upgradeable/WorkerUpgradeable.sol +186 -0
  82. package/contracts/upgradeable/proxy/ProxyAdmin.sol +96 -0
  83. package/contracts/upgradeable/proxy/TransparentUpgradeableProxy.sol +131 -0
  84. package/dist/index.d.ts +7 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +6 -0
  87. package/dist/index.js.map +1 -0
  88. package/package.json +70 -0
@@ -0,0 +1,140 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.20;
4
+
5
+ import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
6
+ import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
7
+
8
+ import { ILayerZeroEndpointV2, MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
9
+ import { IMessageLib, MessageLibType } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol";
10
+ import { ISendLib, Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
11
+ import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
12
+
13
+ import { SendLibBase, WorkerOptions, ExecutorConfig } from "./SendLibBase.sol";
14
+
15
+ /// @dev send-side message library base contract on endpoint v2.
16
+ /// design: the high level logic is the same as SendLibBaseE1
17
+ /// 1/ with added interfaces
18
+ /// 2/ adapt the functions to the new types, like uint32 for eid, address for sender.
19
+ abstract contract SendLibBaseE2 is SendLibBase, ERC165, ISendLib {
20
+ event NativeFeeWithdrawn(address worker, address receiver, uint256 amount);
21
+ event LzTokenFeeWithdrawn(address lzToken, address receiver, uint256 amount);
22
+
23
+ error LZ_MessageLib_NotTreasury();
24
+ error LZ_MessageLib_CannotWithdrawAltToken();
25
+
26
+ constructor(
27
+ address _endpoint,
28
+ uint256 _treasuryGasLimit,
29
+ uint256 _treasuryNativeFeeCap
30
+ ) SendLibBase(_endpoint, ILayerZeroEndpointV2(_endpoint).eid(), _treasuryGasLimit, _treasuryNativeFeeCap) {}
31
+
32
+ function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
33
+ return
34
+ _interfaceId == type(IMessageLib).interfaceId ||
35
+ _interfaceId == type(ISendLib).interfaceId ||
36
+ super.supportsInterface(_interfaceId);
37
+ }
38
+
39
+ // ========================= OnlyEndpoint =========================
40
+ // @dev this function is marked as virtual and public for testing purpose
41
+ function send(
42
+ Packet calldata _packet,
43
+ bytes calldata _options,
44
+ bool _payInLzToken
45
+ ) public virtual onlyEndpoint returns (MessagingFee memory, bytes memory) {
46
+ (bytes memory encodedPacket, uint256 totalNativeFee) = _payWorkers(_packet, _options);
47
+
48
+ (uint256 treasuryNativeFee, uint256 lzTokenFee) = _payTreasury(
49
+ _packet.sender,
50
+ _packet.dstEid,
51
+ totalNativeFee,
52
+ _payInLzToken
53
+ );
54
+ totalNativeFee += treasuryNativeFee;
55
+
56
+ return (MessagingFee(totalNativeFee, lzTokenFee), encodedPacket);
57
+ }
58
+
59
+ // ========================= OnlyOwner =========================
60
+ function setTreasury(address _treasury) external onlyOwner {
61
+ _setTreasury(_treasury);
62
+ }
63
+
64
+ // ========================= External =========================
65
+ /// @dev E2 only
66
+ function withdrawFee(address _to, uint256 _amount) external {
67
+ _debitFee(_amount);
68
+ address nativeToken = ILayerZeroEndpointV2(endpoint).nativeToken();
69
+ // transfers native if nativeToken == address(0x0)
70
+ Transfer.nativeOrToken(nativeToken, _to, _amount);
71
+ emit NativeFeeWithdrawn(msg.sender, _to, _amount);
72
+ }
73
+
74
+ /// @dev _lzToken is a user-supplied value because lzToken might change in the endpoint before all lzToken can be taken out
75
+ /// @dev E2 only
76
+ /// @dev treasury only function
77
+ function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external {
78
+ if (msg.sender != treasury) revert LZ_MessageLib_NotTreasury();
79
+
80
+ // lz token cannot be the same as the native token
81
+ if (ILayerZeroEndpointV2(endpoint).nativeToken() == _lzToken) revert LZ_MessageLib_CannotWithdrawAltToken();
82
+
83
+ Transfer.token(_lzToken, _to, _amount);
84
+
85
+ emit LzTokenFeeWithdrawn(_lzToken, _to, _amount);
86
+ }
87
+
88
+ // ========================= View =========================
89
+ function quote(
90
+ Packet calldata _packet,
91
+ bytes calldata _options,
92
+ bool _payInLzToken
93
+ ) external view returns (MessagingFee memory) {
94
+ (uint256 nativeFee, uint256 lzTokenFee) = _quote(
95
+ _packet.sender,
96
+ _packet.dstEid,
97
+ _packet.message.length,
98
+ _payInLzToken,
99
+ _options
100
+ );
101
+ return MessagingFee(nativeFee, lzTokenFee);
102
+ }
103
+
104
+ function messageLibType() external pure virtual override returns (MessageLibType) {
105
+ return MessageLibType.Send;
106
+ }
107
+
108
+ // ========================= Internal =========================
109
+ /// 1/ handle executor
110
+ /// 2/ handle other workers
111
+ function _payWorkers(
112
+ Packet calldata _packet,
113
+ bytes calldata _options
114
+ ) internal returns (bytes memory encodedPacket, uint256 totalNativeFee) {
115
+ // split workers options
116
+ (bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
117
+
118
+ // handle executor
119
+ ExecutorConfig memory config = getExecutorConfig(_packet.sender, _packet.dstEid);
120
+ uint256 msgSize = _packet.message.length;
121
+ _assertMessageSize(msgSize, config.maxMessageSize);
122
+ totalNativeFee += _payExecutor(config.executor, _packet.dstEid, _packet.sender, msgSize, executorOptions);
123
+
124
+ // handle other workers
125
+ (uint256 verifierFee, bytes memory packetBytes) = _payVerifier(_packet, validationOptions); //for ULN, it will be dvns
126
+ totalNativeFee += verifierFee;
127
+
128
+ encodedPacket = packetBytes;
129
+ }
130
+
131
+ // ======================= Virtual =======================
132
+ // For implementation to override
133
+ function _payVerifier(
134
+ Packet calldata _packet,
135
+ WorkerOptions[] memory _options
136
+ ) internal virtual returns (uint256 otherWorkerFees, bytes memory encodedPacket);
137
+
138
+ // receive native token from endpoint
139
+ receive() external payable virtual {}
140
+ }
@@ -0,0 +1,110 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.20;
4
+
5
+ import { Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
6
+
7
+ import { ILayerZeroReadExecutor } from "./interfaces/ILayerZeroReadExecutor.sol";
8
+ import { ExecutorOptions } from "./libs/ExecutorOptions.sol";
9
+
10
+ struct ExecutionParams {
11
+ address receiver;
12
+ Origin origin;
13
+ bytes32 guid;
14
+ bytes message;
15
+ bytes extraData;
16
+ uint256 gasLimit;
17
+ }
18
+
19
+ interface ILayerZeroEndpointV2 {
20
+ function eid() external view returns (uint32);
21
+
22
+ function lzReceive(
23
+ Origin calldata _origin,
24
+ address _receiver,
25
+ bytes32 _guid,
26
+ bytes calldata _message,
27
+ bytes calldata _extraData
28
+ ) external payable;
29
+
30
+ function lzReceiveAlert(
31
+ Origin calldata _origin,
32
+ address _receiver,
33
+ bytes32 _guid,
34
+ uint256 _gas,
35
+ uint256 _value,
36
+ bytes calldata _message,
37
+ bytes calldata _extraData,
38
+ bytes calldata _reason
39
+ ) external;
40
+ }
41
+
42
+ contract SimpleReadExecutor is ILayerZeroReadExecutor {
43
+ using ExecutorOptions for bytes;
44
+
45
+ address public immutable endpoint;
46
+
47
+ uint128 public gasPerByte;
48
+ uint128 public gasPrice;
49
+
50
+ constructor(address _endpoint) {
51
+ endpoint = _endpoint;
52
+ }
53
+
54
+ function configGas(uint128 _gasPerByte, uint128 _gasPrice) external {
55
+ gasPerByte = _gasPerByte;
56
+ gasPrice = _gasPrice;
57
+ }
58
+
59
+ function assignJob(address _sender, bytes calldata _options) external returns (uint256) {
60
+ return getFee(_sender, _options);
61
+ }
62
+
63
+ function execute(ExecutionParams calldata _executionParams) external payable {
64
+ try
65
+ ILayerZeroEndpointV2(endpoint).lzReceive{ value: msg.value, gas: _executionParams.gasLimit }(
66
+ _executionParams.origin,
67
+ _executionParams.receiver,
68
+ _executionParams.guid,
69
+ _executionParams.message,
70
+ _executionParams.extraData
71
+ )
72
+ {
73
+ // do nothing
74
+ } catch (bytes memory reason) {
75
+ ILayerZeroEndpointV2(endpoint).lzReceiveAlert(
76
+ _executionParams.origin,
77
+ _executionParams.receiver,
78
+ _executionParams.guid,
79
+ _executionParams.gasLimit,
80
+ msg.value,
81
+ _executionParams.message,
82
+ _executionParams.extraData,
83
+ reason
84
+ );
85
+ }
86
+ }
87
+
88
+ function mustExecute(ExecutionParams calldata _executionParams) external payable {
89
+ ILayerZeroEndpointV2(endpoint).lzReceive{ value: msg.value, gas: _executionParams.gasLimit }(
90
+ _executionParams.origin,
91
+ _executionParams.receiver,
92
+ _executionParams.guid,
93
+ _executionParams.message,
94
+ _executionParams.extraData
95
+ );
96
+ }
97
+
98
+ // ========================= View =========================
99
+
100
+ function getFee(address /*_sender*/, bytes calldata _options) public view returns (uint256) {
101
+ // For simplify, we only support one execute option, and must be LZREAD type
102
+ (uint8 optionType, bytes calldata option, ) = _options.nextExecutorOption(0);
103
+ require(optionType == ExecutorOptions.OPTION_TYPE_LZREAD, "SimpleReadExecutor: not LZREAD option");
104
+ (uint128 gas, uint32 calldataSize, uint128 value) = option.decodeLzReadOption();
105
+ // calculate fee
106
+ return (gas + calldataSize * gasPerByte) * gasPrice + value;
107
+ }
108
+
109
+ receive() external payable virtual {}
110
+ }
@@ -0,0 +1,74 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.20;
4
+
5
+ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
6
+
7
+ import { ISendLib } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
8
+ import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
9
+
10
+ import { ILayerZeroTreasury } from "./interfaces/ILayerZeroTreasury.sol";
11
+
12
+ contract Treasury is Ownable, ILayerZeroTreasury {
13
+ uint256 public nativeBP;
14
+ uint256 public lzTokenFee;
15
+ bool public lzTokenEnabled;
16
+
17
+ error LZ_Treasury_LzTokenNotEnabled();
18
+
19
+ function getFee(
20
+ address /*_sender*/,
21
+ uint32 /*_eid*/,
22
+ uint256 _totalFee,
23
+ bool _payInLzToken
24
+ ) external view override returns (uint256) {
25
+ return _getFee(_totalFee, _payInLzToken);
26
+ }
27
+
28
+ function payFee(
29
+ address /*_sender*/,
30
+ uint32 /*_eid*/,
31
+ uint256 _totalFee,
32
+ bool _payInLzToken
33
+ ) external payable override returns (uint256) {
34
+ return _getFee(_totalFee, _payInLzToken);
35
+ }
36
+
37
+ function setLzTokenEnabled(bool _lzTokenEnabled) external onlyOwner {
38
+ lzTokenEnabled = _lzTokenEnabled;
39
+ }
40
+
41
+ function setNativeFeeBP(uint256 _nativeBP) external onlyOwner {
42
+ nativeBP = _nativeBP;
43
+ }
44
+
45
+ function setLzTokenFee(uint256 _lzTokenFee) external onlyOwner {
46
+ lzTokenFee = _lzTokenFee;
47
+ }
48
+
49
+ function withdrawLzToken(address _messageLib, address _lzToken, address _to, uint256 _amount) external onlyOwner {
50
+ ISendLib(_messageLib).withdrawLzTokenFee(_lzToken, _to, _amount);
51
+ }
52
+
53
+ function withdrawNativeFee(address _messageLib, address payable _to, uint256 _amount) external onlyOwner {
54
+ ISendLib(_messageLib).withdrawFee(_to, _amount);
55
+ }
56
+
57
+ // this is for withdrawing lz token sent to this contract by uln301 and fee handler
58
+ // and to withdraw any native sent over via payFee
59
+ function withdrawToken(address _token, address _to, uint256 _amount) external onlyOwner {
60
+ // transfers native if _token is address(0x0)
61
+ Transfer.nativeOrToken(_token, _to, _amount);
62
+ }
63
+
64
+ // ======================= Internal =======================
65
+
66
+ function _getFee(uint256 _totalFee, bool _payInLzToken) internal view returns (uint256) {
67
+ if (_payInLzToken) {
68
+ if (!lzTokenEnabled) revert LZ_Treasury_LzTokenNotEnabled();
69
+ return lzTokenFee;
70
+ } else {
71
+ return (_totalFee * nativeBP) / 10000;
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,167 @@
1
+ // SPDX-License-Identifier: LZBL-1.2
2
+
3
+ pragma solidity ^0.8.20;
4
+
5
+ import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
6
+ import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
7
+
8
+ import { ISendLib } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
9
+ import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
10
+
11
+ import { IWorker } from "./interfaces/IWorker.sol";
12
+
13
+ abstract contract Worker is AccessControl, Pausable, IWorker {
14
+ bytes32 internal constant MESSAGE_LIB_ROLE = keccak256("MESSAGE_LIB_ROLE");
15
+ bytes32 internal constant ALLOWLIST = keccak256("ALLOWLIST");
16
+ bytes32 internal constant DENYLIST = keccak256("DENYLIST");
17
+ bytes32 internal constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
18
+
19
+ address public workerFeeLib;
20
+
21
+ uint64 public allowlistSize;
22
+ uint16 public defaultMultiplierBps;
23
+ address public priceFeed;
24
+
25
+ mapping(uint32 eid => uint8[] optionTypes) internal supportedOptionTypes;
26
+
27
+ // ========================= Constructor =========================
28
+
29
+ /// @param _messageLibs array of message lib addresses that are granted the MESSAGE_LIB_ROLE
30
+ /// @param _priceFeed price feed address
31
+ /// @param _defaultMultiplierBps default multiplier for worker fee
32
+ /// @param _roleAdmin address that is granted the DEFAULT_ADMIN_ROLE (can grant and revoke all roles)
33
+ /// @param _admins array of admin addresses that are granted the ADMIN_ROLE
34
+ constructor(
35
+ address[] memory _messageLibs,
36
+ address _priceFeed,
37
+ uint16 _defaultMultiplierBps,
38
+ address _roleAdmin,
39
+ address[] memory _admins
40
+ ) {
41
+ defaultMultiplierBps = _defaultMultiplierBps;
42
+ priceFeed = _priceFeed;
43
+
44
+ if (_roleAdmin != address(0x0)) {
45
+ _grantRole(DEFAULT_ADMIN_ROLE, _roleAdmin); // _roleAdmin can grant and revoke all roles
46
+ }
47
+
48
+ for (uint256 i = 0; i < _messageLibs.length; ++i) {
49
+ _grantRole(MESSAGE_LIB_ROLE, _messageLibs[i]);
50
+ }
51
+
52
+ for (uint256 i = 0; i < _admins.length; ++i) {
53
+ _grantRole(ADMIN_ROLE, _admins[i]);
54
+ }
55
+ }
56
+
57
+ // ========================= Modifier =========================
58
+
59
+ modifier onlyAcl(address _sender) {
60
+ if (!hasAcl(_sender)) {
61
+ revert Worker_NotAllowed();
62
+ }
63
+ _;
64
+ }
65
+
66
+ /// @dev Access control list using allowlist and denylist
67
+ /// @dev 1) if one address is in the denylist -> deny
68
+ /// @dev 2) else if address in the allowlist OR allowlist is empty (allows everyone)-> allow
69
+ /// @dev 3) else deny
70
+ /// @param _sender address to check
71
+ function hasAcl(address _sender) public view returns (bool) {
72
+ if (hasRole(DENYLIST, _sender)) {
73
+ return false;
74
+ } else if (allowlistSize == 0 || hasRole(ALLOWLIST, _sender)) {
75
+ return true;
76
+ } else {
77
+ return false;
78
+ }
79
+ }
80
+
81
+ // ========================= OnyDefaultAdmin =========================
82
+
83
+ /// @dev flag to pause execution of workers (if used with whenNotPaused modifier)
84
+ /// @param _paused true to pause, false to unpause
85
+ function setPaused(bool _paused) external onlyRole(DEFAULT_ADMIN_ROLE) {
86
+ if (_paused) {
87
+ _pause();
88
+ } else {
89
+ _unpause();
90
+ }
91
+ }
92
+
93
+ // ========================= OnlyAdmin =========================
94
+
95
+ /// @param _priceFeed price feed address
96
+ function setPriceFeed(address _priceFeed) external onlyRole(ADMIN_ROLE) {
97
+ priceFeed = _priceFeed;
98
+ emit SetPriceFeed(_priceFeed);
99
+ }
100
+
101
+ /// @param _workerFeeLib worker fee lib address
102
+ function setWorkerFeeLib(address _workerFeeLib) external onlyRole(ADMIN_ROLE) {
103
+ workerFeeLib = _workerFeeLib;
104
+ emit SetWorkerLib(_workerFeeLib);
105
+ }
106
+
107
+ /// @param _multiplierBps default multiplier for worker fee
108
+ function setDefaultMultiplierBps(uint16 _multiplierBps) external onlyRole(ADMIN_ROLE) {
109
+ defaultMultiplierBps = _multiplierBps;
110
+ emit SetDefaultMultiplierBps(_multiplierBps);
111
+ }
112
+
113
+ /// @dev supports withdrawing fee from ULN301, ULN302 and more
114
+ /// @param _lib message lib address
115
+ /// @param _to address to withdraw fee to
116
+ /// @param _amount amount to withdraw
117
+ function withdrawFee(address _lib, address _to, uint256 _amount) external onlyRole(ADMIN_ROLE) {
118
+ if (!hasRole(MESSAGE_LIB_ROLE, _lib)) revert Worker_OnlyMessageLib();
119
+ ISendLib(_lib).withdrawFee(_to, _amount);
120
+ emit Withdraw(_lib, _to, _amount);
121
+ }
122
+
123
+ /// @dev supports withdrawing token from the contract
124
+ /// @param _token token address
125
+ /// @param _to address to withdraw token to
126
+ /// @param _amount amount to withdraw
127
+ function withdrawToken(address _token, address _to, uint256 _amount) external onlyRole(ADMIN_ROLE) {
128
+ // transfers native if _token is address(0x0)
129
+ Transfer.nativeOrToken(_token, _to, _amount);
130
+ }
131
+
132
+ function setSupportedOptionTypes(uint32 _eid, uint8[] calldata _optionTypes) external onlyRole(ADMIN_ROLE) {
133
+ supportedOptionTypes[_eid] = _optionTypes;
134
+ }
135
+
136
+ // ========================= View Functions =========================
137
+ function getSupportedOptionTypes(uint32 _eid) external view returns (uint8[] memory) {
138
+ return supportedOptionTypes[_eid];
139
+ }
140
+
141
+ // ========================= Internal Functions =========================
142
+
143
+ /// @dev overrides AccessControl to allow for counting of allowlistSize
144
+ /// @param _role role to grant
145
+ /// @param _account address to grant role to
146
+ function _grantRole(bytes32 _role, address _account) internal override {
147
+ if (_role == ALLOWLIST && !hasRole(_role, _account)) {
148
+ ++allowlistSize;
149
+ }
150
+ super._grantRole(_role, _account);
151
+ }
152
+
153
+ /// @dev overrides AccessControl to allow for counting of allowlistSize
154
+ /// @param _role role to revoke
155
+ /// @param _account address to revoke role from
156
+ function _revokeRole(bytes32 _role, address _account) internal override {
157
+ if (_role == ALLOWLIST && hasRole(_role, _account)) {
158
+ --allowlistSize;
159
+ }
160
+ super._revokeRole(_role, _account);
161
+ }
162
+
163
+ /// @dev overrides AccessControl to disable renouncing of roles
164
+ function renounceRole(bytes32 /*role*/, address /*account*/) public pure override {
165
+ revert Worker_RoleRenouncingDisabled();
166
+ }
167
+ }
@@ -0,0 +1,52 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+
3
+ pragma solidity ^0.8.0;
4
+
5
+ import { ExecuteParam } from "../uln/dvn/DVN.sol";
6
+
7
+ library DVNDecoder {
8
+ uint8 internal constant DVN_INDEX_SIZE = 2; // uint16
9
+ uint8 internal constant PARAMS_LENGTH_SIZE = 1; // uint8
10
+ uint8 internal constant TARGET_INDEX_SIZE = 1; // uint8
11
+ uint8 internal constant EXPIRATION_SIZE = 16; // uint128
12
+ uint8 internal constant SIGNATURES_LENGTH_SIZE = 2; // uint16
13
+ uint8 internal constant CALL_DATA_LENGTH_SIZE = 8; // uint64
14
+
15
+ function execute(
16
+ bytes calldata _encoded,
17
+ uint32 _vid,
18
+ mapping(uint8 index => address target) storage _targets
19
+ ) internal view returns (uint16 dvnIndex, ExecuteParam[] memory params) {
20
+ uint256 cursor = 0;
21
+
22
+ dvnIndex = uint16(bytes2(_encoded[cursor:cursor + DVN_INDEX_SIZE]));
23
+ cursor += DVN_INDEX_SIZE;
24
+
25
+ uint8 length = uint8(bytes1(_encoded[cursor:cursor + PARAMS_LENGTH_SIZE]));
26
+ cursor += PARAMS_LENGTH_SIZE;
27
+
28
+ params = new ExecuteParam[](length);
29
+
30
+ for (uint256 i = 0; i < length; i++) {
31
+ uint8 targetIndex = uint8(bytes1(_encoded[cursor:cursor + TARGET_INDEX_SIZE]));
32
+ cursor += TARGET_INDEX_SIZE;
33
+
34
+ uint128 expiration = uint128(bytes16(_encoded[cursor:cursor + EXPIRATION_SIZE]));
35
+ cursor += EXPIRATION_SIZE;
36
+
37
+ uint16 signaturesLength = uint16(bytes2(_encoded[cursor:cursor + SIGNATURES_LENGTH_SIZE]));
38
+ cursor += SIGNATURES_LENGTH_SIZE;
39
+
40
+ bytes memory signatures = _encoded[cursor:cursor + signaturesLength];
41
+ cursor += signaturesLength;
42
+
43
+ uint64 callDataLength = uint64(bytes8(_encoded[cursor:cursor + CALL_DATA_LENGTH_SIZE]));
44
+ cursor += CALL_DATA_LENGTH_SIZE;
45
+
46
+ bytes memory callData = _encoded[cursor:cursor + callDataLength];
47
+ cursor += callDataLength;
48
+
49
+ params[i] = ExecuteParam(_vid, _targets[targetIndex], callData, expiration, signatures);
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,70 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+
3
+ pragma solidity 0.8.22;
4
+
5
+ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
6
+
7
+ import { DVN, ExecuteParam } from "../uln/dvn/DVN.sol";
8
+ import { DVNDecoder } from "./DVNDecoder.sol";
9
+ import { DecompressorExtension } from "./DecompressorExtension.sol";
10
+
11
+ struct TargetParam {
12
+ uint8 idx;
13
+ address addr;
14
+ }
15
+
16
+ struct DVNParam {
17
+ uint16 idx;
18
+ address addr;
19
+ }
20
+
21
+ contract DVNDecompressor is Ownable, DecompressorExtension {
22
+ uint32 public immutable vid;
23
+
24
+ mapping(uint16 index => address dvn) public dvns;
25
+ mapping(uint8 index => address target) public targets;
26
+
27
+ constructor(uint32 _vid, DVNParam[] memory _dvns, TargetParam[] memory _targets) {
28
+ vid = _vid;
29
+
30
+ for (uint256 i = 0; i < _dvns.length; i++) {
31
+ DVNParam memory param = _dvns[i];
32
+ dvns[param.idx] = param.addr;
33
+ }
34
+
35
+ for (uint256 i = 0; i < _targets.length; i++) {
36
+ TargetParam memory param = _targets[i];
37
+ targets[param.idx] = param.addr;
38
+ }
39
+ }
40
+
41
+ function addTargets(TargetParam[] memory _targets) external onlyOwner {
42
+ for (uint256 i = 0; i < _targets.length; i++) {
43
+ targets[_targets[i].idx] = _targets[i].addr;
44
+ }
45
+ }
46
+
47
+ function removeTargets(uint8[] memory _idx) external onlyOwner {
48
+ for (uint256 i = 0; i < _idx.length; i++) {
49
+ delete targets[_idx[i]];
50
+ }
51
+ }
52
+
53
+ function addDVNs(DVNParam[] memory _dvns) external onlyOwner {
54
+ for (uint256 i = 0; i < _dvns.length; i++) {
55
+ dvns[_dvns[i].idx] = _dvns[i].addr;
56
+ }
57
+ }
58
+
59
+ function removeDVNs(uint16[] memory _idx) external onlyOwner {
60
+ for (uint256 i = 0; i < _idx.length; i++) {
61
+ delete dvns[_idx[i]];
62
+ }
63
+ }
64
+
65
+ function execute(bytes calldata _encoded) external onlyOwner {
66
+ (uint16 dvnIndex, ExecuteParam[] memory params) = DVNDecoder.execute(_encoded, vid, targets);
67
+
68
+ DVN(dvns[dvnIndex]).execute(params);
69
+ }
70
+ }