Skip to content

Commit

Permalink
feat: integrate Rewards V2.1 (#534)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomás Grüner <[email protected]>
  • Loading branch information
Sidu28 and MegaRedHand authored Feb 7, 2025
1 parent 9aa22f0 commit afbaa41
Show file tree
Hide file tree
Showing 23 changed files with 606 additions and 31 deletions.
12 changes: 12 additions & 0 deletions chainio/clients/elcontracts/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,18 @@ func (r *ChainReader) GetOperatorPISplit(
return r.rewardsCoordinator.GetOperatorPISplit(&bind.CallOpts{Context: ctx}, operator)
}

func (r *ChainReader) GetOperatorSetSplit(
ctx context.Context,
operator gethcommon.Address,
operatorSet rewardscoordinator.OperatorSet,
) (uint16, error) {
if r.rewardsCoordinator == nil {
return 0, errors.New("RewardsCoordinator contract not provided")
}

return r.rewardsCoordinator.GetOperatorSetSplit(&bind.CallOpts{Context: ctx}, operator, operatorSet)
}

func (r *ChainReader) GetAllocatableMagnitude(
ctx context.Context,
operatorAddress gethcommon.Address,
Expand Down
23 changes: 19 additions & 4 deletions chainio/clients/elcontracts/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,21 @@ func TestInvalidConfig(t *testing.T) {
require.Error(t, err)
})

t.Run("get operator set", func(t *testing.T) {
testAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
operatorSetId := uint32(1)
operatorSet := rewardscoordinator.OperatorSet{
Avs: testAddr,
Id: operatorSetId,
}
_, err = chainReader.GetOperatorSetSplit(
context.Background(),
common.HexToAddress(operatorAddr),
operatorSet,
)
require.Error(t, err)
})

t.Run("try to get strategy and underlying token with wrong strategy address", func(t *testing.T) {
// Invalid strategy address
strategyAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
Expand Down Expand Up @@ -1059,26 +1074,26 @@ func TestOperatorSetsAndSlashableShares(t *testing.T) {
chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, operatorPrivateKeyHex, config)
require.NoError(t, err)

avsAdrr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
avsAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
avsPrivateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY
operatorSetId := uint32(1)
operatorSet := allocationmanager.OperatorSet{
Avs: avsAdrr,
Avs: avsAddr,
Id: operatorSetId,
}

strategyAddr := contractAddrs.Erc20MockStrategy
strategies := []common.Address{strategyAddr}

err = createOperatorSet(anvilHttpEndpoint, avsPrivateKeyHex, avsAdrr, operatorSetId, strategyAddr)
err = createOperatorSet(anvilHttpEndpoint, avsPrivateKeyHex, avsAddr, operatorSetId, strategyAddr)
require.NoError(t, err)

keypair, err := bls.NewKeyPairFromString("0x01")
require.NoError(t, err)

request := elcontracts.RegistrationRequest{
OperatorAddress: operatorAddr,
AVSAddress: avsAdrr,
AVSAddress: avsAddr,
OperatorSetIds: []uint32{operatorSetId},
WaitForReceipt: true,
Socket: "socket",
Expand Down
28 changes: 28 additions & 0 deletions chainio/clients/elcontracts/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,34 @@ func (w *ChainWriter) SetOperatorPISplit(
return receipt, nil
}

func (w *ChainWriter) SetOperatorSetSplit(
ctx context.Context,
operator gethcommon.Address,
operatorSet rewardscoordinator.OperatorSet,
split uint16,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
if w.rewardsCoordinator == nil {
return nil, errors.New("RewardsCoordinator contract not provided")
}

noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
if err != nil {
return nil, utils.WrapError("failed to get no send tx opts", err)
}

tx, err := w.rewardsCoordinator.SetOperatorSetSplit(noSendTxOpts, operator, operatorSet, split)
if err != nil {
return nil, utils.WrapError("failed to create SetOperatorSetSplit tx", err)
}
receipt, err := w.txMgr.Send(ctx, tx, waitForReceipt)
if err != nil {
return nil, utils.WrapError("failed to send tx", err)
}

return receipt, nil
}

// Processes the claims given by `claims`.
// The rewards are transferred to the given `recipientAddress`.
func (w *ChainWriter) ProcessClaims(
Expand Down
114 changes: 114 additions & 0 deletions chainio/clients/elcontracts/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,120 @@ func TestSetOperatorAVSSplit(t *testing.T) {
require.Error(t, err, "split must be less than 10000")
}

func TestSetOperatorSetSplit(t *testing.T) {
testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
require.NoError(t, err)

anvilHttpEndpoint, err := anvilC.Endpoint(context.Background(), "http")
require.NoError(t, err)
contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

operatorPrivateKeyHex := testutils.ANVIL_SECOND_PRIVATE_KEY
operatorAddress := common.HexToAddress(testutils.ANVIL_SECOND_ADDRESS)
privateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY
activationDelay := uint32(0)

// Set activation delay to zero so that the new AVS split can be retrieved immediately after setting it
receipt, err := setTestRewardsCoordinatorActivationDelay(anvilHttpEndpoint, privateKeyHex, activationDelay)
require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)

config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
RewardsCoordinatorAddress: contractAddrs.RewardsCoordinator,
}

// Create operator clients
chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, operatorPrivateKeyHex, config)
require.NoError(t, err)

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

avsAddress := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
operatorSetId := uint32(1)
erc20MockStrategyAddr := contractAddrs.Erc20MockStrategy

// Create an operator set to register an operator on it
err = createOperatorSet(
anvilHttpEndpoint,
privateKeyHex,
avsAddress,
operatorSetId,
erc20MockStrategyAddr,
)
require.NoError(t, err)

//SPLIT TEST START

operatorSetType1 := allocationmanager.OperatorSet{
Avs: avsAddress,
Id: uint32(operatorSetId),
}

//REGISTER OPERATOR IN OPERATOR SET

keypair, err := bls.NewKeyPairFromString("0x01")
require.NoError(t, err)

request := elcontracts.RegistrationRequest{
OperatorAddress: operatorAddress,
AVSAddress: avsAddress,
OperatorSetIds: []uint32{operatorSetId},
WaitForReceipt: true,
Socket: "socket",
BlsKeyPair: keypair,
}

receipt, err = chainWriter.RegisterForOperatorSets(
context.Background(),
contractAddrs.RegistryCoordinator,
request,
)

require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)

isRegistered, err := chainReader.IsOperatorRegisteredWithOperatorSet(
context.Background(),
operatorAddress,
operatorSetType1,
)
require.NoError(t, err)
require.Equal(t, true, isRegistered)

//FIRST GET
operatorSetType2 := rewardscoordinator.OperatorSet{
Avs: avsAddress,
Id: uint32(operatorSetId),
}

expectedInitialSplit := uint16(1000)
initialSplit, err := chainReader.GetOperatorSetSplit(context.Background(), operatorAddress, operatorSetType2)
require.NoError(t, err)
require.Equal(t, expectedInitialSplit, initialSplit)

//FIRST SET
newSplit := initialSplit + 1
waitForReceipt := true
// Set a new operator set split
receipt, err = chainWriter.SetOperatorSetSplit(
context.Background(),
operatorAddress,
operatorSetType2,
newSplit,
waitForReceipt,
)
require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)

//SECOND GET
updatedSplit, err := chainReader.GetOperatorSetSplit(context.Background(), operatorAddress, operatorSetType2)
require.NoError(t, err)
require.Equal(t, newSplit, updatedSplit)
}

func TestSetAllocationDelay(t *testing.T) {
testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
Expand Down
2 changes: 1 addition & 1 deletion contracts/anvil/contracts-deployed-anvil-state.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/bindings/AVSDirectory/binding.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/bindings/AllocationManager/binding.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/bindings/BLSApkRegistry/binding.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/bindings/ContractsRegistry/binding.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contracts/bindings/DelegationManager/binding.go

Large diffs are not rendered by default.

Loading

0 comments on commit afbaa41

Please sign in to comment.