Last active
July 24, 2017 13:18
-
-
Save furusiyya/395db5456529e2b86f3c4ac0f7130891 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
/** | |
* Asset Token contract, ERC20 compliant (see https://github.com/ethereum/EIPs/issues/20) | |
* | |
* Code is based on multiple sources: | |
* https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts | |
* https://github.com/TokenMarketNet/ico/blob/master/contracts | |
* https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts | |
*/ | |
pragma solidity ^0.4.13; | |
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; | |
} | |
} | |
contract AssetToken{ | |
address private owner; | |
address private multiSig; | |
/* AST functions are paused if there is any emergency */ | |
bool public emergency = false; | |
bool private sellingEnabled; | |
uint256 private exchangeRate; | |
using SafeMath for uint; | |
string public name; | |
string public symbol; | |
uint256 public decimals; | |
uint256 public totalSupply; | |
/* Actual balances of token holders */ | |
mapping(address => uint256) balances; | |
/* approve() allowances */ | |
mapping (address => mapping (address => uint256)) allowed; | |
/* freezeAccount() frozen() */ | |
mapping (address => bool) frozenAccount; | |
/* ERC20 standard event */ | |
event Approval(address indexed owner, address indexed spender, uint256 value); | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
/* Notify account frozen activity */ | |
event FrozenFunds(address target, bool frozen); | |
function AssetToken(address _owner, address _multiSig, uint256 _exchangeRate){ | |
name = "Asset Token"; | |
symbol = "AST"; | |
decimals = 18; | |
owner = _owner; | |
multiSig = _multiSig; | |
totalSupply = 1000000000 * 1 ether; | |
// Allocate initial balance to the owner // | |
balances[owner] = 1000000000 * 1 ether; | |
exchangeRate = _exchangeRate; | |
} | |
function transfer(address _to, uint256 _value) stopInEmergency onlyPayloadSize(2 * 32) returns (bool success) { | |
require(_to != 0x00); | |
// Check if frozen // | |
require(!frozenAccount[msg.sender]); | |
balances[msg.sender] = balances[msg.sender].sub( _value); | |
balances[_to] = balances[_to].add(_value); | |
Transfer(msg.sender, _to, _value); | |
return true; | |
} | |
function transferFrom(address _from, address _to, uint256 _value) stopInEmergency returns (bool success) { | |
require(_to != 0x00); | |
// Check if frozen // | |
require(!frozenAccount[_from]); | |
uint256 _allowance = allowed[_from][msg.sender]; | |
balances[_to] = balances[_to].add(_value); | |
balances[_from] = balances[_from].sub(_value); | |
allowed[_from][msg.sender] = _allowance.sub(_value); | |
Transfer(_from, _to, _value); | |
return true; | |
} | |
function balanceOf(address _owner) constant returns (uint256 balance) { | |
return balances[_owner]; | |
} | |
function approve(address _spender, uint256 _value) stopInEmergency returns (bool success) { | |
require(_spender != 0x00); | |
// To change the approve amount you first have to reduce the addresses` | |
// allowance to zero by calling `approve(_spender, 0)` if it is not | |
// already 0 to mitigate the race condition described here: | |
// 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 allowance(address _owner, address _spender) constant returns (uint256 remaining) { | |
return allowed[_owner][_spender]; | |
} | |
/** | |
* It is called Circuit Breakers (Pause contract functionality), it stop execution if certain conditions are met, | |
* and can be useful when new errors are discovered. For example, most actions may be suspended in a contract if a | |
* bug is discovered, so the most feasible option to stop and updated migration message about launching an updated version of contract. | |
* @param _stop Switch the circuite breaker on or off | |
*/ | |
function emergencyStop(bool _stop) onlyOwner { | |
emergency = _stop; | |
} | |
/** | |
* Owner can set any account into freeze state. It is helpful in case if account holder has | |
* lost his key and he want administrator to freeze account until account key is recovered | |
* @param target The account address | |
* @param freeze The state of account | |
*/ | |
function freezeAccount(address target, bool freeze) onlyOwner { | |
frozenAccount[target] = freeze; | |
FrozenFunds(target, freeze); | |
} | |
function frozen(address _target) constant returns (bool frozen) { | |
return frozenAccount[_target]; | |
} | |
/** | |
* @dev Allows the current owner to transfer control of the contract to a newOwner. | |
* @param newOwner The address to transfer ownership to. | |
*/ | |
function transferOwnership(address newOwner) onlyOwner { | |
require(newOwner != 0x00); | |
balances[newOwner] = balances[owner]; | |
balances[owner] = 0; | |
owner = newOwner; | |
Transfer(owner, newOwner,balances[newOwner]); | |
} | |
function astPerEther() constant returns (uint256 ast){ | |
return exchangeRate; | |
} | |
function exchangeStatus() constant returns(bool enabled){ | |
return sellingEnabled; | |
} | |
function contractOwner() constant returns(address _owner){ | |
return owner; | |
} | |
function walletAddress() constant returns(address fundsHolder){ | |
return multiSig; | |
} | |
function setMultiSig(address _newAddress) onlyOwner{ | |
require(_newAddress != 0x00); | |
multiSig = _newAddress; | |
} | |
function setExchangeRate(uint256 _astPerEther) onlyOwner{ | |
require(_astPerEther > 0); | |
exchangeRate = _astPerEther; | |
} | |
function enableExchange(bool _value) onlyOwner{ | |
sellingEnabled = _value; | |
} | |
function () payable nonZero exchangeOn stopInEmergency{ | |
buy(msg.sender); | |
} | |
function buy(address _customer) nonZero exchangeOn stopInEmergency payable { | |
uint256 weiAmount = msg.value; | |
uint256 tokens = weiAmount * exchangeRate; | |
require(balances[owner] >= tokens); | |
balances[_customer] = balances[_customer].add(tokens); | |
balances[owner] = balances[owner].sub(tokens); | |
if(!multiSig.send(weiAmount)){ | |
revert(); | |
} | |
Transfer(owner, _customer, tokens); | |
} | |
/* Interface declaration */ | |
function isToken() public constant returns (bool weAre) { | |
return true; | |
} | |
/** | |
* @dev Throws if called by any account other than the owner. | |
*/ | |
modifier onlyOwner() { | |
if (msg.sender != owner) { | |
revert(); | |
} | |
_; | |
} | |
/** | |
* Fix for the ERC20 short address attack | |
* | |
* http://vessenes.com/the-erc20-short-address-attack-explained/ | |
*/ | |
modifier onlyPayloadSize(uint256 size) { | |
if(msg.data.length < size + 4) { | |
revert(); | |
} | |
_; | |
} | |
modifier stopInEmergency { | |
require(!emergency); | |
_; | |
} | |
modifier nonZero() { | |
require(msg.value > 0); | |
_; | |
} | |
modifier exchangeOn() { | |
require(sellingEnabled); | |
_; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment