Contract Source Code:
File 1 of 1 : SAFEToken
/* -:////:-.
`:ohmMMMMMMMMMMMMmho:`
`+hMMMMMMMMMMMMMMMMMMMMMMh+`
.yMMMMMMMmyo/:----:/oymMMMMMMMy.
`sMMMMMMy/` `/yMMMMMMs`
-NMMMMNo` ./sydddhys/. `oNMMMMN- *** Secure Email & File Storage ***
/MMMMMy` .sNMMMMMMMMMMMMmo. `yMMMMM/
:MMMMM+ `yMMMMMMNmddmMMMMMMMs` +MMMMM: https://safe.ad
mMMMMo .NMMMMNo- `` -sNMMMMm. oMMMMm
/MMMMm `mMMMMy` `hMMm: `hMMMMm mMMMM/
yMMMMo +MMMMd .NMMM+ mMMMM/ oMMMMy
hMMMM/ sMMMMs :MMy yMMMMo /MMMMh
yMMMMo +MMMMd yMMN` `mMMMM: oMMMMy
/MMMMm `mMMMMh` `MMMM/ +MMMMd mMMMM/
mMMMMo .mMMMMNs-`'`'` /MMMMm- `sMMMMm
:MMMMM+ `sMMMMMMMmmmmy. hMMMMMMMMMMMN-
/MMMMMy` .omMMMMMMMMMy +mMMMMMMMMy.
-NMMMMNo` ./oyhhhho` ./oso+:`
`sMMMMMMy/` `-.
.yMMMMMMMmyo/:----:/oymMMMd`
`+hMMMMMMMMMMMMMMMMMMMMMN.
`:ohmMMMMMMMMMMMMmho:
.-:////:-.
*/
pragma solidity ^0.4.18;
/* SAFEToken contract v 1.0 */
contract ERC20Interface{
function balanceOf(address) public constant returns (uint256);
function transfer(address, uint256) public returns (bool);
}
contract SAFEToken{
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
event MintingAgentChanged(address _addr, bool _state);
event Mint(address indexed _to, uint256 _value);
event MintFinished();
event UpdatedTokenInformation(string _newName, string _newSymbol, uint8 _newDecimals);
event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner);
event TransfersAreAllowed();
event Error(address indexed _self, uint8 _errorCode);
uint256 constant private MAX_UINT256 = 2**256 - 1;
uint8 constant private ERROR_ZERO_ADDRESS = 1;
uint8 constant private ERROR_INSUFICIENT_BALANCE = 2;
uint8 constant private ERROR_INSUFICIENT_ALLOWENCE = 3;
uint8 constant private ERROR_ARRAYS_LENGTH_DIFF = 4;
uint8 constant private ERROR_INT_OVERFLOW = 5;
uint8 constant private ERROR_UNAUTHORIZED = 6;
uint8 constant private ERROR_TRANSFER_NOT_ALLOWED = 7;
string public name;
string public symbol;
uint8 public decimals;
bool public transfersSuspended = true;
address owner;
uint256 totalSupply_ = 0;
bool mintingFinished = false;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) internal allowed;
mapping(address => bool) mintAgents;
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
modifier onlyMintAgent(){
require(mintAgents[msg.sender]);
_;
}
modifier canMint(){
require(!mintingFinished);
_;
}
function SAFEToken(uint256 _totalSupply, string _name, string _symbol, uint8 _decimals) public{
totalSupply_ = _totalSupply;
owner = msg.sender;
name = _name;
symbol = _symbol;
decimals = _decimals;
balances[owner] = totalSupply_;
}
function totalSupply() public view returns (uint256){
return totalSupply_;
}
function transfer(address _to, uint256 _value) public returns (bool){
if(transfersSuspended) return isError(ERROR_TRANSFER_NOT_ALLOWED);
if(_to == address(0)) return isError(ERROR_ZERO_ADDRESS);
if(balances[msg.sender] < _value) return isError(ERROR_INSUFICIENT_BALANCE);
balances[msg.sender] -= _value;
balances[_to] += _value;
Transfer(msg.sender, _to, _value);
return true;
}
function balanceOf(address _owner) public view returns (uint256){
return balances[_owner];
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool){
if(transfersSuspended) return isError(ERROR_TRANSFER_NOT_ALLOWED);
uint256 allowance = allowed[_from][msg.sender];
if(balances[_from] < _value) return isError(ERROR_INSUFICIENT_BALANCE);
if(allowance < _value) return isError(ERROR_INSUFICIENT_ALLOWENCE);
balances[_to] += _value;
balances[_from] -= _value;
if(allowance < MAX_UINT256) allowed[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool success){
if(transfersSuspended) return isError(ERROR_TRANSFER_NOT_ALLOWED);
if(_spender == address(0)) return isError(ERROR_ZERO_ADDRESS);
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256){
return allowed[_owner][_spender];
}
function mint(address[] _receivers, uint256[] _values) public onlyMintAgent canMint returns (bool){
if(_receivers.length != _values.length) return isError(ERROR_ARRAYS_LENGTH_DIFF);
for(uint256 i = 0; i < _receivers.length; ++i){
if(totalSupply_ + _values[i] < totalSupply_) return isError(ERROR_INT_OVERFLOW);
totalSupply_ += _values[i];
}
for(i = 0; i < _receivers.length; ++i){
balances[_receivers[i]] += _values[i];
Mint(_receivers[i], _values[i]);
Transfer(address(0), _receivers[i], _values[i]);
}
return true;
}
function setMintAgent(address _addr, bool _state) onlyOwner canMint public returns (bool){
if(_addr == address(0)) return isError(ERROR_ZERO_ADDRESS);
mintAgents[_addr] = _state;
MintingAgentChanged(_addr, _state);
return true;
}
function finishMinting() onlyOwner canMint public returns (bool){
mintingFinished = true;
MintFinished();
return true;
}
function allowTransfers() onlyOwner public returns (bool){
transfersSuspended = false;
TransfersAreAllowed();
return true;
}
function changeOwner(address _newOwner) public onlyOwner returns(bool){
if(_newOwner == address(0)) return isError(ERROR_ZERO_ADDRESS);
address prevOwner = owner;
owner = _newOwner;
OwnershipTransferred(prevOwner, owner);
return true;
}
function setTokenInformation(string _name, string _symbol, uint8 _decimals) public onlyOwner returns (bool){
name = _name;
symbol = _symbol;
decimals = _decimals;
UpdatedTokenInformation(_name, _symbol, _decimals);
return true;
}
function withdrawnTokens(address[] _tokens, address _to) public onlyOwner returns (bool){
for(uint256 i = 0; i < _tokens.length; i++){
address token = _tokens[i];
uint256 balance = ERC20Interface(token).balanceOf(this);
if(balance != 0) ERC20Interface(token).transfer(_to, balance);
}
return true;
}
function isError(uint8 _error) private returns (bool){
Error(msg.sender, _error);
return false;
}
}