Skip to content

Instantly share code, notes, and snippets.

@ryestew
Last active March 1, 2019 10:24
Show Gist options
  • Save ryestew/21cad99396f8c78ecf229834f1b6eaeb to your computer and use it in GitHub Desktop.
Save ryestew/21cad99396f8c78ecf229834f1b6eaeb to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "./Ballot.sol";
contract AwardToken is ERC20Mintable {
uint quantity;
uint ballotPeriod = 7 hours;
Ballot public currBallot;
address[] public prevWinners;
event log (string _msg);
event winLog (address _win);
event newBallot (address _addr);
constructor () public {
quantity = 100;
}
function getPreviousWinners() public view returns (address[] memory) {
return prevWinners;
}
// either a name change or it works fine without it
// function approve(address spender, uint256 value) public returns (bool);
function startRound() onlyMinter public returns (bool) {
// if this is the first minting then we should let this go immediately
if (address(currBallot) == address (0x0)) {
currBallot = new Ballot(ballotPeriod);
emit newBallot(address (currBallot));
} else {
return false;
}
}
function closeRoundEarly () public onlyMinter {
if (address(currBallot) != address (0x0) && !currBallot.timeOut()) {
currBallot.finish();
} else revert();
}
function closeRound() public onlyMinter {
// this can only be done by the owner of the contract
if (address(currBallot) != address(0x0) && currBallot.timeOut()) {
// get winner
address winner = currBallot.winningProposal();
emit winLog(winner);
// send to winner - but first make sure the address is valid
if ( winner == address(0x0)){
emit log("no winner");
} else {
emit winLog(winner);
super.mint(winner, quantity);
prevWinners.push(winner);
}
delete currBallot;
// start new round
}else revert();
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
revert();
}
function approve(address _spender, uint256 _value) public returns (bool) {
revert();
}
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
revert();
}
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
revert();
}
function transfer(address _to, uint256 _value) public returns (bool) {
revert();
}
}
pragma solidity ^0.5.0;
contract Ballot {
uint _duration;
uint _startTime;
bool _finishEarly;
struct Proposal {
string description;
string title;
uint voteCount;
address targetAddress;
}
event log (string _msg);
address chairperson;
mapping(address => mapping (address => uint8)) voters; // map between proposal and voter and votes
mapping(address => Proposal) public proposals;
address[] public proposalsSender;
function getProposals() public view returns (address[] memory) {
return proposalsSender;
}
/// Create a new ballot with $(_numProposals) different proposals.
constructor (uint duration) public {
chairperson = msg.sender;
_duration = duration;
_startTime = now;
_finishEarly = false;
}
// duration issues...
// add a new proposals
function addProposal(string memory desc, string memory title, address targetAddr) public {
if (timeOut() || targetAddr == address (0x0) || proposals[msg.sender].targetAddress != address (0x0)){
revert();
}
proposals[msg.sender].description = desc;
proposals[msg.sender].title = title;
proposals[msg.sender].voteCount = 0;
proposals[msg.sender].targetAddress = targetAddr;
proposalsSender.push(msg.sender);
}
/// Give a single vote to proposal $(toProposal).
function vote(address proposal) public {
// is this msg.sender in vote - the voter the proposal or the owner of the contract?
// apparantly you can't vote more than once
uint8 vote = voters[proposal][msg.sender];
// the revert - takes it back to the initial state - but that blows away everyting - I suppose...
// check on revert();
if (timeOut()) revert();
if (vote != 0) {
revert(); // already voted for this proposal
} else {
voters[proposal][msg.sender] = 1;
proposals[proposal].voteCount += 1;
}
}
function finish() public {
if (chairperson == msg.sender) _startTime = now - _duration;
else revert();
}
// timeOut vs duration in voteCount
// for use in vote(), addProposal(),
function timeOut() public view returns ( bool timeOver) {
if (_startTime + _duration > now){
timeOver = false;
}else timeOver = true;
}
function winningProposal() public returns (address currLeader) {
// does this need to be run only by the contract owner? Currently I think it is not limited
uint vote = 0;
if (timeOut()){
// timeOut - mean that at least the _duration is over
// what if there is tie?
if(proposalsSender.length > 0) {
for (uint8 k = 0; k < proposalsSender.length; k++) {
Proposal memory proposal = proposals[proposalsSender[k]];
if (vote < proposal.voteCount) {
vote = proposal.voteCount;
currLeader = proposal.targetAddress;
}
}
if (vote > 0) {
return currLeader;
}else{
emit log("aint no voters!");
}
}else{
emit log("aint no proposals!");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment