Skip to content

Release/rewards v2.2#497

Open
seanmcgary wants to merge 61 commits into
masterfrom
release/rewards-v2.2
Open

Release/rewards v2.2#497
seanmcgary wants to merge 61 commits into
masterfrom
release/rewards-v2.2

Conversation

@seanmcgary

Copy link
Copy Markdown
Member

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Chore (non-breaking change which does not add functionality)
  • Docs (documentation updates)
  • Performance improvement
  • Refactor (non-breaking change which does not add or remove functionality)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

## Description

Skipping `should process blocks` test due to holesky deprecation and
hoodi/sepolia doesn't have `RewardsClaimed` event yet.

## Type of change

- [x] Chore (non-breaking change which does not add functionality)

## How Has This Been Tested?

Passing CI test.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
## Description

### Testnet Hoodi
Upgrades existing contracts (adds new implementation addresses):
```
DelegationManager: 0x6fe5ebe3ed0f4b2419263868efb5cc640e541407
StrategyManager: 0xfc868562d93c4dc192419e970c220279cdab7b26
AVSDirectory: 0xe368218addc4d2ddc5b0afd70f5878dd8c1713eb
AllocationManager: 0x4a3027fc3ae9593874123df96e21e89a698cd7d9
RewardsCoordinator: 0x4a93d276ea78b48be9d8bb864bacdd5d5a713084
EigenPodManager: 0x0f264e714a3c03309f4041db26229ef4e9b00f5c
```
Adds new contracts (both proxy and implementation):
```
ReleaseManager: proxy 0xe863060013cb95473b96f7c3e1444e3e3df65671, impl 0x7a2b8c559a8c8c71a9d364ad250fce5a24b18f5d
CrossChainRegistry: proxy 0x9269432451965996be7796582c062cb0795d3e8b, impl 0x1bf65df60184a4a112742ce07f857739fedefbc0
OperatorTableUpdater: proxy 0xb02a15c6bd0882b35e9936a9579f35fb26e11476, impl 0x5dd026aa1c431858e439736d063111763243acae
ECDSACertificateVerifier: proxy 0xb3cd1a457dea9a9a6f6406c6419b1c326670a96f, impl 0xe867777f7c45cf6af9b08c7ad62b37c1be61dd25
BN254CertificateVerifier: proxy 0xff58a373c18268f483c1f5ca03cf885c0c43373a, impl 0xe5d02648ddd59ba688846fb5d01f738da6c1ffcb
TaskMailbox: proxy 0xb99cc53e8db7018f557606c2a5b066527bf96b26, impl 0xda35d6af400ef38e91bf3eb6c57d9e8d1bf35e36
```
### Testnet Sepolia
Same contracts upgraded + adding missing KeyRegistrar contract

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
fix test

fix time to utc

fix time

time utc

fix

fix
fix

fix test
#474)

## Description

### 1. Database Migration
(`202511141700_withdrawalQueueAndAllocationRounding`)
- Enhanced `queued_slashing_withdrawals` table with timing columns for
14-day withdrawal tracking:
  - `completed`, `completion_*` - Completion tracking
- Enhanced `operator_allocations` table with rounding support:
- `effective_date` - Rounded date when allocation/deallocation takes
effect

### 2. Allocation/Deallocation Rounding Logic (Sabine Fork)
Implements day-boundary rounding to prevent gaming and mimic existing
registration behavior:
- **Allocations (increases)**: Round **UP** to next day → starts earning
tomorrow
- **Deallocations (decreases)**: Round **DOWN** to current day → stops
earning immediately
- **No change**: Round **DOWN** to current day (conservative default)

### 3. Dual Behavior Implementation
Maintains backward compatibility with fork-based behavior switching:
- **Before Sabine fork**: Uses old behavior (no rounding, date fields
are NULL)
- **After Sabine fork**: Applies rounding logic and populates date
fields
- Model continues processing allocations from Brazos fork onwards

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

