From 1ad8c96cfc1e1a07db951aa4d6b54d8e83e85191 Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 1 Oct 2024 16:06:54 -0400 Subject: [PATCH 1/5] fix: use signing key --- contracts/src/HelloWorldServiceManager.sol | 28 ++++++--------------- contracts/src/IHelloWorldServiceManager.sol | 4 --- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/contracts/src/HelloWorldServiceManager.sol b/contracts/src/HelloWorldServiceManager.sol index d9360905..28e75221 100644 --- a/contracts/src/HelloWorldServiceManager.sol +++ b/contracts/src/HelloWorldServiceManager.sol @@ -7,6 +7,7 @@ import {ECDSAStakeRegistry} from "@eigenlayer-middleware/src/unaudited/ECDSAStak import {IServiceManager} from "@eigenlayer-middleware/src/interfaces/IServiceManager.sol"; import {ECDSAUpgradeable} from "@openzeppelin-upgrades/contracts/utils/cryptography/ECDSAUpgradeable.sol"; +import {IERC1271Upgradeable} from "@openzeppelin-upgrades/contracts/interfaces/IERC1271Upgradeable.sol"; import {IHelloWorldServiceManager} from "./IHelloWorldServiceManager.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; @@ -71,20 +72,12 @@ contract HelloWorldServiceManager is ECDSAServiceManagerBase, IHelloWorldService Task calldata task, uint32 referenceTaskIndex, bytes calldata signature - ) external onlyOperator { - - // TODO Temporarily disabling this until we add in staking & delegation to the Operator scripts. - /** require( - operatorHasMinimumWeight(msg.sender), - string(abi.encodePacked( - "Operator does not have match the weight requirements. ", - "Operator weight=", - Strings.toString(ECDSAStakeRegistry(stakeRegistry).getLastCheckpointOperatorWeight(msg.sender)), - ", Threshold weight=", - Strings.toString(ECDSAStakeRegistry(stakeRegistry).getLastCheckpointThresholdWeight()) - )) - ); - */ + ) external { + bytes32 taskDigest; + bytes4 magicValue = IERC1271Upgradeable.isValidSignature.selector; + if (!(magicValue == ECDSAStakeRegistry(stakeRegistry).isValidSignature(taskDigest,signature))){ + revert(); + } // check that the task is valid, hasn't been responsed yet, and is being responded in time require( @@ -111,11 +104,4 @@ contract HelloWorldServiceManager is ECDSAServiceManagerBase, IHelloWorldService // emitting event emit TaskResponded(referenceTaskIndex, task, msg.sender); } - - function operatorHasMinimumWeight( - address operator - ) public view returns (bool) { - return ECDSAStakeRegistry(stakeRegistry).getLastCheckpointOperatorWeight(operator) - >= ECDSAStakeRegistry(stakeRegistry).getLastCheckpointThresholdWeight(); - } } diff --git a/contracts/src/IHelloWorldServiceManager.sol b/contracts/src/IHelloWorldServiceManager.sol index 2119de68..e674fce6 100644 --- a/contracts/src/IHelloWorldServiceManager.sol +++ b/contracts/src/IHelloWorldServiceManager.sol @@ -22,10 +22,6 @@ interface IHelloWorldServiceManager { uint32 taskIndex ) external view returns (bytes memory); - function operatorHasMinimumWeight( - address operator - ) external view returns (bool); - function createNewTask( string memory name ) external returns (Task memory); From 367d8c4ccc3317f65f8ece7a6b4f13081a968d23 Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 1 Oct 2024 17:19:13 -0400 Subject: [PATCH 2/5] test: hello world signing key --- contracts/src/HelloWorldServiceManager.sol | 17 ++++---------- contracts/test/HelloWorldServiceManager.t.sol | 23 +++++++++++++++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/contracts/src/HelloWorldServiceManager.sol b/contracts/src/HelloWorldServiceManager.sol index 28e75221..145e0a5e 100644 --- a/contracts/src/HelloWorldServiceManager.sol +++ b/contracts/src/HelloWorldServiceManager.sol @@ -71,14 +71,8 @@ contract HelloWorldServiceManager is ECDSAServiceManagerBase, IHelloWorldService function respondToTask( Task calldata task, uint32 referenceTaskIndex, - bytes calldata signature + bytes memory signature ) external { - bytes32 taskDigest; - bytes4 magicValue = IERC1271Upgradeable.isValidSignature.selector; - if (!(magicValue == ECDSAStakeRegistry(stakeRegistry).isValidSignature(taskDigest,signature))){ - revert(); - } - // check that the task is valid, hasn't been responsed yet, and is being responded in time require( keccak256(abi.encode(task)) == allTaskHashes[referenceTaskIndex], @@ -92,11 +86,10 @@ contract HelloWorldServiceManager is ECDSAServiceManagerBase, IHelloWorldService // The message that was signed bytes32 messageHash = keccak256(abi.encodePacked("Hello, ", task.name)); bytes32 ethSignedMessageHash = messageHash.toEthSignedMessageHash(); - - // Recover the signer address from the signature - address signer = ethSignedMessageHash.recover(signature); - - require(signer == msg.sender, "Message signer is not operator"); + bytes4 magicValue = IERC1271Upgradeable.isValidSignature.selector; + if (!(magicValue == ECDSAStakeRegistry(stakeRegistry).isValidSignature(ethSignedMessageHash,signature))){ + revert(); + } // updating the storage with task responses allTaskResponses[msg.sender][referenceTaskIndex] = signature; diff --git a/contracts/test/HelloWorldServiceManager.t.sol b/contracts/test/HelloWorldServiceManager.t.sol index 55034e95..f7ad8b55 100644 --- a/contracts/test/HelloWorldServiceManager.t.sol +++ b/contracts/test/HelloWorldServiceManager.t.sol @@ -259,9 +259,15 @@ contract HelloWorldTaskManagerSetup is Test { bytes memory signature = signWithSigningKey(operator, messageHash); - vm.prank(operator.key.addr); + address[] memory operators = new address[](1); + operators[0]=operator.key.addr; + bytes[] memory signatures = new bytes[](1); + signatures[0]= signature; + + bytes memory signedTask = abi.encode(operators, signatures, uint32(block.number)); + IHelloWorldServiceManager(helloWorldDeployment.helloWorldServiceManager).respondToTask( - task, referenceTaskIndex, signature + task, referenceTaskIndex, signedTask ); } } @@ -415,9 +421,16 @@ contract RespondToTask is HelloWorldTaskManagerSetup { bytes32 messageHash = keccak256(abi.encodePacked("Hello, ", taskName)); bytes32 ethSignedMessageHash = messageHash.toEthSignedMessageHash(); - bytes memory signature = signWithOperatorKey(operators[0], ethSignedMessageHash); // TODO: Use signing key after changes to service manager + bytes memory signature = signWithSigningKey(operators[0], ethSignedMessageHash); // TODO: Use signing key after changes to service manager + + address[] memory operatorsMem = new address[](1); + operatorsMem[0]=operators[0].key.addr; + bytes[] memory signatures = new bytes[](1); + signatures[0]= signature; + + bytes memory signedTask = abi.encode(operatorsMem, signatures, uint32(block.number)); - vm.prank(operators[0].key.addr); - sm.respondToTask(newTask, taskIndex, signature); + vm.roll(block.number+1); + sm.respondToTask(newTask, taskIndex, signedTask); } } From 87298cc8157d5c05aa9e59b59991b4901e611f99 Mon Sep 17 00:00:00 2001 From: Wes Floyd Date: Thu, 3 Oct 2024 09:48:21 -0400 Subject: [PATCH 3/5] initial commit (#78) --- README.md | 2 +- abis/HelloWorldServiceManager.json | 39 +++++++++++++++--------------- package.json | 2 +- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 59532026..01fe5a07 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ For help and support deploying and modifying this repo for your AVS, please: 1. Open a ticket via the intercom link at [support.eigenlayer.xyz](https://support.eigenlayer.xyz). 2. Include the necessary troubleshooting information for your environment: * Local anvil testing: - * Recompile the contracts with the `--revert-strings debug` flag. Deploy the contracts again and retest. + * Redeploy your local test using `--revert-strings debug` flag via the following commands and retest: `npm run deploy:core-debug && npm run deploy:hello-world-debug` * Include the full stacktrace from your error as a .txt file attachment. * Create a minimal repo that demonstrates the behavior (fork or otherwise) * Steps require to reproduce issue (compile and cause the error) diff --git a/abis/HelloWorldServiceManager.json b/abis/HelloWorldServiceManager.json index 61d70f6f..622cf6f6 100644 --- a/abis/HelloWorldServiceManager.json +++ b/abis/HelloWorldServiceManager.json @@ -138,7 +138,25 @@ "internalType": "string" } ], - "outputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IHelloWorldServiceManager.Task", + "components": [ + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "taskCreatedBlock", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ], "stateMutability": "nonpayable" }, { @@ -199,25 +217,6 @@ ], "stateMutability": "view" }, - { - "type": "function", - "name": "operatorHasMinimumWeight", - "inputs": [ - { - "name": "operator", - "type": "address", - "internalType": "address" - } - ], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, { "type": "function", "name": "owner", diff --git a/package.json b/package.json index 0b12c35d..a2d0f39d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "deploy:core-debug": "cd contracts && forge script script/DeployEigenLayerCore.s.sol --rpc-url http://localhost:8545 --broadcast --revert-strings debug", "deploy:hello-world-debug": "cd contracts && forge script script/HelloWorldDeployer.s.sol --rpc-url http://localhost:8545 --broadcast --revert-strings debug", "build": "cd contracts && forge build", - "extract:abis": "npm run build && node utils/abis.js" + "extract:abis": "node utils/abis.js" }, "dependencies": { "dotenv": "^10.0.0", From f771dd48b9f45ae108f554223196c7c82bcacba6 Mon Sep 17 00:00:00 2001 From: steven Date: Thu, 3 Oct 2024 11:17:04 -0400 Subject: [PATCH 4/5] fix: use correct signature structure --- operator/index.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/operator/index.ts b/operator/index.ts index 84fe120c..fa6441e5 100644 --- a/operator/index.ts +++ b/operator/index.ts @@ -46,14 +46,19 @@ const signAndRespondToTask = async (taskIndex: number, taskCreatedBlock: number, const messageBytes = ethers.getBytes(messageHash); const signature = await wallet.signMessage(messageBytes); - console.log( - `Signing and responding to task ${taskIndex}` - ) + console.log(`Signing and responding to task ${taskIndex}`); + + const operators = [await wallet.getAddress()]; + const signatures = [signature]; + const signedTask = ethers.AbiCoder.defaultAbiCoder().encode( + ["address[]", "bytes[]", "uint32"], + [operators, signatures, ethers.toBigInt(await provider.getBlockNumber())] + ); const tx = await helloWorldServiceManager.respondToTask( { name: taskName, taskCreatedBlock: taskCreatedBlock }, taskIndex, - signature + signedTask ); await tx.wait(); console.log(`Responded to task.`); From 481599d0b40d70d363afc78fd08efb7070c79a3b Mon Sep 17 00:00:00 2001 From: steven Date: Thu, 3 Oct 2024 11:17:19 -0400 Subject: [PATCH 5/5] fix: workaround for current state of hello world --- contracts/script/utils/HelloWorldDeploymentLib.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/script/utils/HelloWorldDeploymentLib.sol b/contracts/script/utils/HelloWorldDeploymentLib.sol index 0b77c14a..98988fa9 100644 --- a/contracts/script/utils/HelloWorldDeploymentLib.sol +++ b/contracts/script/utils/HelloWorldDeploymentLib.sol @@ -48,7 +48,7 @@ library HelloWorldDeploymentLib { ); // Upgrade contracts bytes memory upgradeCall = abi.encodeCall( - ECDSAStakeRegistry.initialize, (result.helloWorldServiceManager, 1, quorum) + ECDSAStakeRegistry.initialize, (result.helloWorldServiceManager, 0, quorum) ); UpgradeableProxyLib.upgradeAndCall(result.stakeRegistry, stakeRegistryImpl, upgradeCall); UpgradeableProxyLib.upgrade(result.helloWorldServiceManager, helloWorldServiceManagerImpl);