eigenlayer_contract_deployer/
core.rs

1use crate::bindings::core::rewards_coordinator::IRewardsCoordinatorTypes::RewardsCoordinatorConstructorParams;
2use crate::bindings::{
3    AVSDirectory, AllocationManager, DelegationManager, EigenPod, EigenPodManager, PauserRegistry,
4    PermissionController, ProxyAdmin, RewardsCoordinator, StrategyBase, StrategyFactory,
5    StrategyManager, UpgradeableBeacon,
6};
7use crate::helpers::{deploy_empty_proxy, get_provider_from_signer, upgrade_proxy};
8use alloy_primitives::{Address, Bytes, U256};
9use alloy_sol_types::SolCall;
10use serde::{Deserialize, Serialize};
11use tracing::info;
12
13pub const MIDDLEWARE_VERSION: &str = "v1.4.0-testnet-holesky";
14
15/// Contract Addresses of EigenLayer core contracts
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct DeployedCoreContracts {
18    /// Proxy admin address
19    pub proxy_admin: Address,
20    /// Delegation manager address
21    pub delegation_manager: Address,
22    /// Delegation manager implementation address
23    pub delegation_manager_impl: Address,
24    /// AVS directory address
25    pub avs_directory: Address,
26    /// AVS directory implementation address
27    pub avs_directory_impl: Address,
28    /// Strategy manager address
29    pub strategy_manager: Address,
30    /// Strategy manager implementation address
31    pub strategy_manager_impl: Address,
32    /// `EigenPod` manager address
33    pub eigen_pod_manager: Address,
34    /// `EigenPod` manager implementation address
35    pub eigen_pod_manager_impl: Address,
36    /// Allocation manager address
37    pub allocation_manager: Address,
38    /// Allocation manager implementation address
39    pub allocation_manager_impl: Address,
40    /// Rewards coordinator address
41    pub rewards_coordinator: Address,
42    /// Rewards coordinator implementation address
43    pub rewards_coordinator_impl: Address,
44    /// `EigenPod` beacon address
45    pub eigen_pod_beacon: Address,
46    /// Pauser registry address
47    pub pauser_registry: Address,
48    /// Strategy factory address
49    pub strategy_factory: Address,
50    /// Strategy factory implementation address
51    pub strategy_factory_impl: Address,
52    /// Strategy beacon address
53    pub strategy_beacon: Address,
54    /// Permission controller address
55    pub permission_controller: Address,
56    /// Permission controller implementation address
57    pub permission_controller_impl: Address,
58}
59
60/// Configuration for the strategy manager
61#[derive(Debug, Clone)]
62pub struct StrategyManagerConfig {
63    /// Initial paused status
64    pub init_paused_status: U256,
65    /// Initial withdrawal delay blocks
66    pub init_withdrawal_delay_blocks: u32,
67}
68
69/// Configuration for the delegation manager
70#[derive(Debug, Clone)]
71pub struct DelegationManagerConfig {
72    /// Initial paused status
73    pub init_paused_status: U256,
74    /// Withdrawal delay blocks
75    pub withdrawal_delay_blocks: u32,
76}
77
78/// Configuration for the `EigenPod` manager
79#[derive(Debug, Clone)]
80pub struct EigenPodManagerConfig {
81    /// Initial paused status
82    pub init_paused_status: U256,
83}
84
85/// Configuration for the rewards coordinator
86#[derive(Debug, Clone)]
87pub struct RewardsCoordinatorConfig {
88    /// Initial paused status
89    pub init_paused_status: U256,
90    /// Maximum rewards duration
91    pub max_rewards_duration: u32,
92    /// Maximum retroactive length
93    pub max_retroactive_length: u32,
94    /// Maximum future length
95    pub max_future_length: u32,
96    /// Genesis rewards timestamp
97    pub genesis_rewards_timestamp: u32,
98    /// Updater address
99    pub updater: Address,
100    /// Activation delay
101    pub activation_delay: u32,
102    /// Calculation interval seconds
103    pub calculation_interval_seconds: u32,
104    /// Global operator commission in basis points
105    pub global_operator_commission_bips: u16,
106}
107
108/// Configuration for the strategy factory
109#[derive(Debug, Clone)]
110pub struct StrategyFactoryConfig {
111    /// Initial paused status
112    pub init_paused_status: U256,
113}
114
115/// Configuration for all core contracts
116#[derive(Debug, Clone)]
117pub struct DeploymentConfigData {
118    /// Strategy manager configuration
119    pub strategy_manager: StrategyManagerConfig,
120    /// Delegation manager configuration
121    pub delegation_manager: DelegationManagerConfig,
122    /// `EigenPod` manager configuration
123    pub eigen_pod_manager: EigenPodManagerConfig,
124    /// Rewards coordinator configuration
125    pub rewards_coordinator: RewardsCoordinatorConfig,
126    /// Strategy factory configuration
127    pub strategy_factory: StrategyFactoryConfig,
128}
129
130/// Deploys the EigenLayer core contracts
131///
132/// This function deploys all the necessary core contracts for EigenLayer
133/// following the logic from the provided Solidity script.
134///
135/// # Arguments
136///
137/// * `http_endpoint` - HTTP endpoint for the RPC provider
138/// * `private_key` - Private key for the deployer account
139/// * `deployer_address` - Deployer address
140/// * `config_data` - Configuration data for the deployment
141/// * `eth_pos_deposit` - Address of the ETH POS deposit contract (optional, for mainnet)
142/// * `genesis_time` - Genesis time for the `EigenPod` (optional)
143///
144/// # Errors
145/// Returns an error if any of the contract deployments fail or if any of the contract calls fail.
146#[allow(clippy::too_many_lines)]
147pub async fn deploy_core_contracts(
148    http_endpoint: &str,
149    private_key: &str,
150    deployer_address: Address,
151    config_data: DeploymentConfigData,
152    eth_pos_deposit: Option<Address>,
153    genesis_time: Option<u64>,
154) -> color_eyre::eyre::Result<DeployedCoreContracts> {
155    info!("Starting EigenLayer core contracts deployment...");
156
157    let wallet = get_provider_from_signer(private_key, http_endpoint);
158
159    info!("Deployer address: {}", deployer_address);
160
161    // Deploy ProxyAdmin
162    let proxy_admin = ProxyAdmin::deploy(&wallet).await?;
163    let &proxy_admin_addr = proxy_admin.address();
164    info!("ProxyAdmin deployed at: {}", proxy_admin_addr);
165
166    // Deploy empty proxies
167    info!("Deploying empty proxies...");
168    let delegation_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
169    info!(
170        "DelegationManager proxy deployed at: {}",
171        delegation_manager_proxy
172    );
173    let avs_directory_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
174    info!("AVSDirectory proxy deployed at: {}", avs_directory_proxy);
175    let strategy_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
176    info!(
177        "StrategyManager proxy deployed at: {}",
178        strategy_manager_proxy
179    );
180    let allocation_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
181    info!(
182        "AllocationManager proxy deployed at: {}",
183        allocation_manager_proxy
184    );
185    let rewards_coordinator_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
186    info!(
187        "RewardsCoordinator proxy deployed at: {}",
188        rewards_coordinator_proxy
189    );
190    let eigen_pod_beacon_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
191    info!(
192        "EigenPodBeacon proxy deployed at: {}",
193        eigen_pod_beacon_proxy
194    );
195    let strategy_factory_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
196    info!(
197        "StrategyFactory proxy deployed at: {}",
198        strategy_factory_proxy
199    );
200    let eigen_pod_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
201    info!(
202        "EigenPodManager proxy deployed at: {}",
203        eigen_pod_manager_proxy
204    );
205    let permission_controller_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
206    info!(
207        "PermissionController proxy deployed at: {}",
208        permission_controller_proxy
209    );
210
211    // Deploy PauserRegistry
212    let pauser_registry =
213        PauserRegistry::deploy(&wallet, Vec::<Address>::new(), proxy_admin_addr).await?;
214    let &pauser_registry_addr = pauser_registry.address();
215    info!("PauserRegistry deployed at: {}", pauser_registry_addr);
216
217    // Deploy implementation contracts
218    info!("Deploying implementation contracts...");
219
220    // Deploy DelegationManager implementation
221    let delegation_manager_impl = DelegationManager::deploy(
222        &wallet,
223        strategy_manager_proxy,
224        eigen_pod_manager_proxy,
225        allocation_manager_proxy,
226        pauser_registry_addr,
227        permission_controller_proxy,
228        0u32, // minWithdrawalDelay
229        MIDDLEWARE_VERSION.to_string(),
230    )
231    .await?;
232    let &delegation_manager_impl_addr = delegation_manager_impl.address();
233    info!(
234        "DelegationManager implementation deployed at: {}",
235        delegation_manager_impl_addr
236    );
237
238    // Deploy PermissionController implementation
239    let permission_controller_impl =
240        PermissionController::deploy(&wallet, MIDDLEWARE_VERSION.to_string()).await?;
241    let &permission_controller_impl_addr = permission_controller_impl.address();
242    info!(
243        "PermissionController implementation deployed at: {}",
244        permission_controller_impl_addr
245    );
246
247    // Deploy AVSDirectory implementation
248    let avs_directory_impl = AVSDirectory::deploy(
249        &wallet,
250        delegation_manager_proxy,
251        pauser_registry_addr,
252        MIDDLEWARE_VERSION.to_string(),
253    )
254    .await?;
255    let &avs_directory_impl_addr = avs_directory_impl.address();
256    info!(
257        "AVSDirectory implementation deployed at: {}",
258        avs_directory_impl_addr
259    );
260
261    // Deploy StrategyManager implementation
262    let strategy_manager_impl = StrategyManager::deploy(
263        &wallet,
264        delegation_manager_proxy,
265        pauser_registry_addr,
266        MIDDLEWARE_VERSION.to_string(),
267    )
268    .await?;
269    let &strategy_manager_impl_addr = strategy_manager_impl.address();
270    info!(
271        "StrategyManager implementation deployed at: {}",
272        strategy_manager_impl_addr
273    );
274
275    // Deploy StrategyFactory implementation
276    let strategy_factory_impl = StrategyFactory::deploy(
277        &wallet,
278        strategy_manager_proxy,
279        pauser_registry_addr,
280        MIDDLEWARE_VERSION.to_string(),
281    )
282    .await?;
283    let &strategy_factory_impl_addr = strategy_factory_impl.address();
284    info!(
285        "StrategyFactory implementation deployed at: {}",
286        strategy_factory_impl_addr
287    );
288
289    // Deploy AllocationManager implementation
290    let allocation_manager_impl = AllocationManager::deploy(
291        &wallet,
292        delegation_manager_proxy,
293        pauser_registry_addr,
294        permission_controller_proxy,
295        0u32, // _DEALLOCATION_DELAY
296        0u32, // _ALLOCATION_CONFIGURATION_DELAY
297        MIDDLEWARE_VERSION.to_string(),
298    )
299    .await?;
300    let &allocation_manager_impl_addr = allocation_manager_impl.address();
301    info!(
302        "AllocationManager implementation deployed at: {}",
303        allocation_manager_impl_addr
304    );
305
306    // Determine ETH POS deposit address
307    let eth_pos_deposit_addr = match eth_pos_deposit {
308        Some(addr) => addr,
309        None => {
310            // For non-mainnet chains, you might want to deploy a mock
311            // This is a placeholder address, should be replaced with actual implementation
312            Address::from_slice(&[0u8; 20])
313        }
314    };
315
316    // Deploy EigenPodManager implementation
317    let eigen_pod_manager_impl = EigenPodManager::deploy(
318        &wallet,
319        eth_pos_deposit_addr,
320        eigen_pod_beacon_proxy,
321        delegation_manager_proxy,
322        pauser_registry_addr,
323        MIDDLEWARE_VERSION.to_string(),
324    )
325    .await?;
326    let &eigen_pod_manager_impl_addr = eigen_pod_manager_impl.address();
327    info!(
328        "EigenPodManager implementation deployed at: {}",
329        eigen_pod_manager_impl_addr
330    );
331
332    // Configure RewardsCoordinator parameters
333    let calculation_interval_seconds = config_data.rewards_coordinator.calculation_interval_seconds;
334    let max_rewards_duration = config_data.rewards_coordinator.max_rewards_duration;
335    let max_retroactive_length = config_data.rewards_coordinator.max_retroactive_length;
336    let max_future_length = config_data.rewards_coordinator.max_future_length;
337    let genesis_rewards_timestamp = config_data.rewards_coordinator.genesis_rewards_timestamp;
338
339    // Deploy RewardsCoordinator implementation
340    let rewards_coordinator_impl = RewardsCoordinator::deploy(
341        &wallet,
342        RewardsCoordinatorConstructorParams {
343            delegationManager: delegation_manager_proxy,
344            strategyManager: strategy_manager_proxy,
345            allocationManager: allocation_manager_proxy,
346            pauserRegistry: pauser_registry_addr,
347            permissionController: permission_controller_proxy,
348            version: MIDDLEWARE_VERSION.to_string(),
349            CALCULATION_INTERVAL_SECONDS: calculation_interval_seconds,
350            MAX_REWARDS_DURATION: max_rewards_duration,
351            MAX_RETROACTIVE_LENGTH: max_retroactive_length,
352            MAX_FUTURE_LENGTH: max_future_length,
353            GENESIS_REWARDS_TIMESTAMP: genesis_rewards_timestamp,
354        },
355    )
356    .await?;
357    let &rewards_coordinator_impl_addr = rewards_coordinator_impl.address();
358    info!(
359        "RewardsCoordinator implementation deployed at: {}",
360        rewards_coordinator_impl_addr
361    );
362
363    // Determine genesis time for EigenPod
364    let genesis_time_value = genesis_time.unwrap_or(1_564_000);
365
366    // Deploy EigenPod implementation
367    let eigen_pod_impl = EigenPod::deploy(
368        &wallet,
369        eth_pos_deposit_addr,
370        eigen_pod_manager_proxy,
371        genesis_time_value,
372        MIDDLEWARE_VERSION.to_string(),
373    )
374    .await?;
375    let &eigen_pod_impl_addr = eigen_pod_impl.address();
376    info!(
377        "EigenPod implementation deployed at: {}",
378        eigen_pod_impl_addr
379    );
380
381    // Deploy StrategyBase implementation
382    let base_strategy_impl = StrategyBase::deploy(
383        &wallet,
384        strategy_manager_proxy,
385        pauser_registry_addr,
386        MIDDLEWARE_VERSION.to_string(),
387    )
388    .await?;
389    let &base_strategy_impl_addr = base_strategy_impl.address();
390    info!(
391        "StrategyBase implementation deployed at: {}",
392        base_strategy_impl_addr
393    );
394
395    // Deploy and configure the strategy beacon
396    let strategy_beacon = UpgradeableBeacon::deploy(&wallet, base_strategy_impl_addr).await?;
397    let &strategy_beacon_addr = strategy_beacon.address();
398    info!("StrategyBeacon deployed at: {}", strategy_beacon_addr);
399
400    // Upgrade contracts with implementations and initialize them
401    info!("Upgrading proxies with implementations and initializing...");
402
403    // Upgrade DelegationManager
404    let delegation_manager_init_data = DelegationManager::initializeCall {
405        initialOwner: deployer_address,
406        initialPausedStatus: config_data.delegation_manager.init_paused_status,
407    }
408    .abi_encode()
409    .into();
410
411    upgrade_proxy(
412        &wallet,
413        proxy_admin_addr,
414        delegation_manager_proxy,
415        delegation_manager_impl_addr,
416        delegation_manager_init_data,
417    )
418    .await?;
419    info!("DelegationManager proxy upgraded and initialized");
420
421    // Upgrade StrategyManager
422    let strategy_manager_init_data = StrategyManager::initializeCall {
423        initialOwner: deployer_address,
424        initialStrategyWhitelister: strategy_factory_proxy,
425        initialPausedStatus: config_data.strategy_manager.init_paused_status,
426    }
427    .abi_encode()
428    .into();
429
430    upgrade_proxy(
431        &wallet,
432        proxy_admin_addr,
433        strategy_manager_proxy,
434        strategy_manager_impl_addr,
435        strategy_manager_init_data,
436    )
437    .await?;
438    info!("StrategyManager proxy upgraded and initialized");
439
440    // Upgrade PermissionController
441    upgrade_proxy(
442        &wallet,
443        proxy_admin_addr,
444        permission_controller_proxy,
445        permission_controller_impl_addr,
446        Bytes::new(),
447    )
448    .await?;
449    info!("PermissionController proxy upgraded");
450
451    // Upgrade StrategyFactory
452    let strategy_factory_init_data = StrategyFactory::initializeCall {
453        _initialOwner: deployer_address,
454        _initialPausedStatus: config_data.strategy_factory.init_paused_status,
455        _strategyBeacon: strategy_beacon_addr,
456    }
457    .abi_encode()
458    .into();
459
460    upgrade_proxy(
461        &wallet,
462        proxy_admin_addr,
463        strategy_factory_proxy,
464        strategy_factory_impl_addr,
465        strategy_factory_init_data,
466    )
467    .await?;
468    info!("StrategyFactory proxy upgraded and initialized");
469
470    // Upgrade EigenPodManager
471    let eigen_pod_manager_init_data = EigenPodManager::initializeCall {
472        initialOwner: deployer_address,
473        _initPausedStatus: config_data.eigen_pod_manager.init_paused_status,
474    }
475    .abi_encode()
476    .into();
477
478    upgrade_proxy(
479        &wallet,
480        proxy_admin_addr,
481        eigen_pod_manager_proxy,
482        eigen_pod_manager_impl_addr,
483        eigen_pod_manager_init_data,
484    )
485    .await?;
486    info!("EigenPodManager proxy upgraded and initialized");
487
488    // Upgrade AVSDirectory
489    let avs_directory_init_data = AVSDirectory::initializeCall {
490        initialOwner: deployer_address,
491        initialPausedStatus: U256::from(0), // Using 0 as default
492    }
493    .abi_encode()
494    .into();
495
496    upgrade_proxy(
497        &wallet,
498        proxy_admin_addr,
499        avs_directory_proxy,
500        avs_directory_impl_addr,
501        avs_directory_init_data,
502    )
503    .await?;
504    info!("AVSDirectory proxy upgraded and initialized");
505
506    // Upgrade RewardsCoordinator
507    let rewards_coordinator_init_data = RewardsCoordinator::initializeCall {
508        initialOwner: deployer_address,
509        initialPausedStatus: config_data.rewards_coordinator.init_paused_status,
510        _rewardsUpdater: deployer_address, // Using deployer as rewards updater
511        _activationDelay: config_data.rewards_coordinator.activation_delay,
512        _defaultSplitBips: config_data
513            .rewards_coordinator
514            .global_operator_commission_bips,
515    }
516    .abi_encode()
517    .into();
518
519    upgrade_proxy(
520        &wallet,
521        proxy_admin_addr,
522        rewards_coordinator_proxy,
523        rewards_coordinator_impl_addr,
524        rewards_coordinator_init_data,
525    )
526    .await?;
527    info!("RewardsCoordinator proxy upgraded and initialized");
528
529    // Upgrade EigenPod beacon
530    let eigen_pod_init_data = EigenPod::initializeCall {
531        _podOwner: eigen_pod_manager_proxy,
532    }
533    .abi_encode()
534    .into();
535
536    upgrade_proxy(
537        &wallet,
538        proxy_admin_addr,
539        eigen_pod_beacon_proxy,
540        eigen_pod_impl_addr,
541        eigen_pod_init_data,
542    )
543    .await?;
544    info!("EigenPod beacon proxy upgraded and initialized");
545
546    // Upgrade AllocationManager
547    let allocation_manager_init_data = AllocationManager::initializeCall {
548        initialOwner: deployer_address,
549        initialPausedStatus: config_data.delegation_manager.init_paused_status,
550    }
551    .abi_encode()
552    .into();
553
554    upgrade_proxy(
555        &wallet,
556        proxy_admin_addr,
557        allocation_manager_proxy,
558        allocation_manager_impl_addr,
559        allocation_manager_init_data,
560    )
561    .await?;
562    info!("AllocationManager proxy upgraded and initialized");
563
564    info!("EigenLayer core contracts deployment completed successfully!");
565
566    // Return deployed contract addresses
567    let deployed_contracts = DeployedCoreContracts {
568        proxy_admin: proxy_admin_addr,
569        delegation_manager: delegation_manager_proxy,
570        delegation_manager_impl: delegation_manager_impl_addr,
571        avs_directory: avs_directory_proxy,
572        avs_directory_impl: avs_directory_impl_addr,
573        strategy_manager: strategy_manager_proxy,
574        strategy_manager_impl: strategy_manager_impl_addr,
575        eigen_pod_manager: eigen_pod_manager_proxy,
576        eigen_pod_manager_impl: eigen_pod_manager_impl_addr,
577        allocation_manager: allocation_manager_proxy,
578        allocation_manager_impl: allocation_manager_impl_addr,
579        rewards_coordinator: rewards_coordinator_proxy,
580        rewards_coordinator_impl: rewards_coordinator_impl_addr,
581        eigen_pod_beacon: eigen_pod_beacon_proxy,
582        pauser_registry: pauser_registry_addr,
583        strategy_factory: strategy_factory_proxy,
584        strategy_factory_impl: strategy_factory_impl_addr,
585        strategy_beacon: strategy_beacon_addr,
586        permission_controller: permission_controller_proxy,
587        permission_controller_impl: permission_controller_impl_addr,
588    };
589
590    Ok(deployed_contracts)
591}