FTSO Provider Score Methodology

Algorithm version: v4.6 · Last updated: 2026-07-04

FlareWatch assigns each FTSO data provider a 0–100 composite score across 13 dimensions. The math is deterministic, the inputs are public on-chain and Flare-ecosystem data[Flaremetrics] [FSE] [Flare Explorer], and the same algorithm applies to every provider — including FlareWatch's own FTSO provider, which is scored by this exact function with no special treatment. This page documents every dimension and threshold so delegators and operators can see exactly how the score is computed and why each value was chosen. Every claim here links back to its primary upstream source — see Sources & references at the bottom.

Scope: this page documents the FTSO provider score — what you see in delegation mode on the validators page (delegating WFLR to FTSO data providers for FTSO inflation share). The validator score shown in staking mode (delegating FLR to a P-Chain validator for VRM + MIRROR rewards) uses a separate 9-dimension algorithm focused on validator operations — uptime, fee, reliability, etc. They're distinct on-chain roles with distinct rewards, scored separately. See Validator Score Methodology for the staking side.
FLR / SGB chain coverage: the Delegation tab on the validators page has an FLR / SGB toggle for wallets that hold any Songbird (SGB). This methodology documents the FLR-side score only. Songbird FTSO providers are listed without a composite score — the same accuracy / consistency / FSP rewards data we use for FLR isn't wired into our Songbird pipeline yet (Flaremetrics, our primary FLR data source, doesn't cover Songbird). What SGB delegators see today: provider name + logo from the cross-network TowoLabs registry, current weight (WSGB delegated, read directly from Songbird's WNat contract via our own Songbird RPC), and the provider's URL. Sort by weight; larger weight is the proxy signal until accuracy data lands. When we wire the Songbird-side accuracy + reward-rate pipeline, the same 13-dimension formula will apply to SGB providers — no new scoring algorithm, just the FLR formula computed against Songbird data. The FlareWatch validator scoring (staking tab) doesn't have an SGB equivalent at all: Songbird's P-Chain validator set is restricted to Flare Foundation-approved entities, so retail SGB P-Chain delegation is rare and the staking tab stays FLR-only.
Score bands
90+Top tier — top ~10–20% of FTSO providers. Typical profile: above-median reward rate, high accuracy, full V2 protocol participation (FTSO Scaling + Fast Updates + FDC), low/zero fee, large delegator base, MIRROR-paying validator nodes, named brand. No single dimension required — providers reach Top tier by stacking strength across most categories.
80–89Strong — meets most key benchmarks; one or two dimensions short of top tier.
70–79Good — meets all baseline criteria; no major gaps.
60–69Acceptable — usable but not differentiated.
<60Below median — significant gaps in one or more dimensions. Mathematical fact, not a quality judgment.
Dimensions (raw weights — sum to 177, normalized to 100)
“Active” gates two dimensions (Fee and V2 Participation): a provider that isn't running shouldn't collect credit for advertising a low fee. A provider counts as active if it has a published reward rate or if Flare Systems Protocol reward data shows it paid out in at least one epoch of the scoring window. Until 2026-07-31 it was the reward rate alone, which came from a single third-party API — so a provider that API didn't cover scored zero on both dimensions while visibly distributing rewards every epoch. Activity is a property of the provider, not of who happens to list it.
Reward Rate25 pts max
What: The provider's reward rate per epoch, anchored to the network median.
How: ratio = providerRate / medianRate. Linear: ratio 1.0 (median) → 12.5 pts, ratio 2.0 → 25 pts (cap). Inactive provider (rewardRate ≤ 0) → 0. v4.0 (2026-05-11): cap rebased so median = half the dimension's points (not 40% as before).
if (rate <= 0 || medianRate <= 0): score = 0
else:
  ratio = rate / medianRate
  score = min(25, round(ratio * 12.5 * 10) / 10)   // 1 decimal place

// Anomaly detection: providers > 3× the median are capped at
// median × 3 for scoring purposes (prevents data outliers from
// distorting the linear curve).
Why: Reward rate is the #1 thing delegators experience. Median anchoring keeps the score honest as the network's reward economics shift — a provider at 1.2× the median in an era of low rewards still ranks the same as one at 1.2× in an era of high rewards. Caps and anomaly filters prevent single-epoch outliers from dominating.
Accuracy25 pts max
What: FTSO submission accuracy from Flare Systems Explorer (FSE).
How: Uses FSE's secondary accuracy metric (higher resolution in the 94–97% band where most providers cluster). Piecewise linear preserving bucket values at boundaries — v4.0 eliminated the 7-point cliff at exactly 97% (pre-fix: 96.99% → 18, 97% → 25). Falls back to FSE primary accuracy when secondary is unavailable; neutral 12.5 when no FSE data.
if (fseAccuracySecondary > 0):
  pct = fseAccuracySecondary / 100
  if (pct >= 97) score = 25
  elif (pct >= 95) score = 18 + (pct - 95) * 3.5     // 95 → 18,  97 → 25
  elif (pct >= 93) score = 16 + (pct - 93) * 1       // 93 → 16,  95 → 18
  elif (pct >= 90) score = 13 + (pct - 90) * 1       // 90 → 13,  93 → 16
  elif (pct >= 85) score = 10 + (pct - 85) * 0.6     // 85 → 10,  90 → 13
  elif (pct >= 80) score = 6  + (pct - 80) * 0.8     // 80 → 6,   85 → 10
  else              score = max(0, 2 + (pct - 70) * 0.4)
elif (fseAccuracyPrimary > 0):
  // Primary fallback: similar piecewise linear curve.
else:
  score = WEIGHT_ACCURACY / 2   // Neutral — no FSE data
Why: Missed epochs = missed reward income for delegators. Accuracy is what determines whether the provider's submissions actually count for FTSO consensus, and the secondary metric (which weights more recent epochs) is the one that maps cleanest to current performance.
Consistency20 pts max
What: How stable the provider's reward rate has been across its most recent earning epochs.
How: Robust coefficient of variation over the last 12 positive-reward epochs: cv = 1.4826 × MAD / median (median absolute deviation, scaled to a normal-consistent stddev estimate). cv = 0 → 20 pts (steady). cv ≥ 0.2 → 0 pts. Linear in between. Neutral 10 when fewer than 3 recent earning epochs exist. v4.6 (2026-07-01): switched from mean/stddev over the full 30-epoch history to a trailing window + median/MAD, so a new node's ramp-inflated first epoch is treated as a harmless outlier instead of pinning the CV high for months.
recent = last 12 epochs where rewardRate > 0
if (recent.length < 3) return 10       // Neutral — insufficient recent history
med = median(recent)
cv  = 1.4826 * median(|r - med|) / med
score = max(0, round((1 - min(1, cv * 5)) * 20 * 10) / 10)
Why: Two providers with the same average reward rate can deliver very different staker experiences if one swings ±30% epoch-to-epoch and the other holds steady. Consistency rewards predictability. The robust, recent-window measure judges how stable a provider is NOW — a normalizing new node isn't penalized for months, but genuine ongoing volatility still scores low.
V2 Participation15 pts max
What: Whether the provider is running the modern V2 stack (FTSO Scaling + Fast Updates + FDC).
How: Per-protocol stacking. Active baseline (rewardRate > 0) +3, V1 partial (submit + signing + voter) +4, each V2 protocol (FTSO Scaling / Fast Updates / FDC) +~2.67 each, cap at 15. Inactive → 0. v4.0 (2026-05-11) split the previous all-or-nothing tier (where partial V1 = full V2 = 15 — no incentive to upgrade) into per-protocol bonuses that stack.
if (!isActive) score = 0     // see "Active" below
else:
  score = 3   // active baseline
  if (hasSubmitAddress AND hasSigningPolicyAddress AND voterRegistered):
    score += 4   // V1 registered
  if (fseFtsoScaling)  score += 8/3   // ~2.67 each
  if (fseFastUpdates)  score += 8/3
  if (fseFdc)          score += 8/3
  score = min(15, round(score * 10) / 10)
Why: V2 is where the network is going. v4.0's per-protocol stacking means upgrading from partial V1 to full V2 actually moves the score (pre-fix it didn't — partial V1 and full V2 both returned 15). Adding any single V2 protocol now improves the dimension.
Fee15 pts max
What: The fee the provider charges on delegated rewards.
How: Linear interpolation across breakpoints: 0% → 15, 5% → 13, 10% → 10, 15% → 7, 20% → 4, ≥25% → 0. Inactive provider → 0.
anchor = max(lowest active fee observed, protocol fee floor)
// FIP-16 sets a 20% minimum entity fee. All 98 providers charge
// exactly 20%, so the anchor is 20% and nobody is docked for
// charging the only fee the protocol permits. Same curve and
// same anchor the validator page's Fee dimension uses.

