From 241cd361c838b5359f7ed068d37c4a77d22afac6 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:19:55 +0000 Subject: [PATCH 01/11] Add separate for module entries with aux data --- .../contracts/libs/ModuleEntry.sol | 32 +++++++++++++++++++ .../test/harnesses/ModuleEntryLibHarness.sol | 25 +++++++++++++++ .../test/libs/ModuleEntryLib.t.sol | 29 +++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 packages/contracts-communication/contracts/libs/ModuleEntry.sol create mode 100644 packages/contracts-communication/test/harnesses/ModuleEntryLibHarness.sol create mode 100644 packages/contracts-communication/test/libs/ModuleEntryLib.t.sol diff --git a/packages/contracts-communication/contracts/libs/ModuleEntry.sol b/packages/contracts-communication/contracts/libs/ModuleEntry.sol new file mode 100644 index 0000000000..25c079f54a --- /dev/null +++ b/packages/contracts-communication/contracts/libs/ModuleEntry.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {InterchainEntry} from "./InterchainEntry.sol"; + +library ModuleEntryLib { + /// @notice Encodes the InterchainEntry and the auxiliary module data into a single bytes array + /// @param entry The InterchainEntry to encode + /// @param moduleData The auxiliary module data to encode + function encodeModuleEntry( + InterchainEntry memory entry, + bytes memory moduleData + ) + internal + pure + returns (bytes memory) + { + return abi.encode(entry, moduleData); + } + + /// @notice Decodes the bytes array into the InterchainEntry and the auxiliary module data + /// @param encodedModuleEntry The bytes array to decode + /// @return entry The decoded InterchainEntry + /// @return moduleData The decoded auxiliary module data + function decodeModuleEntry(bytes memory encodedModuleEntry) + internal + pure + returns (InterchainEntry memory entry, bytes memory moduleData) + { + return abi.decode(encodedModuleEntry, (InterchainEntry, bytes)); + } +} diff --git a/packages/contracts-communication/test/harnesses/ModuleEntryLibHarness.sol b/packages/contracts-communication/test/harnesses/ModuleEntryLibHarness.sol new file mode 100644 index 0000000000..b890c8c12f --- /dev/null +++ b/packages/contracts-communication/test/harnesses/ModuleEntryLibHarness.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {InterchainEntry, ModuleEntryLib} from "../../contracts/libs/ModuleEntry.sol"; + +contract ModuleEntryLibHarness { + function encodeModuleEntry( + InterchainEntry memory entry, + bytes memory moduleData + ) + external + pure + returns (bytes memory) + { + return ModuleEntryLib.encodeModuleEntry(entry, moduleData); + } + + function decodeModuleEntry(bytes memory encodedModuleEntry) + external + pure + returns (InterchainEntry memory, bytes memory) + { + return ModuleEntryLib.decodeModuleEntry(encodedModuleEntry); + } +} diff --git a/packages/contracts-communication/test/libs/ModuleEntryLib.t.sol b/packages/contracts-communication/test/libs/ModuleEntryLib.t.sol new file mode 100644 index 0000000000..0879d94a68 --- /dev/null +++ b/packages/contracts-communication/test/libs/ModuleEntryLib.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +import {InterchainEntry, ModuleEntryLibHarness} from "../harnesses/ModuleEntryLibHarness.sol"; + +import {Test} from "forge-std/Test.sol"; + +// solhint-disable func-name-mixedcase +contract ModuleEntryLibTest is Test { + ModuleEntryLibHarness public libHarness; + + function setUp() public { + libHarness = new ModuleEntryLibHarness(); + } + + function assertEq(InterchainEntry memory actual, InterchainEntry memory expected) public { + assertEq(actual.srcChainId, expected.srcChainId, "!srcChainId"); + assertEq(actual.dbNonce, expected.dbNonce, "!dbNonce"); + assertEq(actual.srcWriter, expected.srcWriter, "!srcWriter"); + assertEq(actual.dataHash, expected.dataHash, "!dataHash"); + } + + function test_roundTrip(InterchainEntry memory entry, bytes memory moduleData) public { + bytes memory encoded = libHarness.encodeModuleEntry(entry, moduleData); + (InterchainEntry memory decodedEntry, bytes memory decodedModuleData) = libHarness.decodeModuleEntry(encoded); + assertEq(decodedEntry, entry); + assertEq(decodedModuleData, moduleData); + } +} From e3d7939131e318507e8e011aa99731b5ec413415 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:25:57 +0000 Subject: [PATCH 02/11] InterchainModule: handle relayed entry+data --- .../contracts/modules/InterchainModule.sol | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/contracts-communication/contracts/modules/InterchainModule.sol b/packages/contracts-communication/contracts/modules/InterchainModule.sol index bf93677d9e..396dad385f 100644 --- a/packages/contracts-communication/contracts/modules/InterchainModule.sol +++ b/packages/contracts-communication/contracts/modules/InterchainModule.sol @@ -5,7 +5,7 @@ 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 {InterchainEntry, ModuleEntryLib} from "../libs/ModuleEntry.sol"; import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; @@ -46,20 +46,24 @@ abstract contract InterchainModule is InterchainModuleEvents, IInterchainModule /// @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)); + (InterchainEntry memory entry, bytes memory moduleData) = ModuleEntryLib.decodeModuleEntry(encodedEntry); if (entry.srcChainId == block.chainid) { revert InterchainModule__SameChainId(); } IInterchainDB(INTERCHAIN_DB).verifyEntry(entry); + _receiveModuleData(entry.srcChainId, entry.dbNonce, moduleData); emit EntryVerified( entry.srcChainId, encodedEntry, MessageHashUtils.toEthSignedMessageHash(keccak256(encodedEntry)) ); } + // solhint-disable no-empty-blocks /// @dev Internal logic to request the verification of an entry on the destination chain. - // solhint-disable-next-line no-empty-blocks function _requestVerification(uint256 destChainId, bytes memory encodedEntry) internal virtual {} + /// @dev Internal logic to handle the auxiliary module data relayed from the remote chain. + function _receiveModuleData(uint256 srcChainId, uint256 dbNonce, bytes memory moduleData) 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); } From 4598ae61caec4f6b6411e7e821036f6d140e6dd7 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:38:39 +0000 Subject: [PATCH 03/11] InterchainModule: fill module data on src chain --- .../contracts/modules/InterchainModule.sol | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/contracts-communication/contracts/modules/InterchainModule.sol b/packages/contracts-communication/contracts/modules/InterchainModule.sol index 396dad385f..52ba5c3232 100644 --- a/packages/contracts-communication/contracts/modules/InterchainModule.sol +++ b/packages/contracts-communication/contracts/modules/InterchainModule.sol @@ -32,7 +32,8 @@ abstract contract InterchainModule is InterchainModuleEvents, IInterchainModule if (msg.value < requiredFee) { revert InterchainModule__InsufficientFee({actual: msg.value, required: requiredFee}); } - bytes memory encodedEntry = abi.encode(entry); + bytes memory moduleData = _fillModuleData(destChainId, entry.dbNonce); + bytes memory encodedEntry = ModuleEntryLib.encodeModuleEntry(entry, moduleData); bytes32 ethSignedEntryHash = MessageHashUtils.toEthSignedMessageHash(keccak256(encodedEntry)); _requestVerification(destChainId, encodedEntry); emit VerificationRequested(destChainId, encodedEntry, ethSignedEntryHash); @@ -61,6 +62,9 @@ abstract contract InterchainModule is InterchainModuleEvents, IInterchainModule /// @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 fill the module data for the specified destination chain. + function _fillModuleData(uint256 destChainId, uint256 dbNonce) internal virtual returns (bytes memory) {} + /// @dev Internal logic to handle the auxiliary module data relayed from the remote chain. function _receiveModuleData(uint256 srcChainId, uint256 dbNonce, bytes memory moduleData) internal virtual {} From 2ad2129ecefd8bbb4f237fcd3214ed25f516b361 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:38:45 +0000 Subject: [PATCH 04/11] Adjust tests --- .../test/modules/SynapseModule.Destination.t.sol | 9 +++++---- .../test/modules/SynapseModule.Source.t.sol | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol b/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol index 85c1700490..44d049c7b8 100644 --- a/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol +++ b/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol @@ -32,6 +32,7 @@ contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseMo srcWriter: bytes32(uint256(3)), dataHash: bytes32(uint256(4)) }); + bytes public mockModuleData = ""; uint256 public constant PK_0 = 1000; uint256 public constant PK_1 = 2000; @@ -88,10 +89,10 @@ contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseMo function encodeAndHashEntry(InterchainEntry memory entry) internal - pure + view returns (bytes memory encodedEntry, bytes32 ethSignedHash) { - encodedEntry = abi.encode(entry); + encodedEntry = abi.encode(entry, mockModuleData); ethSignedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(encodedEntry))); } @@ -100,7 +101,7 @@ contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseMo uint256[] memory pks ) internal - pure + view returns (bytes memory signatures) { (, bytes32 ethSignedHash) = encodeAndHashEntry(entry); @@ -112,7 +113,7 @@ contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseMo } function verifyEntry(InterchainEntry memory entry, bytes memory signatures) internal { - module.verifyEntry(abi.encode(entry), signatures); + module.verifyEntry(abi.encode(entry, mockModuleData), signatures); } // ═══════════════════════════════════════════════ TEST HELPERS ════════════════════════════════════════════════════ diff --git a/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol b/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol index 23a4ae7070..af142144de 100644 --- a/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol +++ b/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol @@ -35,6 +35,7 @@ contract SynapseModuleSourceTest is Test, InterchainModuleEvents, SynapseModuleE srcWriter: bytes32(uint256(3)), dataHash: bytes32(uint256(4)) }); + bytes public mockModuleData = ""; function setUp() public { vm.chainId(SRC_CHAIN_ID); @@ -63,10 +64,10 @@ contract SynapseModuleSourceTest is Test, InterchainModuleEvents, SynapseModuleE function encodeAndHashEntry(InterchainEntry memory entry) internal - pure + view returns (bytes memory encodedEntry, bytes32 ethSignedHash) { - encodedEntry = abi.encode(entry); + encodedEntry = abi.encode(entry, mockModuleData); ethSignedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(encodedEntry))); } From 9eb94719a56382b0bf8ac0d847238516f8d0bce0 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:45:30 +0000 Subject: [PATCH 05/11] Introduce SynapseGasOracle --- .../contracts/interfaces/ISynapseGasOracle.sol | 15 +++++++++++++++ .../contracts/interfaces/ISynapseModule.sol | 1 + .../contracts/modules/SynapseModule.sol | 12 ++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 packages/contracts-communication/contracts/interfaces/ISynapseGasOracle.sol diff --git a/packages/contracts-communication/contracts/interfaces/ISynapseGasOracle.sol b/packages/contracts-communication/contracts/interfaces/ISynapseGasOracle.sol new file mode 100644 index 0000000000..18bf67b758 --- /dev/null +++ b/packages/contracts-communication/contracts/interfaces/ISynapseGasOracle.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IGasOracle} from "./IGasOracle.sol"; + +interface ISynapseGasOracle is IGasOracle { + /// @notice Allows Synapse Module to pass the gas data from a remote chain to the Gas Oracle. + /// @dev Could only be called by Synapse Module. + /// @param srcChainId The chain id of the remote chain. + /// @param data The gas data from the remote chain. + function receiveRemoteGasData(uint256 srcChainId, bytes calldata data) external; + + /// @notice Gets the gas data for the local chain. + function getLocalGasData() external view returns (bytes memory); +} diff --git a/packages/contracts-communication/contracts/interfaces/ISynapseModule.sol b/packages/contracts-communication/contracts/interfaces/ISynapseModule.sol index 02ba033590..dc74af53a1 100644 --- a/packages/contracts-communication/contracts/interfaces/ISynapseModule.sol +++ b/packages/contracts-communication/contracts/interfaces/ISynapseModule.sol @@ -7,6 +7,7 @@ interface ISynapseModule is IInterchainModule { error SynapseModule__ClaimFeeFractionExceedsMax(uint256 claimFeeFraction); error SynapseModule__FeeCollectorNotSet(); error SynapseModule__GasOracleNotContract(address gasOracle); + error SynapseModule__GasOracleNotSet(); error SynapseModule__NoFeesToClaim(); // ═══════════════════════════════════════════════ PERMISSIONED ════════════════════════════════════════════════════ diff --git a/packages/contracts-communication/contracts/modules/SynapseModule.sol b/packages/contracts-communication/contracts/modules/SynapseModule.sol index b71c75fe01..6c926a8906 100644 --- a/packages/contracts-communication/contracts/modules/SynapseModule.sol +++ b/packages/contracts-communication/contracts/modules/SynapseModule.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.20; import {InterchainModule} from "./InterchainModule.sol"; import {SynapseModuleEvents} from "../events/SynapseModuleEvents.sol"; -import {IGasOracle} from "../interfaces/IGasOracle.sol"; +import {ISynapseGasOracle} from "../interfaces/ISynapseGasOracle.sol"; import {ISynapseModule} from "../interfaces/ISynapseModule.sol"; import {ThresholdECDSA} from "../libs/ThresholdECDSA.sol"; @@ -183,10 +183,18 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap // entry is 32 (length) + 32*4 (fields) = 160 // signatures: 32 (length) + 65*threshold (padded up to be a multiple of 32 bytes) // Total formula is: 4 + 32 (entry offset) + 32 (signatures offset) + 160 + 32 - return IGasOracle(gasOracle).estimateTxCostInLocalUnits({ + return _getSynapseGasOracle().estimateTxCostInLocalUnits({ remoteChainId: destChainId, gasLimit: getVerifyGasLimit(destChainId), calldataSize: 292 + 64 * getThreshold() }); } + + /// @dev Internal logic to get the Synapse Gas Oracle. Reverts if the gas oracle is not set. + function _getSynapseGasOracle() internal view returns (ISynapseGasOracle synapseGasOracle) { + synapseGasOracle = ISynapseGasOracle(gasOracle); + if (address(synapseGasOracle) == address(0)) { + revert SynapseModule__GasOracleNotSet(); + } + } } From 741c4314c970a32b77398b7b8f960abd201a6016 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:54:00 +0000 Subject: [PATCH 06/11] SynapseModule: fill gas data --- .../contracts/events/SynapseModuleEvents.sol | 3 +++ .../contracts/modules/SynapseModule.sol | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/packages/contracts-communication/contracts/events/SynapseModuleEvents.sol b/packages/contracts-communication/contracts/events/SynapseModuleEvents.sol index 5defbe3fba..84569f0968 100644 --- a/packages/contracts-communication/contracts/events/SynapseModuleEvents.sol +++ b/packages/contracts-communication/contracts/events/SynapseModuleEvents.sol @@ -12,4 +12,7 @@ abstract contract SynapseModuleEvents { event ClaimFeeFractionChanged(uint256 claimFeeFraction); event FeesClaimed(address feeCollector, uint256 collectedFees, address claimer, uint256 claimerFee); + + event GasDataSent(uint256 dstChainId, bytes data); + event GasDataReceived(uint256 srcChainId, bytes data); } diff --git a/packages/contracts-communication/contracts/modules/SynapseModule.sol b/packages/contracts-communication/contracts/modules/SynapseModule.sol index 6c926a8906..9c9dd8b842 100644 --- a/packages/contracts-communication/contracts/modules/SynapseModule.sol +++ b/packages/contracts-communication/contracts/modules/SynapseModule.sol @@ -26,6 +26,8 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap uint256 internal _claimFeeFraction; /// @dev Gas limit for the verifyEntry function on the remote chain. mapping(uint256 chainId => uint256 gasLimit) internal _verifyGasLimit; + /// @dev Hash of the last gas data sent to the remote chain. + mapping(uint256 chainId => bytes32 gasDataHash) internal _lastGasDataHash; /// @inheritdoc ISynapseModule address public feeCollector; @@ -173,6 +175,30 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap emit VerifierRemoved(verifier); } + /// @dev Internal logic to fill the module data for the specified destination chain. + function _fillModuleData( + uint256 destChainId, + uint256 dbNonce + ) + internal + override + returns (bytes memory moduleData) + { + moduleData = _getSynapseGasOracle().getLocalGasData(); + // Exit early if data is empty + if (moduleData.length == 0) { + return moduleData; + } + bytes32 dataHash = keccak256(moduleData); + // Don't send the same data twice + if (dataHash == _lastGasDataHash[destChainId]) { + moduleData = ""; + } else { + _lastGasDataHash[destChainId] = dataHash; + emit GasDataSent(destChainId, moduleData); + } + } + // ══════════════════════════════════════════════ INTERNAL VIEWS ═══════════════════════════════════════════════════ /// @dev Internal logic to get the module fee for verifying an entry on the specified destination chain. From f7d696380b0db4b9f04ab8d6eb71aeab5205c633 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:58:33 +0000 Subject: [PATCH 07/11] SynapseModule: receive gas data --- .../contracts/modules/SynapseModule.sol | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/contracts-communication/contracts/modules/SynapseModule.sol b/packages/contracts-communication/contracts/modules/SynapseModule.sol index 9c9dd8b842..fdae3d1c5f 100644 --- a/packages/contracts-communication/contracts/modules/SynapseModule.sol +++ b/packages/contracts-communication/contracts/modules/SynapseModule.sol @@ -28,6 +28,8 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap mapping(uint256 chainId => uint256 gasLimit) internal _verifyGasLimit; /// @dev Hash of the last gas data sent to the remote chain. mapping(uint256 chainId => bytes32 gasDataHash) internal _lastGasDataHash; + /// @dev Nonce of the last gas data received from the remote chain. + mapping(uint256 chainid => uint256 gasDataNonce) internal _lastGasDataNonce; /// @inheritdoc ISynapseModule address public feeCollector; @@ -199,6 +201,21 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap } } + /// @dev Internal logic to handle the auxiliary module data relayed from the remote chain. + function _receiveModuleData(uint256 srcChainId, uint256 dbNonce, bytes memory moduleData) internal override { + // Exit early if data is empty + if (moduleData.length == 0) { + return; + } + // Don't process outdated data + uint256 lastNonce = _lastGasDataNonce[srcChainId]; + if (lastNonce == 0 || lastNonce < dbNonce) { + _lastGasDataNonce[srcChainId] = dbNonce; + _getSynapseGasOracle().receiveRemoteGasData(srcChainId, moduleData); + emit GasDataReceived(srcChainId, moduleData); + } + } + // ══════════════════════════════════════════════ INTERNAL VIEWS ═══════════════════════════════════════════════════ /// @dev Internal logic to get the module fee for verifying an entry on the specified destination chain. From 1784802f32dc523f8905caa4f90d7c853109b237 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:00:22 +0000 Subject: [PATCH 08/11] Update gas oracle mock --- .../mocks/{GasOracleMock.sol => SynapseGasOracleMock.sol} | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) rename packages/contracts-communication/test/mocks/{GasOracleMock.sol => SynapseGasOracleMock.sol} (69%) diff --git a/packages/contracts-communication/test/mocks/GasOracleMock.sol b/packages/contracts-communication/test/mocks/SynapseGasOracleMock.sol similarity index 69% rename from packages/contracts-communication/test/mocks/GasOracleMock.sol rename to packages/contracts-communication/test/mocks/SynapseGasOracleMock.sol index ef38762239..f730440d58 100644 --- a/packages/contracts-communication/test/mocks/GasOracleMock.sol +++ b/packages/contracts-communication/test/mocks/SynapseGasOracleMock.sol @@ -1,9 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.20; -import {IGasOracle} from "../../contracts/interfaces/IGasOracle.sol"; +import {ISynapseGasOracle} from "../../contracts/interfaces/ISynapseGasOracle.sol"; + +contract SynapseGasOracleMock is ISynapseGasOracle { + function receiveRemoteGasData(uint256 srcChainId, bytes calldata data) external {} + + function getLocalGasData() external view returns (bytes memory) {} -contract GasOracleMock is IGasOracle { function convertRemoteValueToLocalUnits( uint256 remoteChainId, uint256 value From 0835a90b7cc7fdb3024c035634b4d962d0587bec Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:01:51 +0000 Subject: [PATCH 09/11] Update GasOracleMock references --- .../script/MessagingBase.s.sol | 103 ------------------ .../script/testnet-deploy.sh | 2 +- .../test/ExecutionService.t.sol | 6 +- .../modules/SynapseModule.Destination.t.sol | 6 +- .../modules/SynapseModule.Management.t.sol | 6 +- .../test/modules/SynapseModule.Source.t.sol | 8 +- 6 files changed, 14 insertions(+), 117 deletions(-) delete mode 100644 packages/contracts-communication/script/MessagingBase.s.sol diff --git a/packages/contracts-communication/script/MessagingBase.s.sol b/packages/contracts-communication/script/MessagingBase.s.sol deleted file mode 100644 index 4db5ced040..0000000000 --- a/packages/contracts-communication/script/MessagingBase.s.sol +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Script} from "forge-std/Script.sol"; - -import {InterchainDB} from "../contracts/InterchainDB.sol"; - -import {InterchainClientV1} from "../contracts/InterchainClientV1.sol"; - -import {SynapseModule} from "../contracts/modules/SynapseModule.sol"; - -import {InterchainApp} from "../contracts/InterchainApp.sol"; - -import {GasOracleMock} from "../test/mocks/GasOracleMock.sol"; - -import {ExecutionFeesMock} from "../test/mocks/ExecutionFeesMock.sol"; - -contract MessagingBase is Script { - InterchainDB public icDB; - InterchainClientV1 public icClient; - SynapseModule public synapseModule; - GasOracleMock public gasOracleMock; - InterchainApp public icApp; - ExecutionFeesMock public executionFees; - - function run() external { - vm.startBroadcast(); - icDB = new InterchainDB(); - // icClient deployment & config - icClient = new InterchainClientV1(address(icDB), msg.sender); - - synapseModule = new SynapseModule(address(icDB), msg.sender); - gasOracleMock = new GasOracleMock(); - executionFees = new ExecutionFeesMock(); - synapseModule.setGasOracle(address(gasOracleMock)); - icClient.setExecutionFees(address(executionFees)); - icApp = new InterchainApp(address(icClient), new address[](0), new address[](0)); - - vm.stopBroadcast(); - } - - function newApp() external { - vm.startBroadcast(); - icApp = new InterchainApp(0x007f3EC4A8E6DbaA84E50d0901F48966D83B7300, new address[](0), new address[](0)); - vm.stopBroadcast(); - } - - function newAppSepolia() public { - vm.startBroadcast(); - icApp = new InterchainApp(0xFd8A9eDf272e54614426a4c5849851D26A57C644, new address[](0), new address[](0)); - vm.stopBroadcast(); - } - - function newAppConfigOP() external { - vm.startBroadcast(); - icApp = InterchainApp(0x4a1f8D1378b614a59D0BB62EeeD811aaC1d22EC0); - uint64[] memory chainIDs = new uint64[](1); - chainIDs[0] = 11_155_111; - address[] memory linkedIApps = new address[](1); - linkedIApps[0] = 0x4a1f8D1378b614a59D0BB62EeeD811aaC1d22EC0; - address[] memory _sendingModules = new address[](1); - _sendingModules[0] = 0x48ADb7308f59d98657e779681aE6037902901918; - address[] memory _receivingModules = new address[](1); - _receivingModules[0] = 0x48ADb7308f59d98657e779681aE6037902901918; - uint256 _requiredResponses = 1; - uint64 _optimisticTimePeriod = 1; - icApp.setAppConfig( - chainIDs, - linkedIApps, - _sendingModules, - _receivingModules, - address(0), - _requiredResponses, - _optimisticTimePeriod - ); - vm.stopBroadcast(); - } - - function newAppConfigSepolia() external { - vm.startBroadcast(); - icApp = InterchainApp(0x4a1f8D1378b614a59D0BB62EeeD811aaC1d22EC0); - uint64[] memory chainIDs = new uint64[](1); - chainIDs[0] = 11_155_111; - address[] memory linkedIApps = new address[](1); - linkedIApps[0] = 0x4a1f8D1378b614a59D0BB62EeeD811aaC1d22EC0; - address[] memory _sendingModules = new address[](1); - _sendingModules[0] = 0x135189D37b0a734e4A339F0e9fd3219521729e7A; - address[] memory _receivingModules = new address[](1); - _receivingModules[0] = 0x135189D37b0a734e4A339F0e9fd3219521729e7A; - uint256 _requiredResponses = 1; - uint64 _optimisticTimePeriod = 1; - icApp.setAppConfig( - chainIDs, - linkedIApps, - _sendingModules, - _receivingModules, - address(0), - _requiredResponses, - _optimisticTimePeriod - ); - vm.stopBroadcast(); - } -} diff --git a/packages/contracts-communication/script/testnet-deploy.sh b/packages/contracts-communication/script/testnet-deploy.sh index e6c4f38977..52857450ac 100755 --- a/packages/contracts-communication/script/testnet-deploy.sh +++ b/packages/contracts-communication/script/testnet-deploy.sh @@ -21,4 +21,4 @@ yarn fsr script/deploy/DeploySynapseModule.s.sol "$chainName" "$walletName" "$@" yarn fsr-str script/deploy/DeployWithMsgSender.s.sol "$chainName" "$walletName" "ExecutionFees" "$@" yarn fsr-str script/deploy/DeployWithMsgSender.s.sol "$chainName" "$walletName" "ExecutionService" "$@" -yarn fsr-str script/deploy/DeployNoArgs.s.sol "$chainName" "$walletName" "GasOracleMock" "$@" +yarn fsr-str script/deploy/DeployNoArgs.s.sol "$chainName" "$walletName" "SynapseGasOracleMock" "$@" diff --git a/packages/contracts-communication/test/ExecutionService.t.sol b/packages/contracts-communication/test/ExecutionService.t.sol index ad2d19d1f7..e37bd168ed 100644 --- a/packages/contracts-communication/test/ExecutionService.t.sol +++ b/packages/contracts-communication/test/ExecutionService.t.sol @@ -3,18 +3,18 @@ pragma solidity 0.8.20; import {ExecutionService, ExecutionServiceEvents, IExecutionService} from "../contracts/ExecutionService.sol"; import {Test} from "forge-std/Test.sol"; -import {GasOracleMock} from "./mocks/GasOracleMock.sol"; +import {SynapseGasOracleMock} from "./mocks/SynapseGasOracleMock.sol"; contract ExecutionServiceTest is ExecutionServiceEvents, Test { ExecutionService public executionService; - GasOracleMock public gasOracle; + SynapseGasOracleMock public gasOracle; address icClient = address(0x123); address executorEOA = address(0x456); address owner = makeAddr("Owner"); function setUp() public { - gasOracle = new GasOracleMock(); + gasOracle = new SynapseGasOracleMock(); executionService = new ExecutionService(address(this)); executionService.setInterchainClient(icClient); executionService.setExecutorEOA(executorEOA); diff --git a/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol b/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol index 44d049c7b8..71a0eb93c8 100644 --- a/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol +++ b/packages/contracts-communication/test/modules/SynapseModule.Destination.t.sol @@ -8,7 +8,7 @@ import {InterchainEntry} from "../../contracts/libs/InterchainEntry.sol"; import {ThresholdECDSALib} from "../../contracts/libs/ThresholdECDSA.sol"; import {SynapseModule} from "../../contracts/modules/SynapseModule.sol"; -import {GasOracleMock} from "../mocks/GasOracleMock.sol"; +import {SynapseGasOracleMock} from "../mocks/SynapseGasOracleMock.sol"; import {InterchainDBMock, IInterchainDB} from "../mocks/InterchainDBMock.sol"; import {Test} from "forge-std/Test.sol"; @@ -17,7 +17,7 @@ import {Test} from "forge-std/Test.sol"; // solhint-disable ordering contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseModuleEvents { SynapseModule public module; - GasOracleMock public gasOracle; + SynapseGasOracleMock public gasOracle; InterchainDBMock public interchainDB; address public feeCollector = makeAddr("FeeCollector"); @@ -50,7 +50,7 @@ contract SynapseModuleDestinationTest is Test, InterchainModuleEvents, SynapseMo vm.chainId(DST_CHAIN_ID); interchainDB = new InterchainDBMock(); module = new SynapseModule(address(interchainDB), owner); - gasOracle = new GasOracleMock(); + gasOracle = new SynapseGasOracleMock(); vm.startPrank(owner); module.setGasOracle(address(gasOracle)); module.setFeeCollector(feeCollector); diff --git a/packages/contracts-communication/test/modules/SynapseModule.Management.t.sol b/packages/contracts-communication/test/modules/SynapseModule.Management.t.sol index 7ab125ccdf..ede5c5fd3e 100644 --- a/packages/contracts-communication/test/modules/SynapseModule.Management.t.sol +++ b/packages/contracts-communication/test/modules/SynapseModule.Management.t.sol @@ -5,7 +5,7 @@ import {SynapseModuleEvents} from "../../contracts/events/SynapseModuleEvents.so import {SynapseModule, ISynapseModule} from "../../contracts/modules/SynapseModule.sol"; import {ThresholdECDSALib} from "../../contracts/libs/ThresholdECDSA.sol"; -import {GasOracleMock} from "../mocks/GasOracleMock.sol"; +import {SynapseGasOracleMock} from "../mocks/SynapseGasOracleMock.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; @@ -15,7 +15,7 @@ import {Test} from "forge-std/Test.sol"; // solhint-disable ordering contract SynapseModuleManagementTest is Test, SynapseModuleEvents { SynapseModule public module; - GasOracleMock public gasOracle; + SynapseGasOracleMock public gasOracle; address public interchainDB = makeAddr("InterchainDB"); address public owner = makeAddr("Owner"); @@ -29,7 +29,7 @@ contract SynapseModuleManagementTest is Test, SynapseModuleEvents { function setUp() public { module = new SynapseModule(interchainDB, owner); - gasOracle = new GasOracleMock(); + gasOracle = new SynapseGasOracleMock(); allVerifiers.push(VERIFIER_1); allVerifiers.push(VERIFIER_2); allVerifiers.push(VERIFIER_3); diff --git a/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol b/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol index af142144de..119474b537 100644 --- a/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol +++ b/packages/contracts-communication/test/modules/SynapseModule.Source.t.sol @@ -7,7 +7,7 @@ import {IInterchainModule} from "../../contracts/interfaces/IInterchainModule.so import {InterchainEntry} from "../../contracts/libs/InterchainEntry.sol"; import {SynapseModule, ISynapseModule} from "../../contracts/modules/SynapseModule.sol"; -import {GasOracleMock} from "../mocks/GasOracleMock.sol"; +import {SynapseGasOracleMock} from "../mocks/SynapseGasOracleMock.sol"; import {Test} from "forge-std/Test.sol"; @@ -15,7 +15,7 @@ import {Test} from "forge-std/Test.sol"; // solhint-disable ordering contract SynapseModuleSourceTest is Test, InterchainModuleEvents, SynapseModuleEvents { SynapseModule public module; - GasOracleMock public gasOracle; + SynapseGasOracleMock public gasOracle; address public interchainDB = makeAddr("InterchainDB"); address public feeCollector = makeAddr("FeeCollector"); @@ -40,7 +40,7 @@ contract SynapseModuleSourceTest is Test, InterchainModuleEvents, SynapseModuleE function setUp() public { vm.chainId(SRC_CHAIN_ID); module = new SynapseModule(interchainDB, owner); - gasOracle = new GasOracleMock(); + gasOracle = new SynapseGasOracleMock(); vm.startPrank(owner); module.setGasOracle(address(gasOracle)); module.setFeeCollector(feeCollector); @@ -51,7 +51,7 @@ contract SynapseModuleSourceTest is Test, InterchainModuleEvents, SynapseModuleE // Mock: gasOracle.estimateTxCostInLocalUnits(DST_CHAIN_ID, *, *) to return FEE vm.mockCall( address(gasOracle), - abi.encodeWithSelector(GasOracleMock.estimateTxCostInLocalUnits.selector, DST_CHAIN_ID), + abi.encodeWithSelector(SynapseGasOracleMock.estimateTxCostInLocalUnits.selector, DST_CHAIN_ID), abi.encode(FEE) ); } From a1efdd0d29eaa9819120b4235232395f303ba5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CF=87=C2=B2?= <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:43:26 +0000 Subject: [PATCH 10/11] Update packages/contracts-communication/contracts/modules/SynapseModule.sol Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../contracts-communication/contracts/modules/SynapseModule.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-communication/contracts/modules/SynapseModule.sol b/packages/contracts-communication/contracts/modules/SynapseModule.sol index fdae3d1c5f..ca0c5f4e71 100644 --- a/packages/contracts-communication/contracts/modules/SynapseModule.sol +++ b/packages/contracts-communication/contracts/modules/SynapseModule.sol @@ -29,7 +29,7 @@ contract SynapseModule is InterchainModule, Ownable, SynapseModuleEvents, ISynap /// @dev Hash of the last gas data sent to the remote chain. mapping(uint256 chainId => bytes32 gasDataHash) internal _lastGasDataHash; /// @dev Nonce of the last gas data received from the remote chain. - mapping(uint256 chainid => uint256 gasDataNonce) internal _lastGasDataNonce; + mapping(uint256 chainId => uint256 gasDataNonce) internal _lastGasDataNonce; /// @inheritdoc ISynapseModule address public feeCollector; From 70f91985c1ee98631968b6cf71e2e8ecf421910f Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:49:10 +0000 Subject: [PATCH 11/11] Update configs --- .../configs/global/ExecutionService.testnet.json | 2 +- .../configs/global/SynapseModule.testnet.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-communication/configs/global/ExecutionService.testnet.json b/packages/contracts-communication/configs/global/ExecutionService.testnet.json index d4293802bc..459ecaca64 100644 --- a/packages/contracts-communication/configs/global/ExecutionService.testnet.json +++ b/packages/contracts-communication/configs/global/ExecutionService.testnet.json @@ -1,4 +1,4 @@ { "executorEOA": "0xD0D45E468ADF3aCB8A98391ff47267783220ba6F", - "gasOracleName": "GasOracleMock" + "gasOracleName": "SynapseGasOracleMock" } diff --git a/packages/contracts-communication/configs/global/SynapseModule.testnet.json b/packages/contracts-communication/configs/global/SynapseModule.testnet.json index 0ad395d094..e78630c1d7 100644 --- a/packages/contracts-communication/configs/global/SynapseModule.testnet.json +++ b/packages/contracts-communication/configs/global/SynapseModule.testnet.json @@ -1,7 +1,7 @@ { "claimFeeBPS": 10, "feeCollector": "0xD0D45E468ADF3aCB8A98391ff47267783220ba6F", - "gasOracleName": "GasOracleMock", + "gasOracleName": "SynapseGasOracleMock", "threshold": 6, "verifiers": [ "0x0E399F695d72033d598aC2911B8A5e9986d6cbaD",