contract BancrypToken is StandardToken, BurnableToken {
  string public symbol  = "XBANC";
  string public name    = "XBANC";
  uint8 public decimals = 18;

  // Transfers will only be avaiable after the transfer time start
  // 12/31/2018 @ 11:59pm (UTC)
  uint256 public constant TRANSFERABLE_START_TIME = 1546300799;
  
  // Wallets for tokens split amongst team,
  // advisors, reserve fund and social cause addresses
  // Note: Those address will be replaced by the real addresses before the main net deploy
  address public constant ADVISORS_WALLET     = 0x0fC8c4288841CB199bDdbf385BD762938f5A8328;
  address public constant BANCRYP_WALLET      = 0xcafBCD7F36ae4506E4331a27CC6CAF12fD35E83C;
  address public constant FUNDS_WALLET        = 0x66fC388e7AF7ee6198D849A37B89a813d559913a;
  address public constant RESERVE_FUND_WALLET = 0xb8dc7BfB6D987464b2006aBd6B7511C8D2Ebe50f;
  address public constant SOCIAL_CAUSE_WALLET = 0xd71383C04F67e2Db7F95aC58c9B2509Cf15AAa95;
  address public constant TEAM_WALLET         = 0x2b400ee4Ff17dE03453e325e9198E6C9c4F88243;

  // 300.000.000 in initial supply
  uint256 public constant INITIAL_SUPPLY = 300000000;

  // Allows transfer only after TRANSFERABLE_START_TIME
  // With an exception of the wallets allowed on require function
  modifier onlyWhenTransferEnabled(address _to) {
    if ( now <= TRANSFERABLE_START_TIME ) {
      // Only some wallets to transfer
      // in case of transfer isn't available yet
      require(msg.sender == TEAM_WALLET || msg.sender == ADVISORS_WALLET ||
        msg.sender == RESERVE_FUND_WALLET || msg.sender == SOCIAL_CAUSE_WALLET ||
        msg.sender == FUNDS_WALLET || msg.sender == BANCRYP_WALLET ||
        _to == BANCRYP_WALLET, "Forbidden to transfer right now");
    }
    _;
  }

  // Helper to test valid destion to transfer
  modifier validDestination(address to) {
    require(to != address(this));
    _;
  }

  /// @notice Constructor called on deploy of the contract which sets wallets
  /// for team, advisors, reserve fund and social cause, the rest is are for
  /// public sale
  /// will be open to public other than wallets on this constructor
  constructor() public {  
    // After the initial supply been split amongst team, advisors, 
    // reserve and social cause the value available will be 195.000.000
    totalSupply_ = INITIAL_SUPPLY * (10 ** uint256(decimals));
    balances[FUNDS_WALLET] = totalSupply_;
  }

  /// @dev override transfer token for a specified address to add onlyWhenTransferEnabled
  /// @param _to The address to transfer to.
  /// @param _value The amount to be transferred.
  function transfer(address _to, uint256 _value)
      public
      validDestination(_to)
      onlyWhenTransferEnabled(_to)
      returns (bool) 
  {
      return super.transfer(_to, _value);
  }

  /// @dev override transferFrom token for a specified address to add onlyWhenTransferEnabled and validDestination
  /// @param _from The address to transfer from.
  /// @param _to The address to transfer to.
  /// @param _value The amount to be transferred.
  function transferFrom(address _from, address _to, uint256 _value)
    public
    validDestination(_to)
    onlyWhenTransferEnabled(_to)
    returns (bool)
  {
    return super.transferFrom(_from, _to, _value);
  }

  /// @dev Burns a specific amount of tokens.
  /// @param _value The amount of token to be burned.
  function burn(uint256 _value) public {
    require(msg.sender == FUNDS_WALLET, "Only funds wallet can burn");
    _burn(msg.sender, _value);
  }
}
/// @title BancrypToken
/// @author Bancryp
function transferFrom(address _from, address _to, uint256 _value)
  public
  validDestination(_to)
  onlyWhenTransferEnabled(_to)
  returns (bool)
{
  return super.transferFrom(_from, _to, _value);
}

/// @dev override transferFrom token for a specified address to add onlyWhenTransferEnabled and validDestination
/// @param _from The address to transfer from.
/// @param _to The address to transfer to.
/// @param _value The amount to be transferred.