if (!isActive) score = 0
d = fee - anchor              // distance ABOVE the best real offer
if (d <= 0)  score = 15       // at or below the anchor → full marks
elif (d <= 5)  score = 15 - d * 0.43
elif (d <= 10) score = 12.9 - (d - 5) * 0.64
elif (d <= 15) score = 9.6 - (d - 10) * 0.86
elif (d <= 20) score = 5.4 - (d - 15) * 1.07
else: score = 0               // extractive
Why: Fee directly reduces what delegators receive. Linear interpolation (rather than buckets) means a 7% fee scores between 10% and 15% rather than snapping to one bucket — operators don't get credit for rounding their fee down to the next bucket boundary.
MIRROR Participation12 (+3 bonus) pts max
What: Whether the operator's P-Chain validator nodes actively pay FTSO inflation share to stakers, plus an overperformance bonus.
How: Base score scales linearly with the fraction of the operator's nodeIDs paying MIRROR rewards. All nodes active → 12 pts. Partial → proportional. None → 0. As of 2026-05-11 the 'active' signal reads from two canonical sources: on-chain RewardClaimed(claimType=3) events on the V2 RewardManager AND claimType=3 allocations in the official FSP Merkle JSON — either is sufficient. Pre-update we used the on-chain stream as the sole signal, which produced false negatives for providers whose MIRROR settles through a non-standard claim path. Plus an overperformance bonus of up to +3 pts when the operator's validators consistently deliver above 100% of expected (vrm + mirror) / expected — Bayesian shrinkage with a 30-day data accrual gate and a 3-stake sample minimum keeps small or new operators from gaming the bonus on a few lucky reads.
if (no fseNodeIDs) score = 0
if (mirrorStatsMap empty) score = 12 / 2 = 6   // Neutral seed before data lands

activeCount = nodes_with_status_active
fraction = activeCount / fseNodeIDs.length
base = 12 * fraction

// Overperformance bonus per node, applied only when ALL gates pass:
//   - >= 30 days observed since first reading (firstObservedAtMs)
//   - >= 3 paid stake observations
//   - finite medianOverpaymentRatio
// Bayesian shrinkage with prior k=5 toward 1.0 (neutral):
//   shrunken = (observedRatio * N + 1.0 * 5) / (N + 5)
// Bucketed bonus from shrunken:
//   < 1.05 → 0    < 1.15 → 1    < 1.30 → 2    >= 1.30 → 3

