---
# System prepended metadata

title: "\U0001F9ED Migration Guide: Transition to `ssv-rewards` (DIP-34 Revision #3)"

---

# 🧭 Migration Guide: Transition to `ssv-rewards` (DIP-34 Revision #3)

This guide outlines the changes introduced in the updated `ssv-rewards` calculation script and how to adapt your setup to comply with the latest specification.

📄 **Reference**:
[[DIP-34] Incentivized Mainnet Program – Revision #3](https://docs.google.com/document/d/1LuaX9ukms8XrrOASCkRcEvzz_0XLnC9zt3apro_7bBY/edit?tab=t.0)

## 🔄 What's Changed in `rewards.yaml`

### 1. Per-Mechanics Criteria

- `criteria` (like `min_attestations_per_day`) is now defined **under each `mechanics` block**.
- This allows reward thresholds to be adjusted per period.

**Key Change**:
`min_attestations_per_day` is now **213** for rounds from **May 2025 and above**,
reflecting the new **95% performance threshold**
(calculated as `24 * 60 / 6.4 * 0.95`, rounded down).

`min_decideds_per_day` remains unchanged.

---

### 2. Tiers: Participants → Effective Balance

- `max_participants` has been replaced by `max_effective_balance`.
- Each previous tier value was multiplied by **32 ETH** to reflect actual effective balance.

**Before:**
```yaml
tiers:
  - max_participants: 2000
    apr_boost: 0.5
  - max_participants: 5000
    apr_boost: 0.4
```

**After:**
```yaml
tiers:
  - max_effective_balance: 64000
    apr_boost: 0.5
  - max_effective_balance: 160000
    apr_boost: 0.4
```

---

### 3. Reward Attribution to Registered Address Only (Legacy Compatibility via Redirects)

- Validator rewards are now attributed only to the address that registered the validator.
- `features: [gnosis_safe]` is removed.
- Smart contracts that registered validators before this proposal will continue to have rewards attributed to their deployer address using `owner_redirects` feature.

To preserve this behavior for past mechanics, you'll need to generate redirect mappings from the **legacy database** using the following SQL queries:

For a `mechanics` block that starts in `YYYY-MM`, you should run the SQL query using:
```SQL
WHERE ve.block_time < '{start of next mechanics period}' -- in full timestamp format: YYYY-MM-DD HH:MM:SS+00
```

**Example SQL to generate redirects for pre-June 2024 validators (mechanics since 2023-07):**
```sql
SELECT DISTINCT
    ve.owner_address AS from_address,
    d.deployer_address AS to_address
FROM validator_events ve
JOIN deployers d ON ve.owner_address = d.owner_address
WHERE ve.block_time < '2024-06-01 00:00:00+00'
  AND ve.owner_address != d.deployer_address
ORDER BY ve.owner_address;
```

**Example SQL for later periods excluding gnosis safe (mechanics since 2024-06):**
```sql
SELECT DISTINCT
    ve.owner_address AS from_address,
    d.deployer_address AS to_address
FROM validator_events ve
JOIN deployers d ON ve.owner_address = d.owner_address
WHERE ve.block_time < '2024-08-01 00:00:00+00'
  AND ve.owner_address != d.deployer_address
  AND d.gnosis_safe = 'false'
ORDER BY ve.owner_address;
```
🗂️ The resulting CSV (with from,to headers) is saved as the `owner_redirects_file` for each relevant mechanics block. This ensures legacy validator rewards continue flowing to the intended deployers.

## 🆕 New Keys in `rewards.yaml`

### 1. `pectra_support` (per mechanics)

- If `true`, the script uses the actual `end_effective_balance`.
- If `false` or omitted, it uses a fixed 32 ETH for compatibility with the legacy model.
```yaml
pectra_support: true
```

📌 Important:
 - For mechanics up to and including May 2025, you can omit this flag (defaults to legacy behavior with 32 ETH).
 - Starting from June 2025, this flag must be set to true to enable the updated reward logic introduced by the Pectra upgrade.



---

### 2. `network_fee` (per round)

- Deducts a proportional fee in SSV from each recipient’s reward.
```yaml
rounds:
  - period: 2025-06 # Designated period (year-month)
    eth_apr: 0.047 # ETH Staking APR
    ssv_eth: 0.0088235294 # SSV/ETH price
    network_fee: 100_000_000  # Network fee in SSV Gwei
```

## 🚀 Migration Steps

1. Replace your current `rewards.yaml` with the new one provided.
2. Confirm that:
    - criteria exists under each mechanics block.
    - `features: [gnosis_safe]` was removed from mechanics.
    - `max_participants` was replaced by `max_effective_balance`.
    - `pectra_support` and `network_fee` are correctly added where needed.
    - Legacy redirect rules are moved to `owner_redirects_file`.
3. Run full sync from the pulled Github repo
```bash
docker compose run --rm sync sync --fresh
```
4. Recalculate rewards:
```bash
docker-compose run --rm calc
```
5. Compare `cumulative.json` from the legacy and new script to ensure result parity.
(Optional but highly recommended for validation.)



## 🆕 Faster Sync & Lower API Usage

When using the new script, all data fetched from Beaconcha.in (validator stats) and the SSV API (decided data) is cached locally in:
```
<data-dir>/<network>/.cache
```
This caching significantly reduces traffic, accelerates sync time, and protects against API rate limits.

If you want to retain the cache when syncing from scratch using `--fresh`,
use the `--keep-cache` flag to preserve the `.cache` directory:
```bash
docker-compose run --rm sync sync --fresh --keep-cache
```


⚠️ Important:
❗ Without this flag, the entire `.cache` folder will be deleted when using `--fresh`.