@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.
- package/README.md +15 -0
- package/contracts/Executor.sol +339 -0
- package/contracts/ExecutorFeeLib.sol +241 -0
- package/contracts/MessageLibBase.sol +21 -0
- package/contracts/PriceFeed.sol +304 -0
- package/contracts/ReceiveLibBaseE2.sol +28 -0
- package/contracts/SendLibBase.sol +258 -0
- package/contracts/SendLibBaseE2.sol +140 -0
- package/contracts/SimpleReadExecutor.sol +110 -0
- package/contracts/Treasury.sol +74 -0
- package/contracts/Worker.sol +167 -0
- package/contracts/decompressor/DVNDecoder.sol +52 -0
- package/contracts/decompressor/DVNDecompressor.sol +70 -0
- package/contracts/decompressor/DecompressorExtension.sol +204 -0
- package/contracts/decompressor/ExecutorDecoder.sol +147 -0
- package/contracts/decompressor/ExecutorDecompressor.sol +58 -0
- package/contracts/interfaces/IExecutor.sol +47 -0
- package/contracts/interfaces/IExecutorFeeLib.sol +56 -0
- package/contracts/interfaces/ILayerZeroExecutor.sol +29 -0
- package/contracts/interfaces/ILayerZeroPriceFeed.sol +61 -0
- package/contracts/interfaces/ILayerZeroReadExecutor.sol +15 -0
- package/contracts/interfaces/ILayerZeroTreasury.sol +19 -0
- package/contracts/interfaces/IWorker.sol +29 -0
- package/contracts/libs/ExecutorOptions.sol +104 -0
- package/contracts/libs/SafeCall.sol +123 -0
- package/contracts/lowlat/EssenceDVNWrapper.sol +77 -0
- package/contracts/lowlat/MultiCall.sol +42 -0
- package/contracts/mocks/DVNMock.sol +28 -0
- package/contracts/mocks/ExecutorMock.sol +95 -0
- package/contracts/uln/LzExecutor.sol +129 -0
- package/contracts/uln/ReceiveUlnBase.sol +125 -0
- package/contracts/uln/SendUlnBase.sol +129 -0
- package/contracts/uln/UlnBase.sol +195 -0
- package/contracts/uln/dvn/DVN.sol +393 -0
- package/contracts/uln/dvn/DVNFeeLib.sol +288 -0
- package/contracts/uln/dvn/DeadDVN.sol +30 -0
- package/contracts/uln/dvn/MultiSig.sol +135 -0
- package/contracts/uln/dvn/SimpleReadDVN.sol +112 -0
- package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapter.sol +151 -0
- package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapterFeeLib.sol +71 -0
- package/contracts/uln/dvn/adapters/DVNAdapterBase.sol +114 -0
- package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL1.sol +126 -0
- package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL2.sol +50 -0
- package/contracts/uln/dvn/adapters/avalanche/NOTES.md +4 -0
- package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapter.sol +152 -0
- package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapterFeeLib.sol +127 -0
- package/contracts/uln/dvn/adapters/libs/DVNAdapterMessageCodec.sol +41 -0
- package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL1.sol +86 -0
- package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL2.sol +58 -0
- package/contracts/uln/interfaces/IDVN.sol +26 -0
- package/contracts/uln/interfaces/IDVNFeeLib.sol +56 -0
- package/contracts/uln/interfaces/ILayerZeroDVN.sol +34 -0
- package/contracts/uln/interfaces/ILayerZeroReadDVN.sol +27 -0
- package/contracts/uln/interfaces/IReceiveUlnE2.sol +13 -0
- package/contracts/uln/interfaces/adapters/IAxelarDVNAdapter.sol +50 -0
- package/contracts/uln/interfaces/adapters/IAxelarDVNAdapterFeeLib.sol +49 -0
- package/contracts/uln/interfaces/adapters/ICCIPDVNAdapter.sol +34 -0
- package/contracts/uln/interfaces/adapters/ICCIPDVNAdapterFeeLib.sol +46 -0
- package/contracts/uln/libs/DVNOptions.sol +181 -0
- package/contracts/uln/libs/ReadCmdCodecV1.sol +136 -0
- package/contracts/uln/libs/SupportedCmdTypes.sol +29 -0
- package/contracts/uln/libs/UlnOptions.sol +176 -0
- package/contracts/uln/readlib/ReadLib1002.sol +518 -0
- package/contracts/uln/readlib/ReadLib1002View.sol +98 -0
- package/contracts/uln/readlib/ReadLibBase.sol +187 -0
- package/contracts/uln/uln301/AddressSizeConfig.sol +22 -0
- package/contracts/uln/uln301/ReceiveLibBaseE1.sol +103 -0
- package/contracts/uln/uln301/ReceiveUln301.sol +83 -0
- package/contracts/uln/uln301/ReceiveUln301View.sol +89 -0
- package/contracts/uln/uln301/SendLibBaseE1.sol +194 -0
- package/contracts/uln/uln301/SendUln301.sol +99 -0
- package/contracts/uln/uln301/TreasuryFeeHandler.sol +41 -0
- package/contracts/uln/uln301/interfaces/IMessageLibE1.sol +22 -0
- package/contracts/uln/uln301/interfaces/INonceContract.sol +7 -0
- package/contracts/uln/uln301/interfaces/ITreasuryFeeHandler.sol +13 -0
- package/contracts/uln/uln301/interfaces/IUltraLightNode301.sol +7 -0
- package/contracts/uln/uln301/mocks/NonceContractMock.sol +23 -0
- package/contracts/uln/uln302/ReceiveUln302.sol +85 -0
- package/contracts/uln/uln302/ReceiveUln302View.sol +89 -0
- package/contracts/uln/uln302/SendUln302.sol +86 -0
- package/contracts/upgradeable/WorkerUpgradeable.sol +186 -0
- package/contracts/upgradeable/proxy/ProxyAdmin.sol +96 -0
- package/contracts/upgradeable/proxy/TransparentUpgradeableProxy.sol +131 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- 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
|
+
}
|