ETH Price: $2,624.87 (-1.81%)

Token

Angel Token (ANGL)
 

Overview

Max Total Supply

8,629,711.984131059116062167 ANGL

Holders

376

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
1,064.45625 ANGL

Value
$0.00
0xa9fad5a2da799b5d9b12d1aabd15421ca17a19c1
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AngelToken

Compiler Version
v0.4.16+commit.d7661dd9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2017-11-24
*/

pragma solidity ^0.4.16;


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }


  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }


  /**
   * @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) external onlyOwner {
    if (newOwner != address(0)) {
      owner = newOwner;
    }
  }

}



/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant 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 constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}



/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  uint256 public totalSupply;
  function balanceOf(address who) public constant returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}



/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  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;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) public constant returns (uint256 balance) {
    return balances[_owner];
  }

}



/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) public constant returns (uint256);
  function transferFrom(address from, address to, uint256 value) public returns (bool);
  function approve(address spender, uint256 value) public returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}



/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) allowed;


  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amout of tokens to be transfered
   */
  function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    var _allowance = allowed[_from][msg.sender];

    // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
    // require (_value <= _allowance);

    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;
  }

  /**
   * @dev Aprove the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public returns (bool) {

    // 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
    require((_value == 0) || (allowed[msg.sender][_spender] == 0));

    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifing the amount of tokens still avaible for the spender.
   */
  function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
    return allowed[_owner][_spender];
  }

}



/**
 * @title Manageable
 * @dev Contract that allows to grant permissions to any address
 * @dev In real life we are no able to perform all actions with just one Ethereum address
 * @dev because risks are too high.
 * @dev Instead owner delegates rights to manage an contract to the different addresses and
 * @dev stay able to revoke permissions at any time.
 */
contract Manageable is Ownable {

  /* Storage */

  mapping (address => bool) managerEnabled;  // hard switch for a manager - on/off
  mapping (address => mapping (string => bool)) managerPermissions;  // detailed info about manager`s permissions


  /* Events */

  event ManagerEnabledEvent(address indexed manager);
  event ManagerDisabledEvent(address indexed manager);
  event ManagerPermissionGrantedEvent(address indexed manager, string permission);
  event ManagerPermissionRevokedEvent(address indexed manager, string permission);


  /* Configure contract */

  /**
   * @dev Function to add new manager
   * @param _manager address New manager
   */
  function enableManager(address _manager) external onlyOwner onlyValidAddress(_manager) {
    require(managerEnabled[_manager] == false);

    managerEnabled[_manager] = true;
    ManagerEnabledEvent(_manager);
  }

  /**
   * @dev Function to remove existing manager
   * @param _manager address Existing manager
   */
  function disableManager(address _manager) external onlyOwner onlyValidAddress(_manager) {
    require(managerEnabled[_manager] == true);

    managerEnabled[_manager] = false;
    ManagerDisabledEvent(_manager);
  }

  /**
   * @dev Function to grant new permission to the manager
   * @param _manager        address Existing manager
   * @param _permissionName string  Granted permission name
   */
  function grantManagerPermission(
    address _manager, string _permissionName
  )
    external
    onlyOwner
    onlyValidAddress(_manager)
    onlyValidPermissionName(_permissionName)
  {
    require(managerPermissions[_manager][_permissionName] == false);

    managerPermissions[_manager][_permissionName] = true;
    ManagerPermissionGrantedEvent(_manager, _permissionName);
  }

  /**
   * @dev Function to revoke permission of the manager
   * @param _manager        address Existing manager
   * @param _permissionName string  Revoked permission name
   */
  function revokeManagerPermission(
    address _manager, string _permissionName
  )
    external
    onlyOwner
    onlyValidAddress(_manager)
    onlyValidPermissionName(_permissionName)
  {
    require(managerPermissions[_manager][_permissionName] == true);

    managerPermissions[_manager][_permissionName] = false;
    ManagerPermissionRevokedEvent(_manager, _permissionName);
  }


  /* Getters */

  /**
   * @dev Function to check manager status
   * @param _manager address Manager`s address
   * @return True if manager is enabled
   */
  function isManagerEnabled(address _manager) public constant onlyValidAddress(_manager) returns (bool) {
    return managerEnabled[_manager];
  }

  /**
   * @dev Function to check permissions of a manager
   * @param _manager        address Manager`s address
   * @param _permissionName string  Permission name
   * @return True if manager has been granted needed permission
   */
  function isPermissionGranted(
    address _manager, string _permissionName
  )
    public
    constant
    onlyValidAddress(_manager)
    onlyValidPermissionName(_permissionName)
    returns (bool)
  {
    return managerPermissions[_manager][_permissionName];
  }

  /**
   * @dev Function to check if the manager can perform the action or not
   * @param _manager        address Manager`s address
   * @param _permissionName string  Permission name
   * @return True if manager is enabled and has been granted needed permission
   */
  function isManagerAllowed(
    address _manager, string _permissionName
  )
    public
    constant
    onlyValidAddress(_manager)
    onlyValidPermissionName(_permissionName)
    returns (bool)
  {
    return (managerEnabled[_manager] && managerPermissions[_manager][_permissionName]);
  }


  /* Helpers */

  /**
   * @dev Modifier to check manager address
   */
  modifier onlyValidAddress(address _manager) {
    require(_manager != address(0x0));
    _;
  }

  /**
   * @dev Modifier to check name of manager permission
   */
  modifier onlyValidPermissionName(string _permissionName) {
    require(bytes(_permissionName).length != 0);
    _;
  }


  /* Outcome */

  /**
   * @dev Modifier to use in derived contracts
   */
  modifier onlyAllowedManager(string _permissionName) {
    require(isManagerAllowed(msg.sender, _permissionName) == true);
    _;
  }
}



/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 * @dev Based on zeppelin's Pausable, but integrated with Manageable
 * @dev Contract is in paused state by default and should be explicitly unlocked
 */
contract Pausable is Manageable {

  /**
   * Events
   */

  event PauseEvent();
  event UnpauseEvent();


  /**
   * Storage
   */

  bool paused = true;


  /**
   * @dev modifier to allow actions only when the contract IS paused
   */
  modifier whenContractNotPaused() {
    require(paused == false);
    _;
  }

  /**
   * @dev modifier to allow actions only when the contract IS NOT paused
   */
  modifier whenContractPaused {
    require(paused == true);
    _;
  }

  /**
   * @dev called by the manager to pause, triggers stopped state
   */
  function pauseContract() external onlyAllowedManager('pause_contract') whenContractNotPaused {
    paused = true;
    PauseEvent();
  }

  /**
   * @dev called by the manager to unpause, returns to normal state
   */
  function unpauseContract() external onlyAllowedManager('unpause_contract') whenContractPaused {
    paused = false;
    UnpauseEvent();
  }

  /**
   * @dev The getter for "paused" contract variable
   */
  function getPaused() external constant returns (bool) {
    return paused;
  }
}



/**
 * @title NamedToken
 */
contract NamedToken {
  string public name;
  string public symbol;
  uint8 public decimals;

  function NamedToken(string _name, string _symbol, uint8 _decimals) public {
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
  }

  /**
   * @dev Function to calculate hash of the token`s name.
   * @dev Function needed because we can not just return name of the token to another contract - strings have variable length
   * @return Hash of the token`s name
   */
  function getNameHash() external constant returns (bytes32 result){
    return keccak256(name);
  }

  /**
   * @dev Function to calculate hash of the token`s symbol.
   * @dev Function needed because we can not just return symbol of the token to another contract - strings have variable length
   * @return Hash of the token`s symbol
   */
  function getSymbolHash() external constant returns (bytes32 result){
    return keccak256(symbol);
  }
}



/**
 * @title AngelToken
 */
contract AngelToken is StandardToken, NamedToken, Pausable {

  /* Events */

  event MintEvent(address indexed account, uint value);
  event BurnEvent(address indexed account, uint value);
  event SpendingBlockedEvent(address indexed account);
  event SpendingUnblockedEvent(address indexed account);


  /* Storage */

  address public centralBankAddress = 0x0;
  mapping (address => uint) spendingBlocksNumber;


  /* Constructor */

  function AngelToken() public NamedToken('Angel Token', 'ANGL', 18) {
    centralBankAddress = msg.sender;
  }


  /* Methods */

  function transfer(address _to, uint _value) public returns (bool) {
    if (_to != centralBankAddress) {
      require(!paused);
    }
    require(spendingBlocksNumber[msg.sender] == 0);

    bool result = super.transfer(_to, _value);
    if (result == true && _to == centralBankAddress) {
      AngelCentralBank(centralBankAddress).angelBurn(msg.sender, _value);
    }
    return result;
  }

  function approve(address _spender, uint _value) public whenContractNotPaused returns (bool){
    return super.approve(_spender, _value);
  }

  function transferFrom(address _from, address _to, uint _value) public whenContractNotPaused returns (bool){
    require(spendingBlocksNumber[_from] == 0);

    bool result = super.transferFrom(_from, _to, _value);
    if (result == true && _to == centralBankAddress) {
      AngelCentralBank(centralBankAddress).angelBurn(_from, _value);
    }
    return result;
  }


  function mint(address _account, uint _value) external onlyAllowedManager('mint_tokens') {
    balances[_account] = balances[_account].add(_value);
    totalSupply = totalSupply.add(_value);
    MintEvent(_account, _value);
    Transfer(address(0x0), _account, _value); // required for blockexplorers
  }

  function burn(uint _value) external onlyAllowedManager('burn_tokens') {
    balances[msg.sender] = balances[msg.sender].sub(_value);
    totalSupply = totalSupply.sub(_value);
    BurnEvent(msg.sender, _value);
  }

  function blockSpending(address _account) external onlyAllowedManager('block_spending') {
    spendingBlocksNumber[_account] = spendingBlocksNumber[_account].add(1);
    SpendingBlockedEvent(_account);
  }

  function unblockSpending(address _account) external onlyAllowedManager('unblock_spending') {
    spendingBlocksNumber[_account] = spendingBlocksNumber[_account].sub(1);
    SpendingUnblockedEvent(_account);
  }
}



/**
 * @title AngelCentralBank
 *
 * @dev Crowdsale and escrow contract
 */
