Skip to content

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:

Dt+1=max(Dmin,Dt×(1+sign(ntN)×α×|ntN|k))α={αupnt>NαdownntNsign(ntN)={1ntN1nt<Nk1,2,3,...0<αdown<10<αup<1αdown<αup

Where:

  • Dt+1 is the new deposit value, Dmin is the floor deposit value and Dt the deposit at time t
  • nt is the number of active proposals at time t and N the target number of proposals
  • k is a positive integer that expresses the sensitivity of the rate of increase or decrease to the distance of the number of active proposals nt with respect to the target N. Since the rate of change is proportional to this distance, k can be used to tune how much getting further away from N exacerbates things.
  • αup 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)
  • αdown 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)
  • αdown<αup implies that the rate of decrease will be slower than the rate of increase. A typical value might be αdown=αup2

Regarding update frequency of Dt and the possibility to update it lazily

In a naive implementation for time-based updates every T time has elapsed (a tick) the current value of nt should be used to calculate Dt. Having the accurate Dt available to query at all times is important to be able to correctly submit a proposal. But in reality, all we need to know is when nt actually changed the last time (which happens when proposals enter or leave the active proposals queue, and in itself also trigger a MinDeposit update), and how much time has passed since then, anytime the Dt value is requested. Assume nt1 changed at a certain time t1 (and Dt was last updated at that time so it is equal to Dt1), and has not changed up to a certain time t2 when the deposit is queried or requested for a new proposal. At time t2 all we need to know is τ=ticks=ΔtT=t2t1T and then a way to compute easily Dt2 as a function of Dt1 and the number of ticks elapsed τ. Due to the fact that nt has not changed since t1 and is still nt1, all we need is to do is apply the same rate of decrease/increase multiple times, i.e.

Dt+1=max(Dmin,Dt×(1+sign(ntN)×α×|ntN|k)τ)

What does this mean in practice?

  1. The deposit value need to only be actually updated in state when nt 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 1+α×|ntN|k 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 nt also changes again.
  2. If the current deposit value at a certain time t is requested - say t1 was the last time the min deposit was actually updated in state due to a change of the total active proposals nt, it can be computed lazily as Dt=max(Dmin,Dt1×γτ), where again τ=tt1T - i.e. how many ticks have passed since t1, and γ=1+sign(ntN)×α×|ntN|k

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 period
  • update_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 nt in this case is the number of proposals in deposit period, and updates of 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.

References