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

Disable transfers via set of contracts #2283

Closed
2 tasks
ilblackdragon opened this issue Mar 20, 2020 · 15 comments
Closed
2 tasks

Disable transfers via set of contracts #2283

ilblackdragon opened this issue Mar 20, 2020 · 15 comments
Assignees
Labels
A-transaction-runtime Area: transaction runtime (transaction and receipts processing, state transition, etc) P-high Priority: High

Comments

@ilblackdragon
Copy link
Member

ilblackdragon commented Mar 20, 2020

Update: We are not introducing the conditional compilation flag, see the comments.

There needs to be a way to disable transfers at the launch on MainNet.
We also expect validators to enable it later, so it can be just a feature flag that later removed from code.

We want to support the following:

  • We want the users to be able to create accounts, which requires transferring. However we want this to be controlled through special accounts/contracts;
  • Accounts should be able to delegate staking to the validators.

Implementation:

  • We will disable the following functionality of the runtime using feature flag. The set of whitelisted accounts is going to be hardcoded and built-in into the runtime crate.
    • Account X cannot transfer to account Y, unless X is whitelisted;
    • Account X cannot call account Y with attached deposit, unless X is whitelisted OR X is calling a whitelisted contract, see below;
    • Account X cannot create account Y, unless X is whitelisted;
    • Account X cannot delete account Y, unless X is whitelisted and the beneficiary Z is also whitelisted;
  • We will have a special whitelisted contract A which will be whitelisted through its hash. Anyone who has an account will be able to deploy such a contract. This contract loosely follows Staking Contract NEPs#27 (this NEPs needs to be udpated) and will have the following methods: deposit, withdraw, stake, unstake.
@ilblackdragon ilblackdragon added the A-transaction-runtime Area: transaction runtime (transaction and receipts processing, state transition, etc) label Mar 20, 2020
@MaksymZavershynskyi MaksymZavershynskyi added the P-high Priority: High label Mar 22, 2020
@MaksymZavershynskyi
Copy link
Contributor

@ilblackdragon @evgenykuzyakov It sounded like from our discussion offline that there is no need anymore to prohibit transfers on the runtime level? If yes, then I will close this issue since near/NEPs#27 supersedes it.

@MaksymZavershynskyi MaksymZavershynskyi changed the title Feature flag to disable transfers Disable transfers Mar 31, 2020
@MaksymZavershynskyi
Copy link
Contributor

MaksymZavershynskyi commented Mar 31, 2020

Terminology

TED -- Transfer Enable Date, the timestamp after which we allow token holders to transfer unlocked vested tokens.

This post describes the restrictions applied to the Mainnet before TED and after TED. It also describes what TED is.

Before TED we differentiate the following types of the accounts:

  • Genesis accounts:
    • Near foundation
    • Other accounts (various contributors, backers, etc)
  • Non-genesis accounts:
    • New user accounts
    • Projects building on Near

How we disable transfers

After discussion with @ilblackdragon we came up with the following plan to disable transfers without modifications to the runtime. Here is how Mainnet will behave before TED:

  • Testnet will be completely unrestricted in what developers can do on it: create/remove accounts, deploy/call contracts, etc. Developers will be able to create an initial account with some initial tokens using our devtools and/or wallet. (CC @kcole16 , @potatodepaulo );
  • Mainnet will be restricted through the contract mechanism.
    • All user accounts will not be able to transfer any vested unlocked tokens until TED. The TED will be stored in a single account with a special voting contract described in the below section. Token holders will use vesting/lockup contracts and when someone calls transfer() on vesting/lockup contract it first checks with the voting contract on whether the unlock date has happened and if it didn't the transfer fails. (After the unlock date the vesting/lockup contract stops checking the voting contract);
    • When some project wants to be able to run on the Mainnet they submit a request to Near foundation through an online form, we then evaluate their project and create for them an account with some minimal amount of tokens. Then their account is not restricted in what they can do with these tokens but they will only have limit balance to cover storage.
      • The purpose of the form is to build relationship with projects that are building on NEAR at the start and also setup how they want to onboard their users in the beginning as well.
      • Projects that qualify will have an ability to use our link-base faucet to onboard their users. Faucet (run by foundation) will still be creating locked contracts that wait until TED for transfers to be enabled.

Voting contract

Voting contract will have one goal -- it will allow community to decide when to enable transfers. The proxy for the community will be validators. The contract will have access to the list of the current validators through the new host functions. Each account will be then able to cast a vote for a specific TED by calling vote() method on the voting contract (this will overwrite the previous vote with the same account). Then when someone calls ping() on that contract it verifies the following:

there is TED for which simple majority of the current validators (weighted by stake) have casted the vote

When such TED exists the voting contract permanently commits to it.

Work items

Based on the above explanation we need to finish the following work items:

  • Expose current validators in the host functions
  • Implement voting contract
  • Modify the lockup/vesting contract to call the voting contract
  • Create project submission form

@ilblackdragon @evgenykuzyakov please comment.

@MaksymZavershynskyi
Copy link
Contributor

Also moving to genesis contracts Epic, since I think it is more relevant there now.

@evgenykuzyakov
Copy link
Collaborator

I think there might be some additional work with shared staking pools. Those contracts should be able to vote in addition to current delegation/staking work

@bowenwang1996
Copy link
Collaborator

Should there be a lower bound on the TED? For example it cannot be earlier than 3 months from genesis time.

@MaksymZavershynskyi
Copy link
Contributor

@evgenykuzyakov

It can be done the following way:

  • When pool contract changes its state it notifies the voting contract on how its delegated stake is currently distributed (e.g. Alice delegated 10 tokens, Bob delegated 7 tokens).
  • Then when Alice calls vote() on the voting contract it knows what Alice's weights are because it knows the weights of the pools;
  • Alice would need to authorize the pool to represent her in voting by calling: voting_through_pool() on the voting contract and pass the pool account id to it.

WDYT?

@bowenwang1996

Should there be a lower bound on the TED? For example it cannot be earlier than 3 months from genesis time.

Yes, good point.

@evgenykuzyakov
Copy link
Collaborator

It can be done the following way

It's over-complicated right now. All of this work is just to account for one time event that enables transfers for locked contracts. Also this work by itself can contain bugs.

Of course, some of this work can be reused later for governance, but it's unclear whether we should go with it.

How important is validator/community voting to enable transfers? Can this be solved with other options that don't involve voting on chain?

@MaksymZavershynskyi
Copy link
Contributor

Discussed with @evgenykuzyakov in a private channel. Added technical complexity of the voting contract is a lesser evil than taking other non-technical risks.

@evgenykuzyakov
Copy link
Collaborator

To simplify delegation a little, we probably want to shift voting aggregation on the staking pool contract side instead of moving it to voting contract.

  • Add vote to lockup contracts. It will call on_delegate_vote on staking_pool.
  • Add on_delegate_vote to staking_pool. It should take vote from the predecessor and update inner vote count.
  • Voting contract should take percentage of tokens for yes and no during vote function.

I also would suggest we remove staking capability from the lookup contracts by having delegation only. This will remove double staking logic in the lockup.

@ilblackdragon
Copy link
Member Author

@nearmax I've updated your post /\ a bit to clarify few details.

@bowenwang1996

No, we shouldn't have minimum period. There is no real reason to have that.
Stakers and delegators are maintainers of the network - whatever is their decision is the date.
(They can hardfork to re-deploy contract without any limit anyway if 66% of stake agrees)

@evgenykuzyakov

Indeed this is a reusable work for future governance.

Let's discuss separately staking contract, because really I think it should be done separate. We do need voting contract to support weight to the votes in the voting contract. E.g. voting_contract.vote(date, weight) where weight is number of tokens out of total stake that should be considered for this vote.

I don't understand, "add vote to lockup contracts" - are you saying that there are no way to call arbitrary contracts/methods from lockup contracts if they don't require attaching funds?

I'm ok with removing staking capability from lockup contracts, especially given we are planning to split contributors balances into multiple accounts and will need to pool things back.

@evgenykuzyakov
Copy link
Collaborator

evgenykuzyakov commented Apr 1, 2020

voting probably should go into its own NEP.

Should we extend voting contract to support multiple proposals?

NEAR foundation account will be able to create new proposals with new_proposal(..) -> u64 returns new proposal ID with arguments:

  • description: String - Human readable description of the proposal
  • vote_options: Vec<String> - Human readable description of each voting option
  • expiration_timestamp_ns: Option<U64> - The timestamp in nanoseconds when the proposal has receive the majority of votes before it expires.

vote(..) will take the following arguments:

  • proposal_id: u64 - the index of the proposal you vote on
  • votes: Vec<Balance> - distribution of votes weighted in Balance. Staking pool needs to be able to vote on multiple options, because pool users may vote on different options. If the total vote balance exceeds the current stake of the voter, this vote will be considered invalid during resolution.

get_result(..) -> Option<u64> returns Some(vote_index) if the proposal was resolved:

  • proposal_id: u64 - the index of the proposal to check

lockup and staking pools contracts should have the same vote API as voting contract.

@MaksymZavershynskyi
Copy link
Contributor

@ilblackdragon You have changed the description from

Token holders will not be able to transfer any vested unlocked tokens until TED

to

All user accounts will not be able to transfer any vested unlocked tokens until TED

I don't think it is correct. We want user accounts to be able to do anything with their accounts, because (otherwise it will hurt our DevX if we deploy one contract on their account, do not give them full access key and prohibit redeploying it).

@ilblackdragon
Copy link
Member Author

@nearmax It is correct. The goal of disabling transfers is to prevent third parties from transferring tokens to non-authorized entities until network is fully decentralized and controlled by community. Hence all users accounts are not able to transfer.

@ilblackdragon ilblackdragon changed the title Disable transfers Disable transfers via set of contracts Apr 10, 2020
@ilblackdragon
Copy link
Member Author

Created #2474 and #2475 to separate specific action items.

@MaksymZavershynskyi
Copy link
Contributor

It does not look to me like there is a work in addition to #2474 and #2475 . So I am closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-transaction-runtime Area: transaction runtime (transaction and receipts processing, state transition, etc) P-high Priority: High
Projects
None yet
Development

No branches or pull requests

4 participants