Skip to content

Commit

Permalink
feat: add ServiceManagerBase.createAVSRewardsSubmission wrapper (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaRedHand authored Feb 12, 2025
1 parent 6d0777d commit 4d7abd4
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
42 changes: 42 additions & 0 deletions chainio/clients/avsregistry/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,45 @@ func (w *ChainWriter) UpdateAVSMetadataURI(
}
return receipt, nil
}

// Creates a new rewards submission to the EigenLayer RewardsCoordinator contract,
// to be split amongst the set of stakers delegated to operators who are registered
// to this `avs`. Returns the receipt of the transaction in case of success.
//
// Can fail in some cases:
// - Only callable by the permissioned rewardsInitiator address
// - The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION`
// - The tokens are sent to the `RewardsCoordinator` contract
// - Strategies must be in ascending order of addresses to check for duplicates
// - This function may fail to execute with a large number of submissions due to gas limits. Use a
// smaller array of submissions if necessary.
func (w *ChainWriter) CreateAVSRewardsSubmission(
ctx context.Context,
rewardsSubmission []servicemanager.IRewardsCoordinatorTypesRewardsSubmission,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
w.logger.Info("creating AVS rewards submission ", "rewardsSubmission", rewardsSubmission)

// TODO: store binding in struct
serviceManagerContract, err := servicemanager.NewContractServiceManagerBase(
w.serviceManagerAddr,
w.ethClient,
)
if err != nil {
return nil, utils.WrapError("failed to create ServiceManager contract", err)
}

noSendTxOpts, err := w.txMgr.GetNoSendTxOpts()
if err != nil {
return nil, err
}
tx, err := serviceManagerContract.CreateAVSRewardsSubmission(noSendTxOpts, rewardsSubmission)
if err != nil {
return nil, err
}
receipt, err := w.txMgr.Send(ctx, tx, waitForReceipt)
if err != nil {
return nil, utils.WrapError("failed to send CreateAVSRewardsSubmission tx with err", err.Error())
}
return receipt, nil
}
42 changes: 42 additions & 0 deletions chainio/clients/avsregistry/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,48 @@ func TestSetEjectionCooldown(t *testing.T) {
assert.Equal(t, newCooldown, ejectionCooldown)
}

func TestCreateAVSRewardsSubmission(t *testing.T) {
clients, _ := testclients.BuildTestClients(t)
chainWriter := clients.AvsRegistryChainWriter

strategies, err := clients.AvsRegistryChainReader.StrategyParamsByIndex(nil, 0, big.NewInt(0))
require.NoError(t, err)

calculationInterval, err := clients.EigenlayerContractBindings.RewardsCoordinator.CALCULATIONINTERVALSECONDS(nil)
require.NoError(t, err)

strategy := strategies.Strategy

_, token, err := clients.ElChainReader.GetStrategyAndUnderlyingToken(context.TODO(), strategies.Strategy)
require.NoError(t, err)

strategiesAndMultipliers := []servicemanager.IRewardsCoordinatorTypesStrategyAndMultiplier{
{
Strategy: strategy,
Multiplier: big.NewInt(1),
},
}
header, err := clients.EthHttpClient.HeaderByNumber(context.TODO(), nil)
require.NoError(t, err)

// These values are set to align with the contract's requirements for the `OperatorDirectedRewardsSubmission`.
// https://github.com/Layr-Labs/eigenlayer-contracts/blob/ecaff6304de6cb0f43b42024ad55d0e8a0430790/src/contracts/core/RewardsCoordinator.sol#L414
// https://github.com/Layr-Labs/eigenlayer-contracts/blob/ecaff6304de6cb0f43b42024ad55d0e8a0430790/src/contracts/core/RewardsCoordinator.sol#L482
var duration uint32 = calculationInterval
var startTimestamp uint32 = ((uint32(header.Time) / calculationInterval) + 1) * calculationInterval

rewardsSubmission := []servicemanager.IRewardsCoordinatorTypesRewardsSubmission{{
StrategiesAndMultipliers: strategiesAndMultipliers,
Token: token,
Amount: big.NewInt(1000),
StartTimestamp: startTimestamp,
Duration: duration,
}}
receipt, err := chainWriter.CreateAVSRewardsSubmission(context.TODO(), rewardsSubmission, true)
require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)
}

func TestUpdateAVSMetadataURI(t *testing.T) {
clients, _ := testclients.BuildTestClients(t)
chainWriter := clients.AvsRegistryChainWriter
Expand Down

0 comments on commit 4d7abd4

Please sign in to comment.