Skip to content

fix: Unweighted Oracle Standard Deviation Inflates Reward Band#354

Merged
mattkii merged 3 commits into
mainfrom
fix/oracle-weighted-standard-deviation
Jul 8, 2026
Merged

fix: Unweighted Oracle Standard Deviation Inflates Reward Band#354
mattkii merged 3 commits into
mainfrom
fix/oracle-weighted-standard-deviation

Conversation

@mattkii

@mattkii mattkii commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Description

The oracle picks a "median" price weighted by validator stake, but it measured how spread out the votes were without using stake and divided by the number of votes instead of total stake. Because of that mismatch, a few small validators could submit way off prices to make the spread look bigger, which widened the "acceptable" range and let bad votes still count as correct.

The fix weights each vote by its stake when measuring the spread, and divides by total stake so the spread now matches the stake-weighted median.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

go test -tags=test ./x/oracle/...
  • Updated the standard-deviation unit test to expect the stake-weighted result
  • All oracle tests pass

PR Checklist:

  • Updated changelog with PR's intent
  • Lint with make lint-fix

@mattkii mattkii requested a review from jhelison as a code owner July 6, 2026 07:05
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 481dcf60-0724-4de1-81ff-2c8b2fbef99f

📥 Commits

Reviewing files that changed from the base of the PR and between ac6cf8a and e5078ec.

📒 Files selected for processing (1)
  • CHANGELOG.md
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

Walkthrough

The oracle module's StandardDeviation function in ballot.go now computes variance by weighting each vote's squared deviation by its voting power and dividing by total voting power, with a zero-power guard added. The corresponding test expectation was updated, and the changelog records the fix.

Estimated code review effort: 2 (Simple) | ~10 minutes

Changes

File Summary
x/oracle/types/ballot.go StandardDeviation now computes power-weighted variance normalized by total power, with an early zero-power return.
x/oracle/types/ballot_test.go Updated expected standard-deviation value in TestStandardDeviation.
CHANGELOG.md Added a Fixed entry documenting the stake-weighted variance change.

Sequence Diagram(s)

Not applicable.

Related issues: None specified.

Related PRs: None specified.

Suggested labels: bug, oracle

Suggested reviewers: None specified.

Poem
A rabbit weighed each vote with care,
Power tipped the variance there,
Median stayed, the window tight,
Low-stake votes no longer steer it wide.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main bug fix in oracle standard deviation weighting.
Description check ✅ Passed The description matches the changeset and explains the oracle weighting bug fix and test update.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/oracle-weighted-standard-deviation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
x/oracle/types/ballot.go 71.42% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes oracle reward-band inflation caused by calculating ballot standard deviation using an unweighted variance (and dividing by vote count) while the median is stake-weighted. The updated calculation weights each squared deviation by validator power and divides by total voting power, aligning dispersion with the stake-weighted median.

Changes:

  • Update ExchangeRateBallot.StandardDeviation to compute a stake-weighted variance (power-weighted squared deviations / total power).
  • Add a safeguard returning zero deviation when total ballot power is zero.
  • Update the standard deviation unit test to assert the new stake-weighted result.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
x/oracle/types/ballot.go Switch standard deviation computation to power-weighted variance and divide by total voting power.
x/oracle/types/ballot_test.go Update expected standard deviation value to match the new stake-weighted calculation.
CHANGELOG.md Document the oracle standard deviation fix in the Unreleased “Fixed” section.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

jhelison
jhelison previously approved these changes Jul 7, 2026
@mattkii mattkii requested a review from jhelison July 7, 2026 18:51
@mattkii mattkii merged commit 4313157 into main Jul 8, 2026
10 checks passed
@mattkii mattkii deleted the fix/oracle-weighted-standard-deviation branch July 8, 2026 04:17
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.

3 participants