# π§ 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`.