-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contracts/communication synapse module #2050
Merged
ChiTimesChi
merged 34 commits into
contracts/communication
from
contracts/communication-synapse-module
Feb 19, 2024
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
d3d9307
Isolate some common logic into abstract contract
ChiTimesChi b4cd92a
Scaffold `ThresholdECDSAModule`
ChiTimesChi f7c13cd
Add more views
ChiTimesChi dff5724
Implement management tests
ChiTimesChi 9360662
Implement management actions
ChiTimesChi da19b81
Add `InterchainDB` Mock
ChiTimesChi 71e5dc0
Merge branch 'contracts/communication' into contracts/communication-s…
ChiTimesChi d1b7c25
Reorg events following #2049
ChiTimesChi 8051a7e
Also emit ethSingedMsg hash
ChiTimesChi 1668581
More `InterchainModule` errors
ChiTimesChi 25f7f03
Implement tests for fee collector management
ChiTimesChi d632f51
Fix: use the entry hash for signing
ChiTimesChi 9af670e
Implement `feeCollector` management
ChiTimesChi cd3dccf
Start doing source tests
ChiTimesChi 05fe117
Add GasOracle interface
ChiTimesChi 3e96e60
Update `verifyEntry()` interface
ChiTimesChi 82ba2df
Add source chain tests
ChiTimesChi 8f94f6b
Implement source chain funcs
ChiTimesChi 02d7cba
Add tests: `bytes` for signatures instead of `bytes[]`
ChiTimesChi a532869
Implement library update
ChiTimesChi 8b0caa2
Simplify math
ChiTimesChi 50b16a4
Implement `verifyEntry()`
ChiTimesChi de1cc35
Add tests for destination chain
ChiTimesChi 494ee35
Don't use infinity as default threshold
ChiTimesChi 696c4e0
Check source chain id in any InterchainModule
ChiTimesChi 900a52e
Deprecate old SynapseModule
ChiTimesChi e724c38
Fix ClientV1 test
ChiTimesChi 41949cd
Chore: cleanup
ChiTimesChi da01a1e
Chore: renamoooor
ChiTimesChi 268d32e
Revert "Fix ClientV1 test"
ChiTimesChi 553ff99
Revert "Chore: cleanup"
ChiTimesChi 4b93e3f
Merge branch 'contracts/communication' into contracts/communication-s…
ChiTimesChi 0192d56
Fix ClientV1 test
ChiTimesChi 980d1ea
Chore: cleanup
ChiTimesChi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
12 changes: 0 additions & 12 deletions
12
packages/contracts-communication/contracts/InterchainModule.sol
This file was deleted.
Oops, something went wrong.
10 changes: 10 additions & 0 deletions
10
packages/contracts-communication/contracts/events/InterchainModuleEvents.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {InterchainEntry} from "../libs/InterchainEntry.sol"; | ||
|
||
abstract contract InterchainModuleEvents { | ||
event VerificationRequested(uint256 indexed destChainId, bytes entry, bytes32 ethSignedEntryHash); | ||
|
||
event EntryVerified(InterchainEntry entry); | ||
} |
10 changes: 6 additions & 4 deletions
10
packages/contracts-communication/contracts/events/SynapseModuleEvents.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {InterchainEntry} from "../libs/InterchainEntry.sol"; | ||
|
||
abstract contract SynapseModuleEvents { | ||
event VerificationRequested(uint256 indexed destChainId, InterchainEntry entry, bytes32 signableEntryHash); | ||
event EntryVerified(InterchainEntry entry, bytes32 signableEntryHash); | ||
event VerifierAdded(address verifier); | ||
event VerifierRemoved(address verifier); | ||
event ThresholdChanged(uint256 threshold); | ||
|
||
event FeeCollectorChanged(address feeCollector); | ||
event GasOracleChanged(address gasOracle); | ||
} |
40 changes: 40 additions & 0 deletions
40
packages/contracts-communication/contracts/interfaces/IGasOracle.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IGasOracle { | ||
/// @notice Convert a value from the native token of a remote chain to the local native token. | ||
/// @dev Will revert if no price is available for the remote chain. | ||
/// @param remoteChainId The chain id of the remote chain. | ||
/// @param value The value to convert. | ||
function convertRemoteValueToLocalUnits(uint256 remoteChainId, uint256 value) external view returns (uint256); | ||
|
||
/// @notice Estimate the cost of execution a transaction on a remote chain, | ||
/// and convert it to the local native token. | ||
/// @dev Will revert if no price is available for the remote chain. | ||
/// @param remoteChainId The chain id of the remote chain. | ||
/// @param gasLimit The gas limit of the transaction. | ||
/// @param calldataSize The size of the transaction calldata. | ||
function estimateTxCostInLocalUnits( | ||
uint256 remoteChainId, | ||
uint256 gasLimit, | ||
uint256 calldataSize | ||
) | ||
external | ||
view | ||
returns (uint256); | ||
|
||
/// @notice Estimate the cost of execution a transaction on a remote chain, | ||
/// and return it as is in the remote chain's native token. | ||
/// @dev Will revert if no price is available for the remote chain. | ||
/// @param remoteChainId The chain id of the remote chain. | ||
/// @param gasLimit The gas limit of the transaction. | ||
/// @param calldataSize The size of the transaction calldata. | ||
function estimateTxCostInRemoteUnits( | ||
uint256 remoteChainId, | ||
uint256 gasLimit, | ||
uint256 calldataSize | ||
) | ||
external | ||
view | ||
returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 58 additions & 30 deletions
88
packages/contracts-communication/contracts/interfaces/ISynapseModule.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,62 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {InterchainEntry} from "../libs/InterchainEntry.sol"; | ||
|
||
interface ISynapseModule { | ||
/// @notice Sets the address of the InterchainDB contract to be used for verifying entries. | ||
/// @dev This function can only be called by the contract owner. | ||
/// @param _interchainDB The address of the InterchainDB contract. | ||
function setInterchainDB(address _interchainDB) external; | ||
|
||
/// @notice Sets the required threshold for verification. | ||
/// @dev This function updates the threshold value that determines the minimum number of verifications required for an entry to be considered valid. Can only be called by the contract owner. | ||
/// @param _threshold The new threshold value. | ||
function setRequiredThreshold(uint256 _threshold) external; | ||
|
||
/// @notice Updates the list of verifier addresses. | ||
/// @dev This function sets the addresses that are allowed to act as verifiers for entries. Can only be called by the contract owner. | ||
/// @param _verifiers An array of addresses to be set as verifiers. | ||
function setVerifiers(address[] calldata _verifiers) external; | ||
|
||
/// @notice Requests off-chain verification of an interchain entry for a specified destination chain. This function requires a fee. | ||
/// @dev This function can only be called by the InterchainDB contract. It checks if the sent value covers the module fee for the requested destination chain, then proceeds to pay the fee for execution. Emits a VerificationRequested event upon success. | ||
/// @param destChainId The ID of the destination chain where the entry needs to be verified. | ||
/// @param entry The interchain entry to be verified. | ||
function requestVerification(uint256 destChainId, InterchainEntry memory entry) external payable; | ||
|
||
/// @notice Verifies an interchain entry using a set of verifier signatures. | ||
/// @dev This function checks if the provided signatures meet the required threshold for verification. | ||
/// It then calls the InterchainDB contract to verify the entry. Requires that the number of valid signatures meets or exceeds the required threshold. | ||
/// @param entry The interchain entry to be verified. | ||
/// @param signatures An array of signatures used to verify the entry. | ||
function verifyEntry(InterchainEntry memory entry, bytes[] calldata signatures) external; | ||
import {IInterchainModule} from "./IInterchainModule.sol"; | ||
|
||
interface ISynapseModule is IInterchainModule { | ||
error SynapseModule__GasOracleNotContract(address gasOracle); | ||
|
||
// ═══════════════════════════════════════════════ PERMISSIONED ════════════════════════════════════════════════════ | ||
|
||
/// @notice Adds a new verifier to the module. | ||
/// @dev Could be only called by the owner. Will revert if the verifier is already added. | ||
/// @param verifier The address of the verifier to add | ||
function addVerifier(address verifier) external; | ||
|
||
/// @notice Removes a verifier from the module. | ||
/// @dev Could be only called by the owner. Will revert if the verifier is not added. | ||
/// @param verifier The address of the verifier to remove | ||
function removeVerifier(address verifier) external; | ||
|
||
/// @notice Sets the threshold of the module. | ||
/// @dev Could be only called by the owner. Will revert if the threshold is zero. | ||
/// @param threshold The new threshold value | ||
function setThreshold(uint256 threshold) external; | ||
|
||
/// @notice Sets the address of the fee collector, which will have the verification fees forwarded to it. | ||
/// @dev Could be only called by the owner. | ||
/// @param feeCollector_ The address of the fee collector | ||
function setFeeCollector(address feeCollector_) external; | ||
|
||
/// @notice Sets the address of the gas oracle to be used for estimating the verification fees. | ||
/// @dev Could be only called by the owner. Will revert if the gas oracle is not a contract. | ||
/// @param gasOracle_ The address of the gas oracle contract | ||
function setGasOracle(address gasOracle_) external; | ||
|
||
// ══════════════════════════════════════════════ PERMISSIONLESS ═══════════════════════════════════════════════════ | ||
|
||
/// @notice Verifies an entry using a set of verifier signatures. | ||
/// If the threshold is met, the entry will be marked as verified in the Interchain DataBase. | ||
/// @dev List of recovered signers from the signatures must be sorted in the ascending order. | ||
/// @param encodedEntry The encoded entry to verify | ||
/// @param signatures Signatures used to verify the entry, concatenated | ||
function verifyEntry(bytes calldata encodedEntry, bytes calldata signatures) external; | ||
|
||
// ═══════════════════════════════════════════════════ VIEWS ═══════════════════════════════════════════════════════ | ||
|
||
/// @notice Returns the address of the fee collector for the module. | ||
function feeCollector() external view returns (address); | ||
|
||
/// @notice Returns the address of the gas oracle used for estimating the verification fees. | ||
function gasOracle() external view returns (address); | ||
|
||
/// @notice Returns the list of verifiers for the module. | ||
function getVerifiers() external view returns (address[] memory); | ||
|
||
/// @notice Gets the threshold of the module. | ||
/// This is the minimum number of signatures required for verification. | ||
function getThreshold() external view returns (uint256); | ||
|
||
/// @notice Checks if the given account is a verifier for the module. | ||
function isVerifier(address account) external view returns (bool); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
packages/contracts-communication/contracts/modules/InterchainModule.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {InterchainModuleEvents} from "../events/InterchainModuleEvents.sol"; | ||
import {IInterchainDB} from "../interfaces/IInterchainDB.sol"; | ||
import {IInterchainModule} from "../interfaces/IInterchainModule.sol"; | ||
|
||
import {InterchainEntry} from "../libs/InterchainEntry.sol"; | ||
|
||
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; | ||
|
||
/// @notice Common logic for all Interchain Modules. | ||
abstract contract InterchainModule is InterchainModuleEvents, IInterchainModule { | ||
address public immutable INTERCHAIN_DB; | ||
|
||
constructor(address interchainDB) { | ||
INTERCHAIN_DB = interchainDB; | ||
} | ||
|
||
/// @inheritdoc IInterchainModule | ||
function requestVerification(uint256 destChainId, InterchainEntry memory entry) external payable { | ||
if (msg.sender != INTERCHAIN_DB) { | ||
revert InterchainModule__NotInterchainDB(); | ||
} | ||
if (destChainId == block.chainid) { | ||
revert InterchainModule__SameChainId(); | ||
} | ||
if (entry.srcChainId != block.chainid) { | ||
revert InterchainModule__IncorrectSourceChainId({chainId: entry.srcChainId}); | ||
} | ||
uint256 requiredFee = _getModuleFee(destChainId); | ||
if (msg.value < requiredFee) { | ||
revert InterchainModule__InsufficientFee({actual: msg.value, required: requiredFee}); | ||
} | ||
bytes memory encodedEntry = abi.encode(entry); | ||
bytes32 ethSignedEntryHash = MessageHashUtils.toEthSignedMessageHash(keccak256(encodedEntry)); | ||
_requestVerification(destChainId, encodedEntry); | ||
emit VerificationRequested(destChainId, encodedEntry, ethSignedEntryHash); | ||
} | ||
|
||
/// @inheritdoc IInterchainModule | ||
function getModuleFee(uint256 destChainId) external view returns (uint256) { | ||
return _getModuleFee(destChainId); | ||
} | ||
|
||
/// @dev Should be called once the Module has verified the entry and needs to signal this | ||
/// to the InterchainDB. | ||
function _verifyEntry(bytes memory encodedEntry) internal { | ||
InterchainEntry memory entry = abi.decode(encodedEntry, (InterchainEntry)); | ||
if (entry.srcChainId == block.chainid) { | ||
revert InterchainModule__SameChainId(); | ||
} | ||
IInterchainDB(INTERCHAIN_DB).verifyEntry(entry); | ||
emit EntryVerified(entry); | ||
} | ||
|
||
/// @dev Internal logic to request the verification of an entry on the destination chain. | ||
function _requestVerification(uint256 destChainId, bytes memory encodedEntry) internal virtual; | ||
|
||
/// @dev Internal logic to get the module fee for verifying an entry on the specified destination chain. | ||
function _getModuleFee(uint256 destChainId) internal view virtual returns (uint256); | ||
} |
29 changes: 0 additions & 29 deletions
29
packages/contracts-communication/contracts/modules/SynapseGasService.sol
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting that if interchainDB address ever changes, all modules will need to re-deploy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the intended behavior imo, as the module should be compatible only with the latest InterchainDB contract.
In the unlikely event that InterchainDB needs to be updated and redeployed, its design shouldn't be constrained by the existing DB <> Module interaction workflow.