A common requirement I have seen, is the need of having a mechanism that allows listing elements, and manage the presency of these, in a way that promoves that these elements are aligned with the goal of the list:
- For #core-dapps, a descentralized way to control the publishing of DApps.
- For #core-infra, a way to register and discover trusted server nodes.
Probably more requeriments like these will appear in the future, hence the importance of having a form of handling this kind of behaviours, and also to add additional use cases for SNT.
Lots of research have been done already for Token Curated Registries
- https: // medium . com/@tokencuratedregistry/the-token-curated-registry-whitepaper-bd2fb29299d6 A huge list of resources related to TCRs
- https: // github . com/skmgoldin/tcr Generic TCR
Leveraging the work already done on these resources, as well as the ProposalCuration contract 3esmit developed, I have adapted the code from the generic trc to use Status’ set of Democracy contracts for the voting mechanism
https: // github . com/status-im/contracts/tree/000-tcr
The intended flow for using these contracts is the following:
- The controller of a contract (right now a multisig address, in the future a DAO) after instantiating the contract, proceeds to set the TCR parameters:
– Proposal application period: number of blocks before an unchallenged application may be whitelisted and included in the TCR
– Proposal voting period: number of blocks where voting for a challenged proposal is allowed
– Submission price: minimum number of tokens to allow a proposal to be added to a list, and a challenge to be made. (Can be set to specific addreses too)
For the proposal creation,
- A token holder that wishes to submit a proposal, needs to inquiry the submission price via
getSubmitPrice
, and then, to submit a proposal, for this, the functionsubmitProposal
is invoked, with a_data
parameter that will include the information that represents an element in the TCR (think of IPFS/Swarm hashed, Metadata, etc.), and also a_depositAmount
which will be used as a balance for the proposal. This needs to be greater or equal to the submission price, and the TCR contracts needs an allowance equals to this amount for the correct execution of this function. - This balance can be increased and decreased, the only requirement is to keep the balance greater than the submission price
- After the whitelisting period ends, the owner of the proposal can invoke
processProposal
to proceed to whitelist it, however, a proposal may be challenged as soon as it is submitted, so it may not be able to be whitelisted.
For the curation of proposals
- When a proposal is created, a different token holder might challenge it to remove the proposal if he feels it doesn’t belong to the TCR (or if he wants to be a bad actor, but the TCR has a mechanism to handle this case).
- The challenger invokes the
challenge
function specifying which proposal he wants to challenge. He needs to give an allowance to the TCR contract of at least the submission price. - When the proposal is challenged, a votation process is created, and any token holder may vote to allow the proposal to be included in the TCR or not. This voting is done using the ProposalManager contract and specifying the challenge ID:
let receipt1 = await ProposalManager.methods.voteProposal(challengeId, vote).send({from: accounts[0]});
let receipt2 = await ProposalManager.methods.tabulateVote(challengeId, accounts[0]).send({from: accounts[0]});
-
After the voting period is complete, and the votes tabulated,
processProposal
can be invoked by anyone to proceed to determine the voting outcome -
If the proposal is rejected, the submission price is deducted from the proposal balance, the remainder is transferred to the proposal owner, and the proposal is delisted.
-
The proposal balance that was deducted is divided among the challenger and the holders who voted to reject the proposal in a proportion determined by the
rewardPercentage
variable. -
The same behavior is applied when the proposal is approved, but instead of the balance being deducted, is the challenger stake that is deducted, and divided in the same proportion for the tokens holder who approved the proposal, and increasing the balance of the proposal.
-
The token holders that voted may claim their reward after voting ends and proposal is processed using the
claimReward
function.
I made some changes to the ProposalManager contract to add some additional view functions, and also to be able to specify the voting period and the quorum percentage. I’m not sure that having 50% + 1 votes (Majority rule) is the ideal way to determine a proposal result, since we may fall into a classic tirany of the majority result where the other 50% - 1 token holders disagree with the voting result (and this represents a big part of the token holders, as well as the difficulty of getting that amount of votes (even if we use delegates), because of the dificulty of gathering the amount of SNT required due to the existing supply and the interest a token holder may have or not in voting for proposals.
My idea is to have a bonded curve token that can be bought with SNT, and this token is created along with the TCR. The idea is that in order to publish and vote for elements in a TCR, you need to acquire the bonded curve token (BCToken from now on) (where the higher the supply of tokens is, the higher the cost. See https: // medium . com/@simondlr/tokens-2-0-curved-token-bonding-in-curation-markets-1764a2e0bee5), and the BCToken can be sold back for SNT in any moment. Also, since the supply of the BCToken will be way less than the SNT supply, we can change the quorum percentage to a value that is more representative to the wish of the majority. (This is something I’m currently researching).
Also something that caught my attention in https : //github . com/skmgoldin/tcr is that they have a token curated registry for handling the parameters too, which I believe it will not be necessary in the current TCR contract, since in the future these parameters can be handled with the democracy contracts.
The TCR contract can be used without requiring the BCToken, tho. So in case we do not require this, we can use SNT token or any other token without problems.
If you guys wish to see the TCR in action, assuming you have embark installed, you can execute
embark test test/tokenCuratedRegistry.js