Created
September 29, 2017 02:31
-
-
Save sangheraio/328207a44981bc9a77b387d534a0a83b 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.15; | |
| /// ERC Token Standard #20 Interface (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) | |
| contract IERC20 { | |
| uint256 public totalSupply; | |
| function balanceOf(address _owner) constant returns (uint256 balance); | |
| function transfer(address _to, uint256 _value) returns (bool success); | |
| function transferFrom(address _from, address _to, uint256 _value) returns (bool success); | |
| function approve(address _spender, uint256 _value) returns (bool success); | |
| function allowance(address _owner, address _spender) constant returns (uint256 remaining); | |
| event Transfer(address indexed _from, address indexed _to, uint256 _value); | |
| event Approval(address indexed _owner, address indexed _spender, uint256 _value); | |
| } | |
| contract Ownable { | |
| address public owner; | |
| address public newOwnerCandidate; | |
| event OwnershipRequested(address indexed _by, address indexed _to); | |
| event OwnershipTransferred(address indexed _from, address indexed _to); | |
| function Ownable() { | |
| owner = msg.sender; | |
| } | |
| modifier onlyOwner() { | |
| if (msg.sender != owner) { | |
| revert(); | |
| } | |
| _; | |
| } | |
| modifier onlyOwnerCandidate() { | |
| if (msg.sender != newOwnerCandidate) { | |
| revert(); | |
| } | |
| _; | |
| } | |
| function requestOwnershipTransfer(address _newOwnerCandidate) external onlyOwner { | |
| require(_newOwnerCandidate != address(0)); | |
| newOwnerCandidate = _newOwnerCandidate; | |
| OwnershipRequested(msg.sender, newOwnerCandidate); | |
| } | |
| function acceptOwnership() external onlyOwnerCandidate { | |
| address previousOwner = owner; | |
| owner = newOwnerCandidate; | |
| newOwnerCandidate = address(0); | |
| OwnershipTransferred(previousOwner, owner); | |
| } | |
| } | |
| /// @title Math operations with safety checks | |
| library SafeMath { | |
| function mul(uint256 a, uint256 b) internal returns (uint256) { | |
| uint256 c = a * b; | |
| assert(a == 0 || c / a == b); | |
| return c; | |
| } | |
| function div(uint256 a, uint256 b) internal returns (uint256) { | |
| // assert(b > 0); // Solidity automatically throws when dividing by 0 | |
| uint256 c = a / b; | |
| // assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
| return c; | |
| } | |
| function sub(uint256 a, uint256 b) internal returns (uint256) { | |
| assert(b <= a); | |
| return a - b; | |
| } | |
| function add(uint256 a, uint256 b) internal returns (uint256) { | |
| uint256 c = a + b; | |
| assert(c >= a); | |
| return c; | |
| } | |
| function max64(uint64 a, uint64 b) internal constant returns (uint64) { | |
| return a >= b ? a : b; | |
| } | |
| function min64(uint64 a, uint64 b) internal constant returns (uint64) { | |
| return a < b ? a : b; | |
| } | |
| function max256(uint256 a, uint256 b) internal constant returns (uint256) { | |
| return a >= b ? a : b; | |
| } | |
| function min256(uint256 a, uint256 b) internal constant returns (uint256) { | |
| return a < b ? a : b; | |
| } | |
| } | |
| /// Basic ERC20 token contract implementation. | |
| /// Based on OpenZeppelin's StandardToken. | |
| contract ERC20 is IERC20 { | |
| using SafeMath for uint256; | |
| uint256 public totalSupply; | |
| mapping (address => mapping (address => uint256)) allowed; | |
| mapping (address => uint256) balances; | |
| event Approval(address indexed owner, address indexed spender, uint256 value); | |
| event Transfer(address indexed from, address indexed to, uint256 value); | |
| /// Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. | |
| function approve(address _spender, uint256 _value) public returns (bool) { | |
| // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 | |
| if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) { | |
| revert(); | |
| } | |
| allowed[msg.sender][_spender] = _value; | |
| Approval(msg.sender, _spender, _value); | |
| return true; | |
| } | |
| /// Function to check the amount of tokens that an owner allowed to a spender. | |
| function allowance(address _owner, address _spender) constant returns (uint256 remaining) { | |
| return allowed[_owner][_spender]; | |
| } | |
| /// Gets the balance of the specified address. | |
| function balanceOf(address _owner) constant returns (uint256 balance) { | |
| return balances[_owner]; | |
| } | |
| /// Transfer token to a specified address. | |
| function transfer(address _to, uint256 _value) public returns (bool) { | |
| balances[msg.sender] = balances[msg.sender].sub(_value); | |
| balances[_to] = balances[_to].add(_value); | |
| Transfer(msg.sender, _to, _value); | |
| return true; | |
| } | |
| /// Transfer tokens from one address to another. | |
| function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { | |
| uint256 _allowance = allowed[_from][msg.sender]; | |
| balances[_from] = balances[_from].sub(_value); | |
| balances[_to] = balances[_to].add(_value); | |
| allowed[_from][msg.sender] = _allowance.sub(_value); | |
| Transfer(_from, _to, _value); | |
| return true; | |
| } | |
| } | |
| contract SecurityToken is Ownable, ERC20 { | |
| string public version = '0.1'; | |
| string public name; | |
| string public symbol; | |
| uint8 public decimals; | |
| mapping(address => bool) public investors; | |
| mapping(address => bool) public regulators; | |
| event LogNewInvestor(address indexed investor, address indexed by); | |
| event LogNewRegulator(address indexed regulator, string desc); | |
| function SecurityToken(string _name, string _ticker, uint8 _decimals, uint256 _totalSupply) { | |
| name = _name; | |
| symbol = _ticker; | |
| decimals = _decimals; | |
| totalSupply = _totalSupply; | |
| balances[msg.sender] = _totalSupply; | |
| regulators[msg.sender] = true; | |
| } | |
| modifier onlyRegulators() { | |
| require(!regulators[msg.sender]); | |
| _; | |
| } | |
| function transfer(address _to, uint256 _value) returns (bool success) { | |
| if (investors[_to] && balances[msg.sender] >= _value && _value > 0) { | |
| return super.transfer(_to, _value); | |
| } else { | |
| return false; | |
| } | |
| } | |
| function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { | |
| if (investors[_to] && investors[msg.sender] && balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) { | |
| return super.transferFrom(_from, _to, _value); | |
| } else { | |
| return false; | |
| } | |
| } | |
| function approve(address _spender, uint256 _value) returns (bool success) { | |
| if (investors[_spender]) { | |
| return super.approve(_spender, _value); | |
| } else { | |
| return false; | |
| } | |
| } | |
| function addRegulator(address _address, string _desc) onlyOwner returns (bool success) { | |
| regulators[_address] = true; | |
| LogNewRegulator(_address, _desc); | |
| return true; | |
| } | |
| function whitelistInvestor(address _address) onlyRegulators returns (bool success) { | |
| investors[_address] = true; | |
| LogNewInvestor(_address, msg.sender); | |
| return true; | |
| } | |
| function transferAnyERC20Token(address _tokenAddress, uint256 _amount) onlyOwner returns (bool success) { | |
| return ERC20(_tokenAddress).transfer(owner, _amount); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment