diff --git a/chainio/clients/avsregistry/bindings.go b/chainio/clients/avsregistry/bindings.go index 776dca36..943f8e95 100644 --- a/chainio/clients/avsregistry/bindings.go +++ b/chainio/clients/avsregistry/bindings.go @@ -27,6 +27,7 @@ type ContractBindings struct { IndexRegistryAddr gethcommon.Address DelegationManagerAddr gethcommon.Address AvsDirectoryAddr gethcommon.Address + AllocationManagerAddr gethcommon.Address // contract bindings ServiceManager *servicemanager.ContractServiceManagerBase RegistryCoordinator *regcoordinator.ContractRegistryCoordinator @@ -136,6 +137,7 @@ func NewBindingsFromConfig( indexRegistryAddr gethcommon.Address delegationManagerAddr gethcommon.Address avsDirectoryAddr gethcommon.Address + allocationManagerAddr gethcommon.Address contractBlsRegistryCoordinator *regcoordinator.ContractRegistryCoordinator contractServiceManager *servicemanager.ContractServiceManagerBase @@ -209,6 +211,11 @@ func NewBindingsFromConfig( if err != nil { return nil, utils.WrapError("Failed to get AvsDirectory address", err) } + allocationManagerAddr, err = contractServiceManager.AllocationManager(&bind.CallOpts{}) + if err != nil { + return nil, utils.WrapError("Failed to get AllocationManager address", err) + } + } if isZeroAddress(cfg.OperatorStateRetrieverAddress) { @@ -232,6 +239,7 @@ func NewBindingsFromConfig( IndexRegistryAddr: indexRegistryAddr, OperatorStateRetrieverAddr: cfg.OperatorStateRetrieverAddress, DelegationManagerAddr: delegationManagerAddr, + AllocationManagerAddr: allocationManagerAddr, AvsDirectoryAddr: avsDirectoryAddr, ServiceManager: contractServiceManager, RegistryCoordinator: contractBlsRegistryCoordinator, diff --git a/chainio/clients/avsregistry/builder.go b/chainio/clients/avsregistry/builder.go index d9ad5dc2..90432085 100644 --- a/chainio/clients/avsregistry/builder.go +++ b/chainio/clients/avsregistry/builder.go @@ -90,6 +90,7 @@ func BuildClients( elcontracts.Config{ DelegationManagerAddress: avsBindings.DelegationManagerAddr, AvsDirectoryAddress: avsBindings.AvsDirectoryAddr, + AllocationManagerAddress: avsBindings.AllocationManagerAddr, }, client, logger, diff --git a/chainio/clients/avsregistry/writer.go b/chainio/clients/avsregistry/writer.go index 91a1b9d5..0f45e1db 100644 --- a/chainio/clients/avsregistry/writer.go +++ b/chainio/clients/avsregistry/writer.go @@ -127,7 +127,11 @@ func BuildAvsRegistryChainWriter( if err != nil { return nil, utils.WrapError("Failed to get AvsDirectory address", err) } - elReader, err := elcontracts.BuildELChainReader(delegationManagerAddr, avsDirectoryAddr, ethClient, logger) + allocationManagerAddr, err := serviceManager.AllocationManager(&bind.CallOpts{}) + if err != nil { + return nil, utils.WrapError("Failed to get AllocationManager address", err) + } + elReader, err := elcontracts.BuildELChainReader(delegationManagerAddr, avsDirectoryAddr, allocationManagerAddr, ethClient, logger) if err != nil { return nil, utils.WrapError("Failed to create ELChainReader", err) } @@ -158,6 +162,7 @@ func NewWriterFromConfig( elReader, err := elcontracts.NewReaderFromConfig(elcontracts.Config{ DelegationManagerAddress: bindings.DelegationManagerAddr, AvsDirectoryAddress: bindings.AvsDirectoryAddr, + AllocationManagerAddress: bindings.AllocationManagerAddr, }, client, logger) if err != nil { return nil, err @@ -490,7 +495,37 @@ func (w *ChainWriter) DeregisterOperator( if err != nil { return nil, err } - tx, err := w.registryCoordinator.DeregisterOperator(noSendTxOpts, quorumNumbers.UnderlyingType()) + tx, err := w.registryCoordinator.DeregisterOperator0(noSendTxOpts, quorumNumbers.UnderlyingType()) + if err != nil { + return nil, err + } + receipt, err := w.txMgr.Send(ctx, tx, waitForReceipt) + if err != nil { + return nil, errors.New("failed to send tx with err: " + err.Error()) + } + w.logger.Info( + "successfully deregistered operator with the AVS's registry coordinator", + "txHash", + receipt.TxHash.String(), + ) + return receipt, nil +} + +func (w *ChainWriter) DeregisterOperatorOperatorSets( + ctx context.Context, + operatorSetIds types.OperatorSetIds, + operator types.Operator, + pubkey regcoord.BN254G1Point, + waitForReceipt bool, +) (*gethtypes.Receipt, error) { + w.logger.Info("deregistering operator with the AVS's registry coordinator") + + operatorAddress := gethcommon.HexToAddress(operator.Address) + noSendTxOpts, err := w.txMgr.GetNoSendTxOpts() + if err != nil { + return nil, err + } + tx, err := w.registryCoordinator.DeregisterOperator(noSendTxOpts, operatorAddress, operatorSetIds.UnderlyingType()) if err != nil { return nil, err } diff --git a/chainio/clients/elcontracts/bindings.go b/chainio/clients/elcontracts/bindings.go index ee0b5543..897f760b 100644 --- a/chainio/clients/elcontracts/bindings.go +++ b/chainio/clients/elcontracts/bindings.go @@ -7,6 +7,7 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + allocationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/AllocationManager" delegationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/DelegationManager" avsdirectory "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IAVSDirectory" rewardscoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IRewardsCoordinator" @@ -23,10 +24,12 @@ type ContractBindings struct { StrategyManagerAddr gethcommon.Address DelegationManagerAddr gethcommon.Address AvsDirectoryAddr gethcommon.Address + AllocationManagerAddr gethcommon.Address RewardsCoordinatorAddress gethcommon.Address DelegationManager *delegationmanager.ContractDelegationManager StrategyManager *strategymanager.ContractStrategyManager AvsDirectory *avsdirectory.ContractIAVSDirectory + AllocationManager *allocationmanager.ContractAllocationManager RewardsCoordinator *rewardscoordinator.ContractIRewardsCoordinator } @@ -101,6 +104,7 @@ func isZeroAddress(address gethcommon.Address) bool { func NewEigenlayerContractBindings( delegationManagerAddr gethcommon.Address, avsDirectoryAddr gethcommon.Address, + allocationManagerAddr gethcommon.Address, ethclient eth.HttpBackend, logger logging.Logger, ) (*ContractBindings, error) { @@ -123,12 +127,19 @@ func NewEigenlayerContractBindings( return nil, utils.WrapError("Failed to fetch AVSDirectory contract", err) } + allocationManager, err := allocationmanager.NewContractAllocationManager(allocationManagerAddr, ethclient) + if err != nil { + return nil, utils.WrapError("Failed to fetch AllocationManager contract", err) + } + return &ContractBindings{ StrategyManagerAddr: strategyManagerAddr, DelegationManagerAddr: delegationManagerAddr, AvsDirectoryAddr: avsDirectoryAddr, + AllocationManagerAddr: allocationManagerAddr, StrategyManager: contractStrategyManager, DelegationManager: contractDelegationManager, AvsDirectory: avsDirectory, + AllocationManager: allocationManager, }, nil } diff --git a/chainio/clients/elcontracts/builder.go b/chainio/clients/elcontracts/builder.go index ac390e55..a016cbc4 100644 --- a/chainio/clients/elcontracts/builder.go +++ b/chainio/clients/elcontracts/builder.go @@ -28,6 +28,7 @@ func BuildReadClients( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, client, @@ -56,6 +57,7 @@ func BuildClients( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, client, @@ -66,6 +68,7 @@ func BuildClients( elContractBindings.StrategyManager, elContractBindings.RewardsCoordinator, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.StrategyManagerAddr, elChainReader, client, diff --git a/chainio/clients/elcontracts/reader.go b/chainio/clients/elcontracts/reader.go index 4bd311a7..d50ef3bb 100644 --- a/chainio/clients/elcontracts/reader.go +++ b/chainio/clients/elcontracts/reader.go @@ -11,6 +11,7 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + allocationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/AllocationManager" delegationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/DelegationManager" avsdirectory "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IAVSDirectory" erc20 "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IERC20" @@ -25,6 +26,7 @@ import ( type Config struct { DelegationManagerAddress common.Address AvsDirectoryAddress common.Address + AllocationManagerAddress common.Address RewardsCoordinatorAddress common.Address } @@ -33,6 +35,7 @@ type ChainReader struct { delegationManager *delegationmanager.ContractDelegationManager strategyManager *strategymanager.ContractStrategyManager avsDirectory *avsdirectory.ContractIAVSDirectory + allocationManager *allocationmanager.ContractAllocationManager rewardsCoordinator *rewardscoordinator.ContractIRewardsCoordinator ethClient eth.HttpBackend } @@ -41,6 +44,7 @@ func NewChainReader( delegationManager *delegationmanager.ContractDelegationManager, strategyManager *strategymanager.ContractStrategyManager, avsDirectory *avsdirectory.ContractIAVSDirectory, + allocationManager *allocationmanager.ContractAllocationManager, rewardsCoordinator *rewardscoordinator.ContractIRewardsCoordinator, logger logging.Logger, ethClient eth.HttpBackend, @@ -51,6 +55,7 @@ func NewChainReader( delegationManager: delegationManager, strategyManager: strategyManager, avsDirectory: avsDirectory, + allocationManager: allocationManager, rewardsCoordinator: rewardsCoordinator, logger: logger, ethClient: ethClient, @@ -62,12 +67,14 @@ func NewChainReader( func BuildELChainReader( delegationManagerAddr gethcommon.Address, avsDirectoryAddr gethcommon.Address, + allocationManagerAddr gethcommon.Address, ethClient eth.HttpBackend, logger logging.Logger, ) (*ChainReader, error) { elContractBindings, err := NewEigenlayerContractBindings( delegationManagerAddr, avsDirectoryAddr, + allocationManagerAddr, ethClient, logger, ) @@ -78,6 +85,7 @@ func BuildELChainReader( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, ethClient, @@ -101,6 +109,7 @@ func NewReaderFromConfig( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, ethClient, @@ -134,7 +143,7 @@ func (r *ChainReader) GetOperatorDetails( return types.Operator{}, errors.New("DelegationManager contract not provided") } - operatorDetails, err := r.delegationManager.OperatorDetails( + delegationApproverAddr, err := r.delegationManager.DelegationApprover( &bind.CallOpts{Context: ctx}, gethcommon.HexToAddress(operator.Address), ) @@ -142,10 +151,15 @@ func (r *ChainReader) GetOperatorDetails( return types.Operator{}, err } + _, operatorMagnitudeAllocationDelay, err := r.allocationManager.GetAllocationDelay( + &bind.CallOpts{Context: ctx}, + gethcommon.HexToAddress(operator.Address), + ) + return types.Operator{ Address: operator.Address, - StakerOptOutWindowBlocks: operatorDetails.StakerOptOutWindowBlocks, - DelegationApproverAddress: operatorDetails.DelegationApprover.Hex(), + DelegationApproverAddress: delegationApproverAddr.Hex(), + AllocationDelay: operatorMagnitudeAllocationDelay, }, nil } @@ -293,9 +307,9 @@ func (r *ChainReader) CurrRewardsCalculationEndTimestamp(ctx context.Context) (u func (r *ChainReader) GetCurrentClaimableDistributionRoot( ctx context.Context, -) (rewardscoordinator.IRewardsCoordinatorDistributionRoot, error) { +) (rewardscoordinator.IRewardsCoordinatorTypesDistributionRoot, error) { if r.rewardsCoordinator == nil { - return rewardscoordinator.IRewardsCoordinatorDistributionRoot{}, errors.New( + return rewardscoordinator.IRewardsCoordinatorTypesDistributionRoot{}, errors.New( "RewardsCoordinator contract not provided", ) } @@ -328,7 +342,7 @@ func (r *ChainReader) GetCumulativeClaimed( func (r *ChainReader) CheckClaim( ctx context.Context, - claim rewardscoordinator.IRewardsCoordinatorRewardsMerkleClaim, + claim rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim, ) (bool, error) { if r.rewardsCoordinator == nil { return false, errors.New("RewardsCoordinator contract not provided") diff --git a/chainio/clients/elcontracts/writer.go b/chainio/clients/elcontracts/writer.go index f5c9a3f7..63acb6a6 100644 --- a/chainio/clients/elcontracts/writer.go +++ b/chainio/clients/elcontracts/writer.go @@ -11,6 +11,7 @@ import ( "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + allocationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/AllocationManager" delegationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/DelegationManager" avsdirectory "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IAVSDirectory" erc20 "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IERC20" @@ -34,6 +35,7 @@ type ChainWriter struct { strategyManager *strategymanager.ContractStrategyManager rewardsCoordinator *rewardscoordinator.ContractIRewardsCoordinator avsDirectory *avsdirectory.ContractIAVSDirectory + allocationManager *allocationmanager.ContractAllocationManager strategyManagerAddr gethcommon.Address elChainReader Reader ethClient eth.HttpBackend @@ -46,6 +48,7 @@ func NewChainWriter( strategyManager *strategymanager.ContractStrategyManager, rewardsCoordinator *rewardscoordinator.ContractIRewardsCoordinator, avsDirectory *avsdirectory.ContractIAVSDirectory, + allocationManager *allocationmanager.ContractAllocationManager, strategyManagerAddr gethcommon.Address, elChainReader Reader, ethClient eth.HttpBackend, @@ -61,6 +64,7 @@ func NewChainWriter( strategyManagerAddr: strategyManagerAddr, rewardsCoordinator: rewardsCoordinator, avsDirectory: avsDirectory, + allocationManager: allocationManager, elChainReader: elChainReader, logger: logger, ethClient: ethClient, @@ -73,6 +77,7 @@ func NewChainWriter( func BuildELChainWriter( delegationManagerAddr gethcommon.Address, avsDirectoryAddr gethcommon.Address, + allocationManagerAddr gethcommon.Address, ethClient eth.HttpBackend, logger logging.Logger, eigenMetrics metrics.Metrics, @@ -81,6 +86,7 @@ func BuildELChainWriter( elContractBindings, err := NewEigenlayerContractBindings( delegationManagerAddr, avsDirectoryAddr, + allocationManagerAddr, ethClient, logger, ) @@ -91,6 +97,7 @@ func BuildELChainWriter( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, ethClient, @@ -100,6 +107,7 @@ func BuildELChainWriter( elContractBindings.StrategyManager, elContractBindings.RewardsCoordinator, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.StrategyManagerAddr, elChainReader, ethClient, @@ -128,6 +136,7 @@ func NewWriterFromConfig( elContractBindings.DelegationManager, elContractBindings.StrategyManager, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.RewardsCoordinator, logger, ethClient, @@ -137,6 +146,7 @@ func NewWriterFromConfig( elContractBindings.StrategyManager, elContractBindings.RewardsCoordinator, elContractBindings.AvsDirectory, + elContractBindings.AllocationManager, elContractBindings.StrategyManagerAddr, elChainReader, ethClient, @@ -156,19 +166,12 @@ func (w *ChainWriter) RegisterAsOperator( } w.logger.Infof("registering operator %s to EigenLayer", operator.Address) - opDetails := delegationmanager.IDelegationManagerOperatorDetails{ - // Earning receiver has been deprecated, so we just use the operator address as a dummy value - // Any reward related setup is via RewardsCoordinator contract - DeprecatedEarningsReceiver: gethcommon.HexToAddress(operator.Address), - StakerOptOutWindowBlocks: operator.StakerOptOutWindowBlocks, - DelegationApprover: gethcommon.HexToAddress(operator.DelegationApproverAddress), - } noSendTxOpts, err := w.txMgr.GetNoSendTxOpts() if err != nil { return nil, err } - tx, err := w.delegationManager.RegisterAsOperator(noSendTxOpts, opDetails, operator.MetadataUrl) + tx, err := w.delegationManager.RegisterAsOperator(noSendTxOpts, gethcommon.HexToAddress(operator.DelegationApproverAddress), operator.AllocationDelay, operator.MetadataUrl) if err != nil { return nil, err } @@ -191,20 +194,16 @@ func (w *ChainWriter) UpdateOperatorDetails( } w.logger.Infof("updating operator details of operator %s to EigenLayer", operator.Address) - opDetails := delegationmanager.IDelegationManagerOperatorDetails{ - // Earning receiver has been deprecated, so we just use the operator address as a dummy value - // Any reward related setup is via RewardsCoordinator contract - DeprecatedEarningsReceiver: gethcommon.HexToAddress(operator.Address), - DelegationApprover: gethcommon.HexToAddress(operator.DelegationApproverAddress), - StakerOptOutWindowBlocks: operator.StakerOptOutWindowBlocks, - } noSendTxOpts, err := w.txMgr.GetNoSendTxOpts() if err != nil { return nil, err } - tx, err := w.delegationManager.ModifyOperatorDetails(noSendTxOpts, opDetails) + operatorAddress := gethcommon.HexToAddress(operator.Address) + delegationApprover := gethcommon.HexToAddress(operator.DelegationApproverAddress) + + tx, err := w.delegationManager.ModifyOperatorDetails(noSendTxOpts, operatorAddress, delegationApprover) if err != nil { return nil, err } @@ -223,7 +222,7 @@ func (w *ChainWriter) UpdateOperatorDetails( return receipt, nil } -func (w *ChainWriter) UpdateMetadataURI(ctx context.Context, uri string, waitForReceipt bool, +func (w *ChainWriter) UpdateMetadataURI(ctx context.Context, operator types.Operator, uri string, waitForReceipt bool, ) (*gethtypes.Receipt, error) { if w.delegationManager == nil { return nil, errors.New("DelegationManager contract not provided") @@ -234,7 +233,9 @@ func (w *ChainWriter) UpdateMetadataURI(ctx context.Context, uri string, waitFor return nil, err } - tx, err := w.delegationManager.UpdateOperatorMetadataURI(noSendTxOpts, uri) + operatorAddress := gethcommon.HexToAddress(operator.Address) + + tx, err := w.delegationManager.UpdateOperatorMetadataURI(noSendTxOpts, operatorAddress, uri) if err != nil { return nil, err } @@ -324,7 +325,7 @@ func (w *ChainWriter) SetClaimerFor( func (w *ChainWriter) ProcessClaim( ctx context.Context, - claim rewardscoordinator.IRewardsCoordinatorRewardsMerkleClaim, + claim rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim, earnerAddress gethcommon.Address, waitForReceipt bool, ) (*gethtypes.Receipt, error) { @@ -406,7 +407,7 @@ func (w *ChainWriter) SetOperatorPISplit( func (w *ChainWriter) ProcessClaims( ctx context.Context, - claims []rewardscoordinator.IRewardsCoordinatorRewardsMerkleClaim, + claims []rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim, earnerAddress gethcommon.Address, waitForReceipt bool, ) (*gethtypes.Receipt, error) { diff --git a/types/operator.go b/types/operator.go index e0187e9f..c1856425 100644 --- a/types/operator.go +++ b/types/operator.go @@ -26,7 +26,9 @@ type Operator struct { // https://github.com/Layr-Labs/eigenlayer-contracts/blob/delegation-redesign/src/contracts/interfaces/IDelegationManager.sol#L18 DelegationApproverAddress string `yaml:"delegation_approver_address" json:"delegation_approver_address"` - StakerOptOutWindowBlocks uint32 `yaml:"staker_opt_out_window_blocks" json:"staker_opt_out_window_blocks"` + + // https://github.com/Layr-Labs/eigenlayer-contracts/blob/3605cb791c296f7bc8d973018e03a53da15858a9/src/contracts/core/AllocationManager.sol#L420 + AllocationDelay uint32 `yaml:"operator_magnitude_allocation_delay_blocks" json:"operator_magnitude_allocation_delay_blocks"` // MetadataUrl URL where operator metadata is stored MetadataUrl string `yaml:"metadata_url" json:"metadata_url"` @@ -118,6 +120,22 @@ func G1PubkeyFromContractG1Pubkey(pubkey apkreg.BN254G1Point) *bls.G1Point { return bls.NewG1Point(pubkey.X, pubkey.Y) } +type OperatorSetIds []OperatorSetId + +func (o OperatorSetIds) UnderlyingType() []uint32 { + underlying := make([]uint32, len(o)) + for i, v := range o { + underlying[i] = v.UnderlyingType() + } + return underlying +} + +type OperatorSetId uint32 + +func (o OperatorSetId) UnderlyingType() uint32 { + return uint32(o) +} + type QuorumNums []QuorumNum func (q QuorumNums) LogValue() slog.Value {