Constant holding type hash of EIP712 domain as per EIP712 specification
-`VOTE_TYPEHASH`
Constant holding type hash of Vote as per EIP712 specification
-`DOMAIN_SEPARATOR`
Variable holding hash of domain separator according to EIP712 spec. Assigned at smart contract creation.
-`voted`
this variable holds information if given address voted in a given voting room. So it is a mapping of room id to mapping of addresses to bools which say whether or not given address voted.
-`votingRooms`
Array that holds all voting rooms. roomId of voting room is equivalent to its index in array
### Signing with EIP712
This smart contract uses EIP712 for signing vote msg.
The structure of typed data for vote messages is as follows:
```ts
{
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
],
Vote: [
{ name: 'roomIdAndType', type: 'uint256' },
{ name: 'tokenAmount', type: 'uint256' },
{ name: 'voter', type: 'address' },
],
},
primaryType: 'Vote',
domain: {
name: 'Voting Contract',
version: '1',
chainId: chainId,
verifyingContract: contract.address,
},
message: {
voter: voterAddress,
tokenAmount: tokenAmount,
roomIdAndType: roomIdAndType
}
}
```
For more information about EIP-712 go to [docs](https://eips.ethereum.org/EIPS/eip-712)
Returns votingRooms in which `room.endAt > block.timestamp` which means the rooms are still accepting votes.
Since `votingLength` is set at contract creation and never changed, `room.endAt` is never decreasing with increasing index of votingRoom. Therefore it is enough to check from votingRooms.length up to first element which `endAt < block.timestamp`
Sets totalVotes amount of voting room with index corresponding to `roomId`.
If voting first bit of `vote.roomIdAndType` is 1 that means that vote is for and `vote.tokenAmount` is added to `votingRooms[roomId].totalVotesFor`, otherwise if `vote.roomIdAndType` is 0 `vote.tokenAmount` is added to `votingRooms[roomId].totalVotesAgainst`.
After that add new address to room `voters` and updates mapping `voted` accordingly.
-`castVotes(Vote[] calldata votes)`
Function used to cast votes in rooms.
Function accepts an array of votes of type `Vote`.
All votes are looped through and verified that votes are:
- properly signed
- voter has enough tokens to vote
- voting room exists
- voting room hasn't been closed
Vote verification is as follows.
First roomId is decoded from `vote.roomIdAndType` which means shifting it to the right once.
Then it is verified that voting room with given roomId exists and isn't closed if not whole function reverts, this is to discourage grouping votes for different voting rooms together (! maybe it should be changed so that votes for multiple voting rooms can be cast ? !).
After that it is verified that `vote` has been signed by `vote.voter`. If not function goes to another vote in array (IDEA: maybe vote verification failed should be emitted ?).
Then it is checked that `vote.voter` didn't vote in this vote room before if he did function goes to another voter (IDEA: emit alreadyVoted ?).
Last check is whether `vote.voter` has enough tokens to vote. If he does not `NotEnoughToken` is emitted and function goes to another voter. If he does voting room is updated with `updateRoomVotes` and `VoteCast` is emitted.