Voting Operations

As the Proposal Manager supports three token standards--ERC1155, ERC20 and Items--there are different voting methods available.

Vote Using ERC1155s, or Items via the Item Main Interface

To vote for a Proposal using this method, it is necessary to send tokens to the Proposal Manager, which uses the onERC1155Received and onERC1155BatchReceived functions to receive the tokens. In the payload, the sender must also send the following info in order for the vote to be cast correctly:

  • uint256 proposalId -> this is the id of the Proposal that is being voted on.

  • uint256 accept -> this is the number of accept votes being cast.

  • uint256 refuse -> this is the number of refuse votes being cast.

  • address voter -> this is the address of the voter.

  • bool alsoTerminate -> this represents whether the terminate function should be called after the vote is cast, in an attempt to terminate the Proposal (true) or not (false).

The coexistence of the accept and refuse fields here indicates that it is possible to vote both to accept and to refuse the Proposal in the same vote .

For example, it is possible to cast both x number of acceptance votes and y number of refusal votes--or, to cast votes of only one type, leaving the other field empty.

The voter address can be either different than or equal to the token sender (i.e token sender = Proposal voter). In the first case, the votes will refer to the Proposal voter, and not the token sender, and the token sender will not show up in the ProposalManager. Only the voter will be able to withdraw the amount of tokens cast by the vote, after the vote is cast.

Vote Using ERC20s or an Item Via Its Interoperable Interface

A voting operation can be performed in two ways:

  • single -> this allows for voting in a Proposal.

  • batch -> this allows for voting in more than one Proposal at the same time.

Voting operations that use ERC20s or Item Interoperable Interfaces support the permit operation. As a result, approval can be managed and executed using either permit or the classic on-chain approval.

To vote for a Proposal in single mode, use the vote method:

function vote(address erc20Address, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool terminate) external

The parameters of this function are composed as follows:

  • address erc20Address -> this is the address of the token to use. It must be one of the tokens supported by the Proposal Manager.

  • bytes permitSignature -> if the ERC20 supports the permit operation and if you want to use it, this parameter represents the signature.

  • bytes32 proposalId -> this is the id of the Proposal that is being voted on.

  • uint256 accept -> this is the number of accept votes being cast.

  • uint256 refuse -> this is the number of refuse votes being cast.

  • address voter-> this is the address of the voter.

  • bool alsoTerminate -> this represents if the terminate function should be called after the vote, in an attempt to terminate the Proposal (true) or not (false).

To vote for Proposals in batch mode, use the batchVote method:

function batchVote(bytes[] calldata data) external payable;

As input, this function takes an array of bytes data. Each data can contain the following encoded parameters:

(address erc20TokenAddress, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool alsoTerminate) = abi.decode(data[i], (address, bytes, bytes32, uint256, uint256, address, bool));

which are the same as the input parameters of the single vote function.

Withdraw Votes

After a Proposal is voted on by an address, the address can withdraw its votes.

The withdrawAll function can be used to withdraw votes:

function withdrawAll(bytes32[] memory proposalIds, address voterOrReceiver, bool afterTermination) external;

It takes as input:

  • bytes32[] proposalIds -> it represents the ids of the Proposals from which you are withdrawing votes.

  • address voterOrReceiver -> it represents the address receiver of the withdrawn tokens. If passed as address(0) the msg.sender is taken as receiver. If afterTermination is true, the voterOrReceiver must be populated different from address(0).

  • bool afterTermination -> it represents if the Proposals from which you are withdrawing votes are terminated, i.e. can no longer be voted (true) or not (false).

The withdrawal operation can be called both if the Proposal is still in progress or if it has been terminated.

In the first case (i.e, the Proposal is not terminated), the withdrawAll function sends the tokens that were cast as votes back to the receivers, removing them from the Proposal voting count.

In the second case (i.e, the Proposal cannot be voted on anymore, and thus one of the canTerminate contracts returns true), withdrawAll sends the tokens back without removing the votes cast from the vote count.

Last updated