pragma solidity ^0.8.0; contract ERC20Token { // Token name, symbol, and total supply string public name; string public symbol; uint256 public totalSupply; // Mapping from addresses to their token balance mapping(address => uint256) public balanceOf; // Event for when tokens are transferred event Transfer(address indexed from, address indexed to, uint256 value); // Transfer token function function transfer(address _to, uint256 _value) public { require(balanceOf[msg.sender] >= _value); require(balanceOf[_to] + _value >= balanceOf[_to]); balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); } } contract Governance { // ERC20 token contract address ERC20Token public token; // Mapping from proposal ID to proposal details mapping(uint256 => Proposal) public proposals; // Mapping from proposal ID to the total token weight of votes for and against mapping(uint256 => Vote) public voteTotals; // Event for when a proposal is created event ProposalCreated(uint256 indexed proposalId, address indexed creator, string name, string description, uint256 votingPeriod); // Event for when a vote is cast event VoteCast(uint256 indexed proposalId, address indexed voter, bool vote); // Event for when a proposal is executed event ProposalExecuted(uint256 indexed proposalId, bool result); // Proposal struct struct Proposal { address creator; string name; string description; uint256 votingPeriod; bool executed; } // Vote struct struct Vote { uint256 yes; uint256 no; } constructor(address _token) public { token = ERC20Token(_token); } // Create a new proposal function createProposal(string memory _name, string memory _description, uint256 _votingPeriod) public { require(msg.sender == token.owner()); uint256 proposalId = proposals.length; proposals[proposalId] = Proposal(msg.sender, _name, _description, _votingPeriod, false); voteTotals[proposalId] = Vote(0, 0); emit ProposalCreated(proposalId, msg.sender, _name, _description, _votingPeriod); } // Cast a vote on a proposal function vote(uint256 _proposalId, bool _vote) public { require(proposals[_proposalId].votingPeriod > now); require(voteTotals[_proposalId].yes + voteTotals[_proposalId].no == 0 || voteTotals[_proposalId].yes + voteTotals[_proposalId].no > 0); require(_vote == true || _vote == false); if (_vote) { voteTotals[_proposalId].yes += token.balanceOf[msg.sender]; } else { voteTotals[_proposalId].no += token.balanceOf[msg.sender]; } emit VoteCast(_proposalId, msg.sender, _vote); } // Check if a proposal has passed function checkProposalPassed(uint256 _proposalId) public view returns (bool) { return voteTotals[_proposalId].yes > voteTotals[_proposalId].no; } // Execute a proposal function executeProposal(uint256 _proposalId) public { require(proposals[_proposalId].executed == false); require(checkProposalPassed(_proposalId)); proposals[_proposalId].executed = true; emit ProposalExecuted(_proposalId, checkProposalPassed(_proposalId)); }
0.4.18