avgBonus = sum_per_node(bonus) / fseNodeIDs.length
score = round((base + avgBonus) * 10) / 10
Why: MIRROR participation is what delegates the FTSO inflation share to your stakers. A V2-active provider whose validator nodes don't pay MIRROR is shipping ~5–15% less yield to delegators than the same provider with active nodes. The overperformance bonus rewards consistently-better-than-expected delivery without inflating new operators on small samples — Bayesian shrinkage and the 30-day accrual gate keep it fair.
Delegator Count12 pts max
What: Number of distinct delegators (estimated from vote power).
How: Log-scaled from 5 → 500 delegators mapped to 0 → 12. ≤5 → 0, ≥500 → 12 (cap). Matches the validator Trust dimension's count signal style. v4.0 (2026-05-11): fixed a real bug where the previous bucket scheme had a perverse incentive at exactly 500 delegators (pre-fix: 500 → 14, 501 → 12 — gaining a delegator across that boundary LOST 2 points).
if (count <= 5)   score = 0
elif (count >= 500) score = 12
else:
  ratio = log(count / 5) / log(100)   // maps [5, 500] → [0, 1]
  score = round(min(12, max(0, ratio * 12)) * 10) / 10
Why: Delegator count is a trust signal — independent of stake size. A provider with 200 delegators has been picked by 200 independent stakers; one with 5 has been picked by close to its operator. Log scaling gives diminishing returns past ~50 delegators without ever reversing (the way bucketed scoring did pre-v4.0).
Epoch Participation10 pts max
What: Whether the provider is actively participating in epochs.
How: FSE marks the provider active → 10. Provider has rewardRate > 0 (Flaremetrics) but no FSE active flag → 7 (active per market data, missing FSE confirmation). Otherwise → 0.
if (fseActive) score = 10
elif (rewardRate > 0) score = 7
else score = 0
Why: Catches providers whose reward stream has stalled even if Flaremetrics still lists them. Different from Accuracy (which is about per-epoch correctness) — Participation is about showing up at all.
Vote Power Stability10 pts max
What: Day-over-day percent change in the provider's vote power.
How: Piecewise linear in absolute day-over-day percent change. <1% → 10. Linear from 1% → 3% (10 → 7). Linear from 3% → 5% (7 → 4). Linear from 5% → 10% (4 → 2). Continues toward 0 past 10%. v4.0 (2026-05-11): linearized the previous bucket cliffs (was up to 3-point cliffs at each threshold).
change = abs(votePowerDailyChangePct * 100)
if (change < 1)  score = 10
elif (change < 3) score = 10 - (change - 1) * 1.5     // 1 → 10, 3 → 7
elif (change < 5) score = 7  - (change - 3) * 1.5     // 3 → 7,  5 → 4
elif (change < 10) score = 4 - (change - 5) * 0.4     // 5 → 4, 10 → 2
else               score = max(0, 2 - (change - 10) * 0.1)
Why: Big day-over-day swings in vote power often indicate a delegator wave moving in or out — stakers reading the table see a moving target. A stable vote power signals a settled provider with sticky delegators.
Compliance10 pts max
What: Whether the provider was paid in every reward epoch SINCE it went active in the FSP rewards data.
How: Full 10 points for zero missed epochs within the provider's active window. Each missed epoch deducts 3 pts (clamped at 0). Neutral 5 when no FSP data is available. v4.4 (2026-06-30): missed epochs are now counted only from the provider's first participating epoch onward — a new provider is no longer charged for epochs before it existed (which previously kept new-but-clean nodes at 0/10 for weeks).
if (no fspData OR totalEpochs <= 0) score = 5

