Skip to content

Commit

Permalink
feat: rewards 2.1 calculation (#215)
Browse files Browse the repository at this point in the history
# Motivation
We need to support Rewards v2.1 calculation. 

This PR builds on top of #197
which supported the Eigen state models for
`OperatorDirectedOperatorSetRewardSubmissions`, `OperatorSetSplits`,
`OperatorSetOperatorRegistrations`, `OperatorSetStrategyRegistrations`.

# Modifications
* Snapshot generation for:
`OperatorDirectedOperatorSetRewardSubmissions`, `OperatorSetSplits`,
`OperatorSetOperatorRegistrations`, `OperatorSetStrategyRegistrations`.
* Refactoring Staging and Final numbering from 11 and 12 to 15 and 16.
* Mississippi hard fork for Rewards v2.1.
* New Operator Directed Operator Set rewards calculation to be triggered
after Mississippi hard fork.
* Updated Rewards For All Earners (Programmatic Incentives) calculation
to include operators registered to operator sets after Mississippi hard
fork.
* Staker-operator calculation for Rewards v2.1. 

# Results
Rewards v2.1 calculation.

# Tests
Existing Rewards tests passing.

<img width="660" alt="Screenshot 2025-01-31 at 1 33 38 PM"
src="https://github.com/user-attachments/assets/876c2d7c-be22-48b6-a046-55ead8a12530"
/>
  • Loading branch information
0xrajath authored Feb 4, 2025
2 parents b0c93a9 + 089c94a commit 5b9d766
Show file tree
Hide file tree
Showing 35 changed files with 2,768 additions and 168 deletions.
61 changes: 41 additions & 20 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ const (

// Rewards forks named after rivers
const (
RewardsFork_Nile ForkName = "nile"
RewardsFork_Amazon ForkName = "amazon"
RewardsFork_Panama ForkName = "panama"
RewardsFork_Arno ForkName = "arno"
RewardsFork_Trinity ForkName = "trinity"
RewardsFork_Nile ForkName = "nile"
RewardsFork_Amazon ForkName = "amazon"
RewardsFork_Panama ForkName = "panama"
RewardsFork_Arno ForkName = "arno"
RewardsFork_Trinity ForkName = "trinity"
RewardsFork_Mississippi ForkName = "mississippi"
)

func normalizeFlagName(name string) string {
Expand Down Expand Up @@ -293,27 +294,30 @@ func (c *Config) GetRewardsSqlForkDates() (ForkMap, error) {
switch c.Chain {
case Chain_Preprod:
return ForkMap{
RewardsFork_Amazon: "1970-01-01", // Amazon hard fork was never on preprod as we backfilled
RewardsFork_Nile: "2024-08-14", // Last calculation end timestamp was 8-13: https://holesky.etherscan.io/tx/0xb5a6855e88c79312b7c0e1c9f59ae9890b97f157ea27e69e4f0fadada4712b64#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2024-12-11",
RewardsFork_Trinity: "2025-01-09",
RewardsFork_Amazon: "1970-01-01", // Amazon hard fork was never on preprod as we backfilled
RewardsFork_Nile: "2024-08-14", // Last calculation end timestamp was 8-13: https://holesky.etherscan.io/tx/0xb5a6855e88c79312b7c0e1c9f59ae9890b97f157ea27e69e4f0fadada4712b64#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2024-12-11",
RewardsFork_Trinity: "2025-01-09",
RewardsFork_Mississippi: "2025-02-03",
}, nil
case Chain_Holesky:
return ForkMap{
RewardsFork_Amazon: "1970-01-01", // Amazon hard fork was never on testnet as we backfilled
RewardsFork_Nile: "2024-08-13", // Last calculation end timestamp was 8-12: https://holesky.etherscan.io/tx/0x5fc81b5ed2a78b017ef313c181d8627737a97fef87eee85acedbe39fc8708c56#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2024-12-13",
RewardsFork_Trinity: "2025-01-09",
RewardsFork_Amazon: "1970-01-01", // Amazon hard fork was never on testnet as we backfilled
RewardsFork_Nile: "2024-08-13", // Last calculation end timestamp was 8-12: https://holesky.etherscan.io/tx/0x5fc81b5ed2a78b017ef313c181d8627737a97fef87eee85acedbe39fc8708c56#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2024-12-13",
RewardsFork_Trinity: "2025-01-09",
RewardsFork_Mississippi: "2025-02-10",
}, nil
case Chain_Mainnet:
return ForkMap{
RewardsFork_Amazon: "2024-08-02", // Last calculation end timestamp was 8-01: https://etherscan.io/tx/0x2aff6f7b0132092c05c8f6f41a5e5eeeb208aa0d95ebcc9022d7823e343dd012#eventlog
RewardsFork_Nile: "2024-08-12", // Last calculation end timestamp was 8-11: https://etherscan.io/tx/0x922d29d93c02d189fc2332041f01a80e0007cd7a625a5663ef9d30082f7ef66f#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2025-01-21",
RewardsFork_Trinity: "2025-01-21",
RewardsFork_Amazon: "2024-08-02", // Last calculation end timestamp was 8-01: https://etherscan.io/tx/0x2aff6f7b0132092c05c8f6f41a5e5eeeb208aa0d95ebcc9022d7823e343dd012#eventlog
RewardsFork_Nile: "2024-08-12", // Last calculation end timestamp was 8-11: https://etherscan.io/tx/0x922d29d93c02d189fc2332041f01a80e0007cd7a625a5663ef9d30082f7ef66f#eventlog
RewardsFork_Panama: "2024-10-01",
RewardsFork_Arno: "2025-01-21",
RewardsFork_Trinity: "2025-01-21",
RewardsFork_Mississippi: "2025-03-27",
}, nil
}
return nil, errors.New("unsupported chain")
Expand Down Expand Up @@ -386,6 +390,23 @@ func (c *Config) IsRewardsV2EnabledForCutoffDate(cutoffDate string) (bool, error
return cutoffDateTime.Compare(arnoForkDateTime) >= 0, nil
}

func (c *Config) IsRewardsV2_1EnabledForCutoffDate(cutoffDate string) (bool, error) {
forks, err := c.GetRewardsSqlForkDates()
if err != nil {
return false, err
}
cutoffDateTime, err := time.Parse(time.DateOnly, cutoffDate)
if err != nil {
return false, errors.Join(fmt.Errorf("failed to parse cutoff date %s", cutoffDate), err)
}
mississippiForkDateTime, err := time.Parse(time.DateOnly, forks[RewardsFork_Mississippi])
if err != nil {
return false, errors.Join(fmt.Errorf("failed to parse Mississippi fork date %s", forks[RewardsFork_Mississippi]), err)
}

return cutoffDateTime.Compare(mississippiForkDateTime) >= 0, nil
}

// CanIgnoreIncorrectRewardsRoot returns true if the rewards root can be ignored for the given block number
//
// Due to inconsistencies in the rewards root calculation on testnet, we know that some roots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ func (osor *OperatorSetOperatorRegistrationModel) handleOperatorSetOperatorRegis

operatorRegistration := &OperatorSetOperatorRegistration{
Operator: strings.ToLower(arguments[0].Value.(string)),
Avs: outputData.OperatorSet.Avs,
OperatorSetId: outputData.OperatorSet.Id,
Avs: strings.ToLower(outputData.OperatorSet.Avs),
OperatorSetId: uint64(outputData.OperatorSet.Id),
IsActive: isActive,
BlockNumber: log.BlockNumber,
TransactionHash: log.TransactionHash,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ func (ossr *OperatorSetStrategyRegistrationModel) handleOperatorSetStrategyRegis
}

strategyRegistration := &OperatorSetStrategyRegistration{
Strategy: outputData.Strategy,
Avs: outputData.OperatorSet.Avs,
OperatorSetId: outputData.OperatorSet.Id,
Strategy: strings.ToLower(outputData.Strategy),
Avs: strings.ToLower(outputData.OperatorSet.Avs),
OperatorSetId: uint64(outputData.OperatorSet.Id),
IsActive: isActive,
BlockNumber: log.BlockNumber,
TransactionHash: log.TransactionHash,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package _202501301458_operatorSetSplitSnapshots

import (
"database/sql"

"github.com/Layr-Labs/sidecar/internal/config"
"gorm.io/gorm"
)

type Migration struct {
}

func (m *Migration) Up(db *sql.DB, grm *gorm.DB, cfg *config.Config) error {
queries := []string{
`CREATE TABLE IF NOT EXISTS operator_set_split_snapshots (
operator varchar not null,
avs varchar not null,
operator_set_id bigint not null,
split integer not null,
snapshot date not null,
UNIQUE (operator, avs, operator_set_id, snapshot)
)`,
}
for _, query := range queries {
if _, err := db.Exec(query); err != nil {
return err
}
}
return nil
}

func (m *Migration) GetName() string {
return "202501301458_operatorSetSplitSnapshots"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package _202501301502_operatorSetOperatorRegistrationSnapshots

import (
"database/sql"

"github.com/Layr-Labs/sidecar/internal/config"
"gorm.io/gorm"
)

type Migration struct {
}

func (m *Migration) Up(db *sql.DB, grm *gorm.DB, cfg *config.Config) error {
queries := []string{
`CREATE TABLE IF NOT EXISTS operator_set_operator_registration_snapshots (
operator varchar not null,
avs varchar not null,
operator_set_id bigint not null,
snapshot date not null,
UNIQUE (operator, avs, operator_set_id, snapshot)
)`,
}
for _, query := range queries {
if _, err := db.Exec(query); err != nil {
return err
}
}
return nil
}

func (m *Migration) GetName() string {
return "202501301502_operatorSetOperatorRegistrationSnapshots"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package _202501301505_operatorSetStrategyRegistrationSnapshots

import (
"database/sql"

"github.com/Layr-Labs/sidecar/internal/config"
"gorm.io/gorm"
)

type Migration struct {
}

func (m *Migration) Up(db *sql.DB, grm *gorm.DB, cfg *config.Config) error {
queries := []string{
`CREATE TABLE IF NOT EXISTS operator_set_strategy_registration_snapshots (
strategy varchar not null,
avs varchar not null,
operator_set_id bigint not null,
snapshot date not null,
UNIQUE (strategy, avs, operator_set_id, snapshot)
)`,
}
for _, query := range queries {
if _, err := db.Exec(query); err != nil {
return err
}
}
return nil
}

func (m *Migration) GetName() string {
return "202501301505_operatorSetStrategyRegistrationSnapshots"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package _202501301945_operatorDirectedOperatorSetRewards

import (
"database/sql"

"github.com/Layr-Labs/sidecar/internal/config"
"gorm.io/gorm"
)

type Migration struct {
}

func (m *Migration) Up(db *sql.DB, grm *gorm.DB, cfg *config.Config) error {
queries := []string{
`CREATE TABLE IF NOT EXISTS operator_directed_operator_set_rewards (
avs varchar not null,
operator_set_id bigint not null,
reward_hash varchar not null,
token varchar not null,
operator varchar not null,
operator_index integer not null,
amount numeric not null,
strategy varchar not null,
strategy_index integer not null,
multiplier numeric(78) not null,
start_timestamp timestamp(6) not null,
end_timestamp timestamp(6) not null,
duration bigint not null,
block_number bigint not null,
block_time timestamp without time zone not null,
block_date date not null,
UNIQUE (avs, operator_set_id, reward_hash, operator_index, strategy_index),
CONSTRAINT operator_directed_operator_set_rewards_block_number_fkey FOREIGN KEY (block_number) REFERENCES blocks(number) ON DELETE CASCADE
)`,
}

for _, query := range queries {
if err := grm.Exec(query).Error; err != nil {
return err
}
}
return nil
}

func (m *Migration) GetName() string {
return "202501301945_operatorDirectedOperatorSetRewards"
}
11 changes: 10 additions & 1 deletion pkg/postgres/migrations/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package migrations
import (
"database/sql"
"fmt"
_202501241111_addIndexesForRpcFunctions "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501241111_addIndexesForRpcFunctions"
"time"

_202501241111_addIndexesForRpcFunctions "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501241111_addIndexesForRpcFunctions"

"github.com/Layr-Labs/sidecar/internal/config"
_202409061249_bootstrapDb "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202409061249_bootstrapDb"
_202409061250_eigenlayerStateTables "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202409061250_eigenlayerStateTables"
Expand Down Expand Up @@ -54,6 +55,10 @@ import (
_202501241533_operatorSetSplits "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501241533_operatorSetSplits"
_202501271727_operatorSetOperatorRegistrations "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501271727_operatorSetOperatorRegistrations"
_202501281806_operatorSetStrategyRegistrations "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501281806_operatorSetStrategyRegistrations"
_202501301458_operatorSetSplitSnapshots "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501301458_operatorSetSplitSnapshots"
_202501301502_operatorSetOperatorRegistrationSnapshots "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501301502_operatorSetOperatorRegistrationSnapshots"
_202501301505_operatorSetStrategyRegistrationSnapshots "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501301505_operatorSetStrategyRegistrationSnapshots"
_202501301945_operatorDirectedOperatorSetRewards "github.com/Layr-Labs/sidecar/pkg/postgres/migrations/202501301945_operatorDirectedOperatorSetRewards"
"go.uber.org/zap"
"gorm.io/gorm"
)
Expand Down Expand Up @@ -144,6 +149,10 @@ func (m *Migrator) MigrateAll() error {
&_202501241533_operatorSetSplits.Migration{},
&_202501271727_operatorSetOperatorRegistrations.Migration{},
&_202501281806_operatorSetStrategyRegistrations.Migration{},
&_202501301458_operatorSetSplitSnapshots.Migration{},
&_202501301502_operatorSetOperatorRegistrationSnapshots.Migration{},
&_202501301505_operatorSetStrategyRegistrationSnapshots.Migration{},
&_202501301945_operatorDirectedOperatorSetRewards.Migration{},
}

for _, migration := range migrations {
Expand Down
Loading

0 comments on commit 5b9d766

Please sign in to comment.