FlareWatch присваивает каждому P-Chain валидатору композитную оценку от 0 до 100 по 9 измерениям. Расчёты детерминированы, входные данные являются публичными данными сети [Flare Explorer] [FSE] [Flaremetrics], и один и тот же алгоритм применяется ко всем валидаторам сети — включая собственный узел валидатора FlareWatch, который оценивается по этой точной функции без специального обращения. Эта страница описывает все измерения и пороги, чтобы операторы и стейкеры могли точно видеть, как рассчитывается оценка и почему каждое значение было выбрано. Каждое утверждение здесь ссылается на первичный источник в сети или из внешних данных — см. Источники и ссылки внизу.
staking на странице валидаторов (делегирование FLR валидатору P-Chain за награды VRM + MIRROR). Оценка поставщика FTSO, показанная в режиме delegation (делегирование WFLR поставщикам данных FTSO), использует отдельный 13-мерный алгоритм, ориентированный на производительность поставщика данных — точность, участие в протоколе V2 и т.д. Это различные роли в сети с отдельными наградами, оцениваемые отдельно. См. Методология оценки поставщика FTSO для стороны делегирования.APY в таблице стейкинга — это реальная ставка, которую получает делегатор — одна цифра, без ментальной математики. Это измеряется по скриптам вознаграждений Flare (фактические выплаты, не формула), за вычетом комиссии валидатора, и она меняется каждый эпох с реальными вознаграждениями. Везде на FlareWatch APY означает после комиссии и APY означает до комиссии.
Сравнение с Flare Systems Explorer? FSE и другие обозреватели показывают только ставку делегирования — они не добавляют MIRROR — поэтому наш Total APY читается выше на любом MIRROR-активном валидаторе (разница точно равна строке MIRROR выше). Обе цифры — это ~8-эпох усредняющие значения из одних и тех же данных скриптов вознаграждений, поэтому изменение комиссии валидатора в середине окна отстает от снимка текущей комиссии на обоих сайтах, пока оно не пройдет через окно.
Две другие цифры появляются в подсказке APY и не являются ставкой делегатора: теоретический базовый уровень (валовой APY сети × (1 − комиссия), только стейкинг — используется как резерв перед достаточной измеренной историей), и доход от самозалога оператора (возврат собственного залога валидатора, усиленный захватом комиссии — метрика оператора, а не то, что вы зарабатываете).
Для оценки: измерение Net Yield оценивает только ставку делегирования VRM, и MIRROR оценивается в своем собственном измерении — поэтому MIRROR никогда не учитывается дважды, даже если он включен в отображаемый Total APY.
| 90+ | Верхний уровень — верхние ~10–20% операторов. Типичный профиль: полнофункциональный валидатор + FTSO + FDC, низкая комиссия, активный MIRROR, постоянная надёжность FIP-10, здоровая база делегаторов, значительное собственное связывание. Ни одно измерение не требуется — операторы достигают верхнего уровня, накапливая силу по большинству категорий. |
| 80–89 | Сильный — соответствует большинству ключевых критериев; одно или два измерения ниже верхнего уровня. |
| 70–79 | Хороший — соответствует всем базовым критериям; нет серьёзных пробелов. |
| 60–69 | Приемлемый — пригоден, но не дифференцирован. |
| <60 | Ниже среднего — значительные пробелы в одном или нескольких измерениях. Математический факт, не суждение о качестве. |
if (uptime >= 99.5) raw = 17 + (uptime - 99.5) * 6
else if (uptime >= 99) raw = 13 + (uptime - 99) * 8
else if (uptime >= 95) raw = 4 + (uptime - 95) * 2.25 // v3.9: was (u - 95) * 3.25 starting at 0
else raw = max(0, uptime - 90) * 0.8 // 90 → 0, 95 → 4 (continuity)
raw = clamp(raw, 0, 20)
reliability = epochsIncluded / epochsObserved // last ~8 epochs · v4.2: the
// FULL FIP-10 minimums set
// (uptime + FSP + FTSO + FDC),
// not RPC-uptime alone
score = raw * clamp(reliability, 0, 1) // dimension max 20scoreAPR = delegationAPY > 0 ? delegationAPY : baseAPR // VRM, net of fee medianAPR = median(scoreAPR across all validators) cappedAPR = min(scoreAPR, 25) // APY_DISPLAY_CAP if (medianAPR > 0): ratio = cappedAPR / medianAPR score = clamp(((ratio - 0.6) / 0.6) * 18, 0, 18) else: score = min(18, (cappedAPR / 8) * 18) // fallback: BASE_APY = 8
// anchor = max(observed minimum active fee, 20% protocol floor) d = fee - anchor // distance above market best if (d <= 0) score = 7 // at/below best available else if (d <= 5) score = 7 - d * 0.2 // 0 → 5 over: 7 → 6 else if (d <= 10) score = 6 - (d - 5) * 0.3 // 5 → 10 over: 6 → 4.5 else if (d <= 15) score = 4.5 - (d - 10) * 0.4 // 10 → 15 over: 4.5 → 2.5 else if (d <= 20) score = 2.5 - (d - 15) * 0.5 // 15 → 20 over: 2.5 → 0 else score = 0 // fees > anchor+20 saturate at 0/7 — the v4.5 extreme-fee // penalty below takes over from there
// Verification baseline (v3.10 hybrid) isCurated = (in KNOWN_VALIDATORS) OR ( daysObserved >= 90 AND operatorDelegatorCount >= 25 AND retention30d >= -15% AND selfBondFLR >= 1_000_000 ) if (isCurated) verification = 7 else if (name auto-discovered) verification = 3 else verification = 0 // FTSO-derived (only when ftsoOperatorScore is a number) clamped = clamp(ftsoOperatorScore, 50, 100) ftsoDerived = 4 + (clamped - 50) * (8/50) // FTSO 50 → 4, FTSO 100 → 12 // Final score score = max(verification, ftsoDerived)
passthrough = max(0, 1 - fee / 100) if (mirrorStatus == "active") base = 10 * passthrough else if (mirrorStatus == "paused") base = 5 * passthrough else if (mirrorStatus == "inactive") base = 0 else base = 5 * passthrough // no data yet // v4.6 — capped, median-anchored bonus for delivered MIRROR yield. // Only mirror-active validators paying ABOVE 1.2x the network median // delivered rate (mirrorAPY, net of fee) earn it; size-neutral. ratio = mirrorAPY / networkMedianMirrorAPY bonus = clamp((ratio - 1.2) * 5, 0, 2) // active only, else 0 score = base + bonus // dimension max 12
utilization = clamp(1 - freeSpaceFLR / maxDelegationFLR, 0, 1) if (utilization <= 0.70): score = 1.75 + (utilization / 0.70) * 5.25 // 1.75 → 7 ramp else: score = 7 - ((utilization - 0.70) / 0.30) * 1.75 // 7 → 5.25 ramp
// Count signal (max 6)
if (delegatorCount <= 5) countScore = 0
else if (delegatorCount >= 500) countScore = 6
else countScore = clamp(log(delegatorCount / 5) / log(100) * 6, 0, 6)
// Concentration adjustment (-1 to +1) — skip if <3 delegators
avgFLR = delegatedFLR / delegatorCount
if (avgFLR < 500_000) concentrationAdj = +1
else if (avgFLR < 5_000_000) concentrationAdj = +0.5
else if (avgFLR > 50_000_000) concentrationAdj = -1
else if (avgFLR > 20_000_000) concentrationAdj = -0.5
else concentrationAdj = 0
// Longevity bonus (0 to +1)
daysObserved = (now - firstObservedAtMs) / 86400000
if (daysObserved >= 90) longevityBonus = +1
else if (daysObserved >= 30) longevityBonus = +0.5
else longevityBonus = 0
// Self-bond alignment (-1 to +2, two-axis since v4.7)
if (selfBondFLR < 1_000_000) selfBondAdj = -1 // hollow-operator floor
else:
ratio = selfBondFLR / totalStake // totalStake = selfBond + delegated
proportional = ratio >= 0.10 ? +2 : ratio >= 0.05 ? +1 : 0
absolute = min(1, selfBondFLR / 20_000_000) * 2 // saturates at top-decile bond
selfBondAdj = max(proportional, absolute) // the better of the two axes
// Retention (-0.5 to +0.5, v3.7) — skip if no 30-day baseline yet
delta = (delegatedFLR - delegatedFLR30dAgo) / delegatedFLR30dAgo
if (delta >= +0.10) retentionAdj = +0.5
else if (delta <= -0.15) retentionAdj = -0.5
else retentionAdj = 0
// Self-bond trajectory (-0.5 to +0.5, v3.7) — skip if no baseline
sbDelta = (selfBondFLR - selfBondFLR30dAgo) / selfBondFLR30dAgo
if (sbDelta >= +0.20) selfBondTrajectoryAdj = +0.5
else if (sbDelta <= -0.10) selfBondTrajectoryAdj = -0.5
else selfBondTrajectoryAdj = 0
score = clamp(countScore + concentrationAdj + longevityBonus + selfBondAdj
+ retentionAdj + selfBondTrajectoryAdj, 0, 11)// Time-weighted rate is computed upstream from per-epoch // reward-scripts data with decay = 0.85 per epoch back. r = deliveryRatio // capped at 1.0 if (r >= 1.00) base = 10 else if (r >= 0.97) base = 9 + (r - 0.97) * (1 / 0.03) // 0.97 → 9, 1.00 → 10 else if (r >= 0.95) base = 8 + (r - 0.95) * (1 / 0.02) // 0.95 → 8, 0.97 → 9 else if (r >= 0.90) base = 6 + (r - 0.90) * (2 / 0.05) // 0.90 → 6, 0.95 → 8 else if (r >= 0.85) base = 4 + (r - 0.85) * (2 / 0.05) // 0.85 → 4, 0.90 → 6 else if (r >= 0.80) base = 2 + (r - 0.80) * (2 / 0.05) // 0.80 → 2, 0.85 → 4 else base = max(0, r * 2.5) // 0 → 0, 0.80 → 2 // Variance penalty (CoV = std-dev / mean across per-epoch rates) variancePenalty = min(0.30, coefficientOfVariation * 0.5) score = base * (1 - variancePenalty) // Sample-size confidence dampener for < 3 epochs if (totalStakesCompleted < 3): confidence = totalStakesCompleted / 3 score = 5 + (score - 5) * confidence
daysLeft = (endTimeMs - now) / 86_400_000 if (daysLeft < 14) score = 0 else if (daysLeft < 30) score = 0 + (daysLeft - 14) * (2 / 16) // 14 → 0, 30 → 2 else if (daysLeft < 60) score = 2 + (daysLeft - 30) * (1 / 30) // 30 → 2, 60 → 3 else if (daysLeft < 120) score = 3 + (daysLeft - 60) * (2 / 60) // 60 → 3, 120 → 5 else score = 5
consecutiveMisses = 0 for entry in participation.recent (newest-first): if entry.eligible: break consecutiveMisses++ if consecutiveMisses < 2: penalty = 0 elif consecutiveMisses == 2: penalty = 3 elif consecutiveMisses == 3: penalty = 6 else: penalty = 10 // 4+ score = max(0, positiveDimensionsSum - penalty)
// v4.5 — fees beyond the Fee dimension's range (anchor+20)
if fee <= 50: penalty = 0
else: fraction = min(1, (fee - 50) / 50) * 0.75
penalty = positiveDimensionsSum * fraction
// fee 50% → no change · 75% → −37.5% of score · 100% → −75%
score = max(0, positiveDimensionsSum - outagePenalty - penalty)delegationFee, selfBond, delegatedStake и FTSO score (если вы также поставщик данных).generated-files/reward-epoch-N/nodes-data.json. Посчитайте, сколько эпох ваш nodeID имел uptimeEligible: true. Это отношение определяет множитель вашего измерения Uptime.RewardClaimed с claimType=3, ссылающиеся на ваш nodeID. Если таких недавно, вы будете показаны как MIRROR-inactive.GET /api/validators/{nodeID}/score-breakdown, чтобы получить сохраненный разбор — значение каждого измерения, версию алгоритма, которая его произвела, и недавнюю историю баллов — в формате JSON. Панель разбора баллов в пользовательском интерфейсе считывает из того же источника.// Step 1 — Raw composite (sum of dimensions, minus the two penalties)
positive = uptime + netYield + fee + operatorQuality
+ mirror + capacity + trust + delivery + timeRemaining
// Penalties (see the two penalty cards above):
// v4.3 active-outage streak — 0-1 missed epochs → 0, 2 → 3, 3 → 6, 4+ → 10
// v4.5 extreme fee (>50%) — positive × min(1, (fee - 50) / 50) × 0.75
raw = clamp(positive - streakPenalty - extremeFeePenalty, 0, 100)
// Step 2 — Smooth across recent cron snapshots (v3.5)
// Weights: current 0.5, prev1 0.3, prev2 0.15, prev3 0.05
smoothed = 0.5*raw + 0.3*prev1 + 0.15*prev2 + 0.05*prev3
// Step 3 — Apply sudden-change penalty if flagged this run
// Triggers: fee +50% or +5pt jump, self-bond -20% drop, uptime -5% crash
// Magnitude: -10 pts on detection, decays -7, -4, -1 over 3 runs
suddenPenalty = -10 if any flag triggered else (decaying remainder)
// Step 4 — Final score
score = clamp(smoothed + suddenPenalty, 0, 100)services/validators/scoring.ts в исходном коде FlareWatch. Операторы или исследователи, которые хотят проверить реализацию напрямую (вместо чтения текста и формул выше) или которые хотят создать форк для своего использования, могут отправить письмо на [email protected] для запроса доступа. Мы опубликуем файл как отдельный пакет с открытым исходным кодом, если будет реальный спрос./api/cron/refresh-validators пересчитывает оценку каждого активного валидатора каждые 5 минут. Входные данные (считывания P-Chain RPC, Flaremetrics, FSE, reward-scripts) загружаются заново при каждом запуске.Flare не урезает ставку валидатора. Весь механизм штрафов за неправильное поведение валидатора — это конфискация вознаграждения плюс система проходов FIP-10. Нет штрафа за двойную подпись, нет штрафа за эквивокацию, нет события разрушения ставки, которое нам нужно отслеживать. Валидаторы, которые не соответствуют минимальным условиям FIP-10, теряют награды этой эпохи (полная конфискация при нулевых проходах, иначе теряют один проход за каждый протокол, который они не соответствовали); их основная ставка остается нетронутой.
Это означает, что оценка не имеет размерности «история штрафов» — нет такой истории для отслеживания. Что мы ОТСЛЕЖИВАЕМ — это последствие каждого минимального сбоя: валидатор заработал ноль в этой эпохе, что отражено в epochsIncluded / epochsObserved. Обновление версии 4.2 от 14.05.2026 расширило множитель надежности оценки, чтобы использовать это отношение по полному набору минимумов FIP-10 (аптайм, подписание FSP, частота отправки FTSO, участие FDC), поэтому валидатор, который не соответствует любому минимуму, пропорционально штрафуется в измерении Аптайм независимо от того, какая ось сбоя.
Пороги минимумов FIP-10, взятые из dev.flare.network/network/fsp/rewarding: стейкинг требует 80% аптайма + 1M FLR активной собственной ставки; каналы якоря FTSO требуют оценок в пределах 0.5% медианы консенсуса в 80% раундов; каналы задержки блоков FTSO требуют отправки 80% ожидаемых обновлений; FDC требует участия в 60% раундов голосования. Валидаторы, соответствующие полу 80% аптайма + 1M собственной ставки, но ниже порогов 3M / 15M заработков, все еще получают награды, но не могут накапливать пассы — серая зона, выявленная через классификацию passEligibility: "at-risk" этой карточки.