Skip to content

Instantly share code, notes, and snippets.

@partylikeits1983
Created May 21, 2021 11:34
Show Gist options
  • Save partylikeits1983/0e2e9f6fd1686db1789dd7dddc50e63e to your computer and use it in GitHub Desktop.
Save partylikeits1983/0e2e9f6fd1686db1789dd7dddc50e63e to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
/// @title Simple DAO smart contract.
contract simpleDAO {
// This simple DAO smart contract sends ether to the predefined address only if
// the majority of the members agree to send ether to the predefined address.
// If the majority decides not to send ether, the members who deposited ether
// are able to withdraw the ether they deposited.
// address of vending machine
address payable public beneficiary;
// balance of ether in the smart contract
uint public DAObalance;
// allow withdrawals
mapping(address=>uint) balances;
// proposal decision of voters
uint decision;
// default set as false
// makes sure votes are counted before ending vote
bool ended;
struct Voter {
uint weight; // weight is accumulated by delegation
bool voted; // if true, that person already voted
address delegate; // person delegated to
uint vote; // index of the voted proposal
}
struct Proposal {
string name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}
// address of the person who set up the vote
address public chairperson;
mapping(address => Voter) public voters;
Proposal[] public proposals;
// Sample input string: ["buy_cupcakes", "no_cupcakes"]
// First item in string is the one that will execute the purchase
// _beneficiary is the address where the ether will be sent
constructor(
address payable _beneficiary,
string[] memory proposalNames
) {
beneficiary = _beneficiary;
chairperson = msg.sender;
voters[chairperson].weight = 1;
for (uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
// only the chairperson can decide who can vote
function giveRightToVote(address voter) public {
require(
msg.sender == chairperson,
"Only chairperson can give right to vote."
);
require(
!voters[voter].voted,
"The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
// proposals are in format 0,1,2,...
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount += sender.weight;
}
// winningProposal must be executed before EndVote
function winningProposal() public
returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
decision = winningProposal_;
ended = true;
}
}
}
// anyone can deposit ether to the DAO smart contract
function DepositEth() public payable {
DAObalance = address(this).balance;
balances[msg.sender]+=msg.value;
}
// Individuals can only withdraw what they deposited.
// After EndVote function is run and if proposal "buy_cupcakes" won,
// users will not be able to withdraw ether
function withdraw(uint amount) public{
if(balances[msg.sender]>=amount){
balances[msg.sender]-=amount;
payable(msg.sender).transfer(amount);
}
}
// ends the vote
// if DAO decided not to buy cupcakes members can withdraw deposited ether
function EndVote() public {
require(
msg.sender == chairperson,
"Only chairperson can end vote.");
require(
ended == true,
"Must tally vote first");
require(
decision == 0,
"DAO decided to not buy cupcakes. Members may withdraw deposited ether.");
{
beneficiary.transfer(DAObalance);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment