How to Improve Token-Weighted Oracle Voting
Decentralized governance and oracles are necessary in order to enable a wide variety of public blockchain use cases. However, these systems are only possible with well-designed on-chain voting systems and in practice, such systems are typically difficult to implement effectively.
This article will explore practical ideas that protocol designers can use to improve the effectiveness of their token-weighted voting schemes in different contexts. Since every situation is different, I encourage you to modify the strategies here and scale them to your needs. These are certainly not one size fits all!
Note that I will not be discussing or comparing base-layer consensus protocols here that use Byzantine fault tolerant (BFT) voting schemes to decide on blocks such as Tendermint, Casper variations, or any other type of PoA scheme. This is strictly for “dApp level” protocols on a platform like Ethereum.
The two types of on-chain voting
To begin, it’s important to first separate the application of token-weighted voting into two buckets.
The first bucket involves using token-weighted voting for protocol governance. Some simple examples of this are votes deciding on network inflation rates, the use of excess mining rewards, or the allocation of a protocol fund.
I am agnostic here to how the decision is actually implemented — it could be through direct on-chain methods such as in Tezos or simply agreeing that the outcome of the vote should be considered “signalling” to the protocol maintainers as in Ethereum.
The second bucket is more involved and uses token-weighted voting in the context of Schelling point games to create decentralized oracles. The idea here is that some subset of participants in a protocol will vote at particular times and come to a consensus on the Schelling point, which we assume to be the truth.
I like to call this assumption the “Schelling game hypothesis”.
In this case, we might be voting on the outcome of an off-chain event like in a prediction market or voting on an item’s inclusion in a token curated list.
Why is there a need to separate the buckets?
It comes down to whether there can only be one right answer to the vote.
Consider the following scenarios:
- Users voting on the outcome of a sporting event.
- Users voting on whether to include a course graduate in a token curated alumni list.
- Users voting on their favourite development proposal for a DAO fund.
- Users voting on inflation rates of a token.
I would argue that in the first case there is only one right answer. Provided that the information regarding the outcome is readily available, any participant who does not vote for the reference rate either made a mistake or is malicious.
In the second case, it’s possible that perhaps the course graduate is missing some documents and people may disagree, but nevertheless, there can be only one right answer in the end — “yes” or “no”. In both cases, the minority should be punished in some way if we believe in the Schelling game hypothesis.
In the third and fourth cases, however, there are many “correct” answers and it doesn’t make sense to call the minority malicious and therefore punish them.
As a result, we should design voting incentives differently depending on the context. In this article, we’ll only be analyzing the latter case and designing voting incentives to create decentralized oracles.
What does a healthy token-weighted scheme look like?
In order to develop some ideas for improving token-weighted voting in oracles, we should define what a healthy token-weighted voting scheme looks like.
How do we define success?
I believe that in general there are two important metrics that define a healthy and secure voting scheme:
- High voter participation as a percentage of those eligible to vote. For instance, if a token weighted vote was being used to decide on the USD/CAD reference rate at a particular time, ideally we are looking for ~95% of all token holders to vote. This is the most important metric as it greatly improves the security of the system.
- Resistance to cartel formation. Vlad Zamfir talks a lot about this in his work and I believe it is critical to a healthy voting system. What does this mean? Ignoring heavily skewed token distributions, we want to make it difficult for cartels (groups of colluding voters) who own less than 51% of the total tokens to unanimously submit votes for options that are not the “truth”.
We will go over a few techniques for each in this article and highlight some advantages of each.
But first…
Always use a commit-reveal scheme
I cannot think of a reason to not use a commit-reveal scheme in a token-weighted vote. It is the closest thing we have to a secret vote on a public blockchain and it is a simple solution that elegantly mitigates voter collusion and voting bias during the voting process.
(If you’re not familiar with the technique, please check out this excellent article by Karl Floersch which includes an implementation in Solidity)
Although the user now has to make two transactions instead of one and keep a secret, this extra friction can be abstracted away nicely in a well-designed dApp. Moreover, because the commit is a cryptographic attestation, we can actually further increase coordination costs with a simple meta-game:
Suppose Alice and Bob wish to collude in a commit-reveal scheme. Alice needs to prove to Bob that she voted in the same direction as him, and the only way for Alice to prove this is to give Bob her secret so that Bob can check for himself. Here we simply say that if Bob can successfully reproduce Alice’s already-committed vote, then Bob can take a fraction of Alice’s stake as his own and nullify her vote. The protocol can then place additional penalties on Alice as well.
Therefore, this gives Bob an incentive to backstab Alice in the commit period and a disincentive to Alice to share her secret, creating the desired effect of increased coordination costs.
Increasing voter participation
Now that we have a base-line scheme, let’s start with increasing voter participation. Why are some dApps ridden with terrible voter participation? In general, there are four reasons:
- Insufficient rewards for voting, if any
- Insufficient penalties, if any
- Apathy towards the outcome of the vote in the voter’s eyes, and the above two are insufficient for the voter to care
- Frustrating user friction and/or high costs to voting for eligible voters.
The first and second are, in general, directly fixable using carefully thought-out techniques.
The third is more a function of the project and the specifics of the vote. It could be a tragedy of the commons problem where the voter has a relatively small amount of tokens and believes its contributions will not influence the result in a meaningful way. Nevertheless, there are things that can be done to mitigate this problem.
The fourth is a UX problem. User friction during voting has nothing to do with the voting design or the cryptoeconomics of the protocol. Voting in dApps should be extremely easy and the owners of the protocol just need to improve the flow.
Token inflation
The first idea to improve participation is to manually increase the token supply. Suppose every quarter there is a vote to accept or reject proposals to include new members in a token curated list. To incentivize protocol participants to vote in this poll, we can offer a small “payment” to members for voting by inflating the protocol’s native token.
For illustration, suppose a protocol is targeting a 8% inflation rate and assume there is no other use for inflation in the native token. If we held quarterly votes on the token curated list, every vote would distribute 2% of the outstanding tokens to the voters. To be fair to everyone, we can simply stake-weight the rewards such that a voter with 50% of the outstanding tokens will capture half of the inflation. Moreover, to encourage voters to vote for the Schelling point, we will only reward the inflation to those who vote with the majority instead of everyone.
The nice thing about this technique is that if everyone votes and votes unanimously (unlikely), then we achieve high voter participation at low cost because the wealth distribution of the token holders remains identical. To see this, note that if everyone votes with the majority, no one gets wealthier: everyone simply “captures” their token-weighted share of the inflation.
More realistically, if only half of the participants vote (token-weighted) with the majority or at all, then those who vote with the majority get relatively wealthier. This has some nice game theoretic properties because if the inflation is high, then everyone will be encouraged to vote correctly to either not get diluted (if voter participation is high) or capture more than their share of inflation (if voter participation is low).
Token decay/inactivity penalty
A similar idea to rewarding protocol participants with inflation is to apply a decay to protocol participants’ tokens if they do not participate. The idea here is that at every voting round, those who did participate will keep their token balances and those who did not participate will have a small percentage of their tokens slashed the next time they transfer their tokens.
In effect, this technique simply artificially deflates the supply of the protocol token over time, and those who decide to participate in votes will slowly increase their relative ownership of the total supply.
In my opinion, inflating the supply of the token is both easier to implement on a technical level and feels like more of a positive incentive to voters rather than a disincentive, which may increase voter participation in and of itself. However, this might be applicable in some cases where token burning is already a core part of the protocol’s mechanics.
Explicit opt-in governance committee
Finally, instead of adjusting the supply of the token, which may not be practical in certain cases, a third option is to set up an opt-in voting committee that is paid through protocol transaction fees generated during the protocol’s normal operation.
A simple example of this would be to create a committee that refreshes every quarter. At the end/beginning of each committee, protocol token holders would have the opportunity to “opt-in” to the committee by staking any amount of tokens. At the end of the “opt-in period”, the top 50 token holders by stake who opted-in would become committee members for the next quarter, and during that quarter they would be responsible for any and all votes that occur.
At each vote, we can weight each member’s vote by their stake and use the collective stake-weighted votes to determine the outcome. At the end of the quarter, we can distribute the transactions fees generated during that quarter to those who voted in a stake-weighted fashion. For instance, a member with 50% of the total voting weight would receive 50% of the transactions fees generated during that quarter. Those who failed to vote would forfeit their share of the transaction fees.
If we are concerned that the transaction fees may be too volatile or we want more voter participation at the expense of increased financial risk for committee members, we can adjust further:
Instead of just losing claims to transaction fees, we can additionally slash a portion of the deposits of members who fail to vote with the majority or fail to vote at all. The slashed tokens can then be redistributed to the majority in a stake-weighted fashion.
In this case, the slashing percentage can vary depending on the perceived subjectivity of the vote: a more subjective vote such as a dispute on a real-life contract might have a more lenient slashing penalty, whereas a vote on the USD/CAD exchange rate at midnight might have a more severe one.
The advantage of having an explicit voting committee is that we’ve reduced the overall attention requirements of the protocol participants — only those in the committee will be required to keep up with votes.
Moreover, the scheme scales well with the popularity of the protocol; if the protocol is not popular and transaction volumes are low, then we can expect participants to stake only small amounts of the protocol token to get on the committee. Conversely, if transaction volumes increase then we can expect participants to stake more tokens and therefore have more money at risk if they fail to vote or vote with the minority.
Resisting cartels
High voter participation is important and likely the most important factor to maintain a high security margin in the Schelling point game. However, focusing solely on voter participation would be a naive approach that ignores the fact that, in general, voters collude. Voter collusion compromises the game because now voters might have incentives to not vote for the Schelling point.
Therefore, to create a robust voting system, we must design a scheme that resists malicious cartels as much as possible to maintain integrity.
In a pseudo-anonymous system like a public blockchain, it is not possible to eliminate any possibility of cartels forming, but there are effective techniques that can be implemented that make it more difficult and/or risky for voters to collude. Here are a couple of ideas.
The double-agent incentive
Originally conceived by Paul Sztorc in the Truthcoin whitepaper, the “double-agent” incentive in the context of Schelling point games is the idea of punishing the minority and redistributing it to the majority in proportion to the contention of the vote. For this technique to work effectively you must use a commit-reveal scheme where there is punishment for revealing your secret to another party before the reveal period.
For instance, if the majority wins with 90% of the vote, then perhaps we only punish the minority by 10%. However, if the majority wins narrowly with 55% of the vote, then we might punish the minority by 45% or more.
Here’s what the payoff graph might look like for a given voter:
How does it work?
The point of this sliding scale punishment is to make it more risky to collude by giving colluding voters a “double-agent” incentive to instead vote with the majority at the last minute.
For example, if a group of colluding voters believe they have 60% of the vote (which cannot be proven in a commit-reveal scheme), then there is an incentive for all of the colluding voters to claim they will vote with the cartel, but actually vote for the majority. There is even an incentive for the cartel leader to act as a double-agent and vote with the majority, especially if they have a large amount of tokens staked, as they will profit hugely from their “honest” cartel members.
This environment destabilises the cartel as there is a constant prisoner’s dilemma-style game occurring where cartel members have an incentive to defect.
One can scale the penalty and reward based on the subjectivity of the vote, the percentage of those who voted, and the penalty for prematurely revealing your commit-reveal secret. Furthermore, one can set the penalty for abstainers as the minority penalty, making abstainers more likely to vote in very contentious votes.
Appeal systems
The hypothesis of the Schelling point game is that the Schelling point is always the truth. However, what if the voting scheme has been compromised by a less-than-50% cartel and the vote result is not the truth?
Is there anything that can be done to protect the honest minority?
The final safeguard against this is to simply bring in more voters in an appeal vote.
If there is some subset of protocol participants responsible for a particular vote, and if other honest participants are not happy with the result of the vote, then we can open the vote to a larger subset of protocol participants after a sufficient deposit has been placed. This deposit is refundable provided the new vote’s result is not the same as the appealed vote’s result.
The new and larger set of voters will have more severe penalties for voting with the minority in order to incentivize the new voters to participate and vote truthfully. We can repeat this process several times with successively more severe penalties and higher deposits until the vote is open to the whole token supply, at which point the vote will be final.
This technique adds a potentially long delay to the vote, demands significant attention from participants, and introduces a fair bit of complexity. Moreover, if voter participation is already high, then this step might not add much value.
Nevertheless, it can be useful in cases where the vote is subjective or if there is suspicion that a significant and well-coordinated cartel has formed. It’s a trade-off and a quality back-up.
Conclusion
In this article we’ve introduced several experimental techniques to create security in the Schelling game cryptoeconomic “primitive”. The Schelling game is very powerful and holds a lot of promise in pseudo-anonymous public systems but also remember that cryptoeconomics is hard and as of today there really are no right answers to the big questions.
It’s a lot of trial and error, scenario analysis, trade-offs, and resembles more of an art than a science at this point. I encourage you to take these techniques with a grain of salt, build on them, scale them, and share your work with the community.
Thanks for reading and please reach out to me if you have any questions or additional ideas!
CDx is using a careful combination of these techniques to create the most efficient oracle for exchange hacks. Check us out at cdxproject.com.