Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: voting contract #62

Closed
wants to merge 6 commits into from
Closed

feat: voting contract #62

wants to merge 6 commits into from

Conversation

bowenwang1996
Copy link
Collaborator

This NEP describes the voting contract we need for various governance related activities, such as when to reset the network and when to unlock token transfer. There has been some preliminary work around the contract implementation near/core-contracts#6 and necessary protocol changes near/nearcore#2504.

@render
Copy link

render bot commented May 4, 2020

@render
Copy link

render bot commented May 4, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

Copy link
Contributor

@evgenykuzyakov evgenykuzyakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having separate Poll and Proposal is not required and adds to complexity.
Thinking from a high level design, what are the minimum API that is needed to accomplish any action?

Let's say we merge Poll and Proposal into one. Let's call it Proposal.

You need the following properties:

  • human readable description
  • machine readable description (or metadata). This is needed for other contracts relaying on this contract.
  • expiration height. This should be optional, since some proposals don't have to expire ever.
  • votes or result.
  • Maybe you want to have a majority fraction. E.g. 1/2, or 2/3

The rest can be built outside of this contract.

I assume there 2 use-cases right now:

  • unlock transfers
    • no expiration
    • no metadata needed
    • need to know the timestamp when it's resolved
    • may need 1/2
  • network upgrade
    • has expiration
    • has metadata with the block number to shutdown
    • there can be multiple proposals like this
    • may need 2/3

proposals/0000-template.md Outdated Show resolved Hide resolved
@bowenwang1996
Copy link
Collaborator Author

@evgenykuzyakov Two questions:

  1. if there is no poll then how do you know whether the proposals fall into the same category? This is important for calculating how much you can vote as well as for viewing all proposals for the same topic.
  2. If there is no expiration height the state might grow very large.

@evgenykuzyakov
Copy link
Contributor

if there is no poll then how do you know whether the proposals fall into the same category? This is important for calculating how much you can vote as well as for viewing all proposals for the same topic.

If we decide that each proposal is independent, then each proposal can either be accepted or expire. For transfers, you should get to the state where transfers can expire.

For network upgrades, we can have a separate contract that tracks current poll by having a list of proposals.

If there is no expiration height the state might grow very large.

Might need to limit who can create proposals through whitelist. Then network upgrade contract will be able to create proposals.

@bowenwang1996
Copy link
Collaborator Author

@evgenykuzyakov I see. That is an interesting approach. So pretty much you can vote on both "unlocking transfer at height 10000" and "unlocking transfer at height 1000" with all your stake. It definitely simplifies things a lot but at the same time it feels a bit weird...

@bowenwang1996
Copy link
Collaborator Author

Might need to limit who can create proposals through whitelist. Then network upgrade contract will be able to create proposals.

I think that will result in bad UX. You have to go to one contract to create a proposal and another to actually vote on it.

@bowenwang1996
Copy link
Collaborator Author

@evgenykuzyakov

For transfers, you should get to the state where transfers can expire.

What does this mean?

@evgenykuzyakov
Copy link
Contributor

For transfers, you should get to the state where transfers can expire.

Sorry. I meant you should NOT get to the state where transfers vote can expire.

@bowenwang1996
Copy link
Collaborator Author

Update: discussed with @evgenykuzyakov offline. We decide that:

  • we will have one voting contract per poll (which supports multiple proposals). This NEP will provide a template for voting contracts.
  • staking pool will act on behalf of delegators so that there is no need to separately deal with delegator votes.

@bowenwang1996 bowenwang1996 marked this pull request as ready for review May 6, 2020 23:45
@render
Copy link

render bot commented May 7, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

proposals/0000-template.md Outdated Show resolved Hide resolved
proposals/0000-template.md Outdated Show resolved Hide resolved
proposals/0000-template.md Outdated Show resolved Hide resolved
proposals/0000-template.md Outdated Show resolved Hide resolved
@render
Copy link

render bot commented May 8, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

@render
Copy link

render bot commented May 11, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

The voting contract has the following methods to allow creation of polls and proposals, as well as voting for proposals.

