003: Governance Proposal Deposit Auto-Throttler
Changelog
- 26 Nov 2024: Initial draft
- 3 Dec 2024: Improve formulation
- 16 Dec 2024: Write remaining sections
- 17 Dec 2024: Finalize first revision
Status
DRAFT
Abstract
This ADR proposes a mechanism to dynamically adjust the value of MinDeposit
in the x/gov
module, and potentially the value MinInitialDeposit
with a similar but independent mechanism. These parameters represent the minimum deposit required to submit a proposal (MinInitialDeposit
) and to start its voting period (MinDeposit
) - or activate a proposal.
The MinDeposit
value will dynamically adjust with time and upon proposals activation or deactivation. The goal is to prevent an excessive number of active proposals and give individuals enough time to study them and vote with complete information.
While the ADR is focused on presenting the dynamic adjustment of MinDeposit
, the same mechanism can be used to dynamically adjust MinInitialDeposit
- with different values for parameters and focusing on proposals entering or exiting the deposit period instead of the voting period. The two dynamic systems would function in the same way, but independently of each other, allowing even MinInitialDeposit
to grow bigger than MinDeposit
at times.
The proposed mechanism can be vaguely compared to the auto-adjusting inflation rate that targets a 2/3 bonding ratio. However, in this case, it is used to automatically adjust the deposit based on the number of proposals.
Context
At the time of writing, the x/gov
module on AtomOne uses a MinDeposit
parameter set to 512 ATONEs, while the MinInitialDepositRatio
is equal to 10% of the MinDeposit
, which makes the MinInitialDeposit
to be 51.2 ATONEs.
Spam proposals
Many Cosmos chains have been suffering from governance spam, with several proposals being submitted that are aiming at spreading misinformation and scams. While ultimately for proposals that do not enter the voting period the impact for the chain is only an increase in the governance proposal index (as proposals are eventually deleted), the majority of these proposals contain harmful links that could potentially pose a risk to unsuspecting users.
Some mitigations have been designed, like the initial deposit requirement for proposals and front-end level filtering. However, replacing the MinInitialDepositRatio
with a dynamic MinInitialDeposit
could allow the chain to deal more effectively with sudden influxes of large number of spam proposals.
Excessive number of active proposals
Having too many active proposals at a time can be confusing, and dealing with them labor-intensive. The lower the number, the more attention stakers can pay to proposals without getting overwhelmed. This allows the chain governance to remain focused at all times, which will also increases its robustness.
Alternatives
Spam should also be filtered at the front-end level. This is already done by platforms like Mintscan or Keplr and a set of filtering rules was already suggested.
Query filtering: this is an other alternative suggested in the same document as vote-based filtering rules are provided. The idea is to update the list of proposal endpoints, allowing the ability to toggle a filtering option on and off.
The endpoint that serves the proposals list is Proposals. This is the GRPC gov/proposals endpoint. This endpoint takes receives a QueryProposalsRequest. To this request should be added an optional boolean field called “unfiltered”. If unfiltered is set to “true”, then the spam filtering will be disabled. Otherwise, by default, it is false, so filtering is active.
To do the filtering: Some other filtering happens in Proposals. This should be done first to narrow down the results. Then for each remaining proposal, Tally should be called to get the number of votes for each option. Then the same basic procedure as defined above can be followed
Vote-based filtering like the methods above is however harder to do on AtomOne, where the No with Veto option is removed.
Since spam proposals are also occasionally entering the voting period on some Cosmos chains, a possible mitigation to this issue could be raising the MinDeposit
parameter. It is unclear however how high the deposit would need to be in order to disincentivize spam, and continuously adjusting the parameter value would in itself require constant attention and involvement of stakers, hence why we advocate for a dynamically adjusted threshold, that simply targets a low number of active proposals.
Moreover, there is currently no real alternative to throttle the number of active proposals for the purpose of mitigating voters fatigue.
Decision
The MinDeposit
parameter is replaced with a dynamically set variable that can be queried separately through a dedicated query. The MinDeposit
parameter is therefore deprecated.
While the following description focuses on MinDeposit
, the system can be replicated to dynamically adjust the MinInitialDeposit
in place of a fixed MinInitialDepositRatio
.
Dynamically adjusting the MinDeposit
The MinDeposit
should exponentially increase and decrease with time and upon proposal activation and deactivation to target having on average N proposals active at any time, with N being a low number, e.g. 1 or 2. The dynamic value will have a floor below which it will not be able to go. Conversely, it is allowed to grow with no bounds.
An update of the MinDeposit
can be triggered by the passage of a certain amount of time - denoted as a tick - or by the activation or deactivation of a proposal, and the new value is calculated from the previous value as such:
Where:
is the new deposit value, is the floor deposit value and the deposit at time is the number of active proposals at time and the target number of proposals is a positive integer that expresses the sensitivity of the rate of increase or decrease to the distance of the number of active proposals with respect to the target . Since the rate of change is proportional to this distance, can be used to tune how much getting further away from exacerbates things. is the base rate of increase for each tick when the number of proposals exceeds the target by 1, and is a positive number between 0 and 1 (excluded) is the base rate of decrease when the number of proposals is exactly at the target, , and is a positive number between 0 and 1 (excluded) implies that the rate of decrease will be slower than the rate of increase. A typical value might be
Regarding update frequency of and the possibility to update it lazily
In a naive implementation for time-based updates every MinDeposit
update), and how much time has passed since then, anytime the
What does this mean in practice?
- The deposit value need to only be actually updated in state when
changes, i.e. when proposals actually enter or exit the voting period. Time-based updates can be avoided, and the current value calculated on-demand. To further simplify the computation, the value of could also be computed at this time (and maybe cached by nodes in memory instead of being stored in blockchain state) since it also won’t change until also changes again. - If the current deposit value at a certain time
is requested - say was the last time the min deposit was actually updated in state due to a change of the total active proposals , it can be computed lazily as , where again - i.e. how many ticks have passed since , and
Implementation
The following parameters are added to the x/gov
module params, inside a dedicated min_deposit_throttler
struct:
floor_value
: floor value for the minimum deposit required for a proposal to enter the voting periodupdate_period
: duration that dictates after how long the dynamic minimum deposit should be recalculated for time-based updates.target_active_proposals
: the number of active proposals the dynamic minimum deposit should target.increase_ratio
: the ratio of increase for the minimum deposit when the number of active proposals exceeds the target by 1.decrease_ratio
: the ratio of increase for the minimum deposit when the number of active proposals is 1 less than the target.sensitivity_target_distance
: A positive integer representing the sensitivity of the dynamic minimum deposit increase/decrease to the distance from the target number of active proposals. The higher the number, the lower the sensitivity. A value of 1 represents the highest sensitivity.
Proposals activation or deactivation - i.e. when a proposal is added or removed from the keeper.ActiveProposalsQueue
- triggers a MinDeposit
update which is also saved in state via setting the LastMinDeposit
. Both the computed value and the time at which this was done (the ctx.BlockTime()
) are stored. Whenever the MinDeposit
is queried or requested the value is then calculated lazily using the value and timestamp of LastMinDeposit
and computing the ticks passed since LastMinDeposit.Time
, using the formula detailed above.
Querying deposits value
Because the MinDeposit
is no longer a fixed parameter, a new query endpoint is also required. The new endpoint will allow clients to fetch the expected price of the deposit.
Replicating the same system for MinInitialDeposit
The same system described for MinDeposit
could also be replicated for MinInitialDeposit
. The only difference with the above formulation is that MinInitialDeposit
would be triggered upon proposals entering or exiting the deposit period (the keeper.InactiveProposalsQueue
in x/gov
) and with time. Parameters would be an exact replica - a copy of the decicated struct just starting with min_initial_deposit_*
instead - and the implementation would equally be very similar.
The two systems should be independent of each other and have no relation. The value of MinInitialDeposit
should be allowed to even grow higher than MinDeposit
in response to sudden spikes in inactive proposals. The dynamic system for MinInitialDeposit
would have to be fine-tuned differently with respect to the one for MinDeposit
to respond more rapidly to changes but also be able to decade quicker.
Consequences
Simply put, if the total number of active proposals exceeds the target, the MinDeposit
will exponentially increase over time. Also, the the higher the number of active proposals past the target threshold, the faster the increase will be. The MinDeposit
can also decrease if the number of active proposals goes below the target, with a faster decrease the lower the number of active proposals. However, the value cannot go lower than a set MinDepositFloor
.
Backwards Compatibility
Existing non-active proposals will potentially see their MinDeposit
requirement increase after the release of this feature. This will depend also on whether there are active proposals at the time of the upgrade.
Positive
- Many active proposals are discouraged, but not prohibited.
- With a similar mechanism for the
MinInitialDeposit
, spamming governance proposals could become very costly especially if done in large numbers.
Negative
- The cost of deposit can become prohibitive for regular users and price them out. However, this should be mitigated by the fact that total deposit can be crowdsourced.
- Increase the complexity of computing the deposit amount. Currently, the deposit is directly read from the governance parameters. With this change, it will come from a state variable that is re-evaluated every time new proposals enter or exit the voting period.
Neutral
- Increase the number of governance parameters
- Adds a new endpoint to query the
MinDeposit
value.