Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

### Fixed

- Compute the oracle ballot `StandardDeviation` as a stake-weighted variance (weight each squared deviation by the vote's power and divide by total voting power) instead of an unweighted average divided by the vote count, aligning the reward-band width with the stake-weighted median and preventing a group of low-stake validators from inflating the deviation to widen the accepted vote window
- Remove the forced minimum 1-unit-per-block reward release in `CalculateReward` and skip (instead of deactivating) sub-unit blocks in the rewards `BeginBlocker`, so the proportional share accumulates and the pool follows the configured schedule independent of block time (previously a 10-year, 1M-unit schedule drained in ~12 days at the 1s target block time and ~28 days at the current ~2.4s rate, regardless of the configured duration)
- Reject `MsgEthereumTx` from being dispatched through the authz keeper (including when nested inside `authz.MsgExec`), closing an EVM ante bypass on message-router execution paths that skip the ante handler
- Fix feegrant denomination bypass in the cosmos fee ante handler by converting the fee before consuming the grant, so `UseGrantedFees` is checked against the same coins later deducted (prevents a grantee from forcing the granter to pay in a non-granted fee-abstraction denom)
Expand Down
16 changes: 11 additions & 5 deletions x/oracle/types/ballot.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,26 @@ func (ex ExchangeRateBallot) StandardDeviation(median sdkMath.LegacyDec) (standa
}
}()

// Get the total voting power to weight the variance
totalPower := ex.Power()
if totalPower == 0 {
return sdkMath.LegacyZeroDec()
}

sum := sdkMath.LegacyZeroDec()
for _, votes := range ex {
deviation := votes.ExchangeRate.Sub(median) // calculate the ex - median
sum = sum.Add(deviation.Mul(deviation)) // Calculate sum += (ex - median)^2
deviation := votes.ExchangeRate.Sub(median) // calculate the ex - median
sum = sum.Add(deviation.Mul(deviation).MulInt64(votes.Power)) // Calculate sum += power * (ex - median)^2
}

// Divide the result by the number of ex
variance := sum.QuoInt64(int64(len(ex)))
// Divide the result by the total voting power
variance := sum.QuoInt64(totalPower)

// Finally get the square root of variance
standardDeviation, err := variance.ApproxSqrt()
if err != nil {
return sdkMath.LegacyZeroDec()
}

return
return standardDeviation
}
2 changes: 1 addition & 1 deletion x/oracle/types/ballot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func TestStandardDeviation(t *testing.T) {
median := ballot.WeightedMedianWithAssertion()
deviation := ballot.StandardDeviation(median)

expected := sdkMath.LegacyNewDecWithPrec(1224745, 6)
expected := sdkMath.LegacyOneDec()
// 2e-7 tolerance
delta := sdkMath.LegacyNewDecWithPrec(2, 7)

Expand Down
Loading