```rust
impl Poll {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a method get the result

@FelixLutsch
Copy link

FelixLutsch commented May 15, 2020

Randomly landed here: does this mean NEAR will also have on-chain governance? Who could make such proposals? If it's any NEAR account it will probably be useful to add some deposit to the contract that might be burned/given to the community pool or whatever to prevent spam

@bowenwang1996
Copy link
Collaborator Author

does this mean NEAR will also have on-chain governance? Who could make such proposals? If it's any NEAR account it will probably be useful to add some deposit to the contract that might be burned/given to the community pool or whatever to prevent spam

Yes as I said in the proposal this will be the first step towards on-chain governance. The current plan is that anyone can make proposals, but as you point out, we need some economics around that to prevent attacks. That part is not finalized yet and I'll update the proposal when I flesh out the details a bit more.

@render
Copy link

render bot commented May 16, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

@render
Copy link

render bot commented May 21, 2020

Your Render PR Server at https://nomicon-pr-62.onrender.com is now live!

View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80.

bowenwang1996 added a commit to near/nearcore that referenced this pull request May 21, 2020
Expose validator information as host functions:
```
validator_stake(account_id_len: u64, account_id_ptr: u64, stake_ptr: u64) -> []
total_validator_stake(stake_ptr: u64) -> []
```
so that voting contract can calculate the weight of each vote. Resolves #2475. Implements the runtime change specified in near/NEPs#62
@ilblackdragon
Copy link
Member

Posting my comment from here near/core-contracts#6 (comment):

So I thought we are going to do next thing:

  • Proposal are sent with date of unlock all the time, there is a window to vote for proposal is time to unlock - 2 weeks - 4 epochs
  • Validators vote for proposals as they see fit until voting is allowed: either yay or nay
  • Proposal voting locks for 4 epochs and at that point we evaluate who voted for it, and what is their stake. If 66% of total stake voted -> proceed on 2 week waiting period before unlocking.

Why 4 epochs? Because we want to allow delegates to switch their validators if they don't think the validator they are delegating right now represents them.

Why 2 weeks? Because transfer unlock will require various parties to be prepared for it (wallets, possible exchange listings, users, financial participants, etc). Giving them a specific timeline heads up is important. Also if this vote happens right after Phase 1 is done, at least there are couple of weeks between those two events (this is also needed for some internal timelines).

@bowenwang1996
Copy link
Collaborator Author

@ilblackdragon this voting contract design is not specific to voting for unlocking transfer. I am not sure how to best reconcile this suggestion with the general template.

@ilblackdragon
Copy link
Member

Give me an example usage of general template? E.g. I'm not sure why would general template not follow the same rules without understanding where else are you planning to use this general template?

@bowenwang1996
Copy link
Collaborator Author

@ilblackdragon the spec for the next version of the protocol for example. I was concerned with this part

Proposal are sent with date of unlock all the time

I am not sure whether you are talking about proposals in general or proposals in one specific contract. Also 2 weeks seem specific to the concerns of unlocking transfers as well.

@evgenykuzyakov
Copy link
Contributor

Also 2 weeks seem specific to the concerns of unlocking transfers as well.

This can be done on the receiving part. The lockup contracts can use timestamp +2weeks.

@ilblackdragon
Copy link
Member

Fine with moving 2 weeks into lockups.

accounts: Map<AccountId, Balance>,
/// Next proposal id.
next_proposal_id: ProposalId,
/// Threshold for closing the poll, i.e, if the ratio of stake on a certain proposal over total stake reaches
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we also want to have a minumum amount of stake as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can

}
```
Here `metadata` is the json serialized content of the proposal. For example, if the poll is about when the network upgrade
should happen, `metadata` will be something like `{"height": 10000}`. Validators can vote on multiple different proposals
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the proposals are about height - then if I vote for height 10000, I also vote for all heights above it.
So it's a bit unclear how here multiple voting will work, given need to apply full stake on all of them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multiple voting will work

The rule is that the sum of your voted stake cannot exceed your current stake.

```rust
fn resolve_proposal(&mut self, proposal_id: ProposalId) {
// if the epoch height has changed, then
// for each vote in the proposal, its stake is changed to orginal_stake * current_total_account_stake / previous_total_account_stake.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, this is incorrect?
let's say everyone received 10k of rewards, and one validator withdrew 10k from their acount.
total stake didn't change, but that validators stake reduced.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

total stake didn't change

Why? with reward the total stake increases

one validator withdrew 10k from their account

Stake doesn't get returned immediately so I don't think there is a problem.

/// All proposals for this poll.
proposals: Map<ProposalId, Proposal>,
/// Accounts that have participated in this poll and the corresponding stake voted.
accounts: Map<AccountId, Balance>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like this should be fraction of their stake, because stake is changing constantly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it the same thing? If we store fractions here we need the actual stake to compute whether a proposal should be finalized and to update it when a validator changes their vote.

@frol
Copy link
Collaborator

frol commented Sep 5, 2022

@bowenwang1996 I am closing this NEP as it seems that voting contract has been implemented a long time ago

@frol frol closed this Sep 5, 2022
@frol frol added the WG-contract-standards Contract Standards Work Group should be accountable label Sep 5, 2022
@frol frol deleted the voting-contract branch December 20, 2022 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WG-contract-standards Contract Standards Work Group should be accountable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants