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 @@ -552,3 +552,40 @@ func (w *ChainWriter) SetSlashableStakeLookahead(
}
return receipt, nil
}

// This function creates a new Quorum from the new flow (with staking). The operator set params contains
MegaRedHand marked this conversation as resolved.
Show resolved Hide resolved
// the max operator count for that quorum and some churn options, the strategy params contains the specified
// strategy for that quorum and its corresponding multiplier, the minimum stake is the minimum required
// to the operator to be in the quorum and the lookAheadPeriod is the period in days for checking operator
// shares for a specific quorum. Returns the transaction receipt in case of success.
MegaRedHand marked this conversation as resolved.
Show resolved Hide resolved
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
}
70 changes: 67 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 All @@ -15,6 +16,7 @@ import (
"github.com/Layr-Labs/eigensdk-go/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
gethcommon "github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -134,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 @@ -255,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 @@ -327,3 +330,64 @@ func TestBlsSignature(t *testing.T) {
assert.Equal(t, x, "15790168376429033610067099039091292283117017641532256477437243974517959682102")
assert.Equal(t, y, "4960450323239587206117776989095741074887370703941588742100855592356200866613")
}

func TestCreateSlashableStakeQuorum(t *testing.T) {
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)

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)

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

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
}