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: add create slashable stake quorum func #531

37 changes: 37 additions & 0 deletions chainio/clients/avsregistry/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,43 @@ func (w *ChainWriter) SetSlashableStakeLookahead(
return receipt, nil
}

// Creates a new quorum that tracks slashable stake for operators.
// It receives the operator set parameters for the given quorum, the minimum stake required to register,
// and the number of blocks to look ahead when calculating slashable stake.
// Returns the transaction receipt in case of success.
// Note: This function does not work on M2 AVSs.
func (w *ChainWriter) CreateSlashableStakeQuorum(
ctx context.Context,
operatorSetParams regcoord.ISlashingRegistryCoordinatorTypesOperatorSetParam,
minimumStakeRequired *big.Int,
strategyParams []regcoord.IStakeRegistryTypesStrategyParams,
lookAheadPeriod uint32,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
w.logger.Info("Creating slashable stake quorum")

noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
if err != nil {
return nil, err
}

tx, err := w.registryCoordinator.CreateSlashableStakeQuorum(
noSendTxOpts,
operatorSetParams,
minimumStakeRequired,
strategyParams,
lookAheadPeriod,
)
if err != nil {
return nil, err
}
receipt, err := w.txMgr.Send(ctx, tx, waitForReceipt)
if err != nil {
return nil, utils.WrapError("failed to send CreateSlashableStakeQuorum tx with err", err.Error())
}
return receipt, nil
}

// Receives an operator address and quorum numbers and ejects the operator from the given quorums.
// Note: if the operator is not registered, the call will not fail, but will do nothing.
func (w *ChainWriter) EjectOperator(
Expand Down
73 changes: 70 additions & 3 deletions chainio/clients/avsregistry/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package avsregistry_test

import (
"context"
"math/big"
"testing"

"github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry"
chainioutils "github.com/Layr-Labs/eigensdk-go/chainio/utils"
regcoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator"
regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator"
servicemanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/ServiceManagerBase"
stakeregistry "github.com/Layr-Labs/eigensdk-go/contracts/bindings/StakeRegistry"
"github.com/Layr-Labs/eigensdk-go/crypto/bls"
Expand Down Expand Up @@ -135,7 +136,7 @@ func TestWriterMethods(t *testing.T) {
ethHttpClient, err := ethclient.Dial(anvilHttpEndpoint)
require.NoError(t, err)

contractBlsRegistryCoordinator, err := regcoordinator.NewContractRegistryCoordinator(
contractBlsRegistryCoordinator, err := regcoord.NewContractRegistryCoordinator(
contractAddrs.RegistryCoordinator,
ethHttpClient,
)
Expand Down Expand Up @@ -256,7 +257,8 @@ func TestWriterMethods(t *testing.T) {
ethHttpClient, err := ethclient.Dial(anvilHttpEndpoint)
require.NoError(t, err)

contractBlsRegistryCoordinator, err := regcoordinator.NewContractRegistryCoordinator(
contractBlsRegistryCoordinator, err := regcoord.NewContractRegistryCoordinator(

contractAddrs.RegistryCoordinator,
ethHttpClient,
)
Expand Down Expand Up @@ -329,6 +331,71 @@ func TestBlsSignature(t *testing.T) {
assert.Equal(t, y, "4960450323239587206117776989095741074887370703941588742100855592356200866613")
}

func TestCreateSlashableStakeQuorum(t *testing.T) {
// Test set up
clients, anvilHttpEndpoint := testclients.BuildTestClients(t)
chainReader := clients.ReadClients.AvsRegistryChainReader

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

chainWriter := clients.AvsRegistryChainWriter

// Beyond MaxOperatorCount, the other params are not used anywhere other than in registerOperatorWithChurn
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an explanation to the struct elements, and also explains that does not matters the attribute values

operatorSetParams := regcoord.ISlashingRegistryCoordinatorTypesOperatorSetParam{
MaxOperatorCount: 192,
KickBIPsOfOperatorStake: 0,
KickBIPsOfTotalStake: 0,
}
minimumStakeNeeded := big.NewInt(0)

strategyAddr := contractAddrs.Erc20MockStrategy
strategyParam := regcoord.IStakeRegistryTypesStrategyParams{
Strategy: strategyAddr,
Multiplier: big.NewInt(1e18),
}

lookAheadPeriod := uint32(0)

// First, quorum count is 1 because Registry is initialized with 1 quorum
count, err := chainReader.GetQuorumCount(&bind.CallOpts{})
require.NoError(t, err)
assert.Equal(t, count, uint8(1))

registryCoordinatorAddress := contractAddrs.RegistryCoordinator
registryCoordinator, err := regcoord.NewContractRegistryCoordinator(
registryCoordinatorAddress,
clients.EthHttpClient,
)
require.NoError(t, err)

txManager := clients.TxManager
noSendTxOpts, err := txManager.GetNoSendTxOpts()
require.NoError(t, err)

tx, err := registryCoordinator.EnableOperatorSets(noSendTxOpts)
require.NoError(t, err)

_, err = txManager.Send(context.Background(), tx, true)
require.NoError(t, err)

// Create a new slashable stake quorum
receipt, err := chainWriter.CreateSlashableStakeQuorum(
context.Background(),
operatorSetParams,
minimumStakeNeeded,
[]regcoord.IStakeRegistryTypesStrategyParams{strategyParam},
lookAheadPeriod,
true,
)
require.NoError(t, err)
require.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

// After creating a new one, quorum count is 2
count, err = chainReader.GetQuorumCount(&bind.CallOpts{})
require.NoError(t, err)
assert.Equal(t, count, uint8(2))
MegaRedHand marked this conversation as resolved.
Show resolved Hide resolved
}

func TestEjectOperator(t *testing.T) {
// Test set up
clients, _ := testclients.BuildTestClients(t)
Expand Down