Smart Referendum System
What it does:
Enables communities or DAOs to conduct binding or advisory referendums on-chain with transparent, verifiable results.
Why it matters:
Increases democratic participation, prevents tampering, and ensures that collective decisions are recorded immutably for audit and accountability.
How it works:
-
Administrators create referendum proposals with options and deadlines
-
Eligible voters register and are verified via on-chain identity or reputation
-
Votes are cast and recorded on-chain
-
Results are automatically tallied after the referendum ends
-
Outcome can trigger on-chain actions, fund disbursement, or governance changes
-
Public dashboards display live participation and results
-
Can integrate with reputation-weighted or token-weighted governance systems
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title SmartReferendum
* @author Nam
* @notice On-chain referendum system with transparent voting and outcome execution
*/
contract SmartReferendum is Ownable {
struct Referendum {
string description;
string[] options;
uint256 startTime;
uint256 endTime;
bool executed;
mapping(address => bool) hasVoted;
mapping(uint256 => uint256) votes; // option index => vote count
}
uint256 public referendumCount;
mapping(uint256 => Referendum) private referendums;
mapping(address => bool) public eligibleVoters;
// -------------------- EVENTS --------------------
event ReferendumCreated(uint256 indexed id, string description);
event Voted(uint256 indexed referendumId, address voter, uint256 option);
event ReferendumExecuted(uint256 indexed id, uint256 winningOption);
// -------------------- VOTER MANAGEMENT --------------------
function setVoterEligibility(address _voter, bool _eligible) external onlyOwner {
eligibleVoters[_voter] = _eligible;
}
// -------------------- REFERENDUM CREATION --------------------
function createReferendum(string calldata _description, string[] calldata _options, uint256 _duration) external onlyOwner {
require(_options.length >= 2, "At least 2 options required");
referendumCount += 1;
Referendum storage r = referendums[referendumCount];
r.description = _description;
r.startTime = block.timestamp;
r.endTime = block.timestamp + _duration;
for (uint256 i = 0; i = r.startTime && block.timestamp <= r.endTime, "Voting period closed");
require(!r.hasVoted[msg.sender], "Already voted");
require(_option r.endTime, "Voting still active");
uint256 winningOption = 0;
uint256 highestVotes = 0;
for (uint256 i = 0; i highestVotes) {
highestVotes = r.votes[i];
winningOption = i;
}
}
r.executed = true;
emit ReferendumExecuted(_referendumId, winningOption);
// Optional: trigger on-chain action based on result
}
// -------------------- VIEW FUNCTIONS --------------------
function getVotes(uint256 _referendumId, uint256 _option) external view returns (uint256) {
return referendums[_referendumId].votes[_option];
}
function getOptions(uint256 _referendumId) external view returns (string[] memory) {
return referendums[_referendumId].options;
}
}