-
Notifications
You must be signed in to change notification settings - Fork 142
How DAO membership and voting power works
To be a member of a DAO DAO DAO means to have a nonzero voting weight in the DAO.
The job of the DAO DAO voting system is to determine:
- How to assign weights to members.
- The status of a proposal given the positions (e.g., "yes," "no," etc) taken on it by memers.
A DAO's voting contract is a function that takes a member's address and a time and returns their voting power at that time. The consequence is that one's voting weight is determined at the time that a particular proposal is launched.
Why? Well, in most DAOs, voting weight is assigned based on the amount of a governance token you own, and governance tokens are typically transferable. For example, Alice could vote on a proposal and then transfer those tokens to Bob. To prevent double voting using Bob's tokens, the DAO needs to know how many tokens each member had at the time of a proposal's creation.
Now, we could store information about token balances over time, but most tokens do not support this functionality. To make DAO DAO DAO's compatible with all cw20 tokens we require that tokens are staked with the DAO.
In order to get voting power in a DAO DAO DAO, governance tokens need to be staked. This staking is handled by our staking contract.
To stake tokens, an owner of a DAO's governance tokens sends those tokens to the DAO's staking contract. The staking contract then makes a note of how many tokens the sender has sent, and when those tokens were sent. Voting power contracts then query this staking contract to determine how much voting power an address has at a given time.
Why bother with staking? Staking prevents flash loan attacks on governance proposals. Flash loan attacks occur when an attacker takes out a large loan to purchase many governance tokens and uses those tokens to preform a hostile takeover of a DAO. The nature of flash loans is that the loan only lasts for one block (the smallest unit of time on a blockchain).
To prevent flash loan attacks our staking contract does not reflect staked balances until one block after those tokens have been staked. For example, if Alice staked 10 tokens on block N queries for their voting power would not reflect those 10 new tokens until block N+1.
Some DAO DAO DAOs don't want to use tokens for determining governance power. In this case, they may opt to use multisig-style voting. In this voting configuration, members and their weights are determined at the time of the multisig's creation. They are then only modifiable via governance proposals.
In this voting configuration, voting power is still a function of time---that is, voting power on a proposal is determined at the time of that proposal's creation. The cw4-group contract is used to provide information about who was a member at the time of a proposal's creation.
Generally speaking, there are three states that a proposal may be in: open, passed, and closed. All proposals begin as open and during that time may be voted on by DAO members. Once sufficient votes have come in to either pass or fail that proposal the proposal's status changes and voting closes. There are two ways the passing threshold for a DAO DAO proposal may be specified:
- An absolute percentage.
- A quorum requirement and passing threshold.
Percentages may either be "majority" or a particular percentage.
If a proposal's threshold is an absolute percentage, the proposal passes when that percentage of all voting weight has voted yes for the proposal. In the case of a majority percentage passing, a proposal is considered passed if the following is true:
yes_votes * 2 > total_possible_votes
In the case of a non-majority passing percentage, a proposal is considered passed if the following is true:
yes_votes >= total_possible_votes * passing_percentage
Note: in the non-majority case, the condition for passing is >=
;
in the majority case it is >
. We made this decision
after much internal discussion; it seems to match how one would
intuitively expect a voting system to work.
For many DAOs, absolute percentage style voting might be sub-optimal because it requires high voter turnout for a proposal to pass. If a DAO is large and has many voters it may be hard to rally enough voter turnout to pass a proposal.
To address this, we also support quorum style voting. The quorum is the percentage of voters that must turn out for a proposal to be considered. One that percentage has been reached passing is then determined by comparing the passing percentage and the number of votes cast.
For a majority threshold:
yes_votes * 2 > total_vote_turnout
For a non-majority threshold:
yes_votes >= total_vote_turnout * passing_percentage
Quorum is considered to be met if:
total_vote_turnout >= total_possible_votes * quorum
The code for doing these calculations can be found in proposal modules and in the voting package.
The DAO DAO single choice proposal
module
optionally supports changing votes after they are cast via the
allow_revoting
config option. If revoting is enabled proposals will
not pass or be rejected until they have expired. Once the proposal has
expired votes are counted in the standard way and the winning option
is determined.
Consumers of vote hooks ought to be aware of the possibility of revoting and adjust their logic appropriately. For example, someone writing an incentivised voting contract should be sure that voting rewards are not paid out more than once if an address revotes. The vote hook does not include information about if the vote was a revote.