contract AngelCentralBank {

  /* Data structures */

  struct InvestmentRecord {
    uint tokensSoldBeforeWei;
    uint investedEthWei;
    uint purchasedTokensWei;
    uint refundedEthWei;
    uint returnedTokensWei;
  }


  /* Storage - config */

  uint public constant icoCap = 70000000 * (10 ** 18);

  uint public initialTokenPrice = 1 * (10 ** 18) / (10 ** 4); // means 0.0001 ETH for one token

  uint public constant landmarkSize = 1000000 * (10 ** 18);
  uint public constant landmarkPriceStepNumerator = 10;
  uint public constant landmarkPriceStepDenominator = 100;

  uint public constant firstRefundRoundRateNumerator = 80;
  uint public constant firstRefundRoundRateDenominator = 100;
  uint public constant secondRefundRoundRateNumerator = 40;
  uint public constant secondRefundRoundRateDenominator = 100;

  uint public constant initialFundsReleaseNumerator = 20; // part of investment
  uint public constant initialFundsReleaseDenominator = 100;
  uint public constant afterFirstRefundRoundFundsReleaseNumerator = 50; // part of remaining funds
  uint public constant afterFirstRefundRoundFundsReleaseDenominator = 100;

  uint public constant angelFoundationShareNumerator = 30;
  uint public constant angelFoundationShareDenominator = 100;

  /* Storage - state */

  address public angelFoundationAddress = address(0x2b0556a6298eA3D35E90F1df32cc126b31F59770);
  uint public icoLaunchTimestamp = 1511784000;  // November 27th 12:00 GMT
  uint public icoFinishTimestamp = 1513727999;  // December 19th 23:59:59 GMT
  uint public firstRefundRoundFinishTimestamp = 1520424000;  // March 7th 2018 12:00 GMT
  uint public secondRefundRoundFinishTimestamp = 1524744000;  // April 26th 2018 12:00 GMT


  AngelToken public angelToken;

  mapping (address => InvestmentRecord[]) public investments; // investorAddress => list of investments
  mapping (address => bool) public investors;
  uint public totalInvestors = 0;
  uint public totalTokensSold = 0;

  bool isIcoFinished = false;
  bool firstRefundRoundFundsWithdrawal = false;


  /* Events */

  event InvestmentEvent(address indexed investor, uint eth, uint angel);
  event RefundEvent(address indexed investor, uint eth, uint angel);


  /* Constructor and config */

  function AngelCentralBank() public {
    angelToken = new AngelToken();
    angelToken.enableManager(address(this));
    angelToken.grantManagerPermission(address(this), 'mint_tokens');
    angelToken.grantManagerPermission(address(this), 'burn_tokens');
    angelToken.grantManagerPermission(address(this), 'unpause_contract');
    angelToken.transferOwnership(angelFoundationAddress);
  }

  /* Investments */

  /**
   * @dev Fallback function receives ETH and sends tokens back
   */
  function () public payable {
    angelRaise();
  }

  /**
   * @dev Process new ETH investment and sends tokens back
   */
  function angelRaise() internal {
    require(msg.value > 0);
    require(now >= icoLaunchTimestamp && now < icoFinishTimestamp);

    // calculate amount of tokens for received ETH
    uint _purchasedTokensWei = 0;
    uint _notProcessedEthWei = 0;
    (_purchasedTokensWei, _notProcessedEthWei) = calculatePurchasedTokens(totalTokensSold, msg.value);
    uint _actualInvestment = (msg.value - _notProcessedEthWei);

    // create record for the investment
    uint _newRecordIndex = investments[msg.sender].length;
    investments[msg.sender].length += 1;
    investments[msg.sender][_newRecordIndex].tokensSoldBeforeWei = totalTokensSold;
    investments[msg.sender][_newRecordIndex].investedEthWei = _actualInvestment;
    investments[msg.sender][_newRecordIndex].purchasedTokensWei = _purchasedTokensWei;
    investments[msg.sender][_newRecordIndex].refundedEthWei = 0;
    investments[msg.sender][_newRecordIndex].returnedTokensWei = 0;

    // calculate stats
    if (investors[msg.sender] == false) {
      totalInvestors += 1;
    }
    investors[msg.sender] = true;
    totalTokensSold += _purchasedTokensWei;

    // transfer tokens and ETH
    angelToken.mint(msg.sender, _purchasedTokensWei);
    angelToken.mint(angelFoundationAddress,
                    _purchasedTokensWei * angelFoundationShareNumerator / (angelFoundationShareDenominator - angelFoundationShareNumerator));
    angelFoundationAddress.transfer(_actualInvestment * initialFundsReleaseNumerator / initialFundsReleaseDenominator);
    if (_notProcessedEthWei > 0) {
      msg.sender.transfer(_notProcessedEthWei);
    }

    // finish ICO if cap reached
    if (totalTokensSold >= icoCap) {
      icoFinishTimestamp = now;

      finishIco();
    }

    // fire event
    InvestmentEvent(msg.sender, _actualInvestment, _purchasedTokensWei);
  }

  /**
   * @dev Calculate amount of tokens for received ETH
   * @param _totalTokensSoldBefore uint Amount of tokens sold before this investment [token wei]
   * @param _investedEthWei        uint Investment amount [ETH wei]
   * @return Purchased amount of tokens [token wei]
   */
  function calculatePurchasedTokens(
    uint _totalTokensSoldBefore,
    uint _investedEthWei)
    constant public returns (uint _purchasedTokensWei, uint _notProcessedEthWei)
  {
    _purchasedTokensWei = 0;
    _notProcessedEthWei = _investedEthWei;

    uint _landmarkPrice;
    uint _maxLandmarkTokensWei;
    uint _maxLandmarkEthWei;
    bool _isCapReached = false;
    do {
      // get landmark values
      _landmarkPrice = calculateLandmarkPrice(_totalTokensSoldBefore + _purchasedTokensWei);
      _maxLandmarkTokensWei = landmarkSize - ((_totalTokensSoldBefore + _purchasedTokensWei) % landmarkSize);
      if (_totalTokensSoldBefore + _purchasedTokensWei + _maxLandmarkTokensWei >= icoCap) {
        _maxLandmarkTokensWei = icoCap - _totalTokensSoldBefore - _purchasedTokensWei;
        _isCapReached = true;
      }
      _maxLandmarkEthWei = _maxLandmarkTokensWei * _landmarkPrice / (10 ** 18);

      // check investment against landmark values
      if (_notProcessedEthWei >= _maxLandmarkEthWei) {
        _purchasedTokensWei += _maxLandmarkTokensWei;
        _notProcessedEthWei -= _maxLandmarkEthWei;
      }
      else {
        _purchasedTokensWei += _notProcessedEthWei * (10 ** 18) / _landmarkPrice;
        _notProcessedEthWei = 0;
      }
    }
    while ((_notProcessedEthWei > 0) && (_isCapReached == false));

    assert(_purchasedTokensWei > 0);

    return (_purchasedTokensWei, _notProcessedEthWei);
  }


  /* Refunds */

  function angelBurn(
    address _investor,
    uint _returnedTokensWei
  )
    external returns (uint)
  {
    require(msg.sender == address(angelToken));
    require(now >= icoLaunchTimestamp && now < secondRefundRoundFinishTimestamp);

    uint _notProcessedTokensWei = _returnedTokensWei;
    uint _refundedEthWei = 0;

    uint _allRecordsNumber = investments[_investor].length;
    uint _recordMaxReturnedTokensWei = 0;
    uint _recordTokensWeiToProcess = 0;
    uint _tokensSoldWei = 0;
    uint _recordRefundedEthWei = 0;
    uint _recordNotProcessedTokensWei = 0;
    for (uint _recordID = 0; _recordID < _allRecordsNumber; _recordID += 1) {
      if (investments[_investor][_recordID].purchasedTokensWei <= investments[_investor][_recordID].returnedTokensWei ||
          investments[_investor][_recordID].investedEthWei <= investments[_investor][_recordID].refundedEthWei) {
        // tokens already refunded
        continue;
      }

      // calculate amount of tokens to refund with this record
      _recordMaxReturnedTokensWei = investments[_investor][_recordID].purchasedTokensWei -
                                    investments[_investor][_recordID].returnedTokensWei;
      _recordTokensWeiToProcess = (_notProcessedTokensWei < _recordMaxReturnedTokensWei) ? _notProcessedTokensWei :
                                                                                           _recordMaxReturnedTokensWei;
      assert(_recordTokensWeiToProcess > 0);

      // calculate amount of ETH to send back
      _tokensSoldWei = investments[_investor][_recordID].tokensSoldBeforeWei + investments[_investor][_recordID].returnedTokensWei;
      (_recordRefundedEthWei, _recordNotProcessedTokensWei) = calculateRefundedEth(_tokensSoldWei, _recordTokensWeiToProcess);
      if (_recordRefundedEthWei > (investments[_investor][_recordID].investedEthWei - investments[_investor][_recordID].refundedEthWei)) {
        // this can happen due to rounding error
        _recordRefundedEthWei = (investments[_investor][_recordID].investedEthWei - investments[_investor][_recordID].refundedEthWei);
      }
      assert(_recordRefundedEthWei > 0);
      assert(_recordNotProcessedTokensWei == 0);

      // persist changes to the storage
      _refundedEthWei += _recordRefundedEthWei;
      _notProcessedTokensWei -= _recordTokensWeiToProcess;

      investments[_investor][_recordID].refundedEthWei += _recordRefundedEthWei;
      investments[_investor][_recordID].returnedTokensWei += _recordTokensWeiToProcess;
      assert(investments[_investor][_recordID].refundedEthWei <= investments[_investor][_recordID].investedEthWei);
      assert(investments[_investor][_recordID].returnedTokensWei <= investments[_investor][_recordID].purchasedTokensWei);

      // stop if we already refunded all tokens
      if (_notProcessedTokensWei == 0) {
        break;
      }
    }

    // throw if we do not have tokens to refund
    require(_notProcessedTokensWei < _returnedTokensWei);
    require(_refundedEthWei > 0);

    // calculate refund discount
    uint _refundedEthWeiWithDiscount = calculateRefundedEthWithDiscount(_refundedEthWei);

    // transfer ETH and remaining tokens
    angelToken.burn(_returnedTokensWei - _notProcessedTokensWei);
    if (_notProcessedTokensWei > 0) {
      angelToken.transfer(_investor, _notProcessedTokensWei);
    }
    _investor.transfer(_refundedEthWeiWithDiscount);

    // fire event
    RefundEvent(_investor, _refundedEthWeiWithDiscount, _returnedTokensWei - _notProcessedTokensWei);
  }

  /**
   * @dev Calculate discounted amount of ETH for refunded tokens
   * @param _refundedEthWei uint Calculated amount of ETH to refund [ETH wei]
   * @return Discounted amount of ETH for refunded [ETH wei]
   */
  function calculateRefundedEthWithDiscount(
    uint _refundedEthWei
  )
    public constant returns (uint)
  {
    if (now <= firstRefundRoundFinishTimestamp) {
      return (_refundedEthWei * firstRefundRoundRateNumerator / firstRefundRoundRateDenominator);
    }
    else {
      return (_refundedEthWei * secondRefundRoundRateNumerator / secondRefundRoundRateDenominator);
    }
  }

  /**
   * @dev Calculate amount of ETH for refunded tokens. Just abstract price ladder
   * @param _totalTokensSoldBefore     uint Amount of tokens that have been sold (starting point) [token wei]
   * @param _returnedTokensWei uint Amount of tokens to refund [token wei]
   * @return Refunded amount of ETH [ETH wei] (without discounts)
   */
  function calculateRefundedEth(
    uint _totalTokensSoldBefore,
    uint _returnedTokensWei
  )
    public constant returns (uint _refundedEthWei, uint _notProcessedTokensWei)
  {
    _refundedEthWei = 0;
    uint _refundedTokensWei = 0;
    _notProcessedTokensWei = _returnedTokensWei;

    uint _landmarkPrice = 0;
    uint _maxLandmarkTokensWei = 0;
    uint _maxLandmarkEthWei = 0;
    bool _isCapReached = false;
    do {
      // get landmark values
      _landmarkPrice = calculateLandmarkPrice(_totalTokensSoldBefore + _refundedTokensWei);
      _maxLandmarkTokensWei = landmarkSize - ((_totalTokensSoldBefore + _refundedTokensWei) % landmarkSize);
      if (_totalTokensSoldBefore + _refundedTokensWei + _maxLandmarkTokensWei >= icoCap) {
        _maxLandmarkTokensWei = icoCap - _totalTokensSoldBefore - _refundedTokensWei;
        _isCapReached = true;
      }
      _maxLandmarkEthWei = _maxLandmarkTokensWei * _landmarkPrice / (10 ** 18);

      // check investment against landmark values
      if (_notProcessedTokensWei > _maxLandmarkTokensWei) {
        _refundedEthWei += _maxLandmarkEthWei;
        _refundedTokensWei += _maxLandmarkTokensWei;
        _notProcessedTokensWei -= _maxLandmarkTokensWei;
      }
      else {
        _refundedEthWei += _notProcessedTokensWei * _landmarkPrice / (10 ** 18);
        _refundedTokensWei += _notProcessedTokensWei;
        _notProcessedTokensWei = 0;
      }
    }
    while ((_notProcessedTokensWei > 0) && (_isCapReached == false));

    assert(_refundedEthWei > 0);

    return (_refundedEthWei, _notProcessedTokensWei);
  }


  /* Calculation of the price */

  /**
   * @dev Calculate price for tokens
   * @param _totalTokensSoldBefore uint Amount of tokens sold before [token wei]
   * @return Calculated price
   */
  function calculateLandmarkPrice(uint _totalTokensSoldBefore) public constant returns (uint) {
    return initialTokenPrice + initialTokenPrice
                               * landmarkPriceStepNumerator / landmarkPriceStepDenominator
                               * (_totalTokensSoldBefore / landmarkSize);
  }


  /* Lifecycle */

  function finishIco() public {
    require(now >= icoFinishTimestamp);
    require(isIcoFinished == false);

    isIcoFinished = true;

    angelToken.unpauseContract();
  }

  function withdrawFoundationFunds() external {
    require(now > firstRefundRoundFinishTimestamp);

    if (now > firstRefundRoundFinishTimestamp && now <= secondRefundRoundFinishTimestamp) {
      require(firstRefundRoundFundsWithdrawal == false);

      firstRefundRoundFundsWithdrawal = true;
      angelFoundationAddress.transfer(this.balance * afterFirstRefundRoundFundsReleaseNumerator / afterFirstRefundRoundFundsReleaseDenominator);
    } else {
      angelFoundationAddress.transfer(this.balance);
    }
  }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_manager","type":"address"},{"name":"_permissionName","type":"string"}],"name":"isManagerAllowed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"unblockSpending","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"blockSpending","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_manager","type":"address"},{"name":"_permissionName","type":"string"}],"name":"isPermissionGranted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_value","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pauseContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"centralBankAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"}],"name":"enableManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPaused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSymbolHash","outputs":[{"name":"result","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"},{"name":"_permissionName","type":"string"}],"name":"revokeManagerPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"},{"name":"_permissionName","type":"string"}],"name":"grantManagerPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_manager","type":"address"}],"name":"isManagerEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpauseContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_manager","type":"address"}],"name":"disableManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNameHash","outputs":[{"name":"result","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"MintEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"BurnEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"SpendingBlockedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"SpendingUnblockedEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"PauseEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"UnpauseEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"manager","type":"address"}],"name":"ManagerEnabledEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"manager","type":"address"}],"name":"ManagerDisabledEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"manager","type":"address"},{"indexed":false,"name":"permission","type":"string"}],"name":"ManagerPermissionGrantedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"manager","type":"address"},{"indexed":false,"name":"permission","type":"string"}],"name":"ManagerPermissionRevokedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]

