From 4cdd1849eceb21f422f48120a7ec774a103d939e Mon Sep 17 00:00:00 2001 From: Alessandro Manfredi Date: Thu, 25 Jan 2024 07:48:33 +0100 Subject: [PATCH] refactor(evm): refactors Sygma Adapter and adds the Reporter --- .../contracts/adapters/Sygma/SygmaAdapter.sol | 30 ++----- .../adapters/Sygma/SygmaHeaderReporter.sol | 59 -------------- .../adapters/Sygma/SygmaMessageRelay.sol | 38 --------- .../adapters/Sygma/SygmaReporter.sol | 71 +++++++++++------ .../Sygma/test/SygmaTestContracts.sol | 78 ------------------- 5 files changed, 52 insertions(+), 224 deletions(-) delete mode 100644 packages/evm/contracts/adapters/Sygma/SygmaHeaderReporter.sol delete mode 100644 packages/evm/contracts/adapters/Sygma/SygmaMessageRelay.sol delete mode 100644 packages/evm/contracts/adapters/Sygma/test/SygmaTestContracts.sol diff --git a/packages/evm/contracts/adapters/Sygma/SygmaAdapter.sol b/packages/evm/contracts/adapters/Sygma/SygmaAdapter.sol index 451e659d..251a649f 100644 --- a/packages/evm/contracts/adapters/Sygma/SygmaAdapter.sol +++ b/packages/evm/contracts/adapters/Sygma/SygmaAdapter.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.17; -import "@openzeppelin/contracts/access/AccessControl.sol"; -import "../OracleAdapter.sol"; +import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; import "../BlockHashOracleAdapter.sol"; -contract SygmaAdapter is AccessControl, OracleAdapter, BlockHashOracleAdapter { +contract SygmaAdapter is AccessControl, BlockHashOracleAdapter { + string public constant PROVIDER = "sygma"; + struct Reporter { uint128 chainID; bool enabled; @@ -21,9 +22,6 @@ contract SygmaAdapter is AccessControl, OracleAdapter, BlockHashOracleAdapter { event ReporterSet(address reporterAddress, uint256 chainID, bool enabled); - /** - @param handler Contract address of the generic handler. - */ constructor(address handler) { _handler = handler; _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); @@ -34,35 +32,17 @@ contract SygmaAdapter is AccessControl, OracleAdapter, BlockHashOracleAdapter { _; } - /** - @dev Sets parameters of a source chain hash reporter. - @param reporterAddress Hash reporter address on the source chain. - @param chainID ChainID of the source chain. - @param enabled Status of the reporter. - */ function setReporter(address reporterAddress, uint128 chainID, bool enabled) public onlyAdmin { reporters[reporterAddress] = Reporter(chainID, enabled); emit ReporterSet(reporterAddress, chainID, enabled); } - /** - @dev Stores the hashes for a given array of ids. - @param reporterAddress Hash reporter address on the source chain. - @param ids Array of block numbers for which to set the hashes. - @param hashes Array of hashes to set for the given block numbers. - @notice Only callable by `_handler` with a message passed from an authorized reporter. - @notice Will revert if array lengths do not match. - */ function storeHashes(address reporterAddress, uint256[] calldata ids, bytes32[] calldata hashes) public { if (ids.length != hashes.length) revert ArrayLengthMismatch(); if (msg.sender != _handler) revert InvalidHandler(msg.sender); - Reporter memory reporter = reporters[reporterAddress]; if (!reporter.enabled) revert InvalidReporter(reporterAddress); uint256 chainID = uint256(reporter.chainID); - - for (uint i = 0; i < ids.length; i++) { - _storeHash(chainID, ids[i], hashes[i]); - } + _storeHashes(chainID, ids, hashes); } } diff --git a/packages/evm/contracts/adapters/Sygma/SygmaHeaderReporter.sol b/packages/evm/contracts/adapters/Sygma/SygmaHeaderReporter.sol deleted file mode 100644 index f7c95f87..00000000 --- a/packages/evm/contracts/adapters/Sygma/SygmaHeaderReporter.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.17; - -import { SygmaReporter } from "./SygmaReporter.sol"; -import { HeaderStorage } from "../../utils/HeaderStorage.sol"; - -contract SygmaHeaderReporter is SygmaReporter { - HeaderStorage public immutable _headerStorage; - - event HeaderReported(address indexed emitter, uint256 indexed blockNumber, bytes32 indexed blockHeader); - - constructor( - address bridge, - HeaderStorage headerStorage, - bytes32 resourceID, - uint8 defaultDestinationDomainID, - address defaultSygmaAdapter - ) SygmaReporter(bridge, resourceID, defaultDestinationDomainID, defaultSygmaAdapter) { - _headerStorage = headerStorage; - } - - /** - @dev Reports the given block headers to the oracleAdapter via the Sygma bridge to default domain. - @param blockNumbers Uint256 array of block numbers to pass over the Sygma bridge. - @param feeData Additional data to be passed to the fee handler. - */ - function reportHeaders(uint256[] memory blockNumbers, bytes calldata feeData) public payable { - _reportHeaders(blockNumbers, _defaultSygmaAdapter, _defaultDestinationDomainID, feeData); - } - - /** - @dev Reports the given block headers to the oracleAdapter via the Sygma bridge to specified domain. - @param blockNumbers Uint256 array of block numbers to pass over the Sygma bridge. - @param sygmaAdapter Address of the Sygma adapter on the target chain. - @param destinationDomainID Destination domain ID. - @param feeData Additional data to be passed to the fee handler. - */ - function reportHeadersToDomain( - uint256[] memory blockNumbers, - address sygmaAdapter, - uint8 destinationDomainID, - bytes memory feeData - ) public payable { - _reportHeaders(blockNumbers, sygmaAdapter, destinationDomainID, feeData); - } - - function _reportHeaders( - uint256[] memory blockNumbers, - address sygmaAdapter, - uint8 destinationDomainID, - bytes memory feeData - ) internal { - bytes32[] memory blockHeaders = _headerStorage.storeBlockHeaders(blockNumbers); - _reportData(blockNumbers, blockHeaders, sygmaAdapter, destinationDomainID, feeData); - for (uint i = 0; i < blockNumbers.length; i++) { - emit HeaderReported(address(this), blockNumbers[i], blockHeaders[i]); - } - } -} diff --git a/packages/evm/contracts/adapters/Sygma/SygmaMessageRelay.sol b/packages/evm/contracts/adapters/Sygma/SygmaMessageRelay.sol deleted file mode 100644 index 74aafad2..00000000 --- a/packages/evm/contracts/adapters/Sygma/SygmaMessageRelay.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity ^0.8.17; - -import { IMessageRelay } from "../../interfaces/IMessageRelay.sol"; -import { SygmaReporter } from "./SygmaReporter.sol"; -import { Yaho } from "../../Yaho.sol"; - -contract SygmaMessageRelay is SygmaReporter, IMessageRelay { - Yaho public immutable _yaho; - - event MessageRelayed(address indexed emitter, uint256 indexed messageId); - - constructor( - address bridge, - Yaho yaho, - bytes32 resourceID, - uint8 defaultDestinationDomainID, - address defaultSygmaAdapter - ) SygmaReporter(bridge, resourceID, defaultDestinationDomainID, defaultSygmaAdapter) { - _yaho = yaho; - } - - /** - @dev Relays the messages via the Sygma bridge to default domain. - @param messageIds IDs of the messages to pass over the Sygma bridge. - @param sygmaAdapter Address of the Sygma adapter on the target chain. - */ - function relayMessages(uint256[] memory messageIds, address sygmaAdapter) public payable returns (bytes32) { - bytes32[] memory hashes = new bytes32[](messageIds.length); - for (uint256 i = 0; i < messageIds.length; i++) { - uint256 id = messageIds[i]; - hashes[i] = _yaho.hashes(id); - emit MessageRelayed(address(this), messageIds[i]); - } - (uint64 depositNonce, ) = _reportData(messageIds, hashes, sygmaAdapter, _defaultDestinationDomainID, ""); - return bytes32(uint256(depositNonce)); - } -} diff --git a/packages/evm/contracts/adapters/Sygma/SygmaReporter.sol b/packages/evm/contracts/adapters/Sygma/SygmaReporter.sol index 2fcaee60..4a792cd5 100644 --- a/packages/evm/contracts/adapters/Sygma/SygmaReporter.sol +++ b/packages/evm/contracts/adapters/Sygma/SygmaReporter.sol @@ -1,29 +1,46 @@ // SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.17; -import "./interfaces/ISygmaAdapter.sol"; -import "./interfaces/IBridge.sol"; - -contract SygmaReporter { - address public immutable _bridge; - bytes32 public immutable _resourceID; - uint8 public immutable _defaultDestinationDomainID; - address public immutable _defaultSygmaAdapter; - - constructor(address bridge, bytes32 resourceID, uint8 defaultDestinationDomainID, address defaultSygmaAdapter) { - _bridge = bridge; - _resourceID = resourceID; - _defaultDestinationDomainID = defaultDestinationDomainID; - _defaultSygmaAdapter = defaultSygmaAdapter; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { Reporter } from "../Reporter.sol"; +import { ISygmaAdapter } from "./interfaces/ISygmaAdapter.sol"; +import { IBridge } from "./interfaces/IBridge.sol"; + +contract SygmaReporter is Reporter, Ownable { + string public constant PROVIDER = "sygma"; + + IBridge public immutable BRIDGE; + + mapping(uint256 => uint8) public domainIds; + mapping(uint256 => bytes32) public resourceIds; + + error DomainIdNotAvailable(); + error ResourceIdNotAvailable(); + + event DomainIdSet(uint256 indexed chainId, uint8 indexed domainId); + event ResourceIdSet(uint256 indexed chainId, bytes32 indexed resourceId); + + constructor(address headerStorage, address yaho, address bridge) Reporter(headerStorage, yaho) { + BRIDGE = IBridge(bridge); } - function _reportData( - uint256[] memory messageIds, - bytes32[] memory hashes, - address sygmaAdapter, - uint8 destinationDomainID, - bytes memory feeData - ) internal returns (uint64 depositNonce, bytes memory handlerResponse) { + function setDomainIdAndResourceIdByChainId(uint256 chainId, uint8 domainId, bytes32 resourceId) external onlyOwner { + domainIds[chainId] = domainId; + resourceIds[chainId] = resourceId; + emit DomainIdSet(chainId, domainId); + emit ResourceIdSet(chainId, resourceId); + } + + function _dispatch( + uint256 toChainId, + address adapter, + uint256[] memory ids, + bytes32[] memory hashes + ) internal override returns (bytes32) { + uint8 domainId = domainIds[toChainId]; + if (domainId == 0) revert DomainIdNotAvailable(); + bytes32 resourceId = resourceIds[toChainId]; + if (resourceId == bytes32(0)) revert ResourceIdNotAvailable(); bytes memory depositData = abi.encodePacked( // uint256 maxFee uint256(950000), @@ -34,15 +51,21 @@ contract SygmaReporter { // uint8 len(executeContractAddress) uint8(20), // bytes executeContractAddress - sygmaAdapter, + adapter, // uint8 len(executionDataDepositor) uint8(20), // bytes executionDataDepositor address(this), // bytes executionDataDepositor + executionData - prepareDepositData(messageIds, hashes) + prepareDepositData(ids, hashes) + ); + (uint64 nonce, bytes memory handlerResponse) = BRIDGE.deposit{ value: msg.value }( + domainId, + resourceId, + depositData, + "" // feeData ); - return IBridge(_bridge).deposit{ value: msg.value }(destinationDomainID, _resourceID, depositData, feeData); + return bytes32(keccak256(abi.encode(nonce, handlerResponse))); } function slice(bytes calldata input, uint256 position) public pure returns (bytes memory) { diff --git a/packages/evm/contracts/adapters/Sygma/test/SygmaTestContracts.sol b/packages/evm/contracts/adapters/Sygma/test/SygmaTestContracts.sol deleted file mode 100644 index 4c1b7058..00000000 --- a/packages/evm/contracts/adapters/Sygma/test/SygmaTestContracts.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.17; - -import "../interfaces/IBridge.sol"; - -contract MockSygmaBridge { - error CallReverted(); - - event Deposit( - uint8 destinationDomainID, - bytes32 resourceID, - uint64 depositNonce, - address indexed user, - bytes data, - bytes handlerResponse - ); - - function deposit( - uint8 destinationDomainID, - bytes32 resourceID, - bytes calldata depositData, - bytes calldata feeData - ) external payable returns (uint64 depositNonce, bytes memory handlerResponse) { - emit Deposit(destinationDomainID, resourceID, 1, msg.sender, depositData, feeData); - - bool success = _executeProposal(resourceID, depositData); - - if (!success) revert CallReverted(); - - return (1, bytes("2")); - } - - function _executeProposal(bytes32 resourceID, bytes calldata data) internal returns (bool success) { - uint16 lenExecuteFuncSignature; - bytes4 executeFuncSignature; - uint8 lenExecuteContractAddress; - address executeContractAddress; - uint8 lenExecutionDataDepositor; - address executionDataDepositor; - bytes memory executionData; - - lenExecuteFuncSignature = uint16(bytes2(data[32:34])); - executeFuncSignature = bytes4(data[34:34 + lenExecuteFuncSignature]); - lenExecuteContractAddress = uint8(bytes1(data[34 + lenExecuteFuncSignature:35 + lenExecuteFuncSignature])); - executeContractAddress = address( - uint160( - bytes20(data[35 + lenExecuteFuncSignature:35 + lenExecuteFuncSignature + lenExecuteContractAddress]) - ) - ); - lenExecutionDataDepositor = uint8( - bytes1( - data[35 + lenExecuteFuncSignature + lenExecuteContractAddress:36 + - lenExecuteFuncSignature + - lenExecuteContractAddress] - ) - ); - executionDataDepositor = address( - uint160( - bytes20( - data[36 + lenExecuteFuncSignature + lenExecuteContractAddress:36 + - lenExecuteFuncSignature + - lenExecuteContractAddress + - lenExecutionDataDepositor] - ) - ) - ); - executionData = bytes( - data[36 + lenExecuteFuncSignature + lenExecuteContractAddress + lenExecutionDataDepositor:] - ); - - bytes memory callData = abi.encodePacked( - executeFuncSignature, - abi.encode(executionDataDepositor), - executionData - ); - (success, ) = executeContractAddress.call(callData); - } -}