Unit tests

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
…ion (#488)

## Description

sidecar was crashing with this error:
```
pq: unsupported Unicode escape sequence
```
the issue is smart contracts can emit Solidity strings containing null
bytes (`\u0000`), which are valid in Solidity but not supported by
PostgreSQL in text/varchar columns.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

Unit tests

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
- [ ] I have checked my code and corrected any misspellings
…ation (#476)

## Description

### Problem
Operators were not earning rewards during the deallocation queue period,
even though their allocations remain at risk until the `effective_date`.

**Current behavior:**
- Operator deallocates 100 from allocation on Day 1 (effective_date =
Day 15)
- `operator_allocations` table immediately shows reduced allocation
- Rewards calculation uses reduced amount → ❌ Operator loses 14 days of
rewards

**Expected behavior:**
- Operator should continue earning on OLD (higher) allocation until
`effective_date`
- After `effective_date`, earn on NEW (lower) allocation

### Solution
**Deallocation Queue Adjustment**:
Added `AdjustOperatorShareSnapshotsForDeallocationQueue()` function
that:
1. Reads `magnitude_decrease` from `deallocation_queue_snapshots`
2. Aggregates across all AVSs per (operator, strategy)
3. Adds the decrease back to `operator_share_snapshots` during queue
period

This mirrors the existing withdrawal queue adjustment for stakers.

**Operator Allocation Snapshots**:
New operatorAllocationSnapshots.go generates daily snapshots with
allocation rounding:

- Allocations round UP to next day (allocation @ 5pm on 1/4 → starts
1/5)
- Deallocations round DOWN to previous day (deallocation @ 5pm on 1/4,
effective 1/18 → reduced allocation starts 1/17)
- Tracks max_magnitude for slashable stake calculations

**Gold Tables 15-17 (Unique Stake Rewards):**

- Table 15: Operator rewards based on allocated magnitude
- Table 16: Staker rewards (distributed from Table 15)
- Table 17: AVS refunds for unallocated periods

### Changes

- Added deallocationQueueShareSnapshots.go - deallocation queue
adjustment
- Added operatorAllocationSnapshots.go - allocation snapshot generation
with rounding
- Added Gold Tables 15-17 for unique stake reward distribution
- Integrated into rewards calculation pipeline in rewards.go
- Migration: 202511141700_withdrawalQueueAndAllocationRounding - creates
operator_allocation_snapshots table

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?



## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
…al Stake (#481)

## Description

Implements Rewards v2.2 - Operator Set rewards with automatic
stake-weighted distribution for both unique allocated stake and total
delegated stake. This brings forward-looking reward capabilities (up to
2 years) to operator sets managed via AllocationManager, closing the
architectural gap where only AVSDirectory-based AVSs could create
forward-looking rewards.

### Withdrawal Queue Integration (Sabine Fork)
14-day withdrawal delay now integrated into staker share snapshots:

- Withdrawals queued on Day 1 → shares removed starting Day 15
- Slashing during queue period adjusts withdrawable amounts
- Tracked via queued_slashing_withdrawals table
- Migration: 202512101500_queuedWithdrawalSlashingAdjustments

### Unique Stake Rewards (Tables 15-17)
Rewards based on allocated unique stake to operator sets:

- Table 15: Operator rewards - calculates pro-rata distribution based on
(shares × magnitude / max_magnitude) × multiplier
- Table 16: Staker rewards - distributes staker portion from Table 15,
respects withdrawal queue
- Table 17: AVS refunds - refunds for operators without unique stake
allocations

### Total Stake Rewards (Tables 18-20)
Rewards based on total delegated stake (operator set analog to Rewards
v1):

- Table 18: Operator rewards - calculates pro-rata distribution based on
shares × multiplier
- Table 19: Staker rewards - distributes staker portion from Table 18,
queue-aware
- Table 20: AVS refunds - refunds for operators without sufficient total
stake

### Refund Logic
Tables 17 and 20 calculate separate refund buckets (not subtractions)
for three scenarios:

- Operators not registered to operator set
- Operators registered but without required stake (unique stake for
15-17, total stake for 18-20)
- Operators with stake but strategies not registered

These refunds are tracked separately and combined in final staging
tables (Table 21).

### Slashable Period Tracking
Enhanced operatorSetOperatorRegistrationSnapshots to track
slashable_until:

- Operators remain in snapshots until deregistration + 14 days
- Ensures correct reward distribution during post-deregistration
slashable period
- Migration:
202512160000_addSlashableUntilToOperatorRegistrationSnapshots

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

Integration testing

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
Slashes on day X now correctly become visible for snapshots on day X+1,
matching the spec rule: block_date < snapshot_date
)

## Description

### Summary
Adds comprehensive unit, integration, and Anvil tests for Rewards v2.2
(PRs #476, #481), validating operator allocation snapshots, withdrawal
queue logic, and refund calculations. All tests passing with 100%
coverage of edge cases defined in the Rewards V2.2 Testing Plan.

### Test Coverage

**OAS (Operator Allocation Snapshots) - 17 scenarios:**

- OAS-1 to OAS-3: Basic allocation rounding (UP for allocations, DOWN
for deallocations)
- OAS-4 to OAS-9: Same-day allocation changes, effective block delays
- OAS-10 to OAS-14: Max magnitude updates, slashing simulations
- OAS-15 to OAS-17: Multi-strategy allocations, future block scenarios

**SSS (Staker Share Snapshots) - 15 scenarios:**

- SSS-1 to SSS-7: Withdrawal queue timing (14-day delay)
- SSS-8 to SSS-11: Slashing during withdrawal queue
- SSS-12 to SSS-15: Same-block events (withdrawal + slash log ordering),
dual slashing

**R (Refunds) - 4 scenarios:**

- R-1: Full period refund (no allocation)
- R-2: Partial refund (allocation starts mid-period)
- R-3: Post-deallocation refund
- R-4: Multi-operator proportional distribution

**Integration Tests (8 Scenarios - PostgreSQL):**

- Scenario 1: Forward-looking rewards with withdrawal during period
- Scenario 2: Multiple concurrent withdrawals
- Scenario 3: Slash during withdrawal queue
- Scenario 4: 2-year forward-looking rewards
- Scenario 5: Deallocation queue (operator unique stake)
- Scenario 6: Undelegation with slashing (TC4)
- Scenario 7: Withdrawal queue with deallocation
- Scenario 8: Withdrawal completing at reward period end

**Anvil Tests (10 Scenarios - Real Contract Events):**

- Tier 2 and Tier 3 tests with actual AllocationManager events
- Validates event ingestion and snapshot generation
- Configured for PreprodHoodi environment

### Bug Fixes & Improvements
**Schema Corrections:**

- Fixed blocks table inserts (removed non-existent columns)
- Fixed operator_allocations inserts (removed avs_directory, block_time)
- Fixed staker_shares inserts (aligned with migration schema)
- Fixed reward_submissions and operator_set_operator_registrations
schemas

**Snapshot Timing Logic:**

- Corrected off-by-one errors (events on 1/5 appear in 1/6 snapshot)
- Fixed withdrawal queue timing (14-day inclusive/exclusive logic)
- Adjusted all test expectations to match block_date < snapshot_date
logic

**Linter Fixes:**

- Fixed unchecked error returns in rewardsV2_2_anvil_test.go (10
instances)
- Removed unused variables across test files
- Fixed timezone comparison issues (using formatted strings)

**Chain Configuration:**

- Updated all tests to use Chain_PreprodHoodi
- Verified Sabine fork configuration (1970-01-01 for preprod
environments)

### Notes

- Legacy tests in stakerShareSnapshots_test.go intentionally skipped
(incompatible with continuous daily snapshot generation)
- Test database automatically created/dropped for isolation
- Anvil tests require REWARDS_COORDINATOR_ADDRESS and
ALLOCATION_MANAGER_ADDRESS environment variables

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
- [x] Chore (non-breaking change which does not add functionality)

## How Has This Been Tested?

Unit tests

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
@seanmcgary seanmcgary requested a review from a team as a code owner January 30, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants