Skip to content

Instantly share code, notes, and snippets.

@yoninachmany
Created April 15, 2017 16:31
Show Gist options
  • Save yoninachmany/f5ddedfc531a99ad088d8f37ad6d9809 to your computer and use it in GitHub Desktop.
Save yoninachmany/f5ddedfc531a99ad088d8f37ad6d9809 to your computer and use it in GitHub Desktop.
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