Created
April 15, 2017 16:31
-
-
Save yoninachmany/f5ddedfc531a99ad088d8f37ad6d9809 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
pragma solidity ^0.4.8; | |
contract StandardToken{ | |
address public owner = msg.sender; | |
// This contract only defines a modifier but does not use | |
// it - it will be used in derived contracts. | |
// The function body is inserted where the special symbol | |
// "_;" in the definition of a modifier appears. | |
// This means that if the owner calls this function, the | |
// function is executed and otherwise, an exception is | |
// thrown. | |
modifier onlyOwner() { | |
if (msg.sender != owner) | |
throw; | |
_; | |
} | |
function transfer(address _to, uint256 _value) onlyOwner returns (bool success) { | |
//Default assumes totalSupply can't be over max (2^256 - 1). | |
//If your token leaves out totalSupply and can issue more tokens as time goes on, you need to check if it doesn't wrap. | |
//Replace the if with this one instead. | |
if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) { | |
//if (balances[msg.sender] >= _value && _value > 0) { | |
balances[msg.sender] -= _value; | |
balances[_to] += _value; | |
return true; | |
} else { return false; } | |
} | |
function transferFrom(address _from, address _to, uint256 _value) onlyOwner returns (bool success) { | |
//same as above. Replace this line with the following if you want to protect against wrapping uints. | |
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) { | |
//if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) { | |
balances[_to] += _value; | |
balances[_from] -= _value; | |
allowed[_from][msg.sender] -= _value; | |
return true; | |
} else { return false; } | |
} | |
function balanceOf(address _owner) onlyOwner constant returns (uint256 balance) { | |
return balances[_owner]; | |
} | |
function approve(address _spender, uint256 _value) onlyOwner returns (bool success) { | |
allowed[msg.sender][_spender] = _value; | |
return true; | |
} | |
function allowance(address _owner, address _spender) onlyOwner constant returns (uint256 remaining) { | |
return allowed[_owner][_spender]; | |
} | |
function mint(address _owner, uint256 _amount) onlyOwner returns (bool success) { | |
if (_amount < 0) return false; | |
totalSupply += _amount; | |
balances[msg.sender] += _amount; | |
return true; | |
} | |
function burn(address _owner, uint256 _amount) onlyOwner returns (bool success) { | |
if (_amount < 0) return false; | |
totalSupply -= _amount; | |
balances[msg.sender] -= _amount; | |
if (balance[msg.sender] < 0) throw; | |
return true; | |
} | |
mapping(address => uint256) balances; | |
mapping (address => mapping (address => uint256)) allowed; | |
uint256 public totalSupply; | |
} | |
contract DAO { | |
uint tokenSellingPrice; | |
uint tokenSellLength; | |
uint creationTime; | |
StandardToken token; | |
uint proposalID; | |
/// @notice voting on this proposal should only be open for some time period. | |
/// @notice needs to be a way to keep track of votes (not loop) | |
struct Proposal { | |
address recipient; | |
uint amount; | |
string description; | |
uint amountROI; | |
uint proposalTime; | |
} | |
mapping (uint => Proposal) proposals; | |
uint proposalVoteLength; | |
modifier hasEther { | |
if (msg.value <= 0) throw; | |
_; | |
} | |
modifier duringSellTime { | |
if (now > creationTime + tokenSellLength) throw; | |
_; | |
} | |
modifier isDAOTokenHolder(address _recipient) { | |
if (token.balanceOf(_recipient) < 0) throw; | |
_; | |
} | |
modifier duringVotingPeriod(_proposalID) { | |
if (now > proposals[_proposalID].proposalTime + proposalVoteLength) throw; | |
_; | |
} | |
modifier afterVotingPeriod(_proposalID) { | |
if (now <= proposals[_proposalID].proposalTime + proposalVoteLength) throw; | |
_; | |
} | |
/// @param tokenCost how much to sell tokens for | |
/// @param tokenSellLength how long (in seconds) until the token sale ends | |
/// @notice tokens created by token contract, which is created here | |
function DAO (uint tokenSellingPrice, uint tokenSellLength) { | |
tokenSellingPrice = tokenSellingPrice; | |
tokenSellLength = tokenSellLength; | |
creationTime = now; | |
token = new StandardToken(); | |
proposalVoteLength = 100000; | |
} | |
/// @notice tokens the DAO issues should be in the DAO-specific-token-contract | |
function invest() payable hasEther duringSellTime returns (bool) { | |
uint numTokens = msg.value / tokenSellingPrice; | |
if (!token.mint(msg.sender, numTokens)) return false; | |
token.transfer(msg.sender, msg.value - numTokens * tokenSellingPrice); | |
return true; | |
} | |
// @param _amountROI amount that the project promises to pay back on top of the original investment it receives | |
function newProposal(address _recipient, uint _amount, string _description, uint _amountROI) isDAOTokenHolder(_recipient) returns (uint proposalID) { | |
proposals[proposalID] = Proposal({ | |
recipient: _recipient, | |
amount: _amount, | |
description: _description, | |
amountROI: _amountROI, | |
proposalTime: now | |
}); | |
return proposalID++; | |
} | |
/// @notice users should not be able to vote on a proposal from address A, | |
/// then transfer their tokens to address B, and then vote again on the proposal. | |
/// Implement some method of locking their tokens until the end of the voting | |
/// period for that proposal (in which case they can again move their DAO tokens). | |
function vote(uint _proposalID, bool _supportProposal) duringVotingPeriod(_proposalID){ | |
} | |
/// If there was a majority vote to invest in the project (of the people who voted, not of everyone), then payout to the contract address originally defined in the proposal | |
/// @notice passing control over to an unknown contract here | |
function executeProposal(uint _proposalId) afterVotingPeriod(_proposalID) returns (bool success) { | |
} | |
function transfer(address _to, uint _value) isNotLocked(_to) returns (bool) { | |
token.transfer(_to, _value); | |
return true; | |
} | |
function approve(address _spender, uint _value) isNotLocked(_spender) returns (bool) { | |
token.approve(_spender, _value); | |
return true; | |
} | |
function transferFrom(address _from, address _to, uint _value) isNotLocked(_from) isNotLocked(_to) returns (bool) { | |
token.transferFrom(_from, _to, _value); | |
} | |
function balanceOf(address _owner) constant returns (uint256 balance) { | |
return token.balanceOf(_ownder); | |
} | |
function allowance(address _owner, address _spender) constant returns (uint256 remaining) { | |
return token.allowance(_ownder, _spender); | |
} | |
/// @notice locked when currently open proposal that person has voted on | |
modifier isNotLocked(address _address) { | |
// if (now <= proposals[_proposalID].proposalTime + proposalVoteLength) return false; | |
_; | |
} | |
function payBackInvestment(uint _proposalId) payable hasEther returns (bool success) { | |
uint investment = proposals[_proposalID].amount + proposals[_proposalID].amountROI; | |
if (msg.value < investment) return false; | |
token.transferFrom(msg.sender, token, msg.value - numTokens * tokenSellingPrice); | |
return true; | |
} | |
function withdrawEther() isNotLocked(msg.sender) returns (bool) { | |
uint numTokens = msg.value / tokenSellingPrice; | |
token.burn(msg.sender, num_tokens); | |
} | |
Also, they should get the portion of the Ether they deserve, not the same amount they put in (aka, they should get any _amountROI proportionally). | |
// withdraw _amount of Ether that you have in the exchange (from selling tokens). | |
function withdrawEther(uint _amount) { | |
if (etherOf[msg.sender] < _amount) throw; | |
if (!msg.sender.send(etherOf[msg.sender])) throw; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment