Component: Dynamic quorum (x/gov)
Description
This module continuously tunes the minimum voter-participation threshold (quorum) required for proposals to pass, so governance remains possible even when participation fluctuates. It does so by maintaining an exponential moving average (EMA) of participation for general, constitution-amendment, and law proposals. It then computes the next quorum as quorum = min_quorum + (max_quorum − min_quorum) × participationEMA
.
The result is used during tallying and exposed through gRPC/CLI queries. This is how it works.
State keys. These include
KeyParticipationEMA
,KeyConstitutionAmendmentParticipationEMA
, andKeyLawParticipationEMA
.Update flow. After every vote tally,
UpdateParticipationEMA
is called, and it applies the new quorum requirements.Quorum ranges. These are stored in
Params.QuorumRange
,ConstitutionAmendmentQuorumRange
, andLawQuorumRange
as{Min, Max}
strings (sdk.Dec
0--1).Genesis/upgrade. The V3 upgrade handler seeds all EMAs to 12% and copies default quorum ranges into params.
Invariants
0 ≤ participationEMA ≤ 1
.0 ≤ minQuorum ≤ maxQuorum ≤ 1
.minQuorum ≤ computedQuorum ≤ maxQuorum
for each bucket.For every proposal tally, the matching EMA is updated exactly once.
Test coverage
Covered
Get/set each EMA key.
computeQuorum
correctness across custom (min, max, EMA) triples.UpdateParticipationEMA
path for no-kind, law, constitution, and mixed proposals.Genesis/upgrade seeding of params and EMA.
gRPC query returns expected quorum values.
Not covered
Negative tests for malformed params (
min > max
, out-of-range values).Overflow/precision edge cases on large EMAs.
Governance param-change integration tests (end-to-end vote → new quorum).
Attack surface
Governance param changes. An attacker can propose params with
min_quorum > max_quorum
→ inverted curve.values outside
[0,1]
→ runtime panics or impossible quorums.an extremely wide range → quorum swings to 0% or 100%.
Direct state manipulation via migrations/scripts could set EMA outside
[0,1]
; quorum then overflows bounds.