diff --git a/bolt-contracts/config/holesky/deployments.json b/bolt-contracts/config/holesky/deployments.json index 18e40f615..8b028dbec 100644 --- a/bolt-contracts/config/holesky/deployments.json +++ b/bolt-contracts/config/holesky/deployments.json @@ -1,6 +1,7 @@ { "bolt": { - "validators": "0x47D2DC1DE1eFEFA5e6944402f2eda3981D36a9c8" + "validators": "0x47D2DC1DE1eFEFA5e6944402f2eda3981D36a9c8", + "manager": "0x440202829b493F9FF43E730EB5e8379EEa3678CF" }, "symbiotic": { "network": "0xb017002D8024d8c8870A5CECeFCc63887650D2a4", @@ -28,4 +29,4 @@ "0xaccc5A86732BE85b5012e8614AF237801636F8e5" ] } -} \ No newline at end of file +} diff --git a/bolt-contracts/config/holesky/operator.json b/bolt-contracts/config/holesky/operator.json index 0b6373c92..7e1d43c10 100644 --- a/bolt-contracts/config/holesky/operator.json +++ b/bolt-contracts/config/holesky/operator.json @@ -1,5 +1,6 @@ { - "rpc": "localhost:50051", - "salt": "0x000000000000000abc0000000000000000000000000000000000000000000000", - "expiry": null -} \ No newline at end of file + "rpc": ":", + "salt": "0x0000000000000000000_salt_value_0000000000000000000000000000000000", + "expiry": "0x00000000000000000_expiry_value_0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +} + diff --git a/bolt-contracts/config/holesky/operators/eigenlayer/depositIntoStrategy.json b/bolt-contracts/config/holesky/operators/eigenlayer/depositIntoStrategy.json new file mode 100644 index 000000000..f500598aa --- /dev/null +++ b/bolt-contracts/config/holesky/operators/eigenlayer/depositIntoStrategy.json @@ -0,0 +1,5 @@ +{ + "strategy": "", + "token": "", + "amount": "" +} diff --git a/bolt-contracts/script/holesky/operators/RegisterEigenLayerOperator.s.sol b/bolt-contracts/script/holesky/operators/RegisterEigenLayerOperator.s.sol index 3acbe2d81..049ceb699 100644 --- a/bolt-contracts/script/holesky/operators/RegisterEigenLayerOperator.s.sol +++ b/bolt-contracts/script/holesky/operators/RegisterEigenLayerOperator.s.sol @@ -4,13 +4,14 @@ pragma solidity 0.8.25; import {Script, console} from "forge-std/Script.sol"; import {IAVSDirectory} from "@eigenlayer/src/contracts/interfaces/IAVSDirectory.sol"; +import {IDelegationManager} from "@eigenlayer/src/contracts/interfaces/IDelegationManager.sol"; +import {IStrategyManager} from "@eigenlayer/src/contracts/interfaces/IStrategyManager.sol"; +import {IStrategy, IERC20} from "@eigenlayer/src/contracts/interfaces/IStrategy.sol"; import {ISignatureUtils} from "@eigenlayer/src/contracts/interfaces/ISignatureUtils.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - import {BoltEigenLayerMiddlewareV1} from "../../../src/contracts/BoltEigenLayerMiddlewareV1.sol"; import {IBoltMiddlewareV1} from "../../../src/interfaces/IBoltMiddlewareV1.sol"; +import {IBoltManagerV1} from "../../../src/interfaces/IBoltManagerV1.sol"; contract RegisterEigenLayerOperator is Script { struct OperatorConfig { @@ -19,9 +20,27 @@ contract RegisterEigenLayerOperator is Script { uint256 expiry; } - function run() public { + function S01_depositIntoStrategy() public { uint256 operatorSk = vm.envUint("OPERATOR_SK"); + IStrategyManager strategyManager = _readStrategyManager(); + + string memory json = vm.readFile("config/holesky/operators/eigenlayer/depositIntoStrategy.json"); + + IStrategy strategy = IStrategy(vm.parseJsonAddress(json, ".strategy")); + IERC20 token = IERC20(vm.parseJsonAddress(json, ".token")); + uint256 amount = vm.parseJsonUint(json, ".amount"); + + vm.startBroadcast(operatorSk); + // Allowance must be set before depositing + token.approve(address(strategy), amount); + strategyManager.depositIntoStrategy(strategy, token, amount); + console.log("Successfully run StrategyManager.depositIntoStrategy"); + vm.stopBroadcast(); + } + + function S02_registerIntoBoltAVS() public { + uint256 operatorSk = vm.envUint("OPERATOR_SK"); address operator = vm.addr(operatorSk); BoltEigenLayerMiddlewareV1 middleware = _readMiddleware(); @@ -53,6 +72,16 @@ contract RegisterEigenLayerOperator is Script { vm.stopBroadcast(); } + function S03_checkOperatorRegistration() public view { + address operatorPublicKey = vm.envAddress("OPERATOR_PK"); + console.log("Checking operator registration for address", operatorPublicKey); + + IBoltManagerV1 boltManager = _readBoltManager(); + bool isRegistered = boltManager.isOperator(operatorPublicKey); + console.log("Operator is registered:", isRegistered); + require(isRegistered, "Operator is not registered"); + } + function _readMiddleware() public view returns (BoltEigenLayerMiddlewareV1) { string memory root = vm.projectRoot(); string memory path = string.concat(root, "/config/holesky/deployments.json"); @@ -69,6 +98,28 @@ contract RegisterEigenLayerOperator is Script { return IAVSDirectory(vm.parseJsonAddress(json, ".eigenLayer.avsDirectory")); } + function _readDelegationManager() public view returns (IDelegationManager) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/config/holesky/deployments.json"); + string memory json = vm.readFile(path); + + return IDelegationManager(vm.parseJsonAddress(json, ".eigenLayer.delegationManager")); + } + + function _readStrategyManager() public view returns (IStrategyManager) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/config/holesky/deployments.json"); + string memory json = vm.readFile(path); + return IStrategyManager(vm.parseJsonAddress(json, ".eigenLayer.strategyManager")); + } + + function _readBoltManager() public view returns (IBoltManagerV1) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/config/holesky/deployments.json"); + string memory json = vm.readFile(path); + return IBoltManagerV1(vm.parseJsonAddress(json, ".bolt.manager")); + } + function _readConfig( string memory path ) public view returns (OperatorConfig memory) { diff --git a/testnets/holesky/README.md b/testnets/holesky/README.md index 4a6f6df60..cfdf062da 100644 --- a/testnets/holesky/README.md +++ b/testnets/holesky/README.md @@ -524,31 +524,66 @@ If all goes well, your Symbiotic operator was registered into Bolt. > The supported strategies can be found in > [`deployments.json`](../../bolt-contracts/config/holesky/deployments.json). -The Operator will be represented by an Ethereum address that needs to follow the -standard procedure outlined in the [EigenLayer -documentation](https://docs.eigenlayer.xyz/) to opt into EigenLayer. Let's go -through the steps: +If you're not registered as an operator in EigenLayer yet, you need to do so by +following [the official +guide](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-introduction). +This requires installing the EigenLayer CLI and opt into the protocol by +registering via the +[`DelegationManager.registerAsOperator`](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation) +function. + +After that you need to deposit into a supported EigenLayer +strategy using +[`StrategyManager.depositIntoStrategy`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/StrategyManager.sol#L303-L322). +This will add the deposit into the collateral of the operator so that Bolt can +read it. Note that you need to deposit a minimum of `1 ether` of the strategies +underlying token in order to opt in. + +We've provided a script to facilitate the procedure. If you want to use it, +please set the operator private key to an `OPERATOR_SK` environment variable. + +First, you need to first configure the deposit details in this JSON +file: -1. As an Operator, you register into EigenLayer using - [`DelegationManager.registerAsOperator`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/DelegationManager.sol#L107-L119). +```bash +$EDITOR ./config/holesky/operators/eigenlayer/depositIntoStrategy.json +``` + +Then you can run the following Forge script: -2. You can then use the same account to deposit into a supported EigenLayer - strategy using - [`StrategyManager.depositIntoStrategy`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/testnet-holesky/src/contracts/core/StrategyManager.sol#L303-L322). - This will add the deposit into the collateral of the operator so that Bolt can - read it. Note that you need to deposit a minimum of `1 ether` of the strategies - underlying token in order to opt in. +```bash +forge script script/holesky/operators/RegisterEigenLayerOperator.s.sol \ + --sig "S01_depositIntoStrategy()" \ + --rpc-url $HOLESKY_RPC \ + -vvvv \ + --broadcast +``` **Internal Steps** -Set the operator private key to an `OPERATOR_SK` environment variable, and then -run the following Forge script from the `bolt-contracts` directory: +After having deposited collateral into a strategy you need to register into the +Bolt AVS. We've provided a script to facilitate the procedure. If you want to +use it, please set the operator private key to an `OPERATOR_SK` environment +variable, and then run the following Forge script from the `bolt-contracts` +directory: ```bash -forge script script/holesky/operators/RegisterEigenLayerOperator.s.sol --rpc-url $HOLESKY_RPC -vvvv --broadcast +forge script script/holesky/operators/RegisterEigenLayerOperator.s.sol \ + --sig "S02_registerIntoBoltAVS" \ + --rpc-url $HOLESKY_RPC \ + -vvvv \ + --broadcast ``` -If all goes well, your EigenLayer operator was registered into Bolt. +To check if your operator is correctly registered, set the operator public key +in the `OPERATOR_PK` environment variable and run the following script: + +```bash +forge script script/holesky/operators/RegisterEigenLayerOperator.s.sol \ + --sig "S03_checkOperatorRegistration" \ + --rpc-url $HOLESKY_RPC \ + -vvvv +``` # Reference @@ -559,13 +594,14 @@ sidecar. You can see them in your terminal by running the Bolt sidecar binary with the `--help` flag: ``` + Command-line options for the Bolt sidecar Usage: bolt-sidecar [OPTIONS] --validator-indexes --engine-jwt-hex --fee-recipient --builder-private-key --commitment-private-key <--constraint-private-key |--commit-boost-signer-url |--keystore-password |--keystore-secrets-path > Options: - --port - Port to listen on for incoming JSON-RPC requests of the Commitments API. This port should be open on your firewall in order to receive external requests! +--port +Port to listen on for incoming JSON-RPC requests of the Commitments API. This port should be open on your firewall in order to receive external requests! [env: BOLT_SIDECAR_PORT=] [default: 8017] @@ -709,8 +745,9 @@ Options: --disable-metrics [env: BOLT_SIDECAR_DISABLE_METRICS=] - -h, --help - Print help (see a summary with '-h') +-h, --help +Print help (see a summary with '-h') + ``` ## Delegations and signing options for Native and Docker Compose Mode