From 0f705e311ba1d3d69cbefc67ba18f63d89138547 Mon Sep 17 00:00:00 2001 From: noel Date: Mon, 14 Oct 2024 15:08:20 +0900 Subject: [PATCH] feat: IncredibleSquaringTemplate --- .../IIncredibleSquaringTaskManager.sol | 71 +++++++++++++++++++ src/templates/IncredibleSquaringTemplate.sol | 43 +++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/interfaces/IIncredibleSquaringTaskManager.sol create mode 100644 src/templates/IncredibleSquaringTemplate.sol diff --git a/src/interfaces/IIncredibleSquaringTaskManager.sol b/src/interfaces/IIncredibleSquaringTaskManager.sol new file mode 100644 index 0000000..5b890b4 --- /dev/null +++ b/src/interfaces/IIncredibleSquaringTaskManager.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {BN254} from "eigenlayer-middleware/src/libraries/BN254.sol"; + +interface IIncredibleSquaringTaskManager { + // EVENTS + event NewTaskCreated(uint32 indexed taskIndex, Task task); + + event TaskResponded(TaskResponse taskResponse, TaskResponseMetadata taskResponseMetadata); + + event TaskCompleted(uint32 indexed taskIndex); + + event TaskChallengedSuccessfully(uint32 indexed taskIndex, address indexed challenger); + + event TaskChallengedUnsuccessfully(uint32 indexed taskIndex, address indexed challenger); + + event AggregatorUpdated(address indexed oldAggregator, address indexed newAggregator); + + event GeneratorUpdated(address indexed oldGenerator, address indexed newGenerator); + + // STRUCTS + struct Task { + uint256 numberToBeSquared; + uint32 taskCreatedBlock; + // task submitter decides on the criteria for a task to be completed + // note that this does not mean the task was "correctly" answered (i.e. the number was squared correctly) + // this is for the challenge logic to verify + // task is completed (and contract will accept its TaskResponse) when each quorumNumbers specified here + // are signed by at least quorumThresholdPercentage of the operators + // note that we set the quorumThresholdPercentage to be the same for all quorumNumbers, but this could be changed + bytes quorumNumbers; + uint32 quorumThresholdPercentage; + } + + // Task response is hashed and signed by operators. + // these signatures are aggregated and sent to the contract as response. + struct TaskResponse { + // Can be obtained by the operator from the event NewTaskCreated. + uint32 referenceTaskIndex; + // This is just the response that the operator has to compute by itself. + uint256 numberSquared; + } + + // Extra information related to taskResponse, which is filled inside the contract. + // It thus cannot be signed by operators, so we keep it in a separate struct than TaskResponse + // This metadata is needed by the challenger, so we emit it in the TaskResponded event + struct TaskResponseMetadata { + uint32 taskResponsedBlock; + bytes32 hashOfNonSigners; + } + + // FUNCTIONS + // NOTE: this function creates new task. + function createNewTask(uint256 numberToBeSquared, uint32 quorumThresholdPercentage, bytes calldata quorumNumbers) + external; + + /// @notice Returns the current 'taskNumber' for the middleware + function taskNumber() external view returns (uint32); + + // // NOTE: this function raises challenge to existing tasks. + function raiseAndResolveChallenge( + Task calldata task, + TaskResponse calldata taskResponse, + TaskResponseMetadata calldata taskResponseMetadata, + BN254.G1Point[] memory pubkeysOfNonSigningOperators + ) external; + + /// @notice Returns the TASK_RESPONSE_WINDOW_BLOCK + function getTaskResponseWindowBlock() external view returns (uint32); +} diff --git a/src/templates/IncredibleSquaringTemplate.sol b/src/templates/IncredibleSquaringTemplate.sol new file mode 100644 index 0000000..b641bb2 --- /dev/null +++ b/src/templates/IncredibleSquaringTemplate.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +import {ServiceManagerBase} from "eigenlayer-middleware/src/ServiceManagerBase.sol"; +import {IIncredibleSquaringTaskManager} from "../interfaces/IIncredibleSquaringTaskManager.sol"; +import {IAVSDirectory} from "eigenlayer-core/contracts/interfaces/IAVSDirectory.sol"; +import {IRegistryCoordinator} from "eigenlayer-middleware/src/interfaces/IRegistryCoordinator.sol"; +import {IStakeRegistry} from "eigenlayer-middleware/src/interfaces/IStakeRegistry.sol"; +import {IRewardsCoordinator} from "eigenlayer-core/contracts/interfaces/IRewardsCoordinator.sol"; + +/** + * @title Primary entrypoint for procuring services from IncredibleSquaring. + * @author Layr Labs, Inc. + */ +contract IncredibleSquaringTemplate is ServiceManagerBase { + IIncredibleSquaringTaskManager public immutable incredibleSquaringTaskManager; + + /// @notice when applied to a function, ensures that the function is only callable by the `registryCoordinator`. + modifier onlyIncredibleSquaringTaskManager() { + require( + msg.sender == address(incredibleSquaringTaskManager), + "onlyIncredibleSquaringTaskManager: not from credible squaring task manager" + ); + _; + } + + constructor( + IAVSDirectory __avsDirectory, + IRewardsCoordinator __rewardsCoordinator, + IRegistryCoordinator __registryCoordinator, + IStakeRegistry __stakeRegistry, + IIncredibleSquaringTaskManager __incredibleSquaringTaskManager + ) ServiceManagerBase(__avsDirectory, __rewardsCoordinator, __registryCoordinator, __stakeRegistry) { + incredibleSquaringTaskManager = __incredibleSquaringTaskManager; + } + + /// @notice Called in the event of challenge resolution, in order to forward a call to the Slasher, which 'freezes' the `operator`. + /// @dev The Slasher contract is under active development and its interface expected to change. + /// We recommend writing slashing logic without integrating with the Slasher at this point in time. + function freezeOperator(address operatorAddr) external onlyIncredibleSquaringTaskManager { + // slasher.freezeOperator(operatorAddr); + } +}