1use alloy_primitives::{Address, U256};
2use alloy_sol_types::SolCall;
3use color_eyre::eyre::eyre;
4use eigensdk::utils::slashing::sdk::mockerc20::MockERC20;
5use serde::{Deserialize, Serialize};
6use tracing::info;
7
8use crate::bindings::core::islashingregistrycoordinator::ISlashingRegistryCoordinatorTypes::OperatorSetParam;
9use crate::bindings::core::slashingregistrycoordinator::IStakeRegistryTypes::StrategyParams;
10use crate::bindings::{
11 BLSApkRegistry, IStrategy, IndexRegistry, InstantSlasher, OperatorStateRetriever,
12 PauserRegistry, ProxyAdmin, SlashingRegistryCoordinator, SocketRegistry,
13 SquaringServiceManager, SquaringTask, StakeRegistry, StrategyFactory,
14};
15use crate::helpers::{deploy_empty_proxy, get_provider_from_signer, get_receipt, upgrade_proxy};
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct DeployedContracts {
20 pub proxy_admin: Address,
22 pub squaring_service_manager: Address,
24 pub squaring_service_manager_impl: Address,
26 pub squaring_task_manager: Address,
28 pub registry_coordinator: Address,
30 pub bls_apk_registry: Address,
32 pub index_registry: Address,
34 pub stake_registry: Address,
36 pub operator_state_retriever: Address,
38 pub strategy: Address,
40 pub pauser_registry: Address,
42 pub token: Address,
44 pub instant_slasher: Address,
46 pub socket_registry: Address,
48}
49
50#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
78pub async fn deploy_avs_contracts(
79 http_endpoint: &str,
80 private_key: &str,
81 deployer_address: Address,
82 num_quorums: u32,
83 permission_controller_address: Address,
84 allocation_manager_address: Address,
85 avs_directory_addr: Address,
86 delegation_manager_addr: Address,
87 pauser_registry_addr: Address,
88 rewards_coordinator_addr: Address,
89 strategy_factory_addr: Address,
90 task_generator_addr: Address,
91 aggregator_addr: Address,
92 task_response_window_block: u32,
93) -> color_eyre::eyre::Result<DeployedContracts> {
94 info!("Starting AVS deployment...");
95
96 let wallet = get_provider_from_signer(private_key, http_endpoint);
97
98 info!("Deployer address: {}", deployer_address);
99
100 info!("Initializing token...");
101 let mock_erc20 = MockERC20::deploy(wallet.clone()).await?;
102 let token = mock_erc20;
104 let mint_call = token.mint(
107 deployer_address,
108 U256::from(15_000_000_000_000_000_000_000_u128),
109 );
110 let mint_receipt = get_receipt(mint_call).await?;
111 info!("Token mint receipt: {:?}", mint_receipt);
112 if !mint_receipt.status() {
113 return Err(eyre!("Failed to mint tokens to deployer"));
114 }
115 info!("Minted tokens to deployer: {}", deployer_address);
116
117 let mint_call = token.mint(
118 task_generator_addr,
119 U256::from(30_000_000_000_000_000_000_000_u128),
120 );
121 let mint_receipt = get_receipt(mint_call).await?;
122 info!("Token mint receipt: {:?}", mint_receipt);
123 if !mint_receipt.status() {
124 return Err(eyre!("Failed to mint tokens to task generator"));
125 }
126 info!("Minted tokens to task generator: {}", task_generator_addr);
127
128 let balance = token.balanceOf(deployer_address).call().await?._0;
129 info!("Deployer token balance: {}", balance);
130 let balance = token.balanceOf(task_generator_addr).call().await?._0;
131 info!("Task generator token balance: {}", balance);
132
133 let token_total_supply = token.totalSupply().call().await?._0;
134 info!("Token total supply: {}", token_total_supply);
135
136 let strategy_factory = StrategyFactory::new(strategy_factory_addr, wallet.clone());
137
138 let new_strategy_call = strategy_factory.deployNewStrategy(*token.address());
139 let new_strategy_receipt = get_receipt(new_strategy_call).await?;
140 let strategy_addr = if let Some(last_log) = new_strategy_receipt.logs().last() {
141 let data = last_log.data().data.clone();
142 if data.len() >= 32 {
143 let mut addr_bytes = [0u8; 20];
145 addr_bytes.copy_from_slice(&data[12..32]);
146 Address::from_slice(&addr_bytes)
147 } else {
148 return Err(color_eyre::eyre::eyre!("Invalid log data format"));
149 }
150 } else {
151 return Err(eyre!("Failed to get strategy address from receipt"));
152 };
153 info!("Strategy deployed at: {}", strategy_addr);
154 let squaring_strategy = IStrategy::new(strategy_addr, wallet.clone());
155
156 info!("Deploying ProxyAdmin...");
158 let proxy_admin = ProxyAdmin::deploy(&wallet).await?;
159 let &proxy_admin_addr = proxy_admin.address();
160 info!("ProxyAdmin deployed at: {}", proxy_admin_addr);
161
162 info!("Deploying empty proxies...");
164 let squaring_service_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
165 let stake_registry_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
166 let squaring_task_manager_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
167 let slashing_registry_coordinator_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
168 let bls_apk_registry_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
169 let index_registry_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
170 let socket_registry_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
171 let instant_slasher_proxy = deploy_empty_proxy(&wallet, proxy_admin_addr).await?;
172
173 info!("Deploying OperatorStateRetriever...");
175 let operator_state_retriever = OperatorStateRetriever::deploy(&wallet).await?;
176 let &operator_state_retriever_addr = operator_state_retriever.address();
177 info!(
178 "OperatorStateRetriever deployed at: {}",
179 operator_state_retriever_addr
180 );
181
182 info!("Deploying implementation contracts...");
184
185 let stake_registry_impl = StakeRegistry::deploy(
187 &wallet,
188 slashing_registry_coordinator_proxy,
189 delegation_manager_addr,
190 avs_directory_addr,
191 allocation_manager_address,
192 )
193 .await?;
194 let &stake_registry_impl_addr = stake_registry_impl.address();
195 info!(
196 "StakeRegistry implementation deployed at: {}",
197 stake_registry_impl_addr
198 );
199
200 let bls_apk_registry_impl =
202 BLSApkRegistry::deploy(&wallet, slashing_registry_coordinator_proxy).await?;
203 let &bls_apk_registry_impl_addr = bls_apk_registry_impl.address();
204 info!(
205 "BLSApkRegistry implementation deployed at: {}",
206 bls_apk_registry_impl_addr
207 );
208
209 let index_registry_impl =
211 IndexRegistry::deploy(&wallet, slashing_registry_coordinator_proxy).await?;
212 let &index_registry_impl_addr = index_registry_impl.address();
213 info!(
214 "IndexRegistry implementation deployed at: {}",
215 index_registry_impl_addr
216 );
217
218 let instant_slasher_impl = InstantSlasher::deploy(
220 &wallet,
221 allocation_manager_address,
222 slashing_registry_coordinator_proxy,
223 squaring_task_manager_proxy,
224 )
225 .await?;
226 let &instant_slasher_impl_addr = instant_slasher_impl.address();
227 info!(
228 "InstantSlasher implementation deployed at: {}",
229 instant_slasher_impl_addr
230 );
231
232 let registry_coordinator_impl = SlashingRegistryCoordinator::deploy(
234 &wallet,
235 stake_registry_proxy,
236 bls_apk_registry_proxy,
237 index_registry_proxy,
238 socket_registry_proxy,
239 allocation_manager_address,
240 pauser_registry_addr,
241 "v1.4.0-testnet-holesky".to_string(),
242 )
243 .await?;
244 let ®istry_coordinator_impl_addr = registry_coordinator_impl.address();
245 info!(
246 "Registry Coordinator implementation deployed at: {}",
247 registry_coordinator_impl_addr
248 );
249
250 let pausers = vec![deployer_address, deployer_address];
251 let pauser_registry = PauserRegistry::deploy(&wallet, pausers, deployer_address).await?;
252 let &pauser_registry_addr = pauser_registry.address();
253 info!("Pauser Registry deployed at: {}", pauser_registry_addr);
254
255 let mut quorums_operator_set_params = Vec::with_capacity(num_quorums as usize);
256
257 let mut quorums_strategy_params = Vec::with_capacity(num_quorums as usize);
258 let deployed_strategies = [squaring_strategy];
259 let num_strategies = deployed_strategies.len();
260
261 for _i in 0..num_quorums {
262 let quorum_operator_set_param = OperatorSetParam {
263 maxOperatorCount: 10000u32,
264 kickBIPsOfOperatorStake: 15000u16,
265 kickBIPsOfTotalStake: 100u16,
266 };
267 quorums_operator_set_params.push(quorum_operator_set_param);
268
269 let mut quorum_strategy_param = Vec::with_capacity(num_strategies);
270 let multiplier = alloy_primitives::Uint::<96, 2>::from(1u64);
271 for j in deployed_strategies.iter().take(num_strategies) {
272 let strategy_param = StrategyParams {
273 strategy: *j.address(),
274 multiplier,
275 };
276 quorum_strategy_param.push(strategy_param);
277 }
278 quorums_strategy_params.push(quorum_strategy_param);
279 }
280
281 let registry_coordinator_init_data = SlashingRegistryCoordinator::initializeCall {
283 initialOwner: deployer_address,
284 churnApprover: deployer_address,
285 ejector: deployer_address,
286 initialPausedStatus: U256::from(0),
287 avs: squaring_service_manager_proxy,
288 }
289 .abi_encode()
290 .into();
291
292 info!("Upgrading proxies with implementations...");
294
295 upgrade_proxy(
297 &wallet,
298 proxy_admin_addr,
299 stake_registry_proxy,
300 stake_registry_impl_addr,
301 alloy_primitives::Bytes::new(),
302 )
303 .await?;
304 info!("StakeRegistry proxy upgraded");
305
306 upgrade_proxy(
308 &wallet,
309 proxy_admin_addr,
310 bls_apk_registry_proxy,
311 bls_apk_registry_impl_addr,
312 alloy_primitives::Bytes::new(),
313 )
314 .await?;
315 info!("BLSApkRegistry proxy upgraded");
316
317 upgrade_proxy(
319 &wallet,
320 proxy_admin_addr,
321 index_registry_proxy,
322 index_registry_impl_addr,
323 alloy_primitives::Bytes::new(),
324 )
325 .await?;
326 info!("IndexRegistry proxy upgraded");
327
328 upgrade_proxy(
330 &wallet,
331 proxy_admin_addr,
332 slashing_registry_coordinator_proxy,
333 registry_coordinator_impl_addr,
334 registry_coordinator_init_data,
335 )
336 .await?;
337 info!("RegistryCoordinator proxy upgraded and initialized");
338
339 let squaring_service_manager_impl = SquaringServiceManager::deploy(
341 &wallet,
342 avs_directory_addr,
343 slashing_registry_coordinator_proxy,
344 stake_registry_proxy,
345 rewards_coordinator_addr,
346 squaring_task_manager_proxy,
347 permission_controller_address,
348 allocation_manager_address,
349 )
350 .await?;
351 let &squaring_service_manager_impl_addr = squaring_service_manager_impl.address();
352 info!(
353 "SquaringServiceManager implementation deployed at: {}",
354 squaring_service_manager_impl_addr
355 );
356
357 let squaring_task_impl = SquaringTask::deploy(
359 &wallet,
360 slashing_registry_coordinator_proxy,
361 task_response_window_block,
362 )
363 .await?;
364 let &squaring_task_impl_addr = squaring_task_impl.address();
365 info!(
366 "SquaringTask implementation deployed at: {}",
367 squaring_task_impl_addr
368 );
369
370 let service_manager_init_data = SquaringServiceManager::initializeCall {
372 initialOwner: deployer_address,
373 rewardsInitiator: deployer_address,
374 }
375 .abi_encode()
376 .into();
377
378 upgrade_proxy(
380 &wallet,
381 proxy_admin_addr,
382 squaring_service_manager_proxy,
383 squaring_service_manager_impl_addr,
384 service_manager_init_data,
385 )
386 .await?;
387 info!("SquaringServiceManager proxy upgraded and initialized");
388
389 let task_manager_init_data = SquaringTask::initializeCall {
391 _aggregator: aggregator_addr,
392 _generator: task_generator_addr,
393 initialOwner: deployer_address,
394 }
395 .abi_encode()
396 .into();
397
398 upgrade_proxy(
400 &wallet,
401 proxy_admin_addr,
402 squaring_task_manager_proxy,
403 squaring_task_impl_addr,
404 task_manager_init_data,
405 )
406 .await?;
407 info!("SquaringTask proxy upgraded and initialized");
408
409 upgrade_proxy(
411 &wallet,
412 proxy_admin_addr,
413 instant_slasher_proxy,
414 instant_slasher_impl_addr,
415 alloy_primitives::Bytes::new(),
416 )
417 .await?;
418 info!("InstantSlasher proxy upgraded");
419
420 let socket_registry_impl =
422 SocketRegistry::deploy(&wallet, slashing_registry_coordinator_proxy).await?;
423 let &socket_registry_impl_addr = socket_registry_impl.address();
424 info!(
425 "SocketRegistry implementation deployed at: {}",
426 socket_registry_impl_addr
427 );
428
429 upgrade_proxy(
431 &wallet,
432 proxy_admin_addr,
433 socket_registry_proxy,
434 socket_registry_impl_addr,
435 alloy_primitives::Bytes::new(),
436 )
437 .await?;
438 info!("SocketRegistry proxy upgraded");
439
440 info!("AVS deployment completed successfully!");
441
442 let deployed_contracts = DeployedContracts {
444 proxy_admin: proxy_admin_addr,
445 squaring_service_manager: squaring_service_manager_proxy,
446 squaring_service_manager_impl: squaring_service_manager_impl_addr,
447 squaring_task_manager: squaring_task_manager_proxy,
448 registry_coordinator: slashing_registry_coordinator_proxy,
449 bls_apk_registry: bls_apk_registry_proxy,
450 index_registry: index_registry_proxy,
451 stake_registry: stake_registry_proxy,
452 operator_state_retriever: operator_state_retriever_addr,
453 strategy: *deployed_strategies[0].address(),
454 pauser_registry: pauser_registry_addr,
455 token: *token.address(),
456 instant_slasher: instant_slasher_proxy,
457 socket_registry: socket_registry_proxy,
458 };
459
460 Ok(deployed_contracts)
461}