--- title: NDC Elections v2 with quadratic SWV (Stake Weighted Voting) description: Specification of the NDC v2 Elections Framework with quadratic SWV. author: Robert Zaremba --- # NDC Elections v2 with quadratic SWV ###### tags: `NDC` Proposal for the NDC v2 Elections mechanism. * What is [NDC](https://www.neardc.org)? * NDC [gov v1 framework](https://github.com/near-ndc/gov/blob/main/framework-v1/README.md) ## Context NDV v1 was launched in September 2023. Candidates firstly had to nominate themselves and pitch for the Congress elections. The nominations got lot of enthusiasm from the community. We have seen many high profile people nominating themselves. However, the elections were very political. We have seen political blocks forming. The elections mechanism was designed in late 2022. The principle was to give each human on Near equal vote right. There were many criticisms for the mechanism not concentrated on Near. GWG was proposing few minimum requirements, like: account age, account minimum balance. All those proposals were rejected because the goal was to support all Near communities (include people who can't afford few N in their wallets). Again, due to community feedback, the barrier of entry was set very low, and no significant limitation was set. Internally in GWG, we flagged potential voting manipulation. Communities could pay to register more people on Near, to get votes for their candidates in exchange. NDC leaders have seen the onboarding practice as an advantage, because one of the goals of NDC was to onboard new users. Few alternatives were proposed at the end of 2022. Notably, we have been discussing the traditional stake weighted voting, following the Cosmos x/gov design. Our (GWG) dialog with Near OGs and NF (as of early 2023*) resulted in objection to implement stake weighted voting, because of the wealth concentration of the Near tokens. \* In late 2023 NF team changed and their perspecitve changed as well. ## Requirements The following requirements are set for the v2-SWV version. The idea is to have something good enough, limit scenarios where the system can be gamed and improve in the future. - Keep the voting human or DAO oriented. Humans or DAOs should be able to vote. However, stake aggregators, unknown entities should be - Use Near Staking as a measure of affiliation to Near. - Limit the impact of wealthy Near stakes by using a reduction function (eg quadratic voting). - Reintroduce community limits -- we should have quota per community. Single community should not be able to take over the whole congress. As noted earlier, a drawback of the traditional stake weighted voting mechanism is that it supports wealthy users. At the beginning of 2023 we didn't have `I Am Human`. So we were not able to reduce the impact of stake weighted voting whales. ### DAO registration In order for DAO to vote, a DAO has to: - stake Near - pass KYC. For KYC check, a NDC v2 elections commission will be appointed by the NDC v1 Congress. Only DAOs representing a community should be approved by the commission. Commission must be appointed 1.5 month before elections, and it must provide instructions for the DAO KYC process. DAO, that passed the KYC check, will receive a `NDC-CommunityDAO` SBT, which will enable participation in the voting. The SBT minting will use a new deployment of the [Community SBT](https://github.com/near-ndc/i-am-human/tree/master/contracts/community-sbt) smart contract. Minting will be authorized to the KYC Commission SputnikDAO. ## Design ### Mechanism Accounts eligible to vote: - I Am Human KYCed - `NDC-CommunityDAO` holders. Each eligible account will receive voting credits equal to the square root of the Near stake they have at the selected `ndcv2_elections_height`. For example, if an account has 100 Near stake, it will have 10 votes to use during elections. ### Stake Oracle Near Runtime doesn't provide information about the stake to the smart contract environment. Such information must be snapshotted from a full node, and provided to the oracle smart contract by an off-chain oracle stake snapshotter. The oracle smart contract will have the following information: - `ndcv2_elections_height` - Merkle Root @ `ndcv2_elections_height` - map of the account name to the stake - address of the _NDC Elections v2 WG_ oracle, that will be authorized to populate the stake information (the previous point). - boolean flag: `upload_finished`. - `challenge_bond: u128` - Near bond used to secure the contract. - `min_stake: u128` - minimum amount of Near. Must be at least 1 Near (due to the voting mechanism). NDC v1 should sponsor: - transactions to load the stake information to the smart contract. The oracle snapshotter will be open source and everyone should be able to use it. To assure that the snapshot provided by the NDC Elections v2 WG oracle is correct, the oracle smart contract will have two functions: - `challenge_stake(staker: AccountId, expected: U128, proof: MerkleProof)`. The function will validate the proof. If successful it should update the stake map (updating the existing record or inserting a new one in case the staker was not included), and give 25% of the remaining bond to the caller. The function should fail if the `expected < min_stake`. NOTE: in the first version we will store all accounts staking at least `min_stake` (we won't check the I Am Human at this stage - it will be checked during voting). ### Voting Each voter can vote only once and can't overwrite the vote. (**TODO**: need to validate this) Each voter will have maximum `floor(sqrt(voter_total_stake))` (`floor` = rounding down) of vote credits to distribute among all candidates. A voter can distribute more than one vote credit for the same candidate. A vote must be an integer number. Each subsequent vote for the same candidate will be quadratically more expensive. If a voter wants to assign 2 votes to a candidateX, then s/he will need to spend 4 vote credits. If a voter wants to assign 3 votes to candidateX, then s/he will need to spend 9 vote credits. Example: Alice has 250 Near staked in total. She will get 15 vote credits (`sqrt(250)=15.81...` rounded down is `15`). She will be able to give 3 votes to candidate1 (worth 9 vote credits), 1 vote to candidate2, and 2 votes to candidate3 (worth 4 vote credits). She will not use all 15 vote credits. She can't give a fraction of a vote (eg 2.1 votes to candidate3). Voting smart contract will have `vote(ballot: Vec<{candidate: AccountId, votes: u64})>` function. When called by `voter` account: - function will check if the `voter` is eligible for voting (passes `is_human` check or has `NDC-CommunityDAO` SBT); - verify if each account in `elected` is nominated for elections; - query the oracle smart contract for the `voter` total stake; - verify that the square root of the total stake (returned by the oracle), rounded down, divided by `1e24`, is bigger or equal to the sum of `votes` squares (see example above). - increase the sum of votes for each candidate in the `ballot`. - mark the user as voted. ### Voting Initialization Congress will need to propose a set of parameters, and finalize them 2 weeks before the voting: - block height that will determine stake weight: `ndcv2_elections_height`. - voting start, - voting duration, - KYC Commission SputnikDAO, The whole mechanism and new voting parameters will need to be approved by the Voting Body. ### Limitations - Staking pools should not be able to vote. - Protocols should not be able to vote. If a protocol is restaking the tokens, then the protocol owner should not participate in the voting. To implement the limitations above, we should have a list of well known protocols that are blacklisted for voting, even when someone will make a KYC on behalf of that protocol. ### Problems - Entity or staking pools ## Consequences ### Positive - Keep voting human oriented voting. - Use stake as a measure of Near ecosystem affiliation. - Reduce impact of - todo ### Negative - Many entities can be excluded from voting. - Requires significant amount of work, and won't be ready by mid March 2024. - Require a new commission to validate community DAOs. - todo ### Neutral - Oracle proof verification should be audited (additional costs). ## Timeline Review and finalize the spec: 1 week Development. Estimates assume one developer assigned and extensive unit tests. - Voting UI updates: 1 month - Voting UI design: 3 weeks - Oracle snapshotter: 1 month - Voting contract: 1 month Minimum Audits: oracle smart contract + oracle smart contract. Good to have: voting. Time: 2 weeks. Need to book in advance. Additional team that will engage the whole team: - Beta testing & fixes: 3 weeks. TOTAL: 2.5-3 months. ## TODO: - need to specify nominations (contract and UI) ## Future improvements: - Measure account age - [NDC Gov Ultimate](https://hackmd.io/@robert-zaremba/SJ3TM8hIo) # Alternative v2 The proposal above requires more work and more people involved. With a limited budget, this can create a risk of not delivering on time, or have not finished solution. Moreover there is a risk of drama, when the elections will be postponed, but the v1 budget will be over (no money for the community). As an alternative, we can consider taking the existing solution (proof of personhood based) and make few improvements: 1. Limit community representation of elected members: single community / group can't have more than 1/3 of the representation in every house. 2. Lower the min quorum: quorum should be +50% of the house "active" members AND +35% of the initial member set. 3. Increase the minimum bond, to assure we have more Near aligned voters. 4. TODO: we can thing about few other, smaller improvements. NOTE: personally I think the version presented in the first section is better, but given the limited budget and community circumstances, it is more risky.