The Validator Registry contract is an implementation of a token-curated registry (TCR) that enables decentralized curation of validators on the network. Individuals wishing to become validators submit proposals to join the validator set specifying a reward schedule.
The goal of a TCR is to produce a curated set of listings, which are entries that have successfully been included in the registry. Listings begin as proposals which indicate intent to join the registry, backed by a number of tokens. Proposals and listings may be challenged at any time, where a challenger must put up an equal number of tokens as the listing or proposal owner. Challenges trigger votes, which any token holder may participate in. If voted out, the validator’s tokens are distributed to the individuals responsible for raising – and voting in – the successful challenge.
Holders of the protocol’s native staking token, KOSU (ERC-20 standard), with non-zero Treasury balances can vote on governance matters, where votes are weighted proportional to their deposited balance. Validators and Posters who are required to bond KOSU in order to perform their designated roles in the network, will also be able to vote on proposals using bonded tokens. In other words, all tokens deposited in the Treasury count towards a users vote weight, even if they are allocated as stake in challenges/listings or bonded in the Poster registry.
The primary stakeholders within the Kosu system are validators, posters, and voters. It is possible and likely for individual stakeholders to serve two (or more) roles at once.
The Kosu network uses a Tendermint bonded proof-of-stake security model wherein validators stake (by locking) tokens into a contract proportional to the amount of vote power they wish to receive on the network.
Validators are required to run full Ethereum nodes to faciliate a one-way peg-zone between the two chains. To do so, validators submit special attestations, or “witness" transactions, to the Kosu network about specific state changes to the protocol's contract system. These updates include user bonded token balances (which affect an order rate limit enforced by the network), and updates to the dynamic registry contract containing the curated list of validators.
Posters are individuals wishing to leverage the network's decentralized order booking and message relay features. They gain write access to the network by bonding any amount of KOSU tokens in a poster registry contract.
A voter is any entity who holds KOSU and participates in governance polls. Both posters and validators are allowed to participate in votes with their locked balances, and any additional tokens they wish to deposit.
Validator listing process
Right to submit a proposal
Any participant with KOSU deposited in the Treasury may create a proposal that indicates their intent to become a network validator by calling the
registerListing method. The proposal should specify the following as parameters:
tendermintPublicKey: Hex encoded Tendermint public key
tokensToStake: the amount of KOSU at stake if challenged
rewardRate: the rate at which tokens are minted or destroyed over the active listings reward period
details: external link with validator information for voters
Proposal filter (minimum stake)
Proposals must include a stake (
tokenToStake) of KOSU greater than or equal to the specified minimum parameter. The minimum stake amount is currently set at 1 KOSU.
All validator proposals must include a reward (
rewardRate) to be executed to the validator on a periodic basis. This reward may be positive (tokens minted as inflation), negative (tokens burned), or zero. If a listing with a negative reward rate is proposed and accepted, the validator must continually collateralize a treasury balance sufficient to cover the burn rate. If the validator is unable to cover a burn, they may be removed from the listing without a full challenge ("touch-and-remove"). If a listing owner's available balance (number of tokens deposited in treasury) falls below their stake size, they may also be touched-and-removed. An example of the previously described scenario would be a validator withdrawing their staked KOSU.
There is also a specified
maxRewardRate which is the maximum amount of KOSU a validator can propose to mint per period. This
maxRewardRate constriction on proposals is equal to 1.2x the current maximum validator reward rate. For example, if the highest reward rate in the current validator set is 10 KOSU per period, the maximum reward rate that may be proposed by an intended validator is 12 KOSU per period.
Proposals that are not challenged may be confirmed into the registry after a period of time measured in Ethereum blocks using the
confirmListing method with the validator's
tendermintPublicKey as the only parameter.
Pending proposals and accepted listings may be challenged at any time with the
challengeListing method specifying a
tendermintPublicKey and an external link (
details) as parameters. All challenges are identified with a
Challengers must have an available balance of KOSU equal-to or greater-than the stake of the listing or proposal being challenged.
Challenges may be voted on by any KOSU holder using a commit-reveal vote scheme during a specified voting period.
Vote weight is determined by the system balance of a user within the Kosu contract system.
After the completion of a vote period, the ruling is determined based on the binary outcome (yes or no) that received a majority of the participating vote weight.
If a challenge resolves against a listing or proposal, the listing's staked tokens are distributed to the challenger and the winning voters (see below).
If a challenge fails, the challenger's collateral is distributed to the winning voters and the owner of the challenged listing.
Voters are never penalized for voting on the losing side of a challenge.
The payout of resolved challenges is split between the winning stakeholder, and the participating voters on the winning side. The first block produced after a challenge vote ends, the challenge is considered finalized as no more votes can be revealed. At this point, any party may call the
resolveChallenge method and the payout is granted to the winning stakeholder (challenger or challenged listing).
Voters on the winning side can individually claim winnings by calling the
claimWinnings method with the
challengeId as a parameter.
The split payout awarded to voters is distributed proportionally according to each voter's vote weight, which is the number of KOSU committed by an individual voter as a proportion of total tokens committed by all winning voters.
Any holder of KOSU within the Treasury, including participants that are staking/bonding as a Validator/Poster, may choose to vote during a challenge period with their tokens. The voting process uses a commit-reveal scheme to hide voter decisions and ensure that voters do not switch their vote based on the winning outcome.
The commit period begins as soon as a challenge is made and lasts the number of blocks specified in the
constructor. During the commit period, voters signal their vote with the
commitVote method and the following parameters:
_pollId: Poll index to act upon
_vote: Hash encoded vote (i.e. for a binary poll, 0 signifies 'against' and 1 signifies 'in favor')
_tokensToCommit: Number of KOSU comitted to vote
In order to generate the Hash encoded vote (the
_vote parameter in the
commitVote method), the kosu voting library provides the
encodeVote method. This methods accepts two parameters:
_voteOption which is a 0 or 1 signifying 'against' or 'in favor', and
_voteSalt which is a randomly generated string of numbers. The
encodeVote method encodes the vote by hashing the Option and the Salt, creating the Hash encoded vote that is submitted as the
_vote parameter in
The reveal period begins on the same block that the commit period ends. A vote needs to be committed and revealed in order to count. The
revealVote method is used to reveal a vote and accepts
_voteSalt as parameters. If the vote otion (0 or 1) and vote salt (randomly generated bytes) submitted with
revealVote produce the same Hash that was previously committed by the voter during the commit period, the vote is considered valid. Once the reveal period is over and the poll is finalized, the
totalWinningTokens methods can be called (both have
_pollId as the only parameter) to see the total number of votes revealed and the number of votes revealed on the winning side.