60606040526008805461010060a860020a031960ff1990911660011716905534156200002a57600080fd5b5b5b604080519081016040908152600b82527f416e67656c20546f6b656e00000000000000000000000000000000000000000060208301528051908101604052600481527f414e474c00000000000000000000000000000000000000000000000000000000602082015260125b6003838051620000ac9291602001906200011e565b506004828051620000c29291602001906200011e565b506005805460ff191660ff83161790555b50506005805461010060a860020a03191661010033600160a060020a031602179055505b6008805461010060a860020a03191661010033600160a060020a0316021790555b620001c8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200016157805160ff191683800117855562000191565b8280016001018555821562000191579182015b828111156200019157825182559160200191906001019062000174565b5b50620001a0929150620001a4565b5090565b620001c591905b80821115620001a05760008155600101620001ab565b5090565b90565b611a1e80620001d86000396000f3006060604052361561014e5763ffffffff60e060020a6000350416630392d2b4811461015357806306fdde03146101c6578063095ea7b3146102515780630f482da11461028757806318160ddd146102a857806323b872dd146102cd5780632f060d5e14610309578063313ce5671461032a57806332a2fda71461035357806340c10f19146103c657806342966c68146103ea578063439766ce146104025780634ffc9204146104175780635ca5b334146104465780636805b84b146104675780636ea928d91461048e57806370a08231146104b35780637c0efb8b146104e4578063822b08d0146105115780638da5cb5b1461053e57806395d89b411461056d5780639b53d87c146105f8578063a9059cbb1461062b578063b33712c514610661578063d4859dc514610676578063dd62ed3e14610697578063e102d950146106ce578063f2fde38b146106f3575b600080fd5b341561015e57600080fd5b6101b260048035600160a060020a03169060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061071495505050505050565b604051901515815260200160405180910390f35b34156101d157600080fd5b6101d96107ee565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156102165780820151818401525b6020016101fd565b50505050905090810190601f1680156102435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561025c57600080fd5b6101b2600160a060020a036004351660243561088c565b604051901515815260200160405180910390f35b341561029257600080fd5b6102a6600160a060020a03600435166108b3565b005b34156102b357600080fd5b6102bb610979565b60405190815260200160405180910390f35b34156102d857600080fd5b6101b2600160a060020a036004358116906024351660443561097f565b604051901515815260200160405180910390f35b341561031457600080fd5b6102a6600160a060020a0360043516610a7a565b005b341561033557600080fd5b61033d610b40565b60405160ff909116815260200160405180910390f35b341561035e57600080fd5b6101b260048035600160a060020a03169060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610b4995505050505050565b604051901515815260200160405180910390f35b34156103d157600080fd5b6102a6600160a060020a0360043516602435610bff565b005b34156103f557600080fd5b6102a6600435610d27565b005b341561040d57600080fd5b6102a6610e0f565b005b341561042257600080fd5b61042a610eaa565b604051600160a060020a03909116815260200160405180910390f35b341561045157600080fd5b6102a6600160a060020a0360043516610ebe565b005b341561047257600080fd5b6101b2610f71565b604051901515815260200160405180910390f35b341561049957600080fd5b6102bb610f7b565b60405190815260200160405180910390f35b34156104be57600080fd5b6102bb600160a060020a0360043516610fed565b60405190815260200160405180910390f35b34156104ef57600080fd5b6102a660048035600160a060020a0316906024803590810191013561100c565b005b341561051c57600080fd5b6102a660048035600160a060020a0316906024803590810191013561117f565b005b341561054957600080fd5b61042a6112f1565b604051600160a060020a03909116815260200160405180910390f35b341561057857600080fd5b6101d9611305565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156102165780820151818401525b6020016101fd565b50505050905090810190601f1680156102435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561060357600080fd5b6101b2600160a060020a03600435166113a3565b604051901515815260200160405180910390f35b341561063657600080fd5b6101b2600160a060020a03600435166024356113e1565b604051901515815260200160405180910390f35b341561066c57600080fd5b6102a66114f4565b005b341561068157600080fd5b6102a6600160a060020a0360043516611590565b005b34156106a257600080fd5b6102bb600160a060020a0360043581169060243516611644565b60405190815260200160405180910390f35b34156106d957600080fd5b6102bb611671565b60405190815260200160405180910390f35b34156106fe57600080fd5b6102a6600160a060020a03600435166116e3565b005b600082600160a060020a038116151561072c57600080fd5b828051151561073a57600080fd5b600160a060020a03851660009081526006602052604090205460ff1680156107e15750600160a060020a03851660009081526007602052604090819020908590518082805190602001908083835b602083106107a857805182525b601f199092019160209182019101610788565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390205460ff165b92505b5b505b5092915050565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108845780601f1061085957610100808354040283529160200191610884565b820191906000526020600020905b81548152906001019060200180831161086757829003601f168201915b505050505081565b60085460009060ff161561089f57600080fd5b6108a98383611745565b90505b5b92915050565b60408051908101604052601081527f756e626c6f636b5f7370656e64696e670000000000000000000000000000000060208201526108f13382610714565b15156001146108ff57600080fd5b600160a060020a03821660009081526009602052604090205461092990600163ffffffff6117ec16565b600160a060020a0383166000818152600960205260409081902092909255907fdcf34a916d72b8b54142163ead554d22efacd814b0d4591f826eb33a380ade8c905160405180910390a25b5b5050565b60005481565b600854600090819060ff161561099457600080fd5b600160a060020a038516600090815260096020526040902054156109b757600080fd5b6109c2858585611803565b905060018115151480156109e85750600854600160a060020a0385811661010090920416145b15610a6d576008546101009004600160a060020a031663caf439cb868560006040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b1515610a5157600080fd5b6102c65a03f11515610a6257600080fd5b505050604051805150505b8091505b5b509392505050565b60408051908101604052600e81527f626c6f636b5f7370656e64696e670000000000000000000000000000000000006020820152610ab83382610714565b1515600114610ac657600080fd5b600160a060020a038216600090815260096020526040902054610af090600163ffffffff61191816565b600160a060020a0383166000818152600960205260409081902092909255907f15cbfdc163b37373201ba2869dae7fd3181aa74d8df31a08d7cf322e5c39d0fc905160405180910390a25b5b5050565b60055460ff1681565b600082600160a060020a0381161515610b6157600080fd5b8280511515610b6f57600080fd5b600160a060020a03851660009081526007602052604090819020908590518082805190602001908083835b602083106107a857805182525b601f199092019160209182019101610788565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390205460ff1692505b5b505b5092915050565b60408051908101604052600b81527f6d696e745f746f6b656e730000000000000000000000000000000000000000006020820152610c3d3382610714565b1515600114610c4b57600080fd5b600160a060020a038316600090815260016020526040902054610c74908363ffffffff61191816565b600160a060020a03841660009081526001602052604081209190915554610ca1908363ffffffff61191816565b600055600160a060020a0383167f3fffaa5804a26fcec0d70b1d0fb0a2d0031df3a5f9c8af2127c2f4360e97b4638360405190815260200160405180910390a2600160a060020a03831660007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405190815260200160405180910390a35b5b505050565b60408051908101604052600b81527f6275726e5f746f6b656e730000000000000000000000000000000000000000006020820152610d653382610714565b1515600114610d7357600080fd5b600160a060020a033316600090815260016020526040902054610d9c908363ffffffff6117ec16565b600160a060020a03331660009081526001602052604081209190915554610dc9908363ffffffff6117ec16565b600055600160a060020a0333167f512586160ebd4dc6945ba9ec5d21a1f723f26f3c7aa36cdffb6818d4e7b880308360405190815260200160405180910390a25b5b5050565b60408051908101604052600e81527f70617573655f636f6e74726163740000000000000000000000000000000000006020820152610e4d3382610714565b1515600114610e5b57600080fd5b60085460ff1615610e6b57600080fd5b6008805460ff191660011790557f14cc32b2b0edca88201ca20553c392d108a2feb2c750a0ee14c707b4f34fbee260405160405180910390a15b5b5b50565b6008546101009004600160a060020a031681565b60055433600160a060020a039081166101009092041614610ede57600080fd5b80600160a060020a0381161515610ef457600080fd5b600160a060020a03821660009081526006602052604090205460ff1615610f1a57600080fd5b600160a060020a03821660008181526006602052604090819020805460ff191660011790557f7f0b61f78ab0b549b68ce61404f4ee01a26ffdf8d421d099d271d789aaea3a8e905160405180910390a25b5b505b50565b60085460ff165b90565b600060046040518082805460018160011615610100020316600290048015610fda5780601f10610fb8576101008083540402835291820191610fda565b820191906000526020600020905b815481529060010190602001808311610fc6575b5050915050604051809103902090505b90565b600160a060020a0381166000908152600160205260409020545b919050565b60055433600160a060020a03908116610100909204161461102c57600080fd5b82600160a060020a038116151561104257600080fd5b82828080601f0160208091040260200160405190810160405281815292919060208401838380828437508594505050505051151561107f57600080fd5b600160a060020a03851660009081526007602052604090819020908590859051808383808284378201915050925050509081526020016040519081900390205460ff1615156001146110d057600080fd5b600160a060020a03851660009081526007602052604080822090869086905180838380828437820191505092505050908152602001604051908190039020805460ff1916911515919091179055600160a060020a0385167fe2b13fa06e3428fe0e43b2e517d25708ba477cafdff4fbcd06e3e93864517ddc85856040516020808252810182905280604081018484808284378201915050935050505060405180910390a25b5b505b505b505050565b60055433600160a060020a03908116610100909204161461119f57600080fd5b82600160a060020a03811615156111b557600080fd5b82828080601f016020809104026020016040519081016040528181529291906020840183838082843750859450505050505115156111f257600080fd5b600160a060020a03851660009081526007602052604090819020908590859051808383808284378201915050925050509081526020016040519081900390205460ff161561123f57600080fd5b600160a060020a03851660009081526007602052604090819020600191869086905180838380828437820191505092505050908152602001604051908190039020805460ff1916911515919091179055600160a060020a0385167fb76b4ee2621e0744da93fa797bdc4851a3b9e303b2950f2f234a449e5f36d35e85856040516020808252810182905280604081018484808284378201915050935050505060405180910390a25b5b505b505b505050565b6005546101009004600160a060020a031681565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108845780601f1061085957610100808354040283529160200191610884565b820191906000526020600020905b81548152906001019060200180831161086757829003601f168201915b505050505081565b600081600160a060020a03811615156113bb57600080fd5b600160a060020a03831660009081526006602052604090205460ff1691505b5b50919050565b6008546000908190600160a060020a0385811661010090920416146114105760085460ff161561141057600080fd5b5b600160a060020a0333166000908152600960205260409020541561143457600080fd5b61143e8484611932565b905060018115151480156114645750600854600160a060020a0385811661010090920416145b156114e9576008546101009004600160a060020a031663caf439cb338560006040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156114cd57600080fd5b6102c65a03f115156114de57600080fd5b505050604051805150505b8091505b5092915050565b60408051908101604052601081527f756e70617573655f636f6e74726163740000000000000000000000000000000060208201526115323382610714565b151560011461154057600080fd5b60085460ff16151560011461155457600080fd5b6008805460ff191690557f6249a5c797c884cbf33e63e8cfc250816032db24e22051de68a388315e64afc660405160405180910390a15b5b5b50565b60055433600160a060020a0390811661010090920416146115b057600080fd5b80600160a060020a03811615156115c657600080fd5b600160a060020a03821660009081526006602052604090205460ff1615156001146115f057600080fd5b600160a060020a03821660008181526006602052604090819020805460ff191690557f91975e22df3ba360814d3153e8eaef17954cf47d52a42840fc9747ad1086b351905160405180910390a25b5b505b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600060036040518082805460018160011615610100020316600290048015610fda5780601f10610fb8576101008083540402835291820191610fda565b820191906000526020600020905b815481529060010190602001808311610fc6575b5050915050604051809103902090505b90565b60055433600160a060020a03908116610100909204161461170357600080fd5b600160a060020a03811615610ea5576005805474ffffffffffffffffffffffffffffffffffffffff001916610100600160a060020a038416021790555b5b5b50565b60008115806117775750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b151561178257600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b6000828211156117f857fe5b508082035b92915050565b600160a060020a03808416600090815260026020908152604080832033851684528252808320549386168352600190915281205490919061184a908463ffffffff61191816565b600160a060020a03808616600090815260016020526040808220939093559087168152205461187f908463ffffffff6117ec16565b600160a060020a0386166000908152600160205260409020556118a8818463ffffffff6117ec16565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b6000828201838110156114e957fe5b8091505b5092915050565b600160a060020a03331660009081526001602052604081205461195b908363ffffffff6117ec16565b600160a060020a033381166000908152600160205260408082209390935590851681522054611990908363ffffffff61191816565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b929150505600a165627a7a723058206e0da1d1833fc22c24af3a8b3fe6aff47db9cd76ab4690be3da93088d5d9e0b50029

