feat: ✨ Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.
#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported
### Deployment
#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.
#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent
- **EigenLayer**: References existing deployed contracts (not
re-deployed)
#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.
#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands
#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched
## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi
# Check deployment status
bun cli contracts status --chain hoodi
# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.
* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.
* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.
* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
|
|
|
// SPDX-License-Identifier: UNLICENSED
|
|
|
|
|
pragma solidity ^0.8.27;
|
|
|
|
|
|
|
|
|
|
// Testing imports
|
|
|
|
|
import {Script} from "forge-std/Script.sol";
|
|
|
|
|
import {console} from "forge-std/console.sol";
|
|
|
|
|
import {DeployParams} from "./DeployParams.s.sol";
|
|
|
|
|
import {Logging} from "../utils/Logging.sol";
|
|
|
|
|
import {Accounts} from "../utils/Accounts.sol";
|
|
|
|
|
|
|
|
|
|
// Snowbridge imports
|
|
|
|
|
import {Gateway} from "snowbridge/src/Gateway.sol";
|
|
|
|
|
import {IGatewayV2} from "snowbridge/src/v2/IGateway.sol";
|
|
|
|
|
import {GatewayProxy} from "snowbridge/src/GatewayProxy.sol";
|
|
|
|
|
import {AgentExecutor} from "snowbridge/src/AgentExecutor.sol";
|
|
|
|
|
import {Agent} from "snowbridge/src/Agent.sol";
|
|
|
|
|
import {Initializer} from "snowbridge/src/Initializer.sol";
|
|
|
|
|
import {OperatingMode} from "snowbridge/src/types/Common.sol";
|
|
|
|
|
import {ud60x18} from "snowbridge/lib/prb-math/src/UD60x18.sol";
|
|
|
|
|
import {BeefyClient} from "snowbridge/src/BeefyClient.sol";
|
|
|
|
|
|
|
|
|
|
// OpenZeppelin imports
|
|
|
|
|
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
|
2025-10-20 08:20:59 +00:00
|
|
|
import {
|
|
|
|
|
TransparentUpgradeableProxy
|
|
|
|
|
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
|
feat: ✨ Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.
#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported
### Deployment
#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.
#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent
- **EigenLayer**: References existing deployed contracts (not
re-deployed)
#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.
#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands
#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched
## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi
# Check deployment status
bun cli contracts status --chain hoodi
# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.
* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.
* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.
* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
|
|
|
|
|
|
|
|
// EigenLayer imports
|
|
|
|
|
import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol";
|
|
|
|
|
import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol";
|
|
|
|
|
import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol";
|
|
|
|
|
import {RewardsCoordinator} from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol";
|
|
|
|
|
import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol";
|
2025-10-20 08:20:59 +00:00
|
|
|
import {
|
|
|
|
|
PermissionController
|
|
|
|
|
} from "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol";
|
feat: ✨ Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.
#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported
### Deployment
#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.
#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent
- **EigenLayer**: References existing deployed contracts (not
re-deployed)
#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.
#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands
#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched
## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi
# Check deployment status
bun cli contracts status --chain hoodi
# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.
* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.
* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.
* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
|
|
|
import {EigenPodManager} from "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol";
|
|
|
|
|
import {IETHPOSDeposit} from "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol";
|
|
|
|
|
|
|
|
|
|
// DataHaven imports
|
|
|
|
|
import {DataHavenServiceManager} from "../../src/DataHavenServiceManager.sol";
|
|
|
|
|
import {MerkleUtils} from "../../src/libraries/MerkleUtils.sol";
|
|
|
|
|
import {VetoableSlasher} from "../../src/middleware/VetoableSlasher.sol";
|
|
|
|
|
import {RewardsRegistry} from "../../src/middleware/RewardsRegistry.sol";
|
|
|
|
|
import {IRewardsRegistry} from "../../src/interfaces/IRewardsRegistry.sol";
|
|
|
|
|
import {ValidatorsUtils} from "../../script/utils/ValidatorsUtils.sol";
|
|
|
|
|
|
|
|
|
|
// Shared structs
|
|
|
|
|
struct ServiceManagerInitParams {
|
|
|
|
|
address avsOwner;
|
|
|
|
|
address rewardsInitiator;
|
|
|
|
|
address[] validatorsStrategies;
|
|
|
|
|
address gateway;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Struct to store more detailed strategy information
|
|
|
|
|
struct StrategyInfo {
|
|
|
|
|
address address_;
|
|
|
|
|
address underlyingToken;
|
|
|
|
|
address tokenCreator;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @title DeployBase
|
|
|
|
|
* @notice Base contract containing all shared deployment logic between local and testnet deployments
|
|
|
|
|
*/
|
|
|
|
|
abstract contract DeployBase is Script, DeployParams, Accounts {
|
|
|
|
|
// Progress indicator
|
|
|
|
|
uint16 public deploymentStep = 0;
|
|
|
|
|
uint16 public totalSteps;
|
|
|
|
|
|
|
|
|
|
// Shared EigenLayer Contract references
|
|
|
|
|
DelegationManager public delegation;
|
|
|
|
|
StrategyManager public strategyManager;
|
|
|
|
|
AVSDirectory public avsDirectory;
|
|
|
|
|
RewardsCoordinator public rewardsCoordinator;
|
|
|
|
|
AllocationManager public allocationManager;
|
|
|
|
|
PermissionController public permissionController;
|
|
|
|
|
EigenPodManager public eigenPodManager;
|
|
|
|
|
IETHPOSDeposit public ethPOSDeposit;
|
|
|
|
|
|
|
|
|
|
function _logProgress() internal {
|
|
|
|
|
deploymentStep++;
|
|
|
|
|
Logging.logProgress(deploymentStep, totalSteps);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Abstract functions that must be implemented by inheriting contracts
|
|
|
|
|
function _setupEigenLayerContracts(
|
|
|
|
|
EigenLayerConfig memory config
|
|
|
|
|
) internal virtual returns (ProxyAdmin);
|
|
|
|
|
function _getNetworkName() internal virtual returns (string memory);
|
|
|
|
|
function _getDeploymentMode() internal virtual returns (string memory);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Shared deployment flow for both local and testnet deployments
|
|
|
|
|
*/
|
|
|
|
|
function _executeSharedDeployment() internal {
|
|
|
|
|
string memory networkName = _getNetworkName();
|
|
|
|
|
string memory deploymentMode = _getDeploymentMode();
|
|
|
|
|
|
|
|
|
|
Logging.logHeader("DATAHAVEN DEPLOYMENT SCRIPT");
|
|
|
|
|
console.log("| Network: %s", networkName);
|
|
|
|
|
console.log("| Mode: %s", deploymentMode);
|
|
|
|
|
console.log("| Timestamp: %s", vm.toString(block.timestamp));
|
|
|
|
|
Logging.logFooter();
|
|
|
|
|
|
|
|
|
|
// Load configurations
|
|
|
|
|
SnowbridgeConfig memory snowbridgeConfig = getSnowbridgeConfig();
|
|
|
|
|
AVSConfig memory avsConfig = getAVSConfig();
|
|
|
|
|
EigenLayerConfig memory eigenLayerConfig = getEigenLayerConfig();
|
|
|
|
|
|
|
|
|
|
// Setup EigenLayer contracts (implementation varies by deployment type)
|
|
|
|
|
ProxyAdmin proxyAdmin = _setupEigenLayerContracts(eigenLayerConfig);
|
|
|
|
|
_logProgress();
|
|
|
|
|
|
|
|
|
|
// Deploy Snowbridge (same for both modes)
|
|
|
|
|
(
|
|
|
|
|
BeefyClient beefyClient,
|
|
|
|
|
AgentExecutor agentExecutor,
|
|
|
|
|
IGatewayV2 gateway,
|
|
|
|
|
address payable rewardsAgentAddress
|
|
|
|
|
) = _deploySnowbridge(snowbridgeConfig);
|
|
|
|
|
Logging.logFooter();
|
|
|
|
|
_logProgress();
|
|
|
|
|
|
|
|
|
|
// Deploy DataHaven contracts (same for both modes)
|
|
|
|
|
(
|
|
|
|
|
DataHavenServiceManager serviceManager,
|
|
|
|
|
DataHavenServiceManager serviceManagerImplementation,
|
|
|
|
|
VetoableSlasher vetoableSlasher,
|
|
|
|
|
RewardsRegistry rewardsRegistry,
|
|
|
|
|
bytes4 updateRewardsMerkleRootSelector
|
|
|
|
|
) = _deployDataHavenContracts(avsConfig, proxyAdmin, gateway);
|
|
|
|
|
|
|
|
|
|
Logging.logFooter();
|
|
|
|
|
_logProgress();
|
|
|
|
|
|
|
|
|
|
// Final configuration (same for both modes)
|
|
|
|
|
Logging.logHeader("FINAL CONFIGURATION");
|
|
|
|
|
vm.broadcast(_avsOwnerPrivateKey);
|
|
|
|
|
serviceManager.setRewardsAgent(0, address(rewardsAgentAddress));
|
|
|
|
|
Logging.logStep("Agent set in RewardsRegistry");
|
|
|
|
|
Logging.logContractDeployed("Agent Address", rewardsAgentAddress);
|
|
|
|
|
Logging.logFooter();
|
|
|
|
|
_logProgress();
|
|
|
|
|
|
|
|
|
|
// Output deployment info
|
|
|
|
|
_outputDeployedAddresses(
|
|
|
|
|
beefyClient,
|
|
|
|
|
agentExecutor,
|
|
|
|
|
gateway,
|
|
|
|
|
serviceManager,
|
|
|
|
|
serviceManagerImplementation,
|
|
|
|
|
vetoableSlasher,
|
|
|
|
|
rewardsRegistry,
|
|
|
|
|
rewardsAgentAddress
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
_outputRewardsInfo(
|
|
|
|
|
rewardsAgentAddress,
|
|
|
|
|
snowbridgeConfig.rewardsMessageOrigin,
|
|
|
|
|
updateRewardsMerkleRootSelector
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Deploy Snowbridge components (shared across all deployment types)
|
|
|
|
|
*/
|
|
|
|
|
function _deploySnowbridge(
|
|
|
|
|
SnowbridgeConfig memory config
|
|
|
|
|
) internal returns (BeefyClient, AgentExecutor, IGatewayV2, address payable) {
|
2025-11-27 14:06:04 +00:00
|
|
|
Logging.logHeader("SNOWBRIDGE DEPLOYMENT");
|
|
|
|
|
|
feat: ✨ Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.
#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported
### Deployment
#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.
#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent
- **EigenLayer**: References existing deployed contracts (not
re-deployed)
#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.
#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands
#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched
## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi
# Check deployment status
bun cli contracts status --chain hoodi
# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.
* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.
* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.
* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
|
|
|
Logging.logSection("Deploying Snowbridge Core Components");
|
|
|
|
|
|
|
|
|
|
BeefyClient beefyClient = _deployBeefyClient(config);
|
|
|
|
|
Logging.logContractDeployed("BeefyClient", address(beefyClient));
|
|
|
|
|
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
AgentExecutor agentExecutor = new AgentExecutor();
|
|
|
|
|
Logging.logContractDeployed("AgentExecutor", address(agentExecutor));
|
|
|
|
|
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
Gateway gatewayImplementation = new Gateway(address(beefyClient), address(agentExecutor));
|
|
|
|
|
Logging.logContractDeployed("Gateway Implementation", address(gatewayImplementation));
|
|
|
|
|
|
|
|
|
|
// Configure and deploy Gateway proxy
|
|
|
|
|
OperatingMode defaultOperatingMode = OperatingMode.Normal;
|
|
|
|
|
Initializer.Config memory gatewayConfig = Initializer.Config({
|
|
|
|
|
mode: defaultOperatingMode,
|
|
|
|
|
deliveryCost: 1,
|
|
|
|
|
registerTokenFee: 1,
|
|
|
|
|
assetHubCreateAssetFee: 1,
|
|
|
|
|
assetHubReserveTransferFee: 1,
|
|
|
|
|
exchangeRate: ud60x18(1),
|
|
|
|
|
multiplier: ud60x18(1),
|
|
|
|
|
foreignTokenDecimals: 18,
|
|
|
|
|
maxDestinationFee: 1
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
IGatewayV2 gateway = IGatewayV2(
|
|
|
|
|
address(new GatewayProxy(address(gatewayImplementation), abi.encode(gatewayConfig)))
|
|
|
|
|
);
|
|
|
|
|
Logging.logContractDeployed("Gateway Proxy", address(gateway));
|
|
|
|
|
|
|
|
|
|
// Create Agent
|
|
|
|
|
Logging.logSection("Creating Snowbridge Agent");
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
gateway.v2_createAgent(config.rewardsMessageOrigin);
|
|
|
|
|
address payable rewardsAgentAddress = payable(gateway.agentOf(config.rewardsMessageOrigin));
|
|
|
|
|
Logging.logContractDeployed("Rewards Agent", rewardsAgentAddress);
|
|
|
|
|
|
|
|
|
|
return (beefyClient, agentExecutor, gateway, rewardsAgentAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Deploy BeefyClient (shared across all deployment types)
|
|
|
|
|
*/
|
|
|
|
|
function _deployBeefyClient(
|
|
|
|
|
SnowbridgeConfig memory config
|
|
|
|
|
) internal returns (BeefyClient) {
|
|
|
|
|
// Create validator sets using the MerkleUtils library
|
|
|
|
|
BeefyClient.ValidatorSet memory validatorSet =
|
|
|
|
|
ValidatorsUtils._buildValidatorSet(0, config.initialValidatorHashes);
|
|
|
|
|
BeefyClient.ValidatorSet memory nextValidatorSet =
|
|
|
|
|
ValidatorsUtils._buildValidatorSet(1, config.nextValidatorHashes);
|
|
|
|
|
|
|
|
|
|
// Deploy BeefyClient
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
return new BeefyClient(
|
|
|
|
|
config.randaoCommitDelay,
|
|
|
|
|
config.randaoCommitExpiration,
|
|
|
|
|
config.minNumRequiredSignatures,
|
|
|
|
|
config.startBlock,
|
|
|
|
|
validatorSet,
|
|
|
|
|
nextValidatorSet
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Deploy DataHaven custom contracts (shared with mode-specific proxy creation)
|
|
|
|
|
*/
|
|
|
|
|
function _deployDataHavenContracts(
|
|
|
|
|
AVSConfig memory avsConfig,
|
|
|
|
|
ProxyAdmin proxyAdmin,
|
|
|
|
|
IGatewayV2 gateway
|
|
|
|
|
)
|
|
|
|
|
internal
|
|
|
|
|
returns (
|
|
|
|
|
DataHavenServiceManager,
|
|
|
|
|
DataHavenServiceManager,
|
|
|
|
|
VetoableSlasher,
|
|
|
|
|
RewardsRegistry,
|
|
|
|
|
bytes4
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
Logging.logHeader("DATAHAVEN CUSTOM CONTRACTS DEPLOYMENT");
|
|
|
|
|
|
|
|
|
|
// Deploy the Service Manager
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
2025-10-20 08:20:59 +00:00
|
|
|
DataHavenServiceManager serviceManagerImplementation = new DataHavenServiceManager(
|
|
|
|
|
rewardsCoordinator, permissionController, allocationManager
|
|
|
|
|
);
|
feat: ✨ Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.
#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported
### Deployment
#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.
#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent
- **EigenLayer**: References existing deployed contracts (not
re-deployed)
#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.
#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands
#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched
## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi
# Check deployment status
bun cli contracts status --chain hoodi
# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.
* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.
* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.
* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
|
|
|
Logging.logContractDeployed(
|
|
|
|
|
"ServiceManager Implementation", address(serviceManagerImplementation)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Create service manager initialisation parameters struct
|
|
|
|
|
ServiceManagerInitParams memory initParams = ServiceManagerInitParams({
|
|
|
|
|
avsOwner: avsConfig.avsOwner,
|
|
|
|
|
rewardsInitiator: avsConfig.rewardsInitiator,
|
|
|
|
|
validatorsStrategies: avsConfig.validatorsStrategies,
|
|
|
|
|
gateway: address(gateway)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Create the service manager proxy (different logic for local vs testnet)
|
|
|
|
|
DataHavenServiceManager serviceManager =
|
|
|
|
|
_createServiceManagerProxy(serviceManagerImplementation, proxyAdmin, initParams);
|
|
|
|
|
Logging.logContractDeployed("ServiceManager Proxy", address(serviceManager));
|
|
|
|
|
|
|
|
|
|
// Deploy VetoableSlasher
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
VetoableSlasher vetoableSlasher = new VetoableSlasher(
|
|
|
|
|
allocationManager,
|
|
|
|
|
serviceManager,
|
|
|
|
|
avsConfig.vetoCommitteeMember,
|
|
|
|
|
avsConfig.vetoWindowBlocks
|
|
|
|
|
);
|
|
|
|
|
Logging.logContractDeployed("VetoableSlasher", address(vetoableSlasher));
|
|
|
|
|
|
|
|
|
|
// Deploy RewardsRegistry
|
|
|
|
|
vm.broadcast(_deployerPrivateKey);
|
|
|
|
|
RewardsRegistry rewardsRegistry = new RewardsRegistry(
|
|
|
|
|
address(serviceManager),
|
|
|
|
|
address(0) // Will be set to the Agent address after creation
|
|
|
|
|
);
|
|
|
|
|
Logging.logContractDeployed("RewardsRegistry", address(rewardsRegistry));
|
|
|
|
|
bytes4 updateRewardsMerkleRootSelector = IRewardsRegistry.updateRewardsMerkleRoot.selector;
|
|
|
|
|
|
|
|
|
|
Logging.logSection("Configuring Service Manager");
|
|
|
|
|
|
|
|
|
|
// Register the DataHaven service in the AllocationManager
|
|
|
|
|
vm.broadcast(_avsOwnerPrivateKey);
|
|
|
|
|
serviceManager.updateAVSMetadataURI("");
|
|
|
|
|
Logging.logStep("DataHaven service registered in AllocationManager");
|
|
|
|
|
|
|
|
|
|
// Set the slasher in the ServiceManager
|
|
|
|
|
vm.broadcast(_avsOwnerPrivateKey);
|
|
|
|
|
serviceManager.setSlasher(vetoableSlasher);
|
|
|
|
|
Logging.logStep("Slasher set in ServiceManager");
|
|
|
|
|
|
|
|
|
|
// Set the RewardsRegistry in the ServiceManager
|
|
|
|
|
uint32 validatorsSetId = serviceManager.VALIDATORS_SET_ID();
|
|
|
|
|
vm.broadcast(_avsOwnerPrivateKey);
|
|
|
|
|
serviceManager.setRewardsRegistry(validatorsSetId, rewardsRegistry);
|
|
|
|
|
Logging.logStep("RewardsRegistry set in ServiceManager");
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
serviceManager,
|
|
|
|
|
serviceManagerImplementation,
|
|
|
|
|
vetoableSlasher,
|
|
|
|
|
rewardsRegistry,
|
|
|
|
|
updateRewardsMerkleRootSelector
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Create service manager proxy - implementation varies by deployment type
|
|
|
|
|
*/
|
|
|
|
|
function _createServiceManagerProxy(
|
|
|
|
|
DataHavenServiceManager implementation,
|
|
|
|
|
ProxyAdmin proxyAdmin,
|
|
|
|
|
ServiceManagerInitParams memory params
|
|
|
|
|
) internal virtual returns (DataHavenServiceManager);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Output deployed addresses with mode-specific logic
|
|
|
|
|
*/
|
|
|
|
|
function _outputDeployedAddresses(
|
|
|
|
|
BeefyClient beefyClient,
|
|
|
|
|
AgentExecutor agentExecutor,
|
|
|
|
|
IGatewayV2 gateway,
|
|
|
|
|
DataHavenServiceManager serviceManager,
|
|
|
|
|
DataHavenServiceManager serviceManagerImplementation,
|
|
|
|
|
VetoableSlasher vetoableSlasher,
|
|
|
|
|
RewardsRegistry rewardsRegistry,
|
|
|
|
|
address rewardsAgent
|
|
|
|
|
) internal virtual;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Output rewards info (shared across all deployment types)
|
|
|
|
|
*/
|
|
|
|
|
function _outputRewardsInfo(
|
|
|
|
|
address rewardsAgent,
|
|
|
|
|
bytes32 rewardsAgentOrigin,
|
|
|
|
|
bytes4 updateRewardsMerkleRootSelector
|
|
|
|
|
) internal {
|
|
|
|
|
Logging.logHeader("REWARDS AGENT INFO");
|
|
|
|
|
Logging.logContractDeployed("RewardsAgent", rewardsAgent);
|
|
|
|
|
Logging.logAgentOrigin("RewardsAgentOrigin", vm.toString(rewardsAgentOrigin));
|
|
|
|
|
Logging.logFunctionSelector(
|
|
|
|
|
"updateRewardsMerkleRootSelector", vm.toString(updateRewardsMerkleRootSelector)
|
|
|
|
|
);
|
|
|
|
|
Logging.logFooter();
|
|
|
|
|
|
|
|
|
|
// Write to deployment file for future reference
|
|
|
|
|
string memory network = _getNetworkName();
|
|
|
|
|
string memory rewardsInfoPath =
|
|
|
|
|
string.concat(vm.projectRoot(), "/deployments/", network, "-rewards-info.json");
|
|
|
|
|
|
|
|
|
|
// Create directory if it doesn't exist
|
|
|
|
|
vm.createDir(string.concat(vm.projectRoot(), "/deployments"), true);
|
|
|
|
|
|
|
|
|
|
// Create JSON with rewards info
|
|
|
|
|
string memory json = "{";
|
|
|
|
|
json = string.concat(json, '"RewardsAgent": "', vm.toString(rewardsAgent), '",');
|
|
|
|
|
json = string.concat(json, '"RewardsAgentOrigin": "', vm.toString(rewardsAgentOrigin), '",');
|
|
|
|
|
json = string.concat(
|
|
|
|
|
json,
|
|
|
|
|
'"updateRewardsMerkleRootSelector": "',
|
|
|
|
|
_trimToBytes4(vm.toString(updateRewardsMerkleRootSelector)),
|
|
|
|
|
'"'
|
|
|
|
|
);
|
|
|
|
|
json = string.concat(json, "}");
|
|
|
|
|
|
|
|
|
|
// Write to file
|
|
|
|
|
vm.writeFile(rewardsInfoPath, json);
|
|
|
|
|
Logging.logInfo(string.concat("Rewards info saved to: ", rewardsInfoPath));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @notice Helper function to trim a padded hex string to only the first 4 bytes
|
|
|
|
|
*/
|
|
|
|
|
function _trimToBytes4(
|
|
|
|
|
string memory paddedHex
|
|
|
|
|
) internal pure returns (string memory) {
|
|
|
|
|
bytes memory data = bytes(paddedHex);
|
|
|
|
|
bytes memory trimmed = new bytes(10); // 0x + 8 hex chars = 10 total chars
|
|
|
|
|
|
|
|
|
|
for (uint256 i = 0; i < 10; i++) {
|
|
|
|
|
trimmed[i] = data[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return string(trimmed);
|
|
|
|
|
}
|
|
|
|
|
}
|