Skip to content

Commit

Permalink
the rest of logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Arvolear committed Jul 19, 2024
1 parent 6dacc35 commit 5c159f9
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 39 deletions.
142 changes: 109 additions & 33 deletions contracts/state/ProposalsState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s

import {DynamicSet} from "@solarity/solidity-lib/libs/data-structures/DynamicSet.sol";

import {TSSUpgradeable} from "@rarimo/passport-contracts/state/TSSUpgradeable.sol";

import {ProposalSMT} from "./ProposalSMT.sol";
import {BinSearch} from "../utils/BinSearch.sol";

contract ProposalsState is OwnableUpgradeable {
contract ProposalsState is OwnableUpgradeable, TSSUpgradeable {
using BinSearch for *;
using DynamicSet for DynamicSet.StringSet;

enum ProposalStatus {
None,
Waiting,
Started,
Ended
Ended,
DoNotShow
}

/**
Expand Down Expand Up @@ -48,6 +51,7 @@ contract ProposalsState is OwnableUpgradeable {

struct Proposal {
address proposalSMT;
bool hidden;
mapping(uint256 => mapping(uint256 => uint256)) results; // proposal option => choice => number of votes
ProposalConfig config;
}
Expand All @@ -61,7 +65,9 @@ contract ProposalsState is OwnableUpgradeable {

mapping(uint256 => Proposal) internal _proposals;

event ProposalCreated(uint256 indexed proposalId);
event ProposalCreated(uint256 indexed proposalId, address proposalSMT);
event ProposalConfigChanged(uint256 indexed proposalId);
event ProposalHidden(uint256 indexed proposalId, bool hide);
event VoteCast(uint256 indexed proposalId, uint256 userNullifier, uint256[] vote);

modifier onlyVoting() {
Expand All @@ -70,41 +76,19 @@ contract ProposalsState is OwnableUpgradeable {
}

function __ProposalsState_init(
address signer_,
string calldata chainName_,
string calldata initialVotingName_,
address initialVoting_
) external initializer {
__Ownable_init();
__TSSSigner_init(signer_, chainName_);

_addVoting(initialVotingName_, initialVoting_);
}

function createProposal(ProposalConfig calldata proposalConfig_) external onlyOwner {
require(proposalConfig_.startTimestamp > 0, "ProposalsState: zero start timestamp");
require(proposalConfig_.duration > 0, "ProposalsState: zero duration");
require(
proposalConfig_.acceptedOptions.length > 0,
"ProposalsState: the number of options can't be zero"
);
require(
proposalConfig_.votingWhitelist.length > 0 &&
proposalConfig_.votingWhitelist.length ==
proposalConfig_.votingWhitelistData.length,
"ProposalsState: whitelist length mismatch"
);

for (uint256 i = 0; i < proposalConfig_.acceptedOptions.length; ++i) {
require(
proposalConfig_.acceptedOptions[i] > 0,
"ProposalsState: the option can't be zero"
);
}

for (uint256 i = 1; i < proposalConfig_.acceptedOptions.length; ++i) {
require(
proposalConfig_.votingWhitelist[i] > proposalConfig_.votingWhitelist[i - 1],
"ProposalsState: the voting whitelist is not sorted"
);
}
_validateProposalConfig(proposalConfig_);

uint256 proposalId_ = ++lastProposalId;
Proposal storage _proposal = _proposals[proposalId_];
Expand All @@ -117,7 +101,41 @@ contract ProposalsState is OwnableUpgradeable {
);
_proposal.config = proposalConfig_;

emit ProposalCreated(proposalId_);
emit ProposalCreated(proposalId_, _proposal.proposalSMT);
}

function changeProposalConfig(
uint256 proposalId_,
ProposalConfig calldata newProposalConfig_
) external onlyOwner {
require(
getProposalStatus(proposalId_) != ProposalStatus.None,
"ProposalsState: proposal doesn't exist"
);
_validateProposalConfig(newProposalConfig_);

_proposals[proposalId_].config = newProposalConfig_;

emit ProposalConfigChanged(proposalId_);
}

function hideProposal(uint256 proposalId_, bool hide_) external onlyOwner {
require(
getProposalStatus(proposalId_) != ProposalStatus.None,
"ProposalsState: proposal doesn't exist"
);

_proposals[proposalId_].hidden = hide_;

emit ProposalHidden(proposalId_, hide_);
}

function addVoting(string calldata votingName_, address votingAddress_) external onlyOwner {
_addVoting(votingName_, votingAddress_);
}

function removeVoting(string calldata votingName_) external onlyOwner {
_removeVoting(votingName_);
}

function vote(
Expand Down Expand Up @@ -193,6 +211,10 @@ contract ProposalsState is OwnableUpgradeable {
return ProposalStatus.None;
}

if (_proposal.hidden) {
return ProposalStatus.DoNotShow;
}

if (block.timestamp < _config.startTimestamp) {
return ProposalStatus.Waiting;
}
Expand All @@ -204,12 +226,66 @@ contract ProposalsState is OwnableUpgradeable {
return ProposalStatus.Started;
}

function _addVoting(string memory votingName_, address votingAddress) internal {
function getVotings() external view returns (string[] memory keys_, address[] memory values_) {
keys_ = _votingKeys.values();
values_ = new address[](keys_.length);

for (uint256 i = 0; i < keys_.length; i++) {
values_[i] = _votings[keys_[i]];
}
}

function getVotingByKey(string calldata key_) external view returns (address) {
return _votings[key_];
}

function isVoting(address voting_) external view returns (bool) {
return _votingExists[voting_];
}

function _addVoting(string memory votingName_, address votingAddress_) internal {
require(_votingKeys.add(votingName_), "ProposalsState: duplicate voting");
_votings[votingName_] = votingAddress;
_votingExists[votingAddress] = true;
_votings[votingName_] = votingAddress_;
_votingExists[votingAddress_] = true;
}

function _removeVoting(string memory votingName_) internal {
delete _votingExists[_votings[votingName_]];
delete _votings[votingName_];
_votingKeys.remove(votingName_);
}

function _validateProposalConfig(ProposalConfig calldata proposalConfig_) internal pure {
require(proposalConfig_.startTimestamp > 0, "ProposalsState: zero start timestamp");
require(proposalConfig_.duration > 0, "ProposalsState: zero duration");
require(
proposalConfig_.acceptedOptions.length > 0,
"ProposalsState: the number of options can't be zero"
);
require(
proposalConfig_.votingWhitelist.length > 0 &&
proposalConfig_.votingWhitelist.length ==
proposalConfig_.votingWhitelistData.length,
"ProposalsState: whitelist length mismatch"
);

for (uint256 i = 0; i < proposalConfig_.acceptedOptions.length; ++i) {
require(
proposalConfig_.acceptedOptions[i] > 0,
"ProposalsState: the option can't be zero"
);
}

for (uint256 i = 1; i < proposalConfig_.acceptedOptions.length; ++i) {
require(
proposalConfig_.votingWhitelist[i] > proposalConfig_.votingWhitelist[i - 1],
"ProposalsState: the voting whitelist is not sorted"
);
}
}

function _authorizeUpgrade(address) internal virtual override onlyOwner {}

function _onlyVoting() internal view {
require(_votingExists[msg.sender], "ProposalsState: not a voting");
}
Expand Down
8 changes: 7 additions & 1 deletion contracts/voting/Voting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
import {VerifierHelper} from "@solarity/solidity-lib/libs/zkp/snarkjs/VerifierHelper.sol";
import {ArrayHelper} from "@solarity/solidity-lib/libs/arrays/ArrayHelper.sol";

import {TSSUpgradeable} from "@rarimo/passport-contracts/state/TSSUpgradeable.sol";
import {PoseidonSMT} from "@rarimo/passport-contracts/state/PoseidonSMT.sol";
import {Date2Time} from "@rarimo/passport-contracts/utils/Date2Time.sol";

import {ProposalsState} from "../state/ProposalsState.sol";
import {BinSearch} from "../utils/BinSearch.sol";

contract Voting is OwnableUpgradeable {
contract Voting is OwnableUpgradeable, TSSUpgradeable {
using BinSearch for *;
using VerifierHelper for address;

Expand Down Expand Up @@ -41,11 +42,14 @@ contract Voting is OwnableUpgradeable {
address public votingVerifier;

function __Voting_init(
address signer_,
string calldata chainName_,
address registrationSMT_,
address proposalsState_,
address votingVerifier_
) external initializer {
__Ownable_init();
__TSSSigner_init(signer_, chainName_);

registrationSMT = registrationSMT_;

Expand Down Expand Up @@ -106,6 +110,8 @@ contract Voting is OwnableUpgradeable {
ProposalsState(proposalsState).vote(proposalId_, userData_.nullifier, vote_);
}

function _authorizeUpgrade(address) internal virtual override onlyOwner {}

function _getProposalRules(
uint256 proposalId_
) internal view returns (ProposalRules memory proposalRules_) {
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"dependencies": {
"@openzeppelin/contracts": "4.9.6",
"@openzeppelin/contracts-upgradeable": "4.9.6",
"@rarimo/passport-contracts": "0.1.0",
"@rarimo/passport-contracts": "0.1.1",
"@iden3/contracts": "1.4.7",
"@solarity/solidity-lib": "2.7.10"
},
Expand Down

0 comments on commit 5c159f9

Please sign in to comment.