@layerzerolabs/lz-evm-messagelib-v2 2.0.13 → 2.0.15

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 (110) hide show
  1. package/artifacts/contracts/Executor.sol/Executor.json +20 -20
  2. package/artifacts/contracts/ExecutorFeeLib.sol/ExecutorFeeLib.json +19 -19
  3. package/artifacts/contracts/MessageLibBase.sol/MessageLibBase.json +1 -1
  4. package/artifacts/contracts/PriceFeed.sol/PriceFeed.json +15 -15
  5. package/artifacts/contracts/ReceiveLibBaseE2.sol/ReceiveLibBaseE2.json +1 -1
  6. package/artifacts/contracts/SendLibBase.sol/SendLibBase.json +6 -6
  7. package/artifacts/contracts/SendLibBaseE2.sol/SendLibBaseE2.json +10 -10
  8. package/artifacts/contracts/Treasury.sol/Treasury.json +9 -9
  9. package/artifacts/contracts/Worker.sol/Worker.json +18 -18
  10. package/artifacts/contracts/interfaces/IExecutor.sol/IExecutor.json +3 -3
  11. package/artifacts/contracts/interfaces/IExecutorFeeLib.sol/IExecutorFeeLib.json +4 -4
  12. package/artifacts/contracts/interfaces/ILayerZeroPriceFeed.sol/ILayerZeroPriceFeed.json +3 -3
  13. package/artifacts/contracts/interfaces/IWorker.sol/IWorker.json +3 -3
  14. package/artifacts/contracts/uln/LzExecutor.sol/IReceiveUlnView.json +35 -0
  15. package/artifacts/contracts/uln/LzExecutor.sol/LzExecutor.json +279 -20
  16. package/artifacts/contracts/uln/ReceiveUlnBase.sol/ReceiveUlnBase.json +90 -11
  17. package/artifacts/contracts/uln/SendUlnBase.sol/SendUlnBase.json +7 -7
  18. package/artifacts/contracts/uln/UlnBase.sol/UlnBase.json +7 -7
  19. package/artifacts/contracts/uln/dvn/DVN.sol/DVN.json +31 -31
  20. package/artifacts/contracts/uln/dvn/DVNFeeLib.sol/DVNFeeLib.json +14 -14
  21. package/artifacts/contracts/uln/dvn/MultiSig.sol/MultiSig.json +5 -5
  22. package/artifacts/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapter.sol/CCIPDVNAdapter.json +488 -169
  23. package/artifacts/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapterFeeLib.sol/CCIPDVNAdapterFeeLib.json +372 -16
  24. package/artifacts/contracts/uln/dvn/adapters/DVNAdapterBase.sol/DVNAdapterBase.json +419 -93
  25. package/artifacts/contracts/uln/dvn/adapters/DVNAdapterBase.sol/IReceiveUln.json +34 -0
  26. package/artifacts/contracts/uln/dvn/adapters/DVNAdapterBase.sol/ISendLibBase.json +30 -0
  27. package/artifacts/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL1.sol/ArbitrumDVNAdapterL1.json +936 -0
  28. package/artifacts/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL2.sol/ArbitrumDVNAdapterL2.json +868 -0
  29. package/artifacts/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapter.sol/AxelarDVNAdapter.json +611 -249
  30. package/artifacts/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapter.sol/ISendLibBase.json +30 -0
  31. package/artifacts/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapterFeeLib.sol/AxelarDVNAdapterFeeLib.json +526 -13
  32. package/artifacts/contracts/uln/dvn/adapters/libs/DVNAdapterMessageCodec.sol/DVNAdapterMessageCodec.json +16 -0
  33. package/artifacts/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL1.sol/OptimismDVNAdapterL1.json +924 -0
  34. package/artifacts/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL2.sol/OptimismDVNAdapterL2.json +891 -0
  35. package/artifacts/contracts/uln/interfaces/IDVN.sol/IDVN.json +3 -3
  36. package/artifacts/contracts/uln/interfaces/IDVNFeeLib.sol/IDVNFeeLib.json +1 -1
  37. package/artifacts/contracts/uln/interfaces/IReceiveUlnE2.sol/IReceiveUlnE2.json +0 -24
  38. package/artifacts/contracts/uln/interfaces/adapters/IAxelarDVNAdapter.sol/IAxelarDVNAdapter.json +160 -0
  39. package/artifacts/contracts/uln/interfaces/adapters/IAxelarDVNAdapterFeeLib.sol/IAxelarDVNAdapterFeeLib.json +282 -0
  40. package/artifacts/contracts/uln/interfaces/adapters/ICCIPDVNAdapter.sol/ICCIPDVNAdapter.json +91 -0
  41. package/artifacts/contracts/uln/interfaces/adapters/ICCIPDVNAdapterFeeLib.sol/ICCIPDVNAdapterFeeLib.json +290 -0
  42. package/artifacts/contracts/uln/libs/DVNOptions.sol/DVNOptions.json +4 -4
  43. package/artifacts/contracts/uln/libs/UlnOptions.sol/UlnOptions.json +7 -7
  44. package/artifacts/contracts/uln/uln301/AddressSizeConfig.sol/AddressSizeConfig.json +2 -2
  45. package/artifacts/contracts/uln/uln301/ReceiveLibBaseE1.sol/ReceiveLibBaseE1.json +5 -5
  46. package/artifacts/contracts/uln/uln301/ReceiveUln301.sol/ReceiveUln301.json +88 -57
  47. package/artifacts/contracts/uln/uln301/ReceiveUln301View.sol/IReceiveUln301.json +178 -0
  48. package/artifacts/contracts/uln/uln301/ReceiveUln301View.sol/ReceiveUln301View.json +126 -0
  49. package/artifacts/contracts/uln/uln301/SendLibBaseE1.sol/SendLibBaseE1.json +15 -15
  50. package/artifacts/contracts/uln/uln301/SendUln301.sol/SendUln301.json +76 -76
  51. package/artifacts/contracts/uln/uln301/TreasuryFeeHandler.sol/TreasuryFeeHandler.json +5 -5
  52. package/artifacts/contracts/uln/uln301/interfaces/IMessageLibE1.sol/IMessageLibE1.json +4 -4
  53. package/artifacts/contracts/uln/uln302/ReceiveUln302.sol/ReceiveUln302.json +79 -24
  54. package/artifacts/contracts/uln/uln302/ReceiveUln302View.sol/IReceiveUln302.json +146 -0
  55. package/artifacts/contracts/uln/uln302/ReceiveUln302View.sol/ReceiveUln302View.json +251 -0
  56. package/artifacts/contracts/uln/uln302/SendUln302.sol/SendUln302.json +75 -75
  57. package/artifacts/contracts/upgradeable/WorkerUpgradeable.sol/WorkerUpgradeable.json +18 -18
  58. package/contracts/ExecutorFeeLib.sol +6 -6
  59. package/contracts/MessageLibBase.sol +2 -2
  60. package/contracts/PriceFeed.sol +3 -3
  61. package/contracts/ReceiveLibBaseE2.sol +0 -26
  62. package/contracts/SendLibBase.sol +10 -10
  63. package/contracts/SendLibBaseE2.sol +4 -4
  64. package/contracts/Treasury.sol +2 -2
  65. package/contracts/Worker.sol +3 -3
  66. package/contracts/interfaces/IExecutorFeeLib.sol +4 -4
  67. package/contracts/interfaces/ILayerZeroPriceFeed.sol +3 -3
  68. package/contracts/interfaces/IWorker.sol +3 -3
  69. package/contracts/uln/LzExecutor.sol +51 -19
  70. package/contracts/uln/ReceiveUlnBase.sol +21 -14
  71. package/contracts/uln/UlnBase.sol +19 -19
  72. package/contracts/uln/dvn/DVN.sol +16 -16
  73. package/contracts/uln/dvn/DVNFeeLib.sol +2 -2
  74. package/contracts/uln/dvn/MultiSig.sol +13 -13
  75. package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapter.sol +95 -97
  76. package/contracts/uln/dvn/adapters/CCIP/CCIPDVNAdapterFeeLib.sol +64 -2
  77. package/contracts/uln/dvn/adapters/DVNAdapterBase.sol +74 -124
  78. package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL1.sol +126 -0
  79. package/contracts/uln/dvn/adapters/arbitrum/ArbitrumDVNAdapterL2.sol +50 -0
  80. package/contracts/uln/dvn/adapters/avalanche/NOTES.md +4 -0
  81. package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapter.sol +85 -100
  82. package/contracts/uln/dvn/adapters/axelar/AxelarDVNAdapterFeeLib.sol +121 -2
  83. package/contracts/uln/dvn/adapters/libs/DVNAdapterMessageCodec.sol +36 -0
  84. package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL1.sol +86 -0
  85. package/contracts/uln/dvn/adapters/optimism/OptimismDVNAdapterL2.sol +58 -0
  86. package/contracts/uln/interfaces/IDVNFeeLib.sol +1 -1
  87. package/contracts/uln/interfaces/IReceiveUlnE2.sol +0 -5
  88. package/contracts/uln/interfaces/adapters/IAxelarDVNAdapter.sol +45 -0
  89. package/contracts/uln/interfaces/adapters/IAxelarDVNAdapterFeeLib.sol +48 -0
  90. package/contracts/uln/interfaces/adapters/ICCIPDVNAdapter.sol +30 -0
  91. package/contracts/uln/interfaces/adapters/ICCIPDVNAdapterFeeLib.sol +45 -0
  92. package/contracts/uln/libs/DVNOptions.sol +6 -6
  93. package/contracts/uln/libs/UlnOptions.sol +13 -13
  94. package/contracts/uln/uln301/AddressSizeConfig.sol +4 -4
  95. package/contracts/uln/uln301/ReceiveLibBaseE1.sol +4 -4
  96. package/contracts/uln/uln301/ReceiveUln301.sol +4 -41
  97. package/contracts/uln/uln301/ReceiveUln301View.sol +89 -0
  98. package/contracts/uln/uln301/SendLibBaseE1.sol +5 -5
  99. package/contracts/uln/uln301/SendUln301.sol +3 -3
  100. package/contracts/uln/uln301/TreasuryFeeHandler.sol +6 -6
  101. package/contracts/uln/uln301/interfaces/IMessageLibE1.sol +4 -4
  102. package/contracts/uln/uln302/ReceiveUln302.sol +4 -27
  103. package/contracts/uln/uln302/ReceiveUln302View.sol +89 -0
  104. package/contracts/uln/uln302/SendUln302.sol +3 -3
  105. package/contracts/upgradeable/WorkerUpgradeable.sol +3 -3
  106. package/package.json +7 -5
  107. package/artifacts/contracts/uln/dvn/adapters/DVNAdapterFeeLibBase.sol/DVNAdapterFeeLibBase.json +0 -50
  108. package/artifacts/contracts/uln/interfaces/IDVNAdapterFeeLib.sol/IDVNAdapterFeeLib.json +0 -50
  109. package/contracts/uln/dvn/adapters/DVNAdapterFeeLibBase.sol +0 -20
  110. package/contracts/uln/interfaces/IDVNAdapterFeeLib.sol +0 -13
@@ -26,13 +26,13 @@ contract DVN is Worker, MultiSig, IDVN {
26
26
  mapping(uint32 dstEid => DstConfig) public dstConfig;
27
27
  mapping(bytes32 executableHash => bool used) public usedHashes;
28
28
 
29
- error OnlySelf();
30
- error InvalidRole(bytes32 role);
31
- error InstructionExpired();
32
- error InvalidTarget(address target);
33
- error InvalidVid(uint32 vid);
34
- error InvalidSignatures();
35
- error DuplicatedHash(bytes32 executableHash);
29
+ error DVN_OnlySelf();
30
+ error DVN_InvalidRole(bytes32 role);
31
+ error DVN_InstructionExpired();
32
+ error DVN_InvalidTarget(address target);
33
+ error DVN_InvalidVid(uint32 vid);
34
+ error DVN_InvalidSignatures();
35
+ error DVN_DuplicatedHash(bytes32 executableHash);
36
36
 
37
37
  event VerifySignaturesFailed(uint256 idx);
38
38
  event ExecuteFailed(uint256 _index, bytes _data);
@@ -72,20 +72,20 @@ contract DVN is Worker, MultiSig, IDVN {
72
72
  if (_role == ALLOWLIST || _role == DENYLIST || _role == MESSAGE_LIB_ROLE) {
73
73
  // self required
74
74
  if (address(this) != msg.sender) {
75
- revert OnlySelf();
75
+ revert DVN_OnlySelf();
76
76
  }
77
77
  } else if (_role == ADMIN_ROLE) {
78
78
  // admin required
79
79
  _checkRole(ADMIN_ROLE);
80
80
  } else {
81
- revert InvalidRole(_role);
81
+ revert DVN_InvalidRole(_role);
82
82
  }
83
83
  _;
84
84
  }
85
85
 
86
86
  modifier onlySelf() {
87
87
  if (address(this) != msg.sender) {
88
- revert OnlySelf();
88
+ revert DVN_OnlySelf();
89
89
  }
90
90
  _;
91
91
  }
@@ -131,23 +131,23 @@ contract DVN is Worker, MultiSig, IDVN {
131
131
  /// @dev calldata in the case is abi.encode new admin address
132
132
  function quorumChangeAdmin(ExecuteParam calldata _param) external {
133
133
  if (_param.expiration <= block.timestamp) {
134
- revert InstructionExpired();
134
+ revert DVN_InstructionExpired();
135
135
  }
136
136
  if (_param.target != address(this)) {
137
- revert InvalidTarget(_param.target);
137
+ revert DVN_InvalidTarget(_param.target);
138
138
  }
139
139
  if (_param.vid != vid) {
140
- revert InvalidVid(_param.vid);
140
+ revert DVN_InvalidVid(_param.vid);
141
141
  }
142
142
 
143
143
  // generate and validate hash
144
144
  bytes32 hash = hashCallData(_param.vid, _param.target, _param.callData, _param.expiration);
145
145
  (bool sigsValid, ) = verifySignatures(hash, _param.signatures);
146
146
  if (!sigsValid) {
147
- revert InvalidSignatures();
147
+ revert DVN_InvalidSignatures();
148
148
  }
149
149
  if (usedHashes[hash]) {
150
- revert DuplicatedHash(hash);
150
+ revert DVN_DuplicatedHash(hash);
151
151
  }
152
152
 
153
153
  usedHashes[hash] = true;
@@ -221,7 +221,7 @@ contract DVN is Worker, MultiSig, IDVN {
221
221
  /// @param _amount amount to withdraw
222
222
  function withdrawFeeFromUlnV2(address _lib, address payable _to, uint256 _amount) external onlyRole(ADMIN_ROLE) {
223
223
  if (!hasRole(MESSAGE_LIB_ROLE, _lib)) {
224
- revert OnlyMessageLib();
224
+ revert Worker_OnlyMessageLib();
225
225
  }
226
226
  ILayerZeroUltraLightNodeV2(_lib).withdrawNative(_to, _amount);
227
227
  }
@@ -129,9 +129,9 @@ contract DVNFeeLib is Ownable, IDVNFeeLib {
129
129
  while (cursor < _options.length) {
130
130
  (uint8 optionType, , uint256 newCursor) = _options.nextDVNOption(cursor);
131
131
  cursor = newCursor;
132
- revert UnsupportedOptionType(optionType);
132
+ revert DVN_UnsupportedOptionType(optionType);
133
133
  }
134
- if (cursor != _options.length) revert DVNOptions.InvalidDVNOptions(cursor);
134
+ if (cursor != _options.length) revert DVNOptions.DVN_InvalidDVNOptions(cursor);
135
135
 
136
136
  return 0; // todo: precrime fee model
137
137
  }
@@ -16,34 +16,34 @@ abstract contract MultiSig {
16
16
  uint64 public signerSize;
17
17
  uint64 public quorum;
18
18
 
19
- error OnlySigner();
20
- error QuorumIsZero();
21
- error SignersSizeIsLessThanQuorum(uint64 signersSize, uint64 quorum);
22
- error UnorderedSigners();
23
- error StateAlreadySet(address signer, bool active);
19
+ error MultiSig_OnlySigner();
20
+ error MultiSig_QuorumIsZero();
21
+ error MultiSig_SignersSizeIsLessThanQuorum(uint64 signersSize, uint64 quorum);
22
+ error MultiSig_UnorderedSigners();
23
+ error MultiSig_StateAlreadySet(address signer, bool active);
24
24
 
25
25
  event UpdateSigner(address _signer, bool _active);
26
26
  event UpdateQuorum(uint64 _quorum);
27
27
 
28
28
  modifier onlySigner() {
29
29
  if (!signers[msg.sender]) {
30
- revert OnlySigner();
30
+ revert MultiSig_OnlySigner();
31
31
  }
32
32
  _;
33
33
  }
34
34
 
35
35
  constructor(address[] memory _signers, uint64 _quorum) {
36
36
  if (_quorum == 0) {
37
- revert QuorumIsZero();
37
+ revert MultiSig_QuorumIsZero();
38
38
  }
39
39
  if (_signers.length < _quorum) {
40
- revert SignersSizeIsLessThanQuorum(uint64(_signers.length), _quorum);
40
+ revert MultiSig_SignersSizeIsLessThanQuorum(uint64(_signers.length), _quorum);
41
41
  }
42
42
  address lastSigner = address(0);
43
43
  for (uint256 i = 0; i < _signers.length; i++) {
44
44
  address signer = _signers[i];
45
45
  if (signer <= lastSigner) {
46
- revert UnorderedSigners();
46
+ revert MultiSig_UnorderedSigners();
47
47
  }
48
48
  signers[signer] = true;
49
49
  lastSigner = signer;
@@ -54,13 +54,13 @@ abstract contract MultiSig {
54
54
 
55
55
  function _setSigner(address _signer, bool _active) internal {
56
56
  if (signers[_signer] == _active) {
57
- revert StateAlreadySet(_signer, _active);
57
+ revert MultiSig_StateAlreadySet(_signer, _active);
58
58
  }
59
59
  signers[_signer] = _active;
60
60
  uint64 _signerSize = _active ? signerSize + 1 : signerSize - 1;
61
61
  uint64 _quorum = quorum;
62
62
  if (_signerSize < _quorum) {
63
- revert SignersSizeIsLessThanQuorum(_signerSize, _quorum);
63
+ revert MultiSig_SignersSizeIsLessThanQuorum(_signerSize, _quorum);
64
64
  }
65
65
  signerSize = _signerSize;
66
66
  emit UpdateSigner(_signer, _active);
@@ -68,11 +68,11 @@ abstract contract MultiSig {
68
68
 
69
69
  function _setQuorum(uint64 _quorum) internal {
70
70
  if (_quorum == 0) {
71
- revert QuorumIsZero();
71
+ revert MultiSig_QuorumIsZero();
72
72
  }
73
73
  uint64 _signerSize = signerSize;
74
74
  if (_signerSize < _quorum) {
75
- revert SignersSizeIsLessThanQuorum(_signerSize, _quorum);
75
+ revert MultiSig_SignersSizeIsLessThanQuorum(_signerSize, _quorum);
76
76
  }
77
77
  quorum = _quorum;
78
78
  emit UpdateQuorum(_quorum);
@@ -3,57 +3,48 @@
3
3
  pragma solidity ^0.8.20;
4
4
 
5
5
  import { IRouterClient } from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol";
6
- import { CCIPReceiver } from "@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol";
6
+ import { IAny2EVMMessageReceiver } from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol";
7
7
  import { Client } from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol";
8
8
 
9
9
  import { DVNAdapterBase } from "../DVNAdapterBase.sol";
10
-
11
- contract CCIPDVNAdapter is CCIPReceiver, DVNAdapterBase {
12
- struct DstConfigParam {
13
- uint32 dstEid;
14
- // https://docs.chain.link/ccip/supported-networks/v1_2_0/testnet#ethereum-sepolia
15
- // https://docs.chain.link/ccip/supported-networks/v1_0_0/mainnet
16
- uint64 chainSelector;
17
- uint16 multiplierBps;
18
- uint256 gasLimit;
19
- bytes peer;
20
- }
21
-
22
- struct DstConfig {
23
- uint64 chainSelector;
24
- uint16 multiplierBps;
25
- uint256 gasLimit;
26
- bytes peer;
27
- }
28
-
10
+ import { ICCIPDVNAdapter } from "../../../interfaces/adapters/ICCIPDVNAdapter.sol";
11
+ import { ICCIPDVNAdapterFeeLib } from "../../../interfaces/adapters/ICCIPDVNAdapterFeeLib.sol";
12
+
13
+ /// @title CCIPDVNAdapter
14
+ /// @dev How CCIP DVN Adapter works:
15
+ /// 1. Estimate gas cost for the message on-chain by calling `getFee` on the Router contract.
16
+ /// refer to https://docs.chain.link/ccip/api-reference/i-router-client#getfee
17
+ /// 2. Call `ccipSend` on the Router contract to send the message.
18
+ /// refer to https://docs.chain.link/ccip/api-reference/i-router-client#ccipsend
19
+ /// @dev Recovery:
20
+ /// 1. If not enough gas paid, the message will be failed to execute on the destination chain, you can manually retry by calling `manuallyExecute` on the `OffRamp` contract.
21
+ /// refer to https://github.com/smartcontractkit/ccip/blob/ccip-develop/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol#L222
22
+ contract CCIPDVNAdapter is DVNAdapterBase, IAny2EVMMessageReceiver, ICCIPDVNAdapter {
29
23
  address private constant NATIVE_GAS_TOKEN_ADDRESS = address(0);
30
24
 
31
- event DstConfigSet(DstConfigParam[] params);
25
+ IRouterClient public router;
32
26
 
33
27
  mapping(uint32 dstEid => DstConfig config) public dstConfig;
34
- mapping(uint64 chainSelector => uint32 eid) public CCIPChainToEid;
28
+ mapping(uint64 chainSelector => bytes peer) public peers;
35
29
 
36
- constructor(
37
- address _sendLib,
38
- address _receiveLib,
39
- address[] memory _admins,
40
- address router
41
- ) CCIPReceiver(router) DVNAdapterBase(_sendLib, _receiveLib, _admins) {}
30
+ constructor(address[] memory _admins, address _router) DVNAdapterBase(msg.sender, _admins, 12000) {
31
+ router = IRouterClient(_router);
32
+ }
42
33
 
43
- /// @notice sets configuration (`chainSelector`, `multiplierBps`, `gasLimit` and `peer`) for destination chains
44
- /// @dev The `multiplierBps` can be updated separately using `setDstMultiplierBps` function
34
+ // ========================= OnlyAdmin =========================
35
+ /// @notice sets configuration for destination chains
45
36
  /// @param _params array of chain configurations
46
- function setDstConfig(DstConfigParam[] calldata _params) external onlyAdmin {
37
+ function setDstConfig(DstConfigParam[] calldata _params) external onlyRole(ADMIN_ROLE) {
47
38
  for (uint256 i = 0; i < _params.length; i++) {
48
39
  DstConfigParam calldata param = _params[i];
49
40
 
50
- delete CCIPChainToEid[dstConfig[param.dstEid].chainSelector];
41
+ delete peers[dstConfig[param.dstEid].chainSelector]; // delete old peer in case chain by dstEid is updated
42
+ peers[param.chainSelector] = param.peer;
51
43
 
52
- CCIPChainToEid[param.chainSelector] = param.dstEid;
53
44
  dstConfig[param.dstEid] = DstConfig({
54
45
  chainSelector: param.chainSelector,
55
46
  multiplierBps: param.multiplierBps,
56
- gasLimit: param.gasLimit,
47
+ gas: param.gas,
57
48
  peer: param.peer
58
49
  });
59
50
  }
@@ -61,92 +52,99 @@ contract CCIPDVNAdapter is CCIPReceiver, DVNAdapterBase {
61
52
  emit DstConfigSet(_params);
62
53
  }
63
54
 
64
- /// @notice sets fee multiplier in basis points for destination chains
65
- /// @param _params array of multipliers for destination chains
66
- function setDstMultiplier(DstMultiplierParam[] calldata _params) external onlyAdmin {
67
- for (uint256 i = 0; i < _params.length; i++) {
68
- DstMultiplierParam calldata param = _params[i];
69
- dstConfig[param.dstEid].multiplierBps = param.multiplierBps;
70
- }
71
-
72
- emit DstMultiplierSet(_params);
55
+ function setRouter(address _router) external onlyRole(ADMIN_ROLE) {
56
+ router = IRouterClient(_router);
57
+ emit RouterSet(_router);
73
58
  }
74
59
 
75
- function getFee(
76
- uint32 _dstEid,
77
- uint64 /*_confirmations*/,
78
- address _sender,
79
- bytes calldata /*_options*/
80
- ) external view override returns (uint256 fee) {
81
- DstConfig storage config = dstConfig[_dstEid];
82
-
83
- Client.EVM2AnyMessage memory message = _createCCIPMessage(
84
- new bytes(PACKET_HEADER_SIZE),
85
- bytes32(0),
86
- config.peer,
87
- config.gasLimit
60
+ // ========================= OnlyMessageLib =========================
61
+ function assignJob(
62
+ AssignJobParam calldata _param,
63
+ bytes calldata _options
64
+ ) external payable override onlyAcl(_param.sender) returns (uint256 totalFee) {
65
+ bytes32 receiveLib = _getAndAssertReceiveLib(msg.sender, _param.dstEid);
66
+
67
+ ICCIPDVNAdapterFeeLib.Param memory feeLibParam = ICCIPDVNAdapterFeeLib.Param(
68
+ _param.dstEid,
69
+ _param.confirmations,
70
+ _param.sender,
71
+ defaultMultiplierBps
88
72
  );
89
73
 
90
- fee = _getCCIPFee(config.chainSelector, message);
91
- if (address(feeLib) != address(0)) {
92
- fee = feeLib.getFee(_dstEid, _sender, defaultMultiplierBps, config.multiplierBps, fee);
93
- }
74
+ DstConfig memory config = dstConfig[_param.dstEid];
75
+
76
+ bytes memory data = _encode(receiveLib, _param.packetHeader, _param.payloadHash);
77
+ Client.EVM2AnyMessage memory message = _createCCIPMessage(data, config.peer, config.gas);
78
+
79
+ IRouterClient ccipRouter = router;
80
+ uint256 ccipFee;
81
+ (ccipFee, totalFee) = ICCIPDVNAdapterFeeLib(workerFeeLib).getFeeOnSend(
82
+ feeLibParam,
83
+ config,
84
+ message,
85
+ _options,
86
+ ccipRouter
87
+ );
88
+
89
+ _assertBalanceAndWithdrawFee(msg.sender, ccipFee);
90
+
91
+ ccipRouter.ccipSend{ value: ccipFee }(config.chainSelector, message);
94
92
  }
95
93
 
96
- function assignJob(
97
- AssignJobParam calldata _param,
98
- bytes calldata /*_options*/
99
- ) external payable override onlySendLib returns (uint256 fee) {
100
- DstConfig memory config = dstConfig[_param.dstEid];
94
+ // ========================= OnlyRouter =========================
95
+ function ccipReceive(Client.Any2EVMMessage calldata _message) external {
96
+ if (msg.sender != address(router)) revert CCIPDVNAdapter_InvalidRouter(msg.sender);
97
+
98
+ _assertPeer(_message.sourceChainSelector, _message.sender);
101
99
 
102
- Client.EVM2AnyMessage memory message = _createCCIPMessage(
103
- _param.packetHeader,
104
- _param.payloadHash,
105
- config.peer,
106
- config.gasLimit
100
+ _decodeAndVerify(_message.data);
101
+ }
102
+
103
+ // ========================= View =========================
104
+ function getFee(
105
+ uint32 _dstEid,
106
+ uint64 _confirmations,
107
+ address _sender,
108
+ bytes calldata _options
109
+ ) external view override onlyAcl(_sender) returns (uint256 totalFee) {
110
+ ICCIPDVNAdapterFeeLib.Param memory feeLibParam = ICCIPDVNAdapterFeeLib.Param(
111
+ _dstEid,
112
+ _confirmations,
113
+ _sender,
114
+ defaultMultiplierBps
107
115
  );
108
116
 
109
- fee = _getCCIPFee(config.chainSelector, message);
110
- _assertBalanceAndWithdrawFee(fee);
117
+ DstConfig memory config = dstConfig[_dstEid];
111
118
 
112
- IRouterClient(getRouter()).ccipSend{ value: fee }(config.chainSelector, message);
119
+ bytes memory data = _encodeEmpty();
120
+ Client.EVM2AnyMessage memory message = _createCCIPMessage(data, config.peer, config.gas);
113
121
 
114
- if (address(feeLib) != address(0)) {
115
- fee = feeLib.getFee(_param.dstEid, _param.sender, defaultMultiplierBps, config.multiplierBps, fee);
116
- }
122
+ totalFee = ICCIPDVNAdapterFeeLib(workerFeeLib).getFee(feeLibParam, config, message, _options, router);
123
+ }
124
+
125
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
126
+ return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || super.supportsInterface(interfaceId);
117
127
  }
118
128
 
129
+ // ========================= Internal =========================
119
130
  function _createCCIPMessage(
120
- bytes memory _packetHeader,
121
- bytes32 _payloadHash,
131
+ bytes memory _data,
122
132
  bytes memory _receiver,
123
- uint256 _gasLimit
133
+ uint256 _gas
124
134
  ) private pure returns (Client.EVM2AnyMessage memory message) {
125
135
  message = Client.EVM2AnyMessage({
126
136
  receiver: _receiver,
127
- data: _encodePayload(_packetHeader, _payloadHash),
137
+ data: _data,
128
138
  tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array indicating no tokens are being sent
129
- extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({ gasLimit: _gasLimit, strict: false })),
139
+ extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({ gasLimit: _gas, strict: false })),
130
140
  feeToken: NATIVE_GAS_TOKEN_ADDRESS
131
141
  });
132
142
  }
133
143
 
134
- function _getCCIPFee(
135
- uint64 _dstChainSelector,
136
- Client.EVM2AnyMessage memory _message
137
- ) private view returns (uint256 ccipFee) {
138
- ccipFee = IRouterClient(getRouter()).getFee(_dstChainSelector, _message);
139
- }
140
-
141
- function _ccipReceive(Client.Any2EVMMessage memory _message) internal override {
142
- _assertPeer(_message.sourceChainSelector, _message.sender);
143
- _verify(_message.data);
144
- }
145
-
146
144
  function _assertPeer(uint64 _sourceChainSelector, bytes memory _sourceAddress) private view {
147
- uint32 sourceEid = CCIPChainToEid[_sourceChainSelector];
148
- bytes memory sourcePeer = dstConfig[sourceEid].peer;
149
-
150
- if (keccak256(_sourceAddress) != keccak256(sourcePeer)) revert Unauthorized();
145
+ bytes memory sourcePeer = peers[_sourceChainSelector];
146
+ if (keccak256(_sourceAddress) != keccak256(sourcePeer)) {
147
+ revert CCIPDVNAdapter_UntrustedPeer(_sourceChainSelector, _sourceAddress);
148
+ }
151
149
  }
152
150
  }
@@ -2,6 +2,68 @@
2
2
 
3
3
  pragma solidity ^0.8.20;
4
4
 
5
- import { DVNAdapterFeeLibBase } from "../DVNAdapterFeeLibBase.sol";
5
+ import { Proxied } from "hardhat-deploy/solc_0.8/proxy/Proxied.sol";
6
+ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
7
+ import { Client } from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol";
8
+ import { IRouterClient } from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol";
6
9
 
7
- contract CCIPDVNAdapterFeeLib is DVNAdapterFeeLibBase {}
10
+ import { ICCIPDVNAdapter } from "../../../interfaces/adapters/ICCIPDVNAdapter.sol";
11
+ import { ICCIPDVNAdapterFeeLib } from "../../../interfaces/adapters/ICCIPDVNAdapterFeeLib.sol";
12
+
13
+ contract CCIPDVNAdapterFeeLib is OwnableUpgradeable, Proxied, ICCIPDVNAdapterFeeLib {
14
+ uint16 internal constant BPS_DENOMINATOR = 10000;
15
+
16
+ mapping(uint32 dstEid => DstConfig) public dstConfig;
17
+
18
+ function initialize() external proxied initializer {
19
+ __Ownable_init();
20
+ }
21
+
22
+ // ================================ OnlyOwner ===============================
23
+ function setDstConfig(DstConfigParam[] calldata _param) external onlyOwner {
24
+ for (uint256 i = 0; i < _param.length; i++) {
25
+ DstConfigParam calldata param = _param[i];
26
+
27
+ dstConfig[param.dstEid] = DstConfig({ floorMarginUSD: param.floorMarginUSD });
28
+ }
29
+
30
+ emit DstConfigSet(_param);
31
+ }
32
+
33
+ // ================================ External ================================
34
+ function getFeeOnSend(
35
+ Param calldata _params,
36
+ ICCIPDVNAdapter.DstConfig calldata _dstConfig,
37
+ Client.EVM2AnyMessage calldata _message,
38
+ bytes calldata _options,
39
+ IRouterClient _router
40
+ ) external payable returns (uint256 ccipFee, uint256 totalFee) {
41
+ if (_options.length > 0) revert CCIPDVN_OptionsUnsupported();
42
+
43
+ ccipFee = _router.getFee(_dstConfig.chainSelector, _message);
44
+ totalFee = _applyPremium(_dstConfig.multiplierBps, _params.defaultMultiplierBps, ccipFee);
45
+ }
46
+
47
+ function getFee(
48
+ Param calldata _params,
49
+ ICCIPDVNAdapter.DstConfig calldata _dstConfig,
50
+ Client.EVM2AnyMessage calldata _message,
51
+ bytes calldata _options,
52
+ IRouterClient _router
53
+ ) external view returns (uint256 totalFee) {
54
+ if (_options.length > 0) revert CCIPDVN_OptionsUnsupported();
55
+
56
+ totalFee = _router.getFee(_dstConfig.chainSelector, _message);
57
+ totalFee = _applyPremium(_dstConfig.multiplierBps, _params.defaultMultiplierBps, totalFee);
58
+ }
59
+
60
+ // ================================ Internal ================================
61
+ function _applyPremium(
62
+ uint16 _multiplierBps,
63
+ uint16 _defaultMultiplierBps,
64
+ uint256 _fee
65
+ ) internal pure returns (uint256 fee) {
66
+ uint256 multiplier = _multiplierBps == 0 ? _defaultMultiplierBps : _multiplierBps;
67
+ fee = (_fee * multiplier) / BPS_DENOMINATOR;
68
+ }
69
+ }