@hyperlane-xyz/core 1.3.4 → 1.3.5

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 (160) hide show
  1. package/contracts/interfaces/IInterchainSecurityModule.sol +2 -1
  2. package/contracts/isms/multisig/AbstractMerkleRootMultisigIsm.sol +64 -0
  3. package/contracts/isms/multisig/AbstractMessageIdMultisigIsm.sol +54 -0
  4. package/contracts/isms/multisig/AbstractMultisigIsm.sol +32 -56
  5. package/contracts/isms/multisig/LegacyMultisigIsm.sol +2 -2
  6. package/contracts/isms/multisig/StaticMultisigIsm.sol +49 -14
  7. package/contracts/isms/routing/AbstractRoutingIsm.sol +1 -0
  8. package/contracts/libs/CheckpointLib.sol +10 -2
  9. package/contracts/libs/LegacyCheckpointLib.sol +50 -0
  10. package/contracts/libs/Merkle.sol +2 -1
  11. package/contracts/libs/isms/{MultisigIsmMetadata.sol → MerkleRootMultisigIsmMetadata.sol} +37 -21
  12. package/contracts/libs/isms/MessageIdMultisigIsmMetadata.sol +59 -0
  13. package/contracts/test/TestLegacyMultisigIsm.sol +2 -2
  14. package/contracts/test/TestMultisigIsm.sol +1 -1
  15. package/dist/contracts/isms/multisig/AbstractMerkleRootMultisigIsm.d.ts +59 -0
  16. package/dist/contracts/isms/multisig/AbstractMerkleRootMultisigIsm.d.ts.map +1 -0
  17. package/dist/contracts/isms/multisig/AbstractMerkleRootMultisigIsm.js +4 -0
  18. package/dist/contracts/isms/multisig/AbstractMerkleRootMultisigIsm.js.map +1 -0
  19. package/dist/contracts/isms/multisig/AbstractMessageIdMultisigIsm.d.ts +59 -0
  20. package/dist/contracts/isms/multisig/AbstractMessageIdMultisigIsm.d.ts.map +1 -0
  21. package/dist/contracts/isms/multisig/AbstractMessageIdMultisigIsm.js +4 -0
  22. package/dist/contracts/isms/multisig/AbstractMessageIdMultisigIsm.js.map +1 -0
  23. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm.d.ts +59 -0
  24. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm.d.ts.map +1 -0
  25. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm.js +4 -0
  26. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm.js.map +1 -0
  27. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm.d.ts +59 -0
  28. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm.d.ts.map +1 -0
  29. package/dist/contracts/isms/multisig/{StaticMultisigIsmFactory.js → StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm.js} +1 -1
  30. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm.js.map +1 -0
  31. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory.d.ts +59 -0
  32. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory.d.ts.map +1 -0
  33. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory.js +4 -0
  34. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory.js.map +1 -0
  35. package/dist/contracts/isms/multisig/{StaticMultisigIsm.d.ts → StaticMultisigIsm.sol/StaticMessageIdMultisigIsm.d.ts} +5 -5
  36. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm.d.ts.map +1 -0
  37. package/dist/contracts/isms/multisig/{StaticMultisigIsm.js → StaticMultisigIsm.sol/StaticMessageIdMultisigIsm.js} +1 -1
  38. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm.js.map +1 -0
  39. package/dist/contracts/isms/multisig/{StaticMultisigIsmFactory.d.ts → StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory.d.ts} +5 -5
  40. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory.d.ts.map +1 -0
  41. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory.js +4 -0
  42. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory.js.map +1 -0
  43. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/index.d.ts +6 -0
  44. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/index.d.ts.map +1 -0
  45. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/index.js +3 -0
  46. package/dist/contracts/isms/multisig/StaticMultisigIsm.sol/index.js.map +1 -0
  47. package/dist/contracts/isms/multisig/index.d.ts +4 -2
  48. package/dist/contracts/isms/multisig/index.d.ts.map +1 -1
  49. package/dist/contracts/isms/multisig/index.js +1 -0
  50. package/dist/contracts/isms/multisig/index.js.map +1 -1
  51. package/dist/factories/contracts/Mailbox__factory.d.ts +1 -1
  52. package/dist/factories/contracts/Mailbox__factory.js +1 -1
  53. package/dist/factories/contracts/ValidatorAnnounce__factory.d.ts +1 -1
  54. package/dist/factories/contracts/ValidatorAnnounce__factory.js +1 -1
  55. package/dist/factories/contracts/isms/aggregation/StaticAggregationIsmFactory__factory.d.ts +1 -1
  56. package/dist/factories/contracts/isms/aggregation/StaticAggregationIsmFactory__factory.js +1 -1
  57. package/dist/factories/contracts/isms/aggregation/StaticAggregationIsm__factory.d.ts +1 -1
  58. package/dist/factories/contracts/isms/aggregation/StaticAggregationIsm__factory.js +1 -1
  59. package/dist/factories/contracts/isms/multisig/AbstractMerkleRootMultisigIsm__factory.d.ts +23 -0
  60. package/dist/factories/contracts/isms/multisig/AbstractMerkleRootMultisigIsm__factory.d.ts.map +1 -0
  61. package/dist/factories/contracts/isms/multisig/AbstractMerkleRootMultisigIsm__factory.js +79 -0
  62. package/dist/factories/contracts/isms/multisig/AbstractMerkleRootMultisigIsm__factory.js.map +1 -0
  63. package/dist/factories/contracts/isms/multisig/AbstractMessageIdMultisigIsm__factory.d.ts +23 -0
  64. package/dist/factories/contracts/isms/multisig/AbstractMessageIdMultisigIsm__factory.d.ts.map +1 -0
  65. package/dist/factories/contracts/isms/multisig/AbstractMessageIdMultisigIsm__factory.js +79 -0
  66. package/dist/factories/contracts/isms/multisig/AbstractMessageIdMultisigIsm__factory.js.map +1 -0
  67. package/dist/factories/contracts/isms/multisig/LegacyMultisigIsm__factory.d.ts +1 -1
  68. package/dist/factories/contracts/isms/multisig/LegacyMultisigIsm__factory.d.ts.map +1 -1
  69. package/dist/factories/contracts/isms/multisig/LegacyMultisigIsm__factory.js +1 -1
  70. package/dist/factories/contracts/isms/multisig/LegacyMultisigIsm__factory.js.map +1 -1
  71. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm__factory.d.ts +23 -0
  72. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm__factory.d.ts.map +1 -0
  73. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm__factory.js +79 -0
  74. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/AbstractMetaProxyMultisigIsm__factory.js.map +1 -0
  75. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory__factory.d.ts +35 -0
  76. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory__factory.d.ts.map +1 -0
  77. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory__factory.js +89 -0
  78. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsmFactory__factory.js.map +1 -0
  79. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm__factory.d.ts +35 -0
  80. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm__factory.d.ts.map +1 -0
  81. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm__factory.js +102 -0
  82. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMerkleRootMultisigIsm__factory.js.map +1 -0
  83. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory__factory.d.ts +35 -0
  84. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory__factory.d.ts.map +1 -0
  85. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory__factory.js +89 -0
  86. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsmFactory__factory.js.map +1 -0
  87. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm__factory.d.ts +35 -0
  88. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm__factory.d.ts.map +1 -0
  89. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm__factory.js +102 -0
  90. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/StaticMessageIdMultisigIsm__factory.js.map +1 -0
  91. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/index.d.ts +6 -0
  92. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/index.d.ts.map +1 -0
  93. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/index.js +17 -0
  94. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm.sol/index.js.map +1 -0
  95. package/dist/factories/contracts/isms/multisig/index.d.ts +3 -2
  96. package/dist/factories/contracts/isms/multisig/index.d.ts.map +1 -1
  97. package/dist/factories/contracts/isms/multisig/index.js +29 -5
  98. package/dist/factories/contracts/isms/multisig/index.js.map +1 -1
  99. package/dist/factories/contracts/isms/routing/DomainRoutingIsmFactory__factory.d.ts +1 -1
  100. package/dist/factories/contracts/isms/routing/DomainRoutingIsmFactory__factory.js +1 -1
  101. package/dist/factories/contracts/isms/routing/DomainRoutingIsm__factory.d.ts +1 -1
  102. package/dist/factories/contracts/isms/routing/DomainRoutingIsm__factory.js +1 -1
  103. package/dist/factories/contracts/isms/routing/InterchainAccountIsm__factory.d.ts +1 -1
  104. package/dist/factories/contracts/isms/routing/InterchainAccountIsm__factory.js +1 -1
  105. package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.d.ts +1 -1
  106. package/dist/factories/contracts/middleware/InterchainAccountRouter__factory.js +1 -1
  107. package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.d.ts +1 -1
  108. package/dist/factories/contracts/middleware/InterchainQueryRouter__factory.js +1 -1
  109. package/dist/factories/contracts/middleware/liquidity-layer/LiquidityLayerRouter__factory.d.ts +1 -1
  110. package/dist/factories/contracts/middleware/liquidity-layer/LiquidityLayerRouter__factory.js +1 -1
  111. package/dist/factories/contracts/middleware/liquidity-layer/adapters/CircleBridgeAdapter__factory.d.ts +1 -1
  112. package/dist/factories/contracts/middleware/liquidity-layer/adapters/CircleBridgeAdapter__factory.js +1 -1
  113. package/dist/factories/contracts/middleware/liquidity-layer/adapters/PortalAdapter__factory.d.ts +1 -1
  114. package/dist/factories/contracts/middleware/liquidity-layer/adapters/PortalAdapter__factory.js +1 -1
  115. package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.d.ts +1 -1
  116. package/dist/factories/contracts/mock/MockHyperlaneEnvironment__factory.js +1 -1
  117. package/dist/factories/contracts/mock/MockMailbox__factory.d.ts +1 -1
  118. package/dist/factories/contracts/mock/MockMailbox__factory.js +1 -1
  119. package/dist/factories/contracts/test/LightTestRecipient__factory.d.ts +1 -1
  120. package/dist/factories/contracts/test/LightTestRecipient__factory.js +1 -1
  121. package/dist/factories/contracts/test/TestGasRouter__factory.d.ts +1 -1
  122. package/dist/factories/contracts/test/TestGasRouter__factory.js +1 -1
  123. package/dist/factories/contracts/test/TestHyperlaneConnectionClient__factory.d.ts +1 -1
  124. package/dist/factories/contracts/test/TestHyperlaneConnectionClient__factory.js +1 -1
  125. package/dist/factories/contracts/test/TestLegacyMultisigIsm__factory.d.ts +1 -1
  126. package/dist/factories/contracts/test/TestLegacyMultisigIsm__factory.d.ts.map +1 -1
  127. package/dist/factories/contracts/test/TestLegacyMultisigIsm__factory.js +1 -1
  128. package/dist/factories/contracts/test/TestLegacyMultisigIsm__factory.js.map +1 -1
  129. package/dist/factories/contracts/test/TestMailbox__factory.d.ts +1 -1
  130. package/dist/factories/contracts/test/TestMailbox__factory.js +1 -1
  131. package/dist/factories/contracts/test/TestMerkle__factory.d.ts +1 -1
  132. package/dist/factories/contracts/test/TestMerkle__factory.js +1 -1
  133. package/dist/factories/contracts/test/TestMultisigIsm__factory.d.ts +1 -1
  134. package/dist/factories/contracts/test/TestMultisigIsm__factory.js +1 -1
  135. package/dist/factories/contracts/test/TestQuery__factory.d.ts +1 -1
  136. package/dist/factories/contracts/test/TestQuery__factory.js +1 -1
  137. package/dist/factories/contracts/test/TestRecipient__factory.d.ts +1 -1
  138. package/dist/factories/contracts/test/TestRecipient__factory.js +1 -1
  139. package/dist/factories/contracts/test/TestRouter__factory.d.ts +1 -1
  140. package/dist/factories/contracts/test/TestRouter__factory.js +1 -1
  141. package/dist/factories/contracts/test/TestSendReceiver__factory.d.ts +1 -1
  142. package/dist/factories/contracts/test/TestSendReceiver__factory.js +1 -1
  143. package/dist/index.d.ts +14 -4
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +16 -6
  146. package/dist/index.js.map +1 -1
  147. package/package.json +3 -3
  148. package/contracts/isms/multisig/StaticMultisigIsmFactory.sol +0 -16
  149. package/dist/contracts/isms/multisig/StaticMultisigIsm.d.ts.map +0 -1
  150. package/dist/contracts/isms/multisig/StaticMultisigIsm.js.map +0 -1
  151. package/dist/contracts/isms/multisig/StaticMultisigIsmFactory.d.ts.map +0 -1
  152. package/dist/contracts/isms/multisig/StaticMultisigIsmFactory.js.map +0 -1
  153. package/dist/factories/contracts/isms/multisig/StaticMultisigIsmFactory__factory.d.ts +0 -35
  154. package/dist/factories/contracts/isms/multisig/StaticMultisigIsmFactory__factory.d.ts.map +0 -1
  155. package/dist/factories/contracts/isms/multisig/StaticMultisigIsmFactory__factory.js +0 -89
  156. package/dist/factories/contracts/isms/multisig/StaticMultisigIsmFactory__factory.js.map +0 -1
  157. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm__factory.d.ts +0 -35
  158. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm__factory.d.ts.map +0 -1
  159. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm__factory.js +0 -102
  160. package/dist/factories/contracts/isms/multisig/StaticMultisigIsm__factory.js.map +0 -1
