The proposed mechanism involves multiple requirements to vote, including stake, past governance delegation, and humanness, with custom multipliers for each. It will utilize a voting contract that enables users to vote, and Meta Pool-provided indexers to tally those votes against the respective multipliers after the fact.
Timeline
- October 7-20: Work with MetaPool on Setup (2 weeks)Overview: Obtain correct developer endpoints
Description: Collaborate with MetaPool to set up the necessary infrastructure and access the required developer endpoints for the voting mechanism.
- October 7-13: Finalize Mechanisms (1 week)Overview: Define and finalize the voting mechanisms
Description: Complete the design and specifications for the multi-requirement voting system, including stake, past governance delegation, and humanness factors.
- October 14-20: Customize UI and Design Multimechanism System (1 week)Overview: Design user interface and system architecture
Description: Create the user interface for the voting system and design the overall architecture to support multiple voting mechanisms.
- October 14-25: Develop Voting Contract and Testing (2.5 weeks)Overview: Create and test the voting contract
Description: Develop a voting contract, potentially a general-purpose one, and conduct thorough testing to ensure its functionality and security.
- October 20-November 14: Development of Front End for Mechanism (2-3 weeks)Overview: Implement the user-facing interface
Description: Build the front-end components of the voting mechanism, ensuring a smooth and intuitive user experience.
- October 20-November 8: Application Process (3 weeks)Overview: Accept and process project applications
Description: Open the application process for projects to participate in the voting round, reviewing and approving eligible candidates.
- Mid-November: Voting Period (Duration TBD)Overview: Conduct the actual voting round
Description: Launch the voting period for approved projects. Note: The exact date may need to be adjusted based on engineering capacity and progress of previous stages.
Key Considerations
MpDAO Governance
- We had previosuly discussed mpDAO core team voting based on a rubric and this being a factor. Is this still the case?
Distribution of Percentages
- Clarification needed on whether this is a single vote with “extra points” or if people can get a total vote, with different factors contributing fractions of a vote.
Engineering Considerations
- Endpoint Requirements:
- Need endpoints for determining stNEAR amount or decide if this will be snapshotted. and for past governance amount
- Voting Contract Design:
- Consider cross-contract calls (challenging for multichain staking unless exposed to a Nada.bot contract) or indicate individual vote weight.
- Could allow anyone to vote with votes omitted if not a project than has been accepted on contract or they dont meet requirements. Allow anything to display and index later. Would require additoianl workflow on index. .
- Potentially develop a custom contract if x amount of votes (NDC contracts, which were audited, may be suitable: voting-v1/elections at master · near-ndc/voting-v1 · GitHub) or NDC Easy Poll
- Decide between allowing anyone to vote and filtering project applications later, or integrating application and approval into voting contracts during project application (may add complexity).
- History Tab:
- Display votes and badges with their multipliers next to each person.
- Note: Being too granular on calculating payout amounts may lead to controversy and people trying to game the metrics
User Experience (UX)
- Display users’ votes and current boost weight. Whether they voted. Show number of votes
- Toast notifications for can’t vote for multiple participants (wiould check setting of election on vote contracts and configure accordingly.
- Implement notification states for checking changes in humanness, stake, and past governance.
- Clearly indicate in the UX that donations won’t earn points (if applicable).
- Create a checklist for amplification and current score (
- Display current stNEAR
- Show past votes
- Indicate whether the user has voted
- Allow only one vote per user.
- Determine the voting contract’s location and development plan.
- Decide between open voting or verified voters only.
- Consider how challenges will change if they need to reference multiple voting mechanisms.
Snapshot Considerations
- Clarify if data is live or snapshotted.
- Determine how to handle late staking if using a snapshot.
- Decide on leaderboard display: number of votes without weight or weighted votes?
Voting System Design
Election Contract (unlocked) for creating voting elections. This contract is similar to our lists contract (potlock.org/list-docs), but instead of upvoting lists, we implement vote logic on projects within a list. The key additions are helper methods to query votes and surrounding logic.
Key features and considerations:
- Integration challenges: We need to seamlessly integrate the application process, list application, and approval process, potentially on the same account or through a similar admin system.
- Admin configuration: Set up owners and admins for the voting contract, with pot.Chef assigned as the owner.
- Voting system: Decide between a points-based system or a fixed number of votes per user.
- Vote amplification: Consider implementing amplification points for votes above certain thresholds.
- Extra functionality: Include additional flag votes on the contract for more granular control.
pub trait ElectionContract {
// Create a new election with title, description, and end date
fn create_election(&mut self, title: String, description: String, end_date: u64) -> ElectionId;
// Allow accounts to apply for participation in an election
fn apply(&mut self, election_id: ElectionId, description: String);
// Admin-only function to review applications
fn review(&mut self, election_id: ElectionId, account_id: AccountId, status: ApplicationStatus, notes: String);
// Enable voting for one or more candidates in an election
fn vote(&mut self, election_id: ElectionId, candidate_ids: Vec<AccountId>);
// Retrieve details of a specific election
fn get_election(&self, election_id: ElectionId) -> Election;
// Get a list of all participants in an election
fn get_all_participants(&self, election_id: ElectionId) -> Vec<AccountId>;
// Retrieve all votes cast by a specific account in an election
fn get_all_votes_per_account(&self, election_id: ElectionId, account_id: AccountId) -> Vec<Vote>;
// Get a list of all applicants for an election
fn get_all_applicants(&self, election_id: ElectionId) -> Vec<AccountId>;
// Retrieve a list of all approved nominees for an election
fn get_all_nominees(&self, election_id: ElectionId) -> Vec<AccountId>;
// Get details of a specific account in the context of an election
fn get_account(&self, election_id: ElectionId, account_id: AccountId) -> AccountDetails;
// Owner-only function to add a new admin
fn add_admin(&mut self, account_id: AccountId);
// Owner-only function to remove an admin
fn remove_admin(&mut self, account_id: AccountId);
// Owner-only function to transfer ownership to a new account
fn transfer_ownership(&mut self, new_owner: AccountId);
}
Detailed explanation of key methods:
- create_election: Initializes a new election with essential details and returns a unique identifier.
- apply: Enables potential candidates to submit their application for an election.
- review: Allows administrators to evaluate applications and update their status.
- vote: Implements the core voting functionality, allowing users to cast votes for multiple candidates.
- get_election, get_all_participants, get_all_votes_per_account, get_all_applicants, get_all_nominees, get_account: These methods provide various ways to query election data, enhancing transparency and facilitating result analysis.
- add_admin, remove_admin, transfer_ownership: Administrative functions to manage contract ownership and permissions.
To implement this contract effectively, we need to define the following data structures:
pub type ElectionId = u64;
pub struct Election {
id: ElectionId,
title: String,
description: String,
end_date: u64,
// Additional fields for election configuration
}
pub struct Vote {
voter: AccountId,
candidate: AccountId,
// Fields for vote weight, timestamp, etc.
}
pub struct AccountDetails {
account_id: AccountId,
status: ApplicationStatus,
notes: String,
// Fields for voting history, eligibility, etc.
}
pub enum ApplicationStatus {
Pending,
Approved,
Rejected,
// Additional statuses as needed
}
This comprehensive design facilitates the creation and management of elections, handles the application process, implements voting mechanisms, and provides robust querying capabilities. It also includes administrative functions for overseeing the entire election process and managing the contract itself.
Mapping Requirements to Vote
- Assume all projects submit from previously used accounts.
- Address submissions from personal accounts and transferring points.
Additional Concerns
- Security: Implement measures to prevent vote manipulation or gaming of the system. There’s potential for Nada bot exploitation. Also, staking might be used to game across different accounts. A snapshot may be used to prevent this.
- Scalability: Ensure the voting mechanism can handle a large number of participants and votes. This becomes challenging with thousands of votes and participants, potentially resulting in multiple points of failure based on indexers.
- Transparency: Provide clear documentation on how vote weights are calculated and applied. Also, give an audit of snapshots for indexers and how to integrate into payouts & challenges sections.
- Accessibility: Consider users with varying levels of technical expertise and ensure the voting process is user-friendly. We are supplementing with support channels on Meta Pool Discord.
- Compliance: Ensure the voting mechanism complies with relevant regulations and Meta Pool’s governance policies. Where should we integrate KYC in the process? Assuming this is covered if this is retroactive and all participants have been previously paid out. Our required compliance contract features are only available on v2.
- Testing: Conduct thorough testing, including edge cases and potential attack vectors, before implementation. We have limited time to do this.
- Feedback Loop: Establish a process for gathering and incorporating user feedback after the initial implementation. We have limitations on the engineering feedback loop on shipping mechanisms, and user testing for when we want to do the round. We may need to push into December to accommodate.