Created
May 21, 2021 11:34
-
-
Save partylikeits1983/0e2e9f6fd1686db1789dd7dddc50e63e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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