@@ -7,7 +7,8 @@ interface IInterchainSecurityModule {
7
7
  ROUTING,
8
8
  AGGREGATION,
9
9
  LEGACY_MULTISIG,
10
- MULTISIG
10
+ MERKLE_ROOT_MULTISIG,
11
+ MESSAGE_ID_MULTISIG
11
12
  }
12
13
 
13
14
  /**
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity >=0.8.0;
3
+
4
+ // ============ Internal Imports ============
5
+ import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
6
+ import {AbstractMultisigIsm} from "./AbstractMultisigIsm.sol";
7
+ import {MerkleRootMultisigIsmMetadata} from "../../libs/isms/MerkleRootMultisigIsmMetadata.sol";
8
+ import {Message} from "../../libs/Message.sol";
9
+ import {MerkleLib} from "../../libs/Merkle.sol";
10
+ import {CheckpointLib} from "../../libs/CheckpointLib.sol";
11
+
12
+ /**
13
+ * @title MerkleRootMultisigIsm
14
+ * @notice Provides abstract logic for verifying signatures on a merkle root
15
+ * and a merkle proof of message inclusion in that root.
16
+ * @dev Implement and use if you want strong censorship resistance guarantees.
17
+ * @dev May be adapted in future to support batch message verification against a single root.
18
+ */
19
+ abstract contract AbstractMerkleRootMultisigIsm is AbstractMultisigIsm {
20
+ // ============ Constants ============
21
+
22
+ // solhint-disable-next-line const-name-snakecase
23
+ uint8 public constant moduleType =
24
+ uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);
25
+
26
+ /**
27
+ * @inheritdoc AbstractMultisigIsm
28
+ */
29
+ function digest(bytes calldata _metadata, bytes calldata _message)
30
+ internal
31
+ pure
32
+ override
33
+ returns (bytes32)
34
+ {
35
+ // We verify a merkle proof of (messageId, index) I to compute root J
36
+ bytes32 _root = MerkleLib.branchRoot(
37
+ Message.id(_message),
38
+ MerkleRootMultisigIsmMetadata.proof(_metadata),
39
+ Message.nonce(_message)
40
+ );
41
+ // We provide (messageId, index) J in metadata for digest derivation
42
+ return
43
+ CheckpointLib.digest(
44
+ Message.origin(_message),
45
+ MerkleRootMultisigIsmMetadata.originMailbox(_metadata),
46
+ _root,
47
+ MerkleRootMultisigIsmMetadata.index(_metadata),
48
+ MerkleRootMultisigIsmMetadata.messageId(_metadata)
49
+ );
50
+ }
51
+
52
+ /**
53
+ * @inheritdoc AbstractMultisigIsm
54
+ */
55
+ function signatureAt(bytes calldata _metadata, uint256 _index)
56
+ internal
57
+ pure
58
+ virtual
59
+ override
60
+ returns (bytes memory signature)
61
+ {
62
+ return MerkleRootMultisigIsmMetadata.signatureAt(_metadata, _index);
63
+ }
64
+ }
@@ -0,0 +1,54 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity >=0.8.0;
3
+
4
+ // ============ Internal Imports ============
5
+ import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
6
+ import {AbstractMultisigIsm} from "./AbstractMultisigIsm.sol";
7
+ import {MessageIdMultisigIsmMetadata} from "../../libs/isms/MessageIdMultisigIsmMetadata.sol";
8
+ import {Message} from "../../libs/Message.sol";
9
+ import {CheckpointLib} from "../../libs/CheckpointLib.sol";
10
+
11
+ /**
12
+ * @title AbstractMessageIdMultisigIsm
13
+ * @notice Provides abstract logic for verifying signatures on a message ID.
14
+ * @dev Implement and use if you want fastest and cheapest security.
15
+ */
16
+ abstract contract AbstractMessageIdMultisigIsm is AbstractMultisigIsm {
17
+ // ============ Constants ============
18
+
19
+ // solhint-disable-next-line const-name-snakecase
20
+ uint8 public constant moduleType =
21
+ uint8(IInterchainSecurityModule.Types.MESSAGE_ID_MULTISIG);
22
+
23
+ /**
24
+ * @inheritdoc AbstractMultisigIsm
25
+ */
26
+ function digest(bytes calldata _metadata, bytes calldata _message)
27
+ internal
28
+ pure
29
+ override
30
+ returns (bytes32)
31
+ {
32
+ return
33
+ CheckpointLib.digest(
34
+ Message.origin(_message),
35
+ MessageIdMultisigIsmMetadata.originMailbox(_metadata),
36
+ MessageIdMultisigIsmMetadata.root(_metadata),
37
+ Message.nonce(_message),
38
+ Message.id(_message)
39
+ );
40
+ }
41
+
42
+ /**
43
+ * @inheritdoc AbstractMultisigIsm
44
+ */
45
+ function signatureAt(bytes calldata _metadata, uint256 _index)
46
+ internal
47
+ pure
48
+ virtual
49
+ override
50
+ returns (bytes memory)
51
+ {
52
+ return MessageIdMultisigIsmMetadata.signatureAt(_metadata, _index);
53
+ }
54
+ }
@@ -8,22 +8,17 @@ import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
8
8
  import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
9
9
  import {IMultisigIsm} from "../../interfaces/isms/IMultisigIsm.sol";
10
10
  import {Message} from "../../libs/Message.sol";
11
- import {MultisigIsmMetadata} from "../../libs/isms/MultisigIsmMetadata.sol";
12
- import {CheckpointLib} from "../../libs/CheckpointLib.sol";
13
11
  import {MerkleLib} from "../../libs/Merkle.sol";
14
12
 
15
13
  /**
16
14
  * @title MultisigIsm
17
15
  * @notice Manages per-domain m-of-n Validator sets that are used to verify
18
16
  * interchain messages.
17
+ * @dev See ./AbstractMerkleRootMultisigIsm.sol and ./AbstractMessageIdMultisigIsm.sol
18
+ * for concrete implementations of `digest` and `signatureAt`.
19
+ * @dev See ./StaticMultisigIsm.sol for concrete implementations.
19
20
  */
20
21
  abstract contract AbstractMultisigIsm is IMultisigIsm {
21
- // ============ Constants ============
22
-
23
- // solhint-disable-next-line const-name-snakecase
24
- uint8 public constant moduleType =
25
- uint8(IInterchainSecurityModule.Types.MULTISIG);
26
-
27
22
  // ============ Virtual Functions ============
28
23
  // ======= OVERRIDE THESE TO IMPLEMENT =======
29
24
 
@@ -41,74 +36,55 @@ abstract contract AbstractMultisigIsm is IMultisigIsm {
41
36
  virtual
42
37
  returns (address[] memory, uint8);
43
38
 
44
- // ============ Public Functions ============
45
-
46
39
  /**
47
- * @notice Requires that m-of-n validators verify a merkle root,
48
- * and verifies a merkle proof of `_message` against that root.
49
- * @param _metadata ABI encoded module metadata (see MultisigIsmMetadata.sol)
40
+ * @notice Returns the digest to be used for signature verification.
41
+ * @param _metadata ABI encoded module metadata
50
42
  * @param _message Formatted Hyperlane message (see Message.sol).
43
+ * @return digest The digest to be signed by validators
51
44
  */
52
- function verify(bytes calldata _metadata, bytes calldata _message)
53
- public
45
+ function digest(bytes calldata _metadata, bytes calldata _message)
46
+ internal
54
47
  view
55
- returns (bool)
56
- {
57
- require(_verifyMerkleProof(_metadata, _message), "!merkle");
58
- require(_verifyValidatorSignatures(_metadata, _message), "!sigs");
59
- return true;
60
- }
61
-
62
- // ============ Internal Functions ============
48
+ virtual
49
+ returns (bytes32);
63
50
 
64
51
  /**
65
- * @notice Verifies the merkle proof of `_message` against the provided
66
- * checkpoint.
67
- * @param _metadata ABI encoded module metadata (see MultisigIsmMetadata.sol)
68
- * @param _message Formatted Hyperlane message (see Message.sol).
52
+ * @notice Returns the signature at a given index from the metadata.
53
+ * @param _metadata ABI encoded module metadata
54
+ * @param _index The index of the signature to return
55
+ * @return signature Packed encoding of signature (65 bytes)
69
56
  */
70
- function _verifyMerkleProof(
71
- bytes calldata _metadata,
72
- bytes calldata _message
73
- ) internal pure returns (bool) {
74
- // calculate the expected root based on the proof
75
- bytes32 _calculatedRoot = MerkleLib.branchRoot(
76
- Message.id(_message),
77
- MultisigIsmMetadata.proof(_metadata),
78
- Message.nonce(_message)
79
- );
80
- return _calculatedRoot == MultisigIsmMetadata.root(_metadata);
81
- }
57
+ function signatureAt(bytes calldata _metadata, uint256 _index)
58
+ internal
59
+ pure
60
+ virtual
61
+ returns (bytes memory);
62
+
63
+ // ============ Public Functions ============
82
64
 
83
65
  /**
84
- * @notice Verifies that a quorum of the origin domain's validators signed
85
- * the provided checkpoint.
86
- * @param _metadata ABI encoded module metadata (see MultisigIsmMetadata.sol)
66
+ * @notice Requires that m-of-n validators verify a merkle root,
67
+ * and verifies a me∑rkle proof of `_message` against that root.
68
+ * @param _metadata ABI encoded module metadata
87
69
  * @param _message Formatted Hyperlane message (see Message.sol).
88
70
  */
89
- function _verifyValidatorSignatures(
90
- bytes calldata _metadata,
91
- bytes calldata _message
92
- ) internal view returns (bool) {
71
+ function verify(bytes calldata _metadata, bytes calldata _message)
72
+ public
73
+ view
74
+ returns (bool)
75
+ {
76
+ bytes32 _digest = digest(_metadata, _message);
93
77
  (
94
78
  address[] memory _validators,
95
79
  uint8 _threshold
96
80
  ) = validatorsAndThreshold(_message);
97
81
  require(_threshold > 0, "No MultisigISM threshold present for message");
98
- bytes32 _digest = CheckpointLib.digest(
99
- Message.origin(_message),
100
- MultisigIsmMetadata.originMailbox(_metadata),
101
- MultisigIsmMetadata.root(_metadata),
102
- MultisigIsmMetadata.index(_metadata)
103
- );
82
+
104
83
  uint256 _validatorCount = _validators.length;
105
84
  uint256 _validatorIndex = 0;
106
85
  // Assumes that signatures are ordered by validator
107
86
  for (uint256 i = 0; i < _threshold; ++i) {
108
- address _signer = ECDSA.recover(
109
- _digest,
110
- MultisigIsmMetadata.signatureAt(_metadata, i)
111
- );
87
+ address _signer = ECDSA.recover(_digest, signatureAt(_metadata, i));
112
88
  // Loop through remaining validators until we find a match
113
89
  while (
114
90
  _validatorIndex < _validatorCount &&
@@ -12,7 +12,7 @@ import {Message} from "../../libs/Message.sol";
12
12
  import {IMultisigIsm} from "../../interfaces/isms/IMultisigIsm.sol";
13
13
  import {LegacyMultisigIsmMetadata} from "../../libs/isms/LegacyMultisigIsmMetadata.sol";
14
14
  import {MerkleLib} from "../../libs/Merkle.sol";
15
- import {CheckpointLib} from "../../libs/CheckpointLib.sol";
15
+ import {LegacyCheckpointLib} from "../../libs/LegacyCheckpointLib.sol";
16
16
 
17
17
  /**
18
18
  * @title MultisigIsm
@@ -331,7 +331,7 @@ contract LegacyMultisigIsm is IMultisigIsm, Ownable {
331
331
  // non-zero computed commitment, and this check will fail
332
332
  // as the commitment in storage will be zero.
333
333
  require(_commitment == commitment[_origin], "!commitment");
334
- _digest = CheckpointLib.digest(
334
+ _digest = LegacyCheckpointLib.digest(
335
335
  _origin,
336
336
  LegacyMultisigIsmMetadata.originMailbox(_metadata),
337
337
  LegacyMultisigIsmMetadata.root(_metadata),
@@ -1,33 +1,68 @@
1
1
  // SPDX-License-Identifier: MIT OR Apache-2.0
2
2
  pragma solidity >=0.8.0;
3
-
4
3
  // ============ Internal Imports ============
5
4
  import {AbstractMultisigIsm} from "./AbstractMultisigIsm.sol";
6
- import {MultisigIsmMetadata} from "../../libs/isms/MultisigIsmMetadata.sol";
5
+ import {AbstractMerkleRootMultisigIsm} from "./AbstractMerkleRootMultisigIsm.sol";
6
+ import {AbstractMessageIdMultisigIsm} from "./AbstractMessageIdMultisigIsm.sol";
7
7
  import {MetaProxy} from "../../libs/MetaProxy.sol";
8
+ import {StaticMOfNAddressSetFactory} from "../../libs/StaticMOfNAddressSetFactory.sol";
8
9
 
9
10
  /**
10
- * @title StaticMultisigIsm
11
- * @notice Manages per-domain m-of-n Validator sets that are used
11
+ * @title AbstractMetaProxyMultisigIsm
12
+ * @notice Manages per-domain m-of-n Validator set that is used
12
13
  * to verify interchain messages.
13
14
  */
14
- contract StaticMultisigIsm is AbstractMultisigIsm {
15
- // ============ Public Functions ============
16
-
15
+ abstract contract AbstractMetaProxyMultisigIsm is AbstractMultisigIsm {
17
16
  /**
18
- * @notice Returns the set of validators responsible for verifying _message
19
- * and the number of signatures required
20
- * @dev Can change based on the content of _message
21
- * @return validators The array of validator addresses
22
- * @return threshold The number of validator signatures needed
17
+ * @inheritdoc AbstractMultisigIsm
23
18
  */
24
19
  function validatorsAndThreshold(bytes calldata)
25
20
  public
26
- view
27
- virtual
21
+ pure
28
22
  override
29
23
  returns (address[] memory, uint8)
30
24
  {
31
25
  return abi.decode(MetaProxy.metadata(), (address[], uint8));
32
26
  }
33
27
  }
28
+
29
+ // solhint-disable no-empty-blocks
30
+
31
+ /**
32
+ * @title StaticMerkleRootMultisigIsm
33
+ * @notice Manages per-domain m-of-n validator set that is used
34
+ * to verify interchain messages using a merkle root signature quorum
35
+ * and merkle proof of inclusion.
36
+ */
37
+ contract StaticMerkleRootMultisigIsm is
38
+ AbstractMerkleRootMultisigIsm,
39
+ AbstractMetaProxyMultisigIsm
40
+ {
41
+
42
+ }
43
+
44
+ /**
45
+ * @title StaticMessageIdMultisigIsm
46
+ * @notice Manages per-domain m-of-n validator set that is used
47
+ * to verify interchain messages using a message ID signature quorum.
48
+ */
49
+ contract StaticMessageIdMultisigIsm is
50
+ AbstractMessageIdMultisigIsm,
51
+ AbstractMetaProxyMultisigIsm
52
+ {
53
+
54
+ }
55
+
56
+ // solhint-enable no-empty-blocks
57
+
58
+ contract StaticMerkleRootMultisigIsmFactory is StaticMOfNAddressSetFactory {
59
+ function _deployImplementation() internal override returns (address) {
60
+ return address(new StaticMerkleRootMultisigIsm());
61
+ }
62
+ }
63
+
64
+ contract StaticMessageIdMultisigIsmFactory is StaticMOfNAddressSetFactory {
65
+ function _deployImplementation() internal override returns (address) {
66
+ return address(new StaticMessageIdMultisigIsm());
67
+ }
68
+ }
@@ -11,6 +11,7 @@ import {IRoutingIsm} from "../../interfaces/isms/IRoutingIsm.sol";
11
11
  abstract contract AbstractRoutingIsm is IRoutingIsm {
12
12
  // ============ Constants ============
13
13
 
14
+ // solhint-disable-next-line const-name-snakecase
14
15
  uint8 public constant moduleType =
15
16
  uint8(IInterchainSecurityModule.Types.ROUTING);
16
17
 
@@ -4,18 +4,25 @@ pragma solidity >=0.8.0;
4
4
  // ============ External Imports ============
5
5
  import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
6
6
 
7
+ import {LegacyCheckpointLib} from "./LegacyCheckpointLib.sol";
8
+
7
9
  library CheckpointLib {
8
10
  /**
9
11
  * @notice Returns the digest validators are expected to sign when signing checkpoints.
10
12
  * @param _origin The origin domain of the checkpoint.
11
13
  * @param _originMailbox The address of the origin mailbox as bytes32.
14
+ * @param _checkpointRoot The root of the checkpoint.
15
+ * @param _checkpointIndex The index of the checkpoint.
16
+ * @param _messageId The message ID of the checkpoint.
17
+ * @dev Message ID must match leaf content of checkpoint root at index.
12
18
  * @return The digest of the checkpoint.
13
19
  */
14
20
  function digest(
15
21
  uint32 _origin,
16
22
  bytes32 _originMailbox,
17
23
  bytes32 _checkpointRoot,
18
- uint32 _checkpointIndex
24
+ uint32 _checkpointIndex,
25
+ bytes32 _messageId
19
26
  ) internal pure returns (bytes32) {
20
27
  bytes32 _domainHash = domainHash(_origin, _originMailbox);
21
28
  return
@@ -24,7 +31,8 @@ library CheckpointLib {
24
31
  abi.encodePacked(
25
32
  _domainHash,
26
33
  _checkpointRoot,
27
- _checkpointIndex
34
+ _checkpointIndex,
35
+ _messageId
28
36
  )
29
37
  )
30
38
  );
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity >=0.8.0;
3
+
4
+ // ============ External Imports ============
5
+ import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
6
+
7
+ // ============ Internal Imports ============
8
+ import {CheckpointLib} from "./CheckpointLib.sol";
9
+
10
+ library LegacyCheckpointLib {
11
+ /**
12
+ * @notice Returns the digest validators are expected to sign when signing legacy checkpoints.
13
+ * @param _origin The origin domain of the checkpoint.
14
+ * @param _originMailbox The address of the origin mailbox as bytes32.
15
+ * @return The digest of the legacy checkpoint.
16
+ */
17
+ function digest(
18
+ uint32 _origin,
19
+ bytes32 _originMailbox,
20
+ bytes32 _checkpointRoot,
21
+ uint32 _checkpointIndex
22
+ ) internal pure returns (bytes32) {
23
+ bytes32 _domainHash = domainHash(_origin, _originMailbox);
24
+ return
25
+ ECDSA.toEthSignedMessageHash(
26
+ keccak256(
27
+ abi.encodePacked(
28
+ _domainHash,
29
+ _checkpointRoot,
30
+ _checkpointIndex
31
+ )
32
+ )
33
+ );
34
+ }
35
+
36
+ /**
37
+ * @notice Returns the domain hash that validators are expected to use
38
+ * when signing checkpoints.
39
+ * @param _origin The origin domain of the checkpoint.
40
+ * @param _originMailbox The address of the origin mailbox as bytes32.
41
+ * @return The domain hash.
42
+ */
43
+ function domainHash(uint32 _origin, bytes32 _originMailbox)
44
+ internal
45
+ pure
46
+ returns (bytes32)
47
+ {
48
+ return CheckpointLib.domainHash(_origin, _originMailbox);
49
+ }
50
+ }
@@ -124,13 +124,14 @@ library MerkleLib {
124
124
  **/
125
125
  function branchRoot(
126
126
  bytes32 _item,
127
- bytes32[TREE_DEPTH] memory _branch,
127
+ bytes32[TREE_DEPTH] memory _branch, // cheaper than calldata indexing
128
128
  uint256 _index
129
129
  ) internal pure returns (bytes32 _current) {
130
130
  _current = _item;
131
131
 
132
132
  for (uint256 i = 0; i < TREE_DEPTH; i++) {
133
133
  uint256 _ithBit = (_index >> i) & 0x01;
134
+ // cheaper than calldata indexing _branch[i*32:(i+1)*32];
134
135
  bytes32 _next = _branch[i];
135
136
  if (_ithBit == 1) {
136
137
  _current = keccak256(abi.encodePacked(_next, _current));
@@ -3,27 +3,35 @@ pragma solidity >=0.8.0;
3
3
 
4
4
  /**
5
5
  * Format of metadata:
6
- * [ 0: 32] Merkle root
7
- * [ 32: 36] Root index
8
- * [ 36: 68] Origin mailbox address
6
+ * [ 0: 32] Origin mailbox address
7
+ * [ 32: 36] Signed checkpoint index
8
+ * [ 36: 68] Signed checkpoint message ID
9
9
  * [ 68:1092] Merkle proof
10
- * [1092:????] Validator signatures, 65 bytes each, length == Threshold
10
+ * [1092:????] Validator signatures (length := threshold * 65)
11
11
  */
12
- library MultisigIsmMetadata {
13
- uint256 private constant MERKLE_ROOT_OFFSET = 0;
14
- uint256 private constant MERKLE_INDEX_OFFSET = 32;
15
- uint256 private constant ORIGIN_MAILBOX_OFFSET = 36;
16
- uint256 private constant MERKLE_PROOF_OFFSET = 68;
17
- uint256 private constant SIGNATURES_OFFSET = 1092;
18
- uint256 private constant SIGNATURE_LENGTH = 65;
12
+ library MerkleRootMultisigIsmMetadata {
13
+ uint8 private constant ORIGIN_MAILBOX_OFFSET = 0;
14
+ uint8 private constant CHECKPOINT_INDEX_OFFSET = 32;
15
+ uint8 private constant CHECKPOINT_MESSAGE_ID_OFFSET = 36;
16
+ uint8 private constant MERKLE_PROOF_OFFSET = 68;
17
+ uint16 private constant MERKLE_PROOF_LENGTH = 32 * 32;
18
+ uint16 private constant SIGNATURES_OFFSET = 1092;
19
+ uint8 private constant SIGNATURE_LENGTH = 65;
19
20
 
20
21
  /**
21
- * @notice Returns the merkle root of the signed checkpoint.
22
+ * @notice Returns the origin mailbox of the signed checkpoint as bytes32.
22
23
  * @param _metadata ABI encoded Multisig ISM metadata.
23
- * @return Merkle root of the signed checkpoint
24
+ * @return Origin mailbox of the signed checkpoint as bytes32
24
25
  */
25
- function root(bytes calldata _metadata) internal pure returns (bytes32) {
26
- return bytes32(_metadata[MERKLE_ROOT_OFFSET:MERKLE_INDEX_OFFSET]);
26
+ function originMailbox(bytes calldata _metadata)
27
+ internal
28
+ pure
29
+ returns (bytes32)
30
+ {
31
+ return
32
+ bytes32(
33
+ _metadata[ORIGIN_MAILBOX_OFFSET:ORIGIN_MAILBOX_OFFSET + 32]
34
+ );
27
35
  }
28
36
 
29
37
  /**
@@ -34,21 +42,28 @@ library MultisigIsmMetadata {
34
42
  function index(bytes calldata _metadata) internal pure returns (uint32) {
35
43
  return
36
44
  uint32(
37
- bytes4(_metadata[MERKLE_INDEX_OFFSET:ORIGIN_MAILBOX_OFFSET])
45
+ bytes4(
46
+ _metadata[CHECKPOINT_INDEX_OFFSET:CHECKPOINT_INDEX_OFFSET +
47
+ 4]
48
+ )
38
49
  );
39
50
  }
40
51
 
41
52
  /**
42
- * @notice Returns the origin mailbox of the signed checkpoint as bytes32.
53
+ * @notice Returns the message ID of the signed checkpoint.
43
54
  * @param _metadata ABI encoded Multisig ISM metadata.
44
- * @return Origin mailbox of the signed checkpoint as bytes32
55
+ * @return Message ID of the signed checkpoint
45
56
  */
46
- function originMailbox(bytes calldata _metadata)
57
+ function messageId(bytes calldata _metadata)
47
58
  internal
48
59
  pure
49
60
  returns (bytes32)
50
61
  {
51
- return bytes32(_metadata[ORIGIN_MAILBOX_OFFSET:MERKLE_PROOF_OFFSET]);
62
+ return
63
+ bytes32(
64
+ _metadata[CHECKPOINT_MESSAGE_ID_OFFSET:CHECKPOINT_MESSAGE_ID_OFFSET +
65
+ 32]
66
+ );
52
67
  }
53
68
 
54
69
  /**
@@ -65,7 +80,8 @@ library MultisigIsmMetadata {
65
80
  {
66
81
  return
67
82
  abi.decode(
68
- _metadata[MERKLE_PROOF_OFFSET:SIGNATURES_OFFSET],
83
+ _metadata[MERKLE_PROOF_OFFSET:MERKLE_PROOF_OFFSET +
84
+ MERKLE_PROOF_LENGTH],
69
85
  (bytes32[32])
70
86
  );
71
87
  }
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity >=0.8.0;
3
+
4
+ /**
5
+ * Format of metadata:
6
+ * [ 0: 32] Origin mailbox address
7
+ * [ 32: 64] Signed checkpoint root
8
+ * [ 64:????] Validator signatures (length := threshold * 65)
9
+ */
10
+ library MessageIdMultisigIsmMetadata {
11
+ uint8 private constant ORIGIN_MAILBOX_OFFSET = 0;
12
+ uint8 private constant MERKLE_ROOT_OFFSET = 32;
13
+ uint8 private constant SIGNATURES_OFFSET = 64;
14
+ uint8 private constant SIGNATURE_LENGTH = 65;
15
+
16
+ /**
17
+ * @notice Returns the origin mailbox of the signed checkpoint as bytes32.
18
+ * @param _metadata ABI encoded Multisig ISM metadata.
19
+ * @return Origin mailbox of the signed checkpoint as bytes32
20
+ */
21
+ function originMailbox(bytes calldata _metadata)
22
+ internal
23
+ pure
24
+ returns (bytes32)
25
+ {
26
+ return
27
+ bytes32(
28
+ _metadata[ORIGIN_MAILBOX_OFFSET:ORIGIN_MAILBOX_OFFSET + 32]
29
+ );
30
+ }
31
+
32
+ /**
33
+ * @notice Returns the merkle root of the signed checkpoint.
34
+ * @param _metadata ABI encoded Multisig ISM metadata.
35
+ * @return Merkle root of the signed checkpoint
36
+ */
37
+ function root(bytes calldata _metadata) internal pure returns (bytes32) {
38
+ return bytes32(_metadata[MERKLE_ROOT_OFFSET:MERKLE_ROOT_OFFSET + 32]);
39
+ }
40
+
41
+ /**
42
+ * @notice Returns the validator ECDSA signature at `_index`.
43
+ * @dev Assumes signatures are sorted by validator
44
+ * @dev Assumes `_metadata` encodes `threshold` signatures.
45
+ * @dev Assumes `_index` is less than `threshold`
46
+ * @param _metadata ABI encoded Multisig ISM metadata.
47
+ * @param _index The index of the signature to return.
48
+ * @return The validator ECDSA signature at `_index`.
49
+ */
50
+ function signatureAt(bytes calldata _metadata, uint256 _index)
51
+ internal
52
+ pure
53
+ returns (bytes calldata)
54
+ {
55
+ uint256 _start = SIGNATURES_OFFSET + (_index * SIGNATURE_LENGTH);
56
+ uint256 _end = _start + SIGNATURE_LENGTH;
57
+ return _metadata[_start:_end];
58
+ }
59
+ }
@@ -3,7 +3,7 @@ pragma solidity >=0.8.0;
3
3
 
4
4
  // ============ Internal Imports ============
5
5
  import {LegacyMultisigIsm} from "../isms/multisig/LegacyMultisigIsm.sol";
6
- import {CheckpointLib} from "../libs/CheckpointLib.sol";
6
+ import {LegacyCheckpointLib} from "../libs/LegacyCheckpointLib.sol";
7
7
 
8
8
  contract TestLegacyMultisigIsm is LegacyMultisigIsm {
9
9
  function getDomainHash(uint32 _origin, bytes32 _originMailbox)
@@ -11,6 +11,6 @@ contract TestLegacyMultisigIsm is LegacyMultisigIsm {
11
11
  pure
12
12
  returns (bytes32)
13
13
  {
14
- return CheckpointLib.domainHash(_origin, _originMailbox);
14
+ return LegacyCheckpointLib.domainHash(_origin, _originMailbox);
15
15
  }
16
16
  }
@@ -7,7 +7,7 @@ import {IMultisigIsm} from "../interfaces/isms/IMultisigIsm.sol";
7
7
  contract TestMultisigIsm is IMultisigIsm {
8
8
  // solhint-disable-next-line const-name-snakecase
9
9
  uint8 public constant moduleType =
10
- uint8(IInterchainSecurityModule.Types.MULTISIG);
10
+ uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);
11
11
 
12
12
  bool public accept;
13
13