Proposal to Change our Conviction Voting Parameters

TL;DR

General Magic ran a couple workshops with core team members from BrightDAO to reconfigure the Conviction Voting Parameters.

We would like to propose that we adjust the Conviction Voting app to use these Parameters:

Spending Limit: 4%
Minimum Conviction: 3%
Conviction Growth: 5 days

BrightDAO Parameters Revised

This is Part 1 of the results of Revisiting the BrightDAO Parameters with General Magic Support

The General Magic Team adjusted their work for the TEC to make this custom BrightDAO Configuration Dashboard. Which Adam, Phil, Bitsikka, CurlyBracketEffect, Ashraf, Serge and a few others who joined in used to take a deep dive into Tao Voting and Conviction Voting.

They worked together, especially with Adam and Phil, to conclude on this new set of Conviction Voting Parameters.

Conviction Voting Fundamental Strategy

Conviction Voting is the decision making process that controls which proposals get funded.

These params were chosen with the following in mind:

Conviction Growth

  • In general, a voter’s conviction roughly maximizes after staking tokens for 5 x conviction grown (days) - we set a conviction growth of 5 days… so conviction maxes out and begins to plateau around 25 days. This effectively means that if a proposal has enough tokens to pass, it will at most take 25 days.

  • We assume an active voting supply of between 1 million to 2 million BRIGHT (There is only 700k now, but if needed we could mobilize more to vote, and as time goes on we expect more tokens to enter the market). A higher assumed supply than this would just make it harder for proposals to pass, so this is a good starting parameter we can grow into.

  • We also wanted to make sure that Proposals can’t pass while people are sleeping. Below is what it would take to pass a vote in 8 hours… it would take 70-100% of all tokens sitting behind that proposal to pass it in 8 hours, and that is only for small proposals

  • But we still wanted to be able to pass proposals in a day if they are really popular.

  • The compromise we had to make to get great parameters for proposals to pass in 1 day - 3 days is that for longer time frames it is easier than preferred to pass proposals, but given that we have celeste to block bad/malicious proposals we don’t see that as an issue, no bad proposal would go unnoticed for a week.

Spending Limit

  • The Spending Limit is the theoretical maximum amount of Common Pool funds that can be spent in one proposal

  • We wanted to be able to pass proposals for $100,000 without so much issue so we can do token swaps, this meant

  • We wanted to maximize it, but in the end, the bigger the spending limit, the less variance there is between passing a small proposal and a large proposal. There is about 9 million tokens liquid in the common pool so we set the spending limit so that it is relatively easy to vote to spend 0-90,000 BRIGHT, harder to spend 90k-180k BRIGHT, and HARD to spend 180k-270k and almost impossible to spend more than that.

Minimum Conviction

  • Minimum Conviction dictates how many BRIGHT tokens are needed to pass a proposal, no matter how small the amount requested. The Minimum Conviction is set as a percentage of the effective supply , where effective supply is the number of tokens actively voting on proposals aka Total Support.

  • We targeted a 3% minimum conviction to really lean into the ability for minority opinions to be funded.

Simulated results with a 3 day voting period

  • We chose these params and simulated outcomes for various sizes of proposals targeting 3 days as a voting period.


  • We are at a weird early stage for BrightDAO Governance and expect to grow into this parameter set. We expect the BRIGHT price to increase, the number of tokens voting to increase and the Common Pool to decrease, and this parameter set was designed with those concepts in mind. That said, if we see trends that go against those assumptions, we should consider revisiting these parameters again.

In conclusion

After a few workshops and a couple weeks of debates analyzing the options, this set of Parameters was unanimously settled on as the best approach for the next 2- 6 months of BrightDAO. I would recommend revisiting again after 6 months to confirm that they still match the needs of the DAO.

h/t to Lauren from Giveth for her great forum post which was modified to fit this context, and the posts she wrote about Conviction Voting in the TEC’s Forum

1 Like

Here is the vote to update the Conviction Voting settings to the parameters stated in the post above:

https://gardens.1hive.org/#/xdai/garden/0x1e2d5fb385e2eae45bd42357e426507a63597397/vote/0

Thx for this thorough analysis. Really good!

What’s the best way to verify that the evm script will make the changes we think it will?

1 Like

unfortunately Garden’s hasn’t implemented verbose context outputs for all the function calls in the same way that Aragon does for it’s official apps - we should lean on them to work on this since it’s extremely important -
I can share the parameters I used via the EVM executor if you would like to take a further look:

Parameter Value
Decay 9999919
Max Ratio 400000
Weight 480
Minimum Threshold Stake Percentage 20000000000000000

I can see from the bottom of Transaction 0xff9d11f57a156cc12ac52f812612b17bfb4ce580d8290edc79ec37ad8401ab24 - Gnosis Chain Explorer that transaction includes a call to StartVote(uint256 indexed voteId, address indexed creator, bytes context, bytes executionScript) and that the executionScript parameter is 0x00000001828b8e030618deb8aea62a0caa5c0d417b5749ac00000084c35ac76d000000000000000000000000000000000000000000000000000000000098962f0000000000000000000000000000000000000000000000000000000000061a8000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000002c68af0bb140000

How can we decode the executionScript?

We still do not have a method to decode all kind of scripts, unfortunately, but you can use the following script to decode executionScript parameter:

import { decodeCallScript } from "@1hive/connect";
// @ts-ignore
import { evaluate } from "@1hive/radspec";

async function main() {
  const executionScript =
    "0x00000001828b8e030618deb8aea62a0caa5c0d417b5749ac00000084c35ac76d000000000000000000000000000000000000000000000000000000000098962f0000000000000000000000000000000000000000000000000000000000061a8000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000002c68af0bb140000";
  const expression =
    "Update the conviction voting parameters setting decay to `_decay`, max ratio to `_maxRatio`, weight to `_weight`, and min threshold stake percentage to `@formatPct(_minThresholdStakePercentage)`%";
  const call = {
    abi: [
      "function setConvictionCalculationSettings(uint256 _decay, uint256 _maxRatio, uint256 _weight, uint256 _minThresholdStakePercentage) external",
    ],
    transaction: decodeCallScript(executionScript)[0],
  };
  console.log(await evaluate(expression, call));
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

The decoded script using the custom radspec expression will give you the following message: Update the conviction voting parameters setting decay to 9999919, max ratio to 400000, weight to 480, and min threshold stake percentage to 20%.

Those numbers are OK for 5 days of conviction growth, 4% spending limit, and 3% minimum conviction set in the parameters. The vote leaves untouched the minimum threshold stake percentage at 20%.

1 Like

I just realized I was missing a 0 from the Min threshold. I don’t seem to have permissions to edit my post… so just to clarify:

Minimum Threshold Stake Percentage is 200000000000000000 (2e17) which is equivalent to a Minimum Effective Supply of 20% which has not been changed from the previous convction-voting settings

Thanks for decoding that for us, @sem . If maxRatio is supposed to be 4%, why is it 400000? I think, because 9999919 should be .9999919 , the numbers must be shifted by 7 decimal places, making 400000 = .04 . That makes weight = .000048

Using Conviction + Threshold with beta (spending limit) = .04 and M (min conviction) = .03 , I get weight = .000048 as expected. So, max ratio and weight seem correct (shifted by 7 decimals), but I can’t get the right value for alpha (decay).

Why is alpha so high? If the half-life is 5 days, shouldn’t alpha be much lower?

\alpha=\left(\frac{1}{2}\right)^{\left(\frac{1}{T}\right)}

For T = 5, alpha is 0.87 , not .9999919

@sem @divine-comedian I think the decay / halflife must be measured in 5 sec blocks, not days. If that’s the case then alpha would be .999991977495 , which (if we’re using 7 decimal places) would come to 9999919 (truncated, not rounded). Because it’s truncated, it’s actually 4.95 days, not 5 days, but I supposed that’s close enough.

Please verify that what I’m saying here is correct.

1 Like

Yes, you decoded it!!

Because it’s truncated, it’s actually 4.95 days, not 5 days, but I supposed that’s close enough.

Indeed, we want to provide more precision in Conviction Voting v2, with the current implementation halflife is just an approximation.