diff --git a/bolt-contracts/config/holesky/deployments.json b/bolt-contracts/config/holesky/deployments.json index 94d9961d..b8106491 100644 --- a/bolt-contracts/config/holesky/deployments.json +++ b/bolt-contracts/config/holesky/deployments.json @@ -1,16 +1,17 @@ { "symbiotic": { - "network": "0xAdFC41729fF447974cE27DdFa358A0f2096c3F39", + "network": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "operatorRegistry": "0xAdFC41729fF447974cE27DdFa358A0f2096c3F39", "networkOptInService": "0xF5AFc9FA3Ca63a07E529DDbB6eae55C665cCa83E", "vaultFactory": "0x5035c15F3cb4364CF2cF35ca53E3d6FC45FC8899", "networkRegistry": "0xac5acD8A105C8305fb980734a5AD920b5920106A", "networkMiddlewareService": "0x683F470440964E353b389391CdDDf8df381C282f", - "networkMiddleware": "" + "networkMiddleware": "0x61B626A562d39439Ab60fCbF19678Dac036D1209" }, "eigenLayer": { "avsDirectory": "0x055733000064333CaDDbC92763c58BF0192fFeBf", "delegationManager": "0xA44151489861Fe9e3055d95adC98FbD462B948e7", - "strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6" + "strategyManager": "0xdfB5f6CE42aAA7830E94ECFCcAd411beF4d4D5b6", + "networkMiddleware": "0x2575d6D30767149c99589cce743656fA3866ca2e" } } \ No newline at end of file diff --git a/bolt-contracts/docs/avs.json b/bolt-contracts/docs/avs.json new file mode 100644 index 00000000..8461c651 --- /dev/null +++ b/bolt-contracts/docs/avs.json @@ -0,0 +1,7 @@ +{ + "name": "Bolt Protocol", + "website": "https://boltprotocol.xyz", + "description": "Bolt Protocol enables proposers to make credible commitments about their blocks.", + "logo": "http://boltprotocol.xyz/wp-content/uploads/2024/07/Bolt-Logo.png", + "twitter": "https://twitter.com/boltprotocol_" +} \ No newline at end of file diff --git a/bolt-contracts/docs/deploying.md b/bolt-contracts/docs/deploying.md index 8ab60718..740e73fc 100644 --- a/bolt-contracts/docs/deploying.md +++ b/bolt-contracts/docs/deploying.md @@ -25,22 +25,33 @@ anvil --fork-url $HOLESKY_RPC > [!IMPORTANT] > Run everything on the local Anvil fork first! This requires just replacing the $HOLESKY_RPC with the $ANVIL_RPC. +Also set your private keys as environment variables: + +```bash +export NETWORK_PRIVATE_KEY=0x... +export ADMIN_PRIVATE_KEY=0x... +``` + ### Pre-deployment Register a Symbiotic network for Bolt with the Symbiotic `NetworkRegistry`. The private key with which the script is run will determine the network address. This private key will also need to be used later. ```bash -forge script script/holesky/SymbioticSetup.s.sol $HOLESKY_RPC --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerNetwork +forge script script/holesky/helpers/Symbiotic.s.sol $HOLESKY_RPC --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerNetwork ``` +Make sure `deployments.json` contains the correct address for the Symbiotic network. + ### Deployment Run the following script to deploy Bolt V1: ```bash -forge script script/holesky/Deploy.s.sol --rpc-url $HOLESKY_RPC --private-key $PRIVATE_KEY --broadcast -vvvv +forge script script/holesky/Deploy.s.sol --rpc-url $HOLESKY_RPC --private-key $ADMIN_PRIVATE_KEY --broadcast -vvvv ``` -This will deploy all the contracts. Now update `deployments.json` with the Symbiotic middleware, because we'll need to register it +This will deploy all the contracts. The address corresponding to the private key will be the system admin. + +Now update `deployments.json` with the Symbiotic and EigenLayer middleware contracts, because we'll need to register it in the next step. ### Post-deployment @@ -49,5 +60,12 @@ Register the deployed `SymbioticMiddleware` with the Symbiotic `NetworkMiddlewar to be run with the network private key! ```bash -forge script script/holesky/SymbioticSetup.s.sol $HOLESKY_RPC --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerMiddleware -``` \ No newline at end of file +forge script script/holesky/helpers/Symbiotic.s.sol --rpc-url $HOLESKY_RPC --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerMiddleware +``` + +Also set the AVS metadata in the EigenLayer AVS Directory, needs to be run with the **admin private key** used at deployment. + +```bash +forge script script/holesky/helpers/RegisterAVS.s.sol --rpc-url $HOLESKY_RPC --private-key $ADMIN_PRIVATE_KEY --broadcast -vvvv +``` + diff --git a/bolt-contracts/script/holesky/Deploy.s.sol b/bolt-contracts/script/holesky/Deploy.s.sol index f63ac413..375946a6 100644 --- a/bolt-contracts/script/holesky/Deploy.s.sol +++ b/bolt-contracts/script/holesky/Deploy.s.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.25; import {Script, console} from "forge-std/Script.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {Upgrades} from "@openzeppelin-foundry-upgrades/src/Upgrades.sol"; +import {Upgrades, Options} from "@openzeppelin-foundry-upgrades/src/Upgrades.sol"; import {BoltParametersV1} from "../../src/contracts/BoltParametersV1.sol"; import {BoltValidatorsV1} from "../../src/contracts/BoltValidatorsV1.sol"; @@ -16,16 +16,20 @@ import {BoltConfig} from "../../src/lib/Config.sol"; /// @notice Script to deploy the Bolt contracts. contract DeployBolt is Script { function run() public { - vm.startBroadcast(); - // The admin address will be authorized to call the adminOnly functions // on the contract implementations, as well as upgrade the contracts. - address admin = 0xB5d6600D2B4C18E828C5E345Ed094F56d36c3c2F; + address admin = msg.sender; console.log("Deploying with admin", admin); BoltConfig.Parameters memory config = readParameters(); BoltConfig.Deployments memory deployments = readDeployments(); + vm.startBroadcast(admin); + + // TODO: Fix safe deploy, currently failing with `ASTDereferencerError` from openzeppelin + Options memory opts; + opts.unsafeSkipAllChecks = true; + bytes memory initParameters = abi.encodeCall( BoltParametersV1.initialize, ( @@ -42,17 +46,17 @@ contract DeployBolt is Script { config.minimumOperatorStake ) ); - address parametersProxy = Upgrades.deployUUPSProxy("BoltParametersV1.sol", initParameters); + address parametersProxy = Upgrades.deployUUPSProxy("BoltParametersV1.sol", initParameters, opts); console.log("BoltParametersV1 proxy deployed at", parametersProxy); // Generate the `initialize` call data for the contract. bytes memory initValidators = abi.encodeCall(BoltValidatorsV1.initialize, (admin, parametersProxy)); // Deploy the UUPSProxy through the `Upgrades` library, with the correct `initialize` call data. - address validatorsProxy = Upgrades.deployUUPSProxy("BoltValidatorsV1.sol", initValidators); + address validatorsProxy = Upgrades.deployUUPSProxy("BoltValidatorsV1.sol", initValidators, opts); console.log("BoltValidatorsV1 proxy deployed at", validatorsProxy); bytes memory initManager = abi.encodeCall(BoltManagerV1.initialize, (admin, parametersProxy, validatorsProxy)); - address managerProxy = Upgrades.deployUUPSProxy("BoltManagerV1.sol", initManager); + address managerProxy = Upgrades.deployUUPSProxy("BoltManagerV1.sol", initManager, opts); console.log("BoltManagerV1 proxy deployed at", managerProxy); bytes memory initEigenLayerMiddleware = abi.encodeCall( @@ -67,7 +71,7 @@ contract DeployBolt is Script { ) ); address eigenLayerMiddlewareProxy = - Upgrades.deployUUPSProxy("BoltEigenLayerMiddlewareV1.sol", initEigenLayerMiddleware); + Upgrades.deployUUPSProxy("BoltEigenLayerMiddlewareV1.sol", initEigenLayerMiddleware, opts); console.log("BoltEigenLayerMiddlewareV1 proxy deployed at", eigenLayerMiddlewareProxy); bytes memory initSymbioticMiddleware = abi.encodeCall( @@ -83,9 +87,17 @@ contract DeployBolt is Script { ) ); address symbioticMiddlewareProxy = - Upgrades.deployUUPSProxy("BoltSymbioticMiddlewareV1.sol", initSymbioticMiddleware); + Upgrades.deployUUPSProxy("BoltSymbioticMiddlewareV1.sol", initSymbioticMiddleware, opts); console.log("BoltSymbioticMiddlewareV1 proxy deployed at", address(symbioticMiddlewareProxy)); + console.log("Core contracts deployed succesfully, whitelisting middleware contracts in BoltManager..."); + console.log("EigenLayer middleware:", address(eigenLayerMiddlewareProxy)); + console.log("Symbiotic middleware:", address(symbioticMiddlewareProxy)); + BoltManagerV1(managerProxy).addRestakingProtocol(address(eigenLayerMiddlewareProxy)); + BoltManagerV1(managerProxy).addRestakingProtocol(address(symbioticMiddlewareProxy)); + + console.log("Whitelisted middleware contracts in BoltManager, adding supported collateral..."); + vm.stopBroadcast(); } diff --git a/bolt-contracts/script/holesky/UnsafeDeploy.s.sol b/bolt-contracts/script/holesky/UnsafeDeploy.s.sol deleted file mode 100644 index 71a6f76d..00000000 --- a/bolt-contracts/script/holesky/UnsafeDeploy.s.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.25; - -import {Script, console} from "forge-std/Script.sol"; - -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {Upgrades, Options} from "@openzeppelin-foundry-upgrades/src/Upgrades.sol"; - -import {BoltParametersV1} from "../../src/contracts/BoltParametersV1.sol"; -import {BoltValidatorsV1} from "../../src/contracts/BoltValidatorsV1.sol"; -import {BoltManagerV1} from "../../src/contracts/BoltManagerV1.sol"; -import {BoltEigenLayerMiddlewareV1} from "../../src/contracts/BoltEigenLayerMiddlewareV1.sol"; -import {BoltSymbioticMiddlewareV1} from "../../src/contracts/BoltSymbioticMiddlewareV1.sol"; -import {BoltConfig} from "../../src/lib/Config.sol"; - -/// @notice Script to deploy the Bolt contracts. -contract UnsafeDeployBolt is Script { - function run() public { - vm.startBroadcast(); - - // The admin address will be authorized to call the adminOnly functions - // on the contract implementations, as well as upgrade the contracts. - address admin = 0xB5d6600D2B4C18E828C5E345Ed094F56d36c3c2F; - console.log("Deploying with admin", admin); - - BoltConfig.Parameters memory config = readParameters(); - BoltConfig.Deployments memory deployments = readDeployments(); - - Options memory opts; - opts.unsafeSkipAllChecks = true; - - bytes memory initParameters = abi.encodeCall( - BoltParametersV1.initialize, - ( - admin, - config.epochDuration, - config.slashingWindow, - config.maxChallengeDuration, - config.allowUnsafeRegistration, - config.challengeBond, - config.blockhashEvmLookback, - config.justificationDelay, - config.eth2GenesisTimestamp, - config.slotTime, - config.minimumOperatorStake - ) - ); - address parametersProxy = Upgrades.deployUUPSProxy("BoltParametersV1.sol", initParameters, opts); - console.log("BoltParametersV1 proxy deployed at", parametersProxy); - - // Generate the `initialize` call data for the contract. - bytes memory initValidators = abi.encodeCall(BoltValidatorsV1.initialize, (admin, parametersProxy)); - // Deploy the UUPSProxy through the `Upgrades` library, with the correct `initialize` call data. - address validatorsProxy = Upgrades.deployUUPSProxy("BoltValidatorsV1.sol", initValidators, opts); - console.log("BoltValidatorsV1 proxy deployed at", validatorsProxy); - - bytes memory initManager = abi.encodeCall(BoltManagerV1.initialize, (admin, parametersProxy, validatorsProxy)); - address managerProxy = Upgrades.deployUUPSProxy("BoltManagerV1.sol", initManager, opts); - console.log("BoltManagerV1 proxy deployed at", managerProxy); - - bytes memory initEigenLayerMiddleware = abi.encodeCall( - BoltEigenLayerMiddlewareV1.initialize, - ( - admin, - parametersProxy, - managerProxy, - deployments.eigenLayerAVSDirectory, - deployments.eigenLayerDelegationManager, - deployments.eigenLayerStrategyManager - ) - ); - address eigenLayerMiddlewareProxy = - Upgrades.deployUUPSProxy("BoltEigenLayerMiddlewareV1.sol", initEigenLayerMiddleware, opts); - console.log("BoltEigenLayerMiddlewareV1 proxy deployed at", eigenLayerMiddlewareProxy); - - bytes memory initSymbioticMiddleware = abi.encodeCall( - BoltSymbioticMiddlewareV1.initialize, - ( - admin, - parametersProxy, - managerProxy, - deployments.symbioticNetwork, - deployments.symbioticOperatorRegistry, - deployments.symbioticOperatorNetOptIn, - deployments.symbioticVaultFactory - ) - ); - address symbioticMiddlewareProxy = - Upgrades.deployUUPSProxy("BoltSymbioticMiddlewareV1.sol", initSymbioticMiddleware, opts); - console.log("BoltSymbioticMiddlewareV1 proxy deployed at", address(symbioticMiddlewareProxy)); - - vm.stopBroadcast(); - } - - function readParameters() public view returns (BoltConfig.Parameters memory) { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/config/holesky/parameters.json"); - string memory json = vm.readFile(path); - - uint48 epochDuration = uint48(vm.parseJsonUint(json, ".epochDuration")); - uint48 slashingWindow = uint48(vm.parseJsonUint(json, ".slashingWindow")); - uint48 maxChallengeDuration = uint48(vm.parseJsonUint(json, ".maxChallengeDuration")); - bool allowUnsafeRegistration = vm.parseJsonBool(json, ".allowUnsafeRegistration"); - uint256 challengeBond = vm.parseJsonUint(json, ".challengeBond"); - uint256 blockhashEvmLookback = vm.parseJsonUint(json, ".blockhashEvmLookback"); - uint256 justificationDelay = vm.parseJsonUint(json, ".justificationDelay"); - uint256 eth2GenesisTimestamp = vm.parseJsonUint(json, ".eth2GenesisTimestamp"); - uint256 slotTime = vm.parseJsonUint(json, ".slotTime"); - uint256 minimumOperatorStake = vm.parseJsonUint(json, ".minimumOperatorStake"); - - return BoltConfig.Parameters({ - epochDuration: epochDuration, - slashingWindow: slashingWindow, - maxChallengeDuration: maxChallengeDuration, - challengeBond: challengeBond, - blockhashEvmLookback: blockhashEvmLookback, - justificationDelay: justificationDelay, - eth2GenesisTimestamp: eth2GenesisTimestamp, - slotTime: slotTime, - allowUnsafeRegistration: allowUnsafeRegistration, - minimumOperatorStake: minimumOperatorStake - }); - } - - function readDeployments() public view returns (BoltConfig.Deployments memory) { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/config/holesky/deployments.json"); - string memory json = vm.readFile(path); - - return BoltConfig.Deployments({ - symbioticNetwork: vm.parseJsonAddress(json, ".symbiotic.network"), - symbioticOperatorRegistry: vm.parseJsonAddress(json, ".symbiotic.operatorRegistry"), - symbioticOperatorNetOptIn: vm.parseJsonAddress(json, ".symbiotic.networkOptInService"), - symbioticVaultFactory: vm.parseJsonAddress(json, ".symbiotic.vaultFactory"), - eigenLayerAVSDirectory: vm.parseJsonAddress(json, ".eigenLayer.avsDirectory"), - eigenLayerDelegationManager: vm.parseJsonAddress(json, ".eigenLayer.delegationManager"), - eigenLayerStrategyManager: vm.parseJsonAddress(json, ".eigenLayer.strategyManager") - }); - } -} diff --git a/bolt-contracts/script/holesky/helpers/RegisterAVS.s.sol b/bolt-contracts/script/holesky/helpers/RegisterAVS.s.sol new file mode 100644 index 00000000..ed994fbd --- /dev/null +++ b/bolt-contracts/script/holesky/helpers/RegisterAVS.s.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {Script, console} from "forge-std/Script.sol"; + +import {BoltEigenLayerMiddlewareV1} from "../../../src/contracts/BoltEigenLayerMiddlewareV1.sol"; + +contract RegisterAVS is Script { + function run() public { + address admin = msg.sender; + console.log("Running with admin address:", admin); + + BoltEigenLayerMiddlewareV1 middleware = BoltEigenLayerMiddlewareV1(readMiddleware()); + + string memory avsURI = "https://boltprotocol.xyz/avs.json"; + console.log("Setting AVS metadata URI to:", avsURI); + + vm.startBroadcast(admin); + + middleware.updateAVSMetadataURI(avsURI); + vm.stopBroadcast(); + } + + function readMiddleware() public view returns (address) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/config/holesky/deployments.json"); + string memory json = vm.readFile(path); + + return vm.parseJsonAddress(json, ".eigenLayer.networkMiddleware"); + } +} diff --git a/bolt-contracts/script/holesky/helpers/SymbioticSetup.s.sol b/bolt-contracts/script/holesky/helpers/Symbiotic.s.sol similarity index 56% rename from bolt-contracts/script/holesky/helpers/SymbioticSetup.s.sol rename to bolt-contracts/script/holesky/helpers/Symbiotic.s.sol index ca85f4ec..f6f50153 100644 --- a/bolt-contracts/script/holesky/helpers/SymbioticSetup.s.sol +++ b/bolt-contracts/script/holesky/helpers/Symbiotic.s.sol @@ -3,31 +3,42 @@ pragma solidity 0.8.25; import {Script, console} from "forge-std/Script.sol"; -import {BoltConfig} from "../../../src/lib/Config.sol"; - import {INetworkRegistry} from "@symbiotic/interfaces/INetworkRegistry.sol"; import {INetworkMiddlewareService} from "@symbiotic/interfaces/service/INetworkMiddlewareService.sol"; -/// forge script script/holesky/SymbioticSetup.s.sol --rpc-url $RPC_HOLESKY --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerNetwork -/// forge script script/holesky/SymbioticSetup.s.sol --rpc-url $RPC_HOLESKY --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerMiddleware -contract SymbioticSetup is Script { +/// forge script script/holesky/Symbiotic.s.sol --rpc-url $RPC_HOLESKY --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerNetwork +/// forge script script/holesky/Symbiotic.s.sol --rpc-url $RPC_HOLESKY --private-key $NETWORK_PRIVATE_KEY --broadcast -vvvv --sig "run(string memory arg)" registerMiddleware +contract SymbioticHelper is Script { function run( string memory arg ) public { address networkAdmin = msg.sender; - console.log("Deploying with network admin", networkAdmin); + console.log("Running with network admin", networkAdmin); + + vm.startBroadcast(networkAdmin); - vm.startBroadcast(); + console.log(arg); + console.logBytes32(keccak256(abi.encode(arg))); + console.logBytes32(keccak256(abi.encode("registerNetwork"))); + console.logBytes32(keccak256(abi.encode("registerMiddleware"))); if (keccak256(abi.encode(arg)) == keccak256(abi.encode("registerNetwork"))) { INetworkRegistry networkRegistry = INetworkRegistry(readNetworkRegistry()); + console.log("Registering network with NetworkRegistry (%s)", address(networkRegistry)); + networkRegistry.registerNetwork(); } else if (keccak256(abi.encode(arg)) == keccak256(abi.encode("registerMiddleware"))) { INetworkMiddlewareService middlewareService = INetworkMiddlewareService(readMiddlewareService()); address middleware = readMiddleware(); + console.log( + "Registering network middleware (%s) with MiddlewareService (%s)", + middleware, + address(middlewareService) + ); + middlewareService.setMiddleware(middleware); } @@ -36,25 +47,25 @@ contract SymbioticSetup is Script { function readNetworkRegistry() public view returns (address) { string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/config/holesky/network-registry.json"); + string memory path = string.concat(root, "/config/holesky/deployments.json"); string memory json = vm.readFile(path); - return vm.parseJsonAddress(json, ".networkRegistry"); + return vm.parseJsonAddress(json, ".symbiotic.networkRegistry"); } function readMiddlewareService() public view returns (address) { string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/config/holesky/middleware-service.json"); + string memory path = string.concat(root, "/config/holesky/deployments.json"); string memory json = vm.readFile(path); - return vm.parseJsonAddress(json, ".networkMiddlewareService"); + return vm.parseJsonAddress(json, ".symbiotic.networkMiddlewareService"); } function readMiddleware() public view returns (address) { string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/config/holesky/middleware.json"); + string memory path = string.concat(root, "/config/holesky/deployments.json"); string memory json = vm.readFile(path); - return vm.parseJsonAddress(json, ".networkMiddleware"); + return vm.parseJsonAddress(json, ".symbiotic.networkMiddleware"); } } diff --git a/bolt-contracts/src/contracts/BoltEigenLayerMiddlewareV1.sol b/bolt-contracts/src/contracts/BoltEigenLayerMiddlewareV1.sol index 2931dea8..a9a4eb9f 100644 --- a/bolt-contracts/src/contracts/BoltEigenLayerMiddlewareV1.sol +++ b/bolt-contracts/src/contracts/BoltEigenLayerMiddlewareV1.sol @@ -54,7 +54,7 @@ contract BoltEigenLayerMiddlewareV1 is IBoltMiddleware, OwnableUpgradeable, UUPS EnumerableSet.AddressSet private whitelistedCollaterals; /// @notice Address of the EigenLayer AVS Directory contract. - AVSDirectoryStorage public AVS_DIRECTORY; + IAVSDirectory public AVS_DIRECTORY; /// @notice Address of the EigenLayer Delegation Manager contract. DelegationManagerStorage public DELEGATION_MANAGER; @@ -103,7 +103,7 @@ contract BoltEigenLayerMiddlewareV1 is IBoltMiddleware, OwnableUpgradeable, UUPS manager = IBoltManager(_manager); START_TIMESTAMP = Time.timestamp(); - AVS_DIRECTORY = AVSDirectoryStorage(_eigenlayerAVSDirectory); + AVS_DIRECTORY = IAVSDirectory(_eigenlayerAVSDirectory); DELEGATION_MANAGER = DelegationManagerStorage(_eigenlayerDelegationManager); STRATEGY_MANAGER = StrategyManagerStorage(_eigenlayerStrategyManager); NAME_HASH = keccak256("EIGENLAYER");