Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new method set_slashable_stake_lookahead #278

Open
wants to merge 23 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ Those changes in added, changed or breaking changes, should include usage exampl
* Added `eigen_common` dependency to the `eigensdk` crate when "full" feature is enabled in [#249](https://github.com/Layr-Labs/eigensdk-rs/pull/249).
* Added bindings for `ECDSAStakeRegistry` and `ECDSAServiceManagerBase` in [#269](https://github.com/Layr-Labs/eigensdk-rs/pull/269).
* Added release-plz in ci in [#275](https://github.com/Layr-Labs/eigensdk-rs/pull/275).
* Added new method `set_slashable_stake_lookahead` in `avsregistry/writer` in [#278](https://github.com/Layr-Labs/eigensdk-rs/pull/278).
```rust
let quorum_number = 0_u8;
let lookahead = 10_u32;
let tx_hash = avs_writer
.set_slashable_stake_lookahead(quorum_number, lookahead)
.await
.unwrap();
```
* Added new method `set_rewards_initiator` in `avsregistry/writer` in [#273](https://github.com/Layr-Labs/eigensdk-rs/pull/273).
```rust
let tx_hash = avs_writer
Expand Down
87 changes: 86 additions & 1 deletion crates/chainio/clients/avsregistry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,95 @@ pub mod fake_reader;

#[cfg(test)]
pub(crate) mod test_utils {
use alloy::primitives::{address, Address};
use alloy::{
primitives::{address, aliases::U96, Address},
providers::WalletProvider,
sol_types::SolCall,
};
use eigen_common::get_signer;
use eigen_testing_utils::anvil_constants::{
get_allocation_manager_address, get_erc20_mock_strategy, get_registry_coordinator_address,
get_service_manager_address,
};
use eigen_utils::slashing::{
core::allocationmanager::AllocationManager,
middleware::registrycoordinator::{
ISlashingRegistryCoordinatorTypes::OperatorSetParam,
IStakeRegistryTypes::StrategyParams, RegistryCoordinator,
},
sdk::mockavsservicemanager::MockAvsServiceManager,
};

pub(crate) const ANVIL_FIRST_PRIVATE_KEY: &str =
"ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
pub(crate) const ANVIL_SECOND_ADDRESS: Address =
address!("70997970C51812dc3A010C7d01b50e0d17dc79C8");

pub(crate) async fn create_operator_set(http_endpoint: &str, avs_address: Address) {
let allocation_manager_addr =
get_allocation_manager_address(http_endpoint.to_string()).await;
let default_signer = get_signer(ANVIL_FIRST_PRIVATE_KEY, http_endpoint);
let allocation_manager =
AllocationManager::new(allocation_manager_addr, default_signer.clone());
let registry_coordinator_addr =
get_registry_coordinator_address(http_endpoint.to_string()).await;
let service_manager_address = get_service_manager_address(http_endpoint.to_string()).await;
let service_manager =
MockAvsServiceManager::new(service_manager_address, default_signer.clone());
service_manager
.setAppointee(
default_signer.default_signer_address(),
allocation_manager_addr,
alloy::primitives::FixedBytes(AllocationManager::setAVSRegistrarCall::SELECTOR),
)
.send()
.await
.unwrap()
.get_receipt()
.await
.unwrap();
allocation_manager
.setAVSRegistrar(avs_address, registry_coordinator_addr)
.send()
.await
.unwrap()
.get_receipt()
.await
.unwrap();

// Create slashable quorum
let contract_registry_coordinator =
RegistryCoordinator::new(registry_coordinator_addr, default_signer.clone());
let operator_set_params = OperatorSetParam {
maxOperatorCount: 10,
kickBIPsOfOperatorStake: 100,
kickBIPsOfTotalStake: 1000,
};
let strategy = get_erc20_mock_strategy(http_endpoint.to_string()).await;
service_manager
.setAppointee(
registry_coordinator_addr,
allocation_manager_addr,
alloy::primitives::FixedBytes(AllocationManager::createOperatorSetsCall::SELECTOR),
)
.send()
.await
.unwrap()
.get_receipt()
.await
.unwrap();
let strategy_params = StrategyParams {
strategy,
multiplier: U96::from(1),
};

contract_registry_coordinator
.createSlashableStakeQuorum(operator_set_params, U96::from(0), vec![strategy_params], 0)
.send()
.await
.unwrap()
.get_receipt()
.await
.unwrap();
}
}
69 changes: 68 additions & 1 deletion crates/chainio/clients/avsregistry/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,36 @@ impl AvsRegistryChainWriter {
Ok(*tx.tx_hash())
}

/// Sets the look-ahead time for checking operator shares for a specific quorum
///
/// # Arguments
///
/// * `quorum_number` - The quorum number to set the look-ahead period for
/// * `lookahead` - The number of blocks to look ahead when checking shares
///
/// # Returns
/// * `TxHash` - The transaction hash of the set slashable stake lookahead transaction
pub async fn set_slashable_stake_lookahead(
&self,
quorum_number: u8,
lookahead: u32,
) -> Result<TxHash, AvsRegistryError> {
info!("setting slashable stake lookahead");
let provider = get_signer(&self.signer.clone(), &self.provider);

let contract_stake_registry = StakeRegistry::new(self.stake_registry_addr, provider);

let contract_call =
contract_stake_registry.setSlashableStakeLookahead(quorum_number, lookahead);

contract_call
.send()
.await
.map_err(AvsRegistryError::AlloyContractError)
.inspect(|tx| info!(tx_hash = ?tx,"successfully set slashable stake lookahead" ))
.map(|tx_hash| *tx_hash.tx_hash())
}

/// Set a new address as the rewards initiator
///
/// # Arguments
Expand Down Expand Up @@ -365,18 +395,20 @@ impl AvsRegistryChainWriter {
mod tests {

use super::AvsRegistryChainWriter;
use crate::test_utils::{ANVIL_FIRST_PRIVATE_KEY, ANVIL_SECOND_ADDRESS};
use crate::test_utils::{create_operator_set, ANVIL_FIRST_PRIVATE_KEY, ANVIL_SECOND_ADDRESS};
use alloy::primitives::{Address, Bytes, FixedBytes, U256};
use eigen_common::get_signer;
use eigen_crypto_bls::BlsKeyPair;
use eigen_logging::get_test_logger;
use eigen_testing_utils::anvil::{start_anvil_container, start_m2_anvil_container};
use eigen_testing_utils::anvil_constants::{
get_operator_state_retriever_address, get_registry_coordinator_address,
get_service_manager_address,
};
use eigen_testing_utils::transaction::wait_transaction;
use eigen_utils::rewardsv2::middleware::servicemanagerbase::ServiceManagerBase;
use eigen_utils::slashing::middleware::registrycoordinator::RegistryCoordinator;
use eigen_utils::slashing::middleware::stakeregistry::StakeRegistry;
use futures_util::StreamExt;
use std::str::FromStr;

Expand Down Expand Up @@ -431,6 +463,41 @@ mod tests {
test_deregister_operator(&avs_writer, quorum_nums, http_endpoint.clone()).await;
}

#[tokio::test]
async fn test_set_slashable_stake_lookahead() {
let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await;
let private_key = ANVIL_FIRST_PRIVATE_KEY.to_string();
let avs_writer =
build_avs_registry_chain_writer(http_endpoint.clone(), private_key.clone()).await;
let avs_address = get_service_manager_address(http_endpoint.clone()).await;
create_operator_set(http_endpoint.as_str(), avs_address).await;

// Set up event poller to listen to `LookAheadPeriodChanged` events
let provider = get_signer(&avs_writer.signer.clone(), &avs_writer.provider);
let contract_stake_registry = StakeRegistry::new(avs_writer.stake_registry_addr, provider);
let event = contract_stake_registry.LookAheadPeriodChanged_filter();
let poller = event.watch().await.unwrap();

// Set the slashable stake lookahead period. Old period is 0.
let quorum_number = 0_u8;
let lookahead = 10_u32;
let tx_hash = avs_writer
.set_slashable_stake_lookahead(quorum_number, lookahead)
.await
.unwrap();

let tx_status = wait_transaction(&http_endpoint, tx_hash)
.await
.unwrap()
.status();
assert!(tx_status);

// Assert that event `LookAheadPeriodChanged` is the same as `new_rewards_init_address`
let mut stream = poller.into_stream();
let (stream_event, _) = stream.next().await.unwrap().unwrap();
assert_eq!(stream_event.newLookAheadBlocks, lookahead);
}

#[tokio::test]
async fn test_set_rewards_initiator() {
let (_container, http_endpoint, _ws_endpoint) = start_anvil_container().await;
Expand Down
Loading