This EIP is an API for implementing voting with smart contract. This standard provides functionalities to voting as well as to view the vote result and set voting status.
Voting is one of the earliest example of EVM programming, and also a key to DAO/organizational governance process. We foresee many DAOs will ultimately need to leverage voting as one of the important part of their governance. By creating a voting standard for smart contract / token, we can have the following benefits
proposalId
but what information of the proposal includes,
whether they are on-chain or off-chain and whether they are exeutable, is leaved out from this proposal. A separate EIP could be proposed to address this particular use case. See one of such proposals ERC-5247IERC1202Core
belowinterface IERC1202Core {
event VoteCast(
address indexed voter,
uint256 indexed proposalId,
uint8 support,
uint256 weight,
string reason,
bytes extraParams
);
function castVote(
uint256 proposalId,
uint8 support,
uint256 weight,
string calldata reasonUri,
bytes calldata extraParams
) external payable returns;
function castVoteFrom(
address from,
uint256 proposalId,
uint8 support,
uint256 weight,
string calldata reasonUri,
bytes calldata extraParams
) external payable returns;
function execute(uint256 proposalId, bytes memory extraParams) payable external;
}
IERC1202MultiVote
Interface. If the intention is for multi-options to be supported, e.g. for ranked-choices
or variant weights voting, Compliant contracts MUST implement IERC1202MultiVote
Interface.interface IERC1202MultiVote {
event MultiVoteCast(
address indexed voter,
uint256 indexed proposalId,
uint8[] support,
uint256[] weight,
string reason,
bytes extraParams
);
function castMultiVote(
uint256 proposalId,
uint8[] support,
uint256[] weight,
string calldata reasonUri,
bytes calldata extraParams
) external payable;
}
interface IERC1202Info {
function votingPeriodFor(uint256 proposalId) external view returns (uint256 startPointOfTime, uint256 endPointOfTime);
function eligibleVotingWeight(uint256 proposalId, address voter) external view returns (uint256);
}
We made the following design decisions and here are the rationales.
We created a view
function ballotOf
primarily making it easier for people to check the vote from certain address. This has the following assumptions:
It's possible to check someone's vote directly given an address. If implementor don't want to make it so easily, they can simply reject all calls to this function. We want to make sure that we support both anonymous voting an non-anonymous voting. However since all calls to a smart contract is logged in block history, there is really no secrecy unless done with cryptography tricks. I am not cryptography-savvy enough to comment on the possibility. Please see "Second Feedback Questions 2018" for related topic.
It's assumes for each individual address, they can only vote for one decision. They can distribute their available voting power into more granular level. If implementor wants allow this, they ask the user to create another wallet address and grant the new address certain power. For example, a token based voting where voting weight is determined by the amount of token held by a voter, a voter who wants to distribute its voting power in two different option(option set) can transfer some of the tokens to the new account and cast the votes from both accounts.
We assume there are weight
of votes and can be checked by calling eligibleVotingWeight(proposalId, address voter)
, and the weight distribution is either internally determined or determined by constructor.
support
options are chosen to be uint8
for the purpose to be backward compatible for GovernorBravo. It can be increased in the futureWe expect the voting standard to be used in connection with other contracts such as token distributions, conducting actions in consensus or on behalf of an entity, multi-signature wallets, etc.
The major security consideration is to ensure only using the standard interface for performing downstream actions or receiving upstream input (vote casting). We expect future audit tool to be based on standard interfaces.
It's also important to note as discussed in this standard that for the sake of simplicity, this EIP is kept in the very basic form. It can be extended to support many different implementation variations. Such variations might contain different assumptions of the behavior and interpretation of actions. One example would be: What does it mean if someone votes multiple times through vote
?
Because of the flexible nature of voting, we expect many subsequent standards need to be created as an extension of this EIP. We suggest any extension or implementations of this standard be thoroughly audited before included in large scale or high asset volume applications.
The third consideration is non-triviality. Some voting applications assume anonymity, randomness, time-based deadline, ordering, etc, these requirements in Ethereum are known to be non-trivial to achieve. We suggest any applications or organizations rely on audited and time-proven shared libraries when these requirements need to be enforced in their applications.
The fourth consideration is potential abuse. When voting is standardized and put on contract, it is possible to write another contract that rewards a voter to vote in a certain way. It creates potential issues of bribery and conflict of interest abuse that is previously hard to implement.
Copyright and related rights waived via CC0.