// active window = epochs from the provider's first paid epoch to now
missed = (active-window epochs) - (epochs the provider was paid)
score = max(0, 10 - missed * 3)
Why: A missed epoch in the official Flare Systems Protocol reward distribution means the provider failed protocol compliance for that epoch — minimum conditions, signing policy, etc. Counting only from first participation keeps the measure fair to new providers while still penalizing genuine misses. Three points per miss is steep so a single miss is a noticeable signal but recoverable; ~3 misses zeroes the dimension.
Rewards Distributed8 pts max
What: Total delegation rewards the provider distributed across the recent reward-epoch window, measured from on-chain FSP reward claims, scaled against the network max.
How: Linear: amount / maxAmount × 8 pts.
if (amount <= 0 OR maxAmount <= 0) score = 0
score = min(8, round((amount / maxAmount) * 8 * 10) / 10)
Why: Captures the providers actually moving the most reward volume. Complements the per-rate scoring with an absolute-volume signal — helps distinguish high-rate-low-volume providers from high-rate-high-volume ones.
Identity8 pts max
What: Whether the provider has a real brand name or just a hex address.
How: Named brand (≥4 chars, not starting with 0x) → 8. Short or anonymous (<4 chars) → 4. Pure hex / 0x address as name → 0.
if (no name) score = 0
elif (name starts with 0x or matches hex regex) score = 0
elif (name.length < 4) score = 4
else score = 8
Why: A named provider has chosen to be findable and accountable — they can be looked up, contacted, and held to the published commitments. Anonymous-by-address providers are functional but offer fewer trust signals to delegators evaluating them.
Self-Bond7 pts max
What: The operator's OWN P-Chain node bond (skin in the game) — excluding stake others delegate to the node. A size-neutral commitment gate, not a wealth ranking.
How: Credited on the GREATER of two saturating axes: (1) alignment — own bond as a share of total committed stake (≥10% → full); or (2) absolute — own capital at stake, capped at 5M FLR so 5M and 80M score the same. v4.4 (2026-06-30): re-sourced from the operator's true P-Chain self-bond (validator weight cross-referenced by nodeID) — the previous Flaremetrics field it read was discontinued, so every provider had scored 0. v4.5 (2026-06-30): added the absolute axis + saturation so a large self-bond at a low ratio isn't scored below a small one at a high ratio, without letting size win or punishing small operators.
ownBond      = operator's own P-Chain node bond (FLR)
total        = ownBond + delegated WFLR vote power
alignment    = piecewise-linear ratio curve (0% → 0 … ≥10% → 7)
absolute     = min(7, ownBond / 5,000,000 * 7)   // saturates at 5M FLR
score        = max(alignment, absolute)
Why: Skin in the game — an operator with their own capital at risk is aligned with delegators. But self-bond size is not a proxy for operator QUALITY (that lives in the other dimensions), so a small fully-aligned operator and a large committed one both earn full marks. Only an operator with little of their own capital committed — small share AND small amount — scores below full.
How to score 100/100 — an FTSO provider playbook
The v4.0 fairness audit was specifically designed so that maxing every score dimension genuinely makes you a better FTSO provider for your delegators. Improving your score isn't gaming the system — it's the system working as designed. Here's the per-dimension playbook.
Reward Rate — 25 pts. Deliver ≥ 2× the network median FSP reward rate per epoch (after-fee, post-protocol-distribution). Linear from 0 to 2× median: median → 12.5, 2× median → 25. Why this aligns: this is the dollar amount actually reaching your delegators per epoch.
Accuracy — 25 pts. Target ≥97% secondary-band landing rate on FSE for full points. Piecewise linear so 95% → 18, 93% → 16, 90% → 13, etc. — every 1% improvement moves the score. This is price-QUALITY, not epoch participation: it measures what fraction of submitted prices land inside the on-chain accepted band. A provider with high Accuracy publishes prices close to consensus; one with low Accuracy submits reliably but is off-consensus more often. Why this aligns: off-band submissions produce smaller delegator rewards even when the provider participates in every epoch. The separate Compliance dimension below tracks epoch participation.
Consistency — 20 pts. Minimize per-epoch reward-rate variance (CV = stddev/mean across recent epochs). CV = 0 → 20, CV = 0.2+ → 0. Why this aligns: two providers with the same mean reward rate aren't equivalent — predictable payouts beat volatile ones for staker UX.
V2 Participation — 15 pts. Stack protocols additively: active baseline + V1 partial registration + each V2 protocol (Scaling, FastUpdates, FDC). Full V2 + active + V1 registered = 15. Why this aligns: V2 is where the network is going; each additional protocol you adopt is a forward investment your delegators benefit from.
Fee — 15 pts. Charge ≤ 5% for 13 pts, 0% for 15. Piecewise linear ramp through 5%/10%/15%/20%/25% breakpoints to 0. Why this aligns: lower fee = more reward reaches your delegators directly.
MIRROR Participation — 12 + up to 3 bonus. Run all your operator's P-Chain validator nodes as MIRROR-active (either via on-chain RewardClaimed events OR FSP Merkle JSON allocations — v3.6 dual-source). Sustained overperformance (median (vrm+mirror)/expected ratio above 1.05) on ≥3 paid stakes after 30 days of observation earns up to +3 bonus. Why this aligns: MIRROR is your delegators' share of FTSO inflation; nodes not paying MIRROR ship ~5-15% less yield to stakers.
Delegator Count — 12 pts. Log-scaled 5 → 500 delegators mapped to 0 → 12. Build a base of independent stakers, not just a few whales. Why this aligns: count is a trust signal independent of stake size; 200 delegators picking you means 200 independent endorsements.
Epoch Participation — 10 pts. Show up in every epoch with positive reward rate and active FSE flag. Why this aligns: catches stalled-out reward streams that the per-epoch dimensions might miss.
Stability — 10 pts. Keep day-over-day vote-power change under 1%. Piecewise linear ramp from there. Why this aligns: stable vote power signals settled delegators (sticky community) rather than transient whale waves.
Compliance — 10 pts. Zero missed reward epochs in the FSP data. Each miss costs 3 pts; ~3 misses zeroes the dimension. This is PARTICIPATION, not price quality: it counts epochs where the provider was penalized for missing minimum conditions, signing policy, or other protocol requirements — distinct from the Accuracy dimension above which scores in-band price landing. Why this aligns: a missed epoch in the protocol's own reward distribution means the provider failed minimum conditions and delegators earned nothing that epoch. A provider can have great Accuracy on participated epochs and still miss epochs entirely.
Rewards Distributed — 8 pts. Distribute more rewards than the network max (linear vs network max amount). The size signal — providers moving the most reward volume have proven they can deliver at scale.
Identity — 8 pts. Register a real brand name (≥4 chars, not a hex address) on Flaremetrics or FSE. Anonymous-by-address providers score 0; named providers score 8. Why this aligns: named providers are findable and accountable; that's the baseline trust signal.
Self-Bond — 7 pts. Commit your own P-Chain node bond (not stake others delegate to you). Full marks for EITHER a meaningful share of your total stake (≥10%) OR a meaningful absolute amount (the absolute axis saturates at 5M FLR, so a large operator can't out-score a small one on size). Why this aligns: skin-in-the-game — operators with their own capital at risk share their delegators' yield outcomes. It's a size-neutral commitment gate, not a wealth ranking: a fully-aligned small operator and a large committed one both max it, and your operational quality is judged by the other dimensions.
Time-gated signals you can't shortcut: Consistency needs ≥3 epochs of history. MIRROR overperformance bonus needs 30 days of observation plus ≥3 paid stake samples. Compliance needs FSP data spanning enough epochs to count. Build a track record; the score will follow.
The raw score sums to a max of 177 across all 13 dimensions and is then normalized to 100. A perfect run on inputs hits 177/177 → 100 displayed. A vote-power dilution penalty of up to −3 pts applies for very large providers (>1.34B VP) as a tiebreaker.
How to verify your own score
Every score on the providers table is reproducible from public data. If you're an operator and the math here doesn't match the score you see, the right move is to verify it yourself before assuming we made an error. Walkthrough:
  1. Look up your provider's public stats at flaremetrics.io (search by name or paste your delegation address). Note your fspRewardRate, delegationFeePercentage, wNatWeight, and votePowerDailyChangePct.
  2. Verify your FTSO V2 + accuracy at flare-systems-explorer.flare.network. Find your entity. Check providersuccessrate.secondary for accuracy, plus the entityminimalconditionslatest.ftso_scaling / ftso_fast_updates / fdc flags for V2 status.
  3. Check your MIRROR participation on the V2 RewardManager contract via flare-explorer.flare.network. Look for RewardClaimed events with claimType=3 referencing your nodeIDs. If there are none recent for any of your nodes, you'll show as MIRROR-inactive on the score.
  4. Plug your inputs into the formulas above. Each dimension's code block tells you exactly what arithmetic to run. Sum the dimensions, divide by 177 (raw max), multiply by 100, and you have your raw composite score.
  5. Apply the dilution penalty if you're large. Vote power above 1.34B is −3, above 1B is −1. The Final Score card below has the exact thresholds.
  6. Compare to your displayed score. The displayed score also reflects dynamic weight redistribution — when most providers cluster in a dimension (low standard deviation across the active set), that dimension's weight gets redistributed to dimensions where the spread is wider. The score-breakdown panel on each provider row shows the current per-dimension values.
  7. If the math doesn't add up, email hello@flarewatch.io with your delegation address, the inputs you used, and the score you computed. We'll respond, and if we made an error we'll fix it publicly.
Common operator concerns
My reward rate is above the median but my Reward Rate score isn't 25/25 — why?
Reward Rate is linear in ratio-to-median: score = ratio × 12.5, so 1.0× median = 12.5/25 and you need a 2.0× ratio to hit the cap. A provider at 1.2× the median scores 15, at 1.5× scores ~18.8, at 2.0× scores the full 25. The cap (plus the 3×-median anomaly filter) exists so a single anomalously high reward epoch can't dominate the dimension; if your rate is consistently top-decile, the score still rewards it heavily.
I just upgraded to V2 — when does my V2 score update?
V2 status comes from FSE's entityminimalconditionslatest flags (ftso_scaling, ftso_fast_updates, fdc). Since v4.0 the dimension stacks per protocol: active baseline +3, V1 registration (submit + signing + voter) +4, and each V2 protocol +~2.67. So a voter-registered provider with submit + signing addresses but none of the three V2 protocols scores 7/15, and every individual V2 protocol you turn on moves the score — all three live gets you the full 15. Changes land on the next FlareWatch cron run (every 5 minutes) after FSE reflects them.
My accuracy on FSE is 96% but I'm scoring lower than I expected.
The Accuracy dimension uses FSE's secondary accuracy metric (higher resolution in the 94–97% band where most providers cluster). 95–96% maps to 18 pts; you need ≥97% for the full 25. The buckets are tight at the top because a few tenths of a percent in the 95–97% band represents real performance separation between providers.
I deliver MIRROR — why does FlareWatch show me as MIRROR-inactive on my provider score?
As of 2026-05-11, MIRROR participation is detected from TWO sources: on-chain RewardClaimed(claimType=3) events on the V2 RewardManager, AND claimType=3 allocations in the official FSP Merkle JSON. A nodeID showing in either source counts as active. For multi-node operators the score uses the fraction of your nodes that are active (1/3 active = 4/12 base, etc.). If a node should be classified active but isn't after the next sweep cycle, email us with the nodeID and the specific epoch you'd expect to appear in — we'll cross-check both sources.
My vote power moved 8% yesterday — why does Stability score ~2.8/10?
Vote Power Stability is piecewise linear in absolute day-over-day change (linearized in v4.0 — no bucket cliffs): <1% → 10, ramping 1→3% down to 7, 3→5% down to 4, 5→10% down to 2, then toward 0 past 10%. An 8% move lands on the 5–10% ramp at 4 − (8 − 5) × 0.4 = 2.8. The intent is to flag providers experiencing meaningful delegator turnover so stakers can see it on the table. The score recovers as soon as your vote power stabilizes; one volatile day doesn't permanently anchor you low.
My provider is named with my entity address (0x…). Why does Identity score 0?
Identity awards 8 pts for a real brand name (≥4 chars, not starting with 0x or hex-only) and 0 for a pure-address name. We can't fabricate a name — set your profile.name on Flaremetrics and we'll pick it up on the next cron run. If your entity has a profile but the name field is empty, the same applies.
I have a small but committed delegator base — why is my Delegator Count score capped?
Delegator Count uses estimated delegator counts from vote power (we estimate one delegator per ~500K FLR of vote power). Since v4.0 it's log-scaled from 5 → 500 delegators mapped to 0 → 12 pts, capping at 500 (≤5 scores 0). Log scaling means smaller providers with strong delegator-count growth climb fastest; past ~50 delegators, additional delegators move the dial less — but the curve is monotonic, so gaining a delegator can never lower the score (the pre-v4.0 buckets could).
My score dropped after I added a node — what happened?
If the new node isn't yet showing claimType=3 MIRROR events, your MIRROR fraction drops (e.g., from 1/1 = 100% to 1/2 = 50%), reducing the MIRROR Participation base score. Once the new node starts paying MIRROR (typically within one or two reward epochs of activation), the fraction recovers and the score climbs back.
Can I appeal my score or request a manual review?
Yes. Email hello@flarewatch.io with your delegation address and a specific concern. We respond to every operator. Things we'll act on: MIRROR-classification corrections, dimension-specific math errors, name/logo fixes through Flaremetrics. Things we won't act on: requests to manually raise a score outside the algorithm, requests to exclude or de-rank a competitor.
What we will and won't do
To remove ambiguity about how we operate the score, here are explicit commitments. If we ever violate one of these, document it and email hello@flarewatch.io — we will publicly correct it.
We will not accept payment for higher scores, sponsored placement, or favorable treatment of any kind. The score is computed deterministically from public data.
We will not hand-code per-provider bumps. There is no "X gets +5 because we like them" line anywhere in the code. The same algorithm applies to every provider including FlareWatch's own provider, which is scored by this exact function.
We will not exclude providers from the table for non-public reasons. The list is sourced from Flaremetrics + FSE; our display includes every active provider those sources surface.
We will publish algorithm changes. Every version bump is documented in the Versions card on this page with the rationale and what moved. Major changes get an additional changelog entry visible from the app's changelog page.
We will respond to operator emails. Every operator who emails hello@flarewatch.io with a substantive concern about their score gets a real response within a few business days.
We will publicly correct our mistakes. If we discover a bug in the algorithm, a data-source error, or a methodology gap, we ship a fix and document it. We don't silently re-rank.
We will not share email contents publicly without the sender's permission, or use operator emails for anything other than the score conversation that produced them.
We will not share our future plans for an algorithm change with select operators in advance — every version goes live for everyone simultaneously.
Final score (how dimensions combine)
All 13 dimensions sum to a raw composite (max 177). The raw composite is normalized to a 0–100 scale, then a vote-power dilution penalty and a dynamic weight redistribution are applied to produce the final displayed score.
// Step 1 — Raw composite (sum of 13 dimensions, max 177)
raw = rewardRate + accuracy + consistency + v2 + fee + mirror
    + delegators + participation + stability + compliance
    + distributed + identity + selfBond

// An UNMEASURED reward rate is not a FAILED one. When a provider is
// demonstrably distributing but we hold no rate figure for it, the
// Reward Rate weight leaves the DENOMINATOR rather than scoring 0
// against it — we score what we measured, over what we could measure.
maxRaw = (rewardRate figure missing AND isActive) ? 177 - 25 : 177
normalized = round((raw / maxRaw) * 100)

// Step 2 — Vote power dilution penalty
//   Larger providers deliver lower per-FLR returns due to dilution.
//   Penalty applied AFTER normalization.
if (votePower > 1_340_000_000)  normalized -= 3
elif (votePower > 1_000_000_000) normalized -= 1
normalized = max(0, normalized)

// Step 3 — Dynamic weight redistribution
//   Across the active provider set, dimensions where everyone clusters
//   (stddev < 1.0) become non-discriminating. Their weight gets
//   redistributed evenly across dimensions where the spread is wider
//   (stddev >= 1.0). The redistribution recomputes the score:
//
//   for each dim d:
//     multiplier[d] = 1.0                 if stddev[d] < 1.0
//                   = (weight[d] + bonus) / weight[d]   otherwise
//   bonus = sum(weights of low-stddev dims) / count(high-stddev dims)
//
//   adjusted_raw = sum(breakdown[d] * multiplier[d])
//   adjusted_max = sum(weight[d]    * multiplier[d])
//   final = round((adjusted_raw / adjusted_max) * 100)

// Step 4 — Final score (capped at 100)
score = min(100, final)
Note on the two cap signals: the score's dilution penalty above uses fixed anchors (1.34B / 1.0B FLR) so historical scores stay comparable. The Diluted / Near cap badge in the provider table is a separate, live signal — it computes the FSP protocol cap as 2.5% of the WNat contract's current total vote power on every page load, because the cap base drifts as FLR is wrapped and unwrapped. A provider can carry the badge before the fixed score penalty engages; the badge is the delegation-decision signal, the penalty is a score-history signal.
Display-layer outlier flag: a provider whose current reward rate sits more than three robust deviations (median absolute deviation, scaled ×1.4826) above the field median — and at least 50% above it — carries an Outlier badge in the provider table. The badge does not change the score; the score's own anomaly guard separately caps rates above 3× median before scoring. Annualized epoch-rate spikes usually come from very small vote power and normalize within an epoch.
Data sources (every input is public)
Flare contracts, read directly on-chain: the registered provider set (VoterRegistry), entity → delegation address and nodeID links plus submit/signing address registration (EntityManager), delegated vote power (WNat), and delegation fee (WNatDelegationFee). This is what makes the provider list independent of any one index: at reward epoch 420 the chain held 98 registered providers against 80 in the third-party listing, and the 18 in the gap were previously absent from this site entirely.
Flaremetrics public API: reward rate, delegation fee, vote power, vote power daily change, locked vote power (self-bond), profile name + logo + region, fspRewardRate.
Flare Systems Explorer (FSE): FTSO accuracy (primary + secondary), V2 status flags (ftso_scaling, ftso_fast_updates, fdc), entity address linkage, signing/submit address presence, voter registration, P-Chain nodeID linkage, and the per-entity delegation reward rate (reward_rate_wnat). The reward rate is deliberately sourced from BOTH FSE and Flaremetrics: they publish the same figure in different units (FSE decimal, Flaremetrics percent — verified identical across all 72 providers carrying both, to five decimal places), and FSE covers 154 entities against Flaremetrics' 80. Either source alone leaves providers with no rate through no fault of their own.
Flare Systems Protocol rewards data (FSP): per-epoch reward distribution per provider, used for the Compliance dimension (counts epochs without rewards) and as the authoritative source for delegation reward totals.
V2 RewardManager (claimType=3 events): on-chain claimed MIRROR distribution per validator nodeID. Filtered strictly on type 3 — no conflation with VRM, FTSO delegation, or DIRECT rewards. FlareWatch's own indexer surfaces these for the MIRROR Participation dimension.
FSP Merkle JSON (claimType=3 allocations): canonical published record of who is owed MIRROR per epoch (the same data Flare's own signing tool reads). Added as a second authoritative source 2026-05-11 — catches validators whose MIRROR is allocated but not yet claimed on-chain.
FlareWatch historical snapshots: per-epoch reward rates feed the Consistency CV; per-validator paid-stake observations feed the MIRROR overperformance bonus (with the 30-day data accrual gate).
What's NOT in the score
Self-promotion or paid placement. No provider can pay or sponsor a higher score.
Hand-coded provider-specific bumps. No "X gets +5 because we like them" lines anywhere in the code. The same algorithm applies to every provider including FlareWatch's own provider, which is scored by this exact function.
Subjective infrastructure quality. We don't try to evaluate uptime SLAs, geographic distribution, or hardware specs beyond what FSE and Flaremetrics surface as public data.
Lockups or commitments to FlareWatch. No favorable scoring for stakers using FlareWatch vs. another tool.
Future signals not yet wired. Community presence (verified socials, governance participation), historical slashing, response latency, and per-epoch trend lines are scoped for future versions but aren't in v3 today. None are weighted secretly.
Operator feedback
See something off in your provider's score? Email hello@flarewatch.io with your delegation address and concern. We respond to every operator. Common requests we'll act on:
  • MIRROR-classification corrections (claimType=3 attribution to your nodeIDs).
  • Dimension-specific math errors with the inputs you used.
  • Name / logo / profile corrections through Flaremetrics or FSE.
  • General algorithm critique.
Sources & references
Every input to the score comes from public, verifiable Flare-ecosystem sources. Anyone can cross-check our claims against these primary sources and reproduce the math from raw data. If you spot a discrepancy between this page and what the upstream sources say, email hello@flarewatch.io and we'll fix it.
Authoritative protocol docs. Covers FTSO V2, FSP, P-Chain validation, FAssets, and the rest of the Flare stack.
Flare governance portal (FIPs)https://proposals.flare.network
Flare Improvement Proposals — the source of truth for V2 protocol minimum conditions, fee mechanics, and reward economics changes that feed this score.
Flare Systems Explorer (FSE)https://flare-systems-explorer.flare.network
Official Flare-operated registry of FTSO data providers, entity addresses, P-Chain nodeID linkages, and minimum-conditions flags. Primary source for our Accuracy, V2, and Participation dimensions.
Flaremetricshttps://flaremetrics.io
Independent Flare-ecosystem metrics provider. Source of reward rates, fees, vote power, vote power daily change, locked vote power, profile names + logos, and the fspRewardRate metric.
Flare Block Explorerhttps://flare-explorer.flare.network
Read-only browser of all on-chain state. Lets anyone verify the V2 RewardManager's RewardClaimed events (claimType=3 for MIRROR), reward epoch transitions, and the rest.
Flare Foundation reward-scripts repohttps://github.com/flare-foundation/reward-scripts
Per-reward-epoch JSON published by the Flare Foundation showing per-validator delivered rewards. Indirect input — feeds the MIRROR overperformance bonus calculation via FlareWatch's per-stake observation indexer.
Flaremetrics public API (FTSO providers)https://api.flaremetrics.io/api/v1/ftso/providers?limit=200
The exact endpoint our cron consumes, returning entity profiles, reward rates, fees, and vote power. Anyone can hit it directly.
Flaremetrics public API (node registrations)https://api.flaremetrics.io/api/v1/node-registrations?limit=500
Hex → cb58 NodeID conversion table. We paginate this to build the entity-to-NodeID lookup that drives the MIRROR Participation dimension.
No private data, no closed-source models. The scoring algorithm is implemented in services/ftso/scoring.ts in the FlareWatch codebase. Operators or researchers who want to inspect the implementation directly (rather than reading the prose + formulas above) — or who want to fork it for their own use — can email hello@flarewatch.io to request access. We'll publish the file as a standalone open-source package if there's real demand.
How scores update
FTSO provider scoring runs as a pass inside the cron at /api/cron/refresh-validators, which recomputes every active provider's score every 5 minutes (the same run that rescores P-Chain validators). Inputs (Flaremetrics, FSE, FSP rewards, V2 RewardManager events) are fetched fresh on every run.
Consistency CV uses the recent epoch history — the dimension can move as the rolling window shifts. Newcomer providers with fewer than 3 historical epochs score the neutral 10 until enough data accumulates.
Dynamic weight redistribution is recomputed each run based on the current active provider set. As providers move (e.g., a wave of new V2 upgrades) the dimension that becomes non-discriminating shifts; the redistribution adapts automatically.
Algorithm version is stamped in this page's header. When we ship a new version, the version string here changes and the Versions card below documents what moved.
Versions
v4.7 (2026-07-31) — The provider list stopped depending on a single index, and the score stopped punishing our own data gaps. (1) The list is now built from the on-chain registered voter set and backfilled where the third-party index is missing entities: 98 providers against the 80 previously shown, so 18 real providers that were unsearchable and undelegatable-from-here now appear. (2) “Active” had meant “has a reward rate from that index”, which zeroed the Fee (15) and V2 (15) dimensions for every backfilled provider even when our own FSP data showed them paying out every epoch; it now accepts distribution evidence. (3) A missing reward rate no longer scores 0 against the full denominator — the 25-point weight leaves the denominator instead, so a provider is scored on what we measured rather than charged for what we couldn't. (4) The Fee dimension was still scored on the pre-FIP-16 curve, where a 0% fee earned full marks. FIP-16 makes 20% the minimum legal entity fee and every one of the 98 providers charges exactly that, so the dimension awarded 4.00/15 to the entire field with zero variance — 11 points nobody could earn, worth about 4.3 points off every published score including the highest one. Fee is now anchored to max(lowest fee observed, protocol floor), the same way the validator page has anchored it since the Granite fork: charging the legal minimum earns full marks, and only fees ABOVE it are penalised, by distance. This raises every score by a similar amount and does not change the ranking. Providers with a published rate are unaffected by changes (1) to (3). No reward rate is estimated or inferred: those rows read “No data”. (5) The reward rate no longer depends on a single index. It was read from Flaremetrics alone, so a provider that index stopped covering lost its Net and Gross APR and scored 0/25 on Reward Rate — a 25-point penalty for someone else's coverage gap. Flare Systems Explorer publishes the same number and covers more entities, so it now fills any gap; a live Flaremetrics rate is never overwritten. On the day this shipped it restored a published rate to 15 providers that had none.
v4.6 (2026-07-01) — Consistency de-biased for new nodes. It was mean/stddev of the reward rate over the full 30-epoch history, so a new node's ramp-inflated first earning epoch (tiny vote weight → high per-unit rate, which then normalizes) acted as an outlier that pinned the CV high — scoring 0 — for months until it aged out. Now it uses a trailing window (last 12 earning epochs) and a robust median/MAD dispersion, so that ramp epoch is a harmless outlier while genuine ongoing volatility still scores low.
v4.5 (2026-06-30) — Self-Bond made size-neutral. The ratio-only curve could score a large absolute self-bond at a low ratio BELOW a small self-bond at a high ratio. Self-Bond now credits the greater of an alignment ratio or a saturating absolute amount (capped at 5M FLR), so a large committed operator and a small fully-aligned one both earn full marks — it rewards commitment, not wealth, and validator quality stays in the other dimensions.
v4.4 (2026-06-30) — Two real-bug fixes. (1) Self-Bond was a DEAD dimension: it read a Flaremetrics field the API had dropped, so every provider scored 0/7. Re-sourced from the operator's true P-Chain node self-bond (cross-referenced from the validator set by nodeID). (2) Compliance stopped penalizing epochs before a provider was active — a new node earning cleanly since it launched was previously charged for every epoch that predated it, keeping it at 0/10 for weeks. Missed epochs are now counted only within each provider's active window.
v4.3 (2026-06-03) — Methodology clarification, no scoring math change. The Accuracy dimension is now explicitly defined as the on-chain secondary-band landing rate (price QUALITY — what fraction of submitted prices land inside the accepted band), distinct from the Compliance dimension, which counts missed reward epochs (FSP PARTICIPATION). This page and the validators-table tooltips were rewritten to make the distinction explicit, and a Compliance column was added alongside Accuracy. Both dimensions keep their prior weights (25 and 10) and inputs (fseAccuracySecondary and epochsWithoutRewards).
v4.2 (2026-05-20) — Rewards Distributed dimension repaired. It was wired to a Flaremetrics reward-distribution field that the provider's v3 API dropped, so the dimension read 0 for every provider and contributed nothing. Rewired to on-chain FSP delegation-reward totals — the same reward-claim data the Compliance dimension already aggregates — so the dimension differentiates again.
v4.1 (2026-05-20) — Compliance dimension clamped. epochsWithoutRewards could arrive negative because the FSP rewards cron accumulated its epoch-presence count past the rolling window, which let Compliance exceed its 10-point cap (observed up to ~58) and pushed the composite past its maximum — saturating roughly 70% of providers at a flat 100. Compliance is now clamped to its weight, and the FSP cron recomputes reward summaries statelessly per window so the count can no longer drift.
v4.0 (2026-05-11) — Full fairness audit pass equivalent to the validator score's v4.0 release. Two real bugs fixed: (1) Delegator Count had a perverse incentive at 500 — pre-fix the 500-delegator bucket returned 14 pts but the >500 cap returned the underlying WEIGHT_DELEGATORS (12), so gaining a delegator across that boundary LOST 2 points. Now log-scaled from 5 → 500, monotonic upward. (2) V2 Participation tiers were collapsed — partial V1 registration and full V2 (Scaling + FastUpdates + FDC) both returned 15, so upgrading from partial to full V2 provided zero score improvement. Now per-protocol stacking (active +3, V1 +4, each V2 protocol +~2.67). Boundary cliffs eliminated in Accuracy (had a 7-pt cliff at 97%), Stability, and Self-Bond Ratio — all linearized with values preserved at the bucket boundaries. Reward Rate curve rebalanced so median = half the dimension's points (was 40%). Reconciled stale dimension docstrings with actual weight values. Net effect: every dimension is monotonic upward on the input axis, and no provider can lower their FlareWatch score by improving an actual operational metric.
v3 (2026-05-09 → 2026-05-11) — 13-dimension scoring with dynamic weight redistribution and vote-power dilution penalty. MIRROR Participation introduced as a first-class dimension (12 base + up to +3 overperformance bonus with Bayesian shrinkage and 30-day data accrual gate). Identity and Self-Bond added as discrete dimensions. Reward Rate moved to median-anchored. Accuracy uses FSE secondary metric for the high-resolution band. Consistency uses CV across recent epochs.
v2 and earlier — Pre-v3 versions are not documented here; they used a simpler subset of dimensions and predate the dynamic weight redistribution. Versions retired in favor of the current model.
FlareWatch FTSO delegation addresses. Flare (chainId 14): 0x973B899Fe1422efDdeBE1d54E9A6487a70966aC5. Songbird (chainId 19): 0xaf4eF2A0Ecf8d914Db6b721D3eb79C46CA612796.