Deployed Bytecode

0x6060604052361561014e5763ffffffff60e060020a6000350416630392d2b4811461015357806306fdde03146101c6578063095ea7b3146102515780630f482da11461028757806318160ddd146102a857806323b872dd146102cd5780632f060d5e14610309578063313ce5671461032a57806332a2fda71461035357806340c10f19146103c657806342966c68146103ea578063439766ce146104025780634ffc9204146104175780635ca5b334146104465780636805b84b146104675780636ea928d91461048e57806370a08231146104b35780637c0efb8b146104e4578063822b08d0146105115780638da5cb5b1461053e57806395d89b411461056d5780639b53d87c146105f8578063a9059cbb1461062b578063b33712c514610661578063d4859dc514610676578063dd62ed3e14610697578063e102d950146106ce578063f2fde38b146106f3575b600080fd5b341561015e57600080fd5b6101b260048035600160a060020a03169060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061071495505050505050565b604051901515815260200160405180910390f35b34156101d157600080fd5b6101d96107ee565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156102165780820151818401525b6020016101fd565b50505050905090810190601f1680156102435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561025c57600080fd5b6101b2600160a060020a036004351660243561088c565b604051901515815260200160405180910390f35b341561029257600080fd5b6102a6600160a060020a03600435166108b3565b005b34156102b357600080fd5b6102bb610979565b60405190815260200160405180910390f35b34156102d857600080fd5b6101b2600160a060020a036004358116906024351660443561097f565b604051901515815260200160405180910390f35b341561031457600080fd5b6102a6600160a060020a0360043516610a7a565b005b341561033557600080fd5b61033d610b40565b60405160ff909116815260200160405180910390f35b341561035e57600080fd5b6101b260048035600160a060020a03169060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610b4995505050505050565b604051901515815260200160405180910390f35b34156103d157600080fd5b6102a6600160a060020a0360043516602435610bff565b005b34156103f557600080fd5b6102a6600435610d27565b005b341561040d57600080fd5b6102a6610e0f565b005b341561042257600080fd5b61042a610eaa565b604051600160a060020a03909116815260200160405180910390f35b341561045157600080fd5b6102a6600160a060020a0360043516610ebe565b005b341561047257600080fd5b6101b2610f71565b604051901515815260200160405180910390f35b341561049957600080fd5b6102bb610f7b565b60405190815260200160405180910390f35b34156104be57600080fd5b6102bb600160a060020a0360043516610fed565b60405190815260200160405180910390f35b34156104ef57600080fd5b6102a660048035600160a060020a0316906024803590810191013561100c565b005b341561051c57600080fd5b6102a660048035600160a060020a0316906024803590810191013561117f565b005b341561054957600080fd5b61042a6112f1565b604051600160a060020a03909116815260200160405180910390f35b341561057857600080fd5b6101d9611305565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156102165780820151818401525b6020016101fd565b50505050905090810190601f1680156102435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561060357600080fd5b6101b2600160a060020a03600435166113a3565b604051901515815260200160405180910390f35b341561063657600080fd5b6101b2600160a060020a03600435166024356113e1565b604051901515815260200160405180910390f35b341561066c57600080fd5b6102a66114f4565b005b341561068157600080fd5b6102a6600160a060020a0360043516611590565b005b34156106a257600080fd5b6102bb600160a060020a0360043581169060243516611644565b60405190815260200160405180910390f35b34156106d957600080fd5b6102bb611671565b60405190815260200160405180910390f35b34156106fe57600080fd5b6102a6600160a060020a03600435166116e3565b005b600082600160a060020a038116151561072c57600080fd5b828051151561073a57600080fd5b600160a060020a03851660009081526006602052604090205460ff1680156107e15750600160a060020a03851660009081526007602052604090819020908590518082805190602001908083835b602083106107a857805182525b601f199092019160209182019101610788565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390205460ff165b92505b5b505b5092915050565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108845780601f1061085957610100808354040283529160200191610884565b820191906000526020600020905b81548152906001019060200180831161086757829003601f168201915b505050505081565b60085460009060ff161561089f57600080fd5b6108a98383611745565b90505b5b92915050565b60408051908101604052601081527f756e626c6f636b5f7370656e64696e670000000000000000000000000000000060208201526108f13382610714565b15156001146108ff57600080fd5b600160a060020a03821660009081526009602052604090205461092990600163ffffffff6117ec16565b600160a060020a0383166000818152600960205260409081902092909255907fdcf34a916d72b8b54142163ead554d22efacd814b0d4591f826eb33a380ade8c905160405180910390a25b5b5050565b60005481565b600854600090819060ff161561099457600080fd5b600160a060020a038516600090815260096020526040902054156109b757600080fd5b6109c2858585611803565b905060018115151480156109e85750600854600160a060020a0385811661010090920416145b15610a6d576008546101009004600160a060020a031663caf439cb868560006040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b1515610a5157600080fd5b6102c65a03f11515610a6257600080fd5b505050604051805150505b8091505b5b509392505050565b60408051908101604052600e81527f626c6f636b5f7370656e64696e670000000000000000000000000000000000006020820152610ab83382610714565b1515600114610ac657600080fd5b600160a060020a038216600090815260096020526040902054610af090600163ffffffff61191816565b600160a060020a0383166000818152600960205260409081902092909255907f15cbfdc163b37373201ba2869dae7fd3181aa74d8df31a08d7cf322e5c39d0fc905160405180910390a25b5b5050565b60055460ff1681565b600082600160a060020a0381161515610b6157600080fd5b8280511515610b6f57600080fd5b600160a060020a03851660009081526007602052604090819020908590518082805190602001908083835b602083106107a857805182525b601f199092019160209182019101610788565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390205460ff1692505b5b505b5092915050565b60408051908101604052600b81527f6d696e745f746f6b656e730000000000000000000000000000000000000000006020820152610c3d3382610714565b1515600114610c4b57600080fd5b600160a060020a038316600090815260016020526040902054610c74908363ffffffff61191816565b600160a060020a03841660009081526001602052604081209190915554610ca1908363ffffffff61191816565b600055600160a060020a0383167f3fffaa5804a26fcec0d70b1d0fb0a2d0031df3a5f9c8af2127c2f4360e97b4638360405190815260200160405180910390a2600160a060020a03831660007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405190815260200160405180910390a35b5b505050565b60408051908101604052600b81527f6275726e5f746f6b656e730000000000000000000000000000000000000000006020820152610d653382610714565b1515600114610d7357600080fd5b600160a060020a033316600090815260016020526040902054610d9c908363ffffffff6117ec16565b600160a060020a03331660009081526001602052604081209190915554610dc9908363ffffffff6117ec16565b600055600160a060020a0333167f512586160ebd4dc6945ba9ec5d21a1f723f26f3c7aa36cdffb6818d4e7b880308360405190815260200160405180910390a25b5b5050565b60408051908101604052600e81527f70617573655f636f6e74726163740000000000000000000000000000000000006020820152610e4d3382610714565b1515600114610e5b57600080fd5b60085460ff1615610e6b57600080fd5b6008805460ff191660011790557f14cc32b2b0edca88201ca20553c392d108a2feb2c750a0ee14c707b4f34fbee260405160405180910390a15b5b5b50565b6008546101009004600160a060020a031681565b60055433600160a060020a039081166101009092041614610ede57600080fd5b80600160a060020a0381161515610ef457600080fd5b600160a060020a03821660009081526006602052604090205460ff1615610f1a57600080fd5b600160a060020a03821660008181526006602052604090819020805460ff191660011790557f7f0b61f78ab0b549b68ce61404f4ee01a26ffdf8d421d099d271d789aaea3a8e905160405180910390a25b5b505b50565b60085460ff165b90565b600060046040518082805460018160011615610100020316600290048015610fda5780601f10610fb8576101008083540402835291820191610fda565b820191906000526020600020905b815481529060010190602001808311610fc6575b5050915050604051809103902090505b90565b600160a060020a0381166000908152600160205260409020545b919050565b60055433600160a060020a03908116610100909204161461102c57600080fd5b82600160a060020a038116151561104257600080fd5b82828080601f0160208091040260200160405190810160405281815292919060208401838380828437508594505050505051151561107f57600080fd5b600160a060020a03851660009081526007602052604090819020908590859051808383808284378201915050925050509081526020016040519081900390205460ff1615156001146110d057600080fd5b600160a060020a03851660009081526007602052604080822090869086905180838380828437820191505092505050908152602001604051908190039020805460ff1916911515919091179055600160a060020a0385167fe2b13fa06e3428fe0e43b2e517d25708ba477cafdff4fbcd06e3e93864517ddc85856040516020808252810182905280604081018484808284378201915050935050505060405180910390a25b5b505b505b505050565b60055433600160a060020a03908116610100909204161461119f57600080fd5b82600160a060020a03811615156111b557600080fd5b82828080601f016020809104026020016040519081016040528181529291906020840183838082843750859450505050505115156111f257600080fd5b600160a060020a03851660009081526007602052604090819020908590859051808383808284378201915050925050509081526020016040519081900390205460ff161561123f57600080fd5b600160a060020a03851660009081526007602052604090819020600191869086905180838380828437820191505092505050908152602001604051908190039020805460ff1916911515919091179055600160a060020a0385167fb76b4ee2621e0744da93fa797bdc4851a3b9e303b2950f2f234a449e5f36d35e85856040516020808252810182905280604081018484808284378201915050935050505060405180910390a25b5b505b505b505050565b6005546101009004600160a060020a031681565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108845780601f1061085957610100808354040283529160200191610884565b820191906000526020600020905b81548152906001019060200180831161086757829003601f168201915b505050505081565b600081600160a060020a03811615156113bb57600080fd5b600160a060020a03831660009081526006602052604090205460ff1691505b5b50919050565b6008546000908190600160a060020a0385811661010090920416146114105760085460ff161561141057600080fd5b5b600160a060020a0333166000908152600960205260409020541561143457600080fd5b61143e8484611932565b905060018115151480156114645750600854600160a060020a0385811661010090920416145b156114e9576008546101009004600160a060020a031663caf439cb338560006040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b15156114cd57600080fd5b6102c65a03f115156114de57600080fd5b505050604051805150505b8091505b5092915050565b60408051908101604052601081527f756e70617573655f636f6e74726163740000000000000000000000000000000060208201526115323382610714565b151560011461154057600080fd5b60085460ff16151560011461155457600080fd5b6008805460ff191690557f6249a5c797c884cbf33e63e8cfc250816032db24e22051de68a388315e64afc660405160405180910390a15b5b5b50565b60055433600160a060020a0390811661010090920416146115b057600080fd5b80600160a060020a03811615156115c657600080fd5b600160a060020a03821660009081526006602052604090205460ff1615156001146115f057600080fd5b600160a060020a03821660008181526006602052604090819020805460ff191690557f91975e22df3ba360814d3153e8eaef17954cf47d52a42840fc9747ad1086b351905160405180910390a25b5b505b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600060036040518082805460018160011615610100020316600290048015610fda5780601f10610fb8576101008083540402835291820191610fda565b820191906000526020600020905b815481529060010190602001808311610fc6575b5050915050604051809103902090505b90565b60055433600160a060020a03908116610100909204161461170357600080fd5b600160a060020a03811615610ea5576005805474ffffffffffffffffffffffffffffffffffffffff001916610100600160a060020a038416021790555b5b5b50565b60008115806117775750600160a060020a03338116600090815260026020908152604080832093871683529290522054155b151561178257600080fd5b600160a060020a03338116600081815260026020908152604080832094881680845294909152908190208590557f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b6000828211156117f857fe5b508082035b92915050565b600160a060020a03808416600090815260026020908152604080832033851684528252808320549386168352600190915281205490919061184a908463ffffffff61191816565b600160a060020a03808616600090815260016020526040808220939093559087168152205461187f908463ffffffff6117ec16565b600160a060020a0386166000908152600160205260409020556118a8818463ffffffff6117ec16565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b6000828201838110156114e957fe5b8091505b5092915050565b600160a060020a03331660009081526001602052604081205461195b908363ffffffff6117ec16565b600160a060020a033381166000908152600160205260408082209390935590851681522054611990908363ffffffff61191816565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b929150505600a165627a7a723058206e0da1d1833fc22c24af3a8b3fe6aff47db9cd76ab4690be3da93088d5d9e0b50029

Swarm Source

bzzr://6e0da1d1833fc22c24af3a8b3fe6aff47db9cd76ab4690be3da93088d5d9e0b5
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.