// /**
//  *Submitted for verification at Etherscan.io on 2020-07-16
// */

// pragma solidity >=0.4.23;


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



// /**
//  * @title SafeMath
//  * @dev Math operations with safety checks that throw on error
//  */
// library SafeMath {

//   /**
//   * @dev Multiplies two numbers, throws on overflow.
//   */
//   function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
//     // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
//     // benefit is lost if 'b' is also tested.
//     // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
//     if (a == 0) {
//       return 0;
//     }

//     c = a * b;
//     assert(c / a == b);
//     return c;
//   }

//   /**
//   * @dev Integer division of two numbers, truncating the quotient.
//   */
//   function div(uint256 a, uint256 b) internal pure 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 a / b;
//   }

//   /**
//   * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
//   */
//   function sub(uint256 a, uint256 b) internal pure returns (uint256) {
//     assert(b <= a);
//     return a - b;
//   }

//   /**
//   * @dev Adds two numbers, throws on overflow.
//   */
//   function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
//     c = a + b;
//     assert(c >= a);
//     return c;
//   }
// }



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

//   mapping(address => uint256) balances;

//   uint256 totalSupply_;

//   /**
//   * @dev total number of tokens in existence
//   */
//   function totalSupply() public view returns (uint256) {
//     return totalSupply_;
//   }

//   /**
//   * @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) {
//     require(_to != address(0));
//     require(_value <= balances[msg.sender]);

//     balances[msg.sender] = balances[msg.sender].sub(_value);
//     balances[_to] = balances[_to].add(_value);
//     emit 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 view returns (uint256) {
//     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 view 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)) internal 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 amount of tokens to be transferred
//    */
//   function transferFrom(
//     address _from,
//     address _to,
//     uint256 _value
//   )
//     public
//     returns (bool)
//   {
//     require(_to != address(0));
//     require(_value <= balances[_from]);
//     require(_value <= allowed[_from][msg.sender]);

//     balances[_from] = balances[_from].sub(_value);
//     balances[_to] = balances[_to].add(_value);
//     allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
//     emit Transfer(_from, _to, _value);
//     return true;
//   }

//   /**
//    * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
//    *
//    * Beware that changing an allowance with this method brings the risk that someone may use both the old
//    * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
//    * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
//    * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
//    * @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) {
//     allowed[msg.sender][_spender] = _value;
//     emit 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 specifying the amount of tokens still available for the spender.
//    */
//   function allowance(
//     address _owner,
//     address _spender
//    )
//     public
//     view
//     returns (uint256)
//   {
//     return allowed[_owner][_spender];
//   }

//   /**
//    * @dev Increase the amount of tokens that an owner allowed to a spender.
//    *
//    * approve should be called when allowed[_spender] == 0. To increment
//    * allowed value is better to use this function to avoid 2 calls (and wait until
//    * the first transaction is mined)
//    * From MonolithDAO Token.sol
//    * @param _spender The address which will spend the funds.
//    * @param _addedValue The amount of tokens to increase the allowance by.
//    */
//   function increaseApproval(
//     address _spender,
//     uint _addedValue
//   )
//     public
//     returns (bool)
//   {
//     allowed[msg.sender][_spender] = (
//       allowed[msg.sender][_spender].add(_addedValue));
//     emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
//     return true;
//   }

//   /**
//    * @dev Decrease the amount of tokens that an owner allowed to a spender.
//    *
//    * approve should be called when allowed[_spender] == 0. To decrement
//    * allowed value is better to use this function to avoid 2 calls (and wait until
//    * the first transaction is mined)
//    * From MonolithDAO Token.sol
//    * @param _spender The address which will spend the funds.
//    * @param _subtractedValue The amount of tokens to decrease the allowance by.
//    */
//   function decreaseApproval(
//     address _spender,
//     uint _subtractedValue
//   )
//     public
//     returns (bool)
//   {
//     uint oldValue = allowed[msg.sender][_spender];
//     if (_subtractedValue > oldValue) {
//       allowed[msg.sender][_spender] = 0;
//     } else {
//       allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
//     }
//     emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
//     return true;
//   }

// }



// /**
//  * @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;


//   event OwnershipRenounced(address indexed previousOwner);
//   event OwnershipTransferred(
//     address indexed previousOwner,
//     address indexed newOwner
//   );


//   /**
//    * @dev The Ownable constructor sets the original `owner` of the contract to the sender
//    * account.
//    */
//   constructor() 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 relinquish control of the contract.
//    */
//   function renounceOwnership() public onlyOwner {
//     emit OwnershipRenounced(owner);
//     owner = address(0);
//   }

//   /**
//    * @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) public onlyOwner {
//     _transferOwnership(_newOwner);
//   }

//   /**
//    * @dev Transfers control of the contract to a newOwner.
//    * @param _newOwner The address to transfer ownership to.
//    */
//   function _transferOwnership(address _newOwner) internal {
//     require(_newOwner != address(0));
//     emit OwnershipTransferred(owner, _newOwner);
//     owner = _newOwner;
//   }
// }


// /**
//  * @title Mintable token
//  * @dev Simple ERC20 Token example, with mintable token creation
//  * @dev Issue: * https://github.com/OpenZeppelin/openzeppelin-solidity/issues/120
//  * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
//  */
// contract MintableToken is StandardToken, Ownable {
//   event Mint(address indexed to, uint256 amount);
//   event MintFinished();

//   bool public mintingFinished = false;


//   modifier canMint() {
//     require(!mintingFinished);
//     _;
//   }

//   modifier hasMintPermission() {
//     require(msg.sender == owner);
//     _;
//   }

//   /**
//    * @dev Function to mint tokens
//    * @param _to The address that will receive the minted tokens.
//    * @param _amount The amount of tokens to mint.
//    * @return A boolean that indicates if the operation was successful.
//    */
//   function mint(
//     address _to,
//     uint256 _amount
//   )
//     hasMintPermission
//     canMint
//     public
//     returns (bool)
//   {
//     totalSupply_ = totalSupply_.add(_amount);
//     balances[_to] = balances[_to].add(_amount);
//     emit Mint(_to, _amount);
//     emit Transfer(address(0), _to, _amount);
//     return true;
//   }

//   /**
//    * @dev Function to stop minting new tokens.
//    * @return True if the operation was successful.
//    */
//   function finishMinting() onlyOwner canMint public returns (bool) {
//     mintingFinished = true;
//     emit MintFinished();
//     return true;
//   }
// }


// contract FreezableToken is StandardToken {
//     // freezing chains
//     mapping (bytes32 => uint64) internal chains;
//     // freezing amounts for each chain
//     mapping (bytes32 => uint) internal freezings;
//     // total freezing balance per address
//     mapping (address => uint) internal freezingBalance;

//     event Freezed(address indexed to, uint64 release, uint amount);
//     event Released(address indexed owner, uint amount);

//     /**
//      * @dev Gets the balance of the specified address include freezing tokens.
//      * @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 view returns (uint256) {
//         return super.balanceOf(_owner) + freezingBalance[_owner];
//     }

//     /**
//      * @dev Gets the balance of the specified address without freezing tokens.
//      * @param _owner The address to query the the balance of.
//      * @return An uint256 representing the amount owned by the passed address.
//      */
//     function actualBalanceOf(address _owner) public view returns (uint256) {
//         return super.balanceOf(_owner);
//     }

//     function freezingBalanceOf(address _owner) public view returns (uint256) {
//         return freezingBalance[_owner];
//     }

//     /**
//      * @dev gets freezing count
//      * @param _addr Address of freeze tokens owner.
//      */
//     function freezingCount(address _addr) public view returns (uint count) {
//         uint64 release = chains[toKey(_addr, 0)];
//         while (release != 0) {
//             count++;
//             release = chains[toKey(_addr, release)];
//         }
//     }

//     /**
//      * @dev gets freezing end date and freezing balance for the freezing portion specified by index.
//      * @param _addr Address of freeze tokens owner.
//      * @param _index Freezing portion index. It ordered by release date descending.
//      */
//     function getFreezing(address _addr, uint _index) public view returns (uint64 _release, uint _balance) {
//         for (uint i = 0; i < _index + 1; i++) {
//             _release = chains[toKey(_addr, _release)];
//             if (_release == 0) {
//                 return;
//             }
//         }
//         _balance = freezings[toKey(_addr, _release)];
//     }

//     /**
//      * @dev freeze your tokens to the specified address.
//      *      Be careful, gas usage is not deterministic,
//      *      and depends on how many freezes _to address already has.
//      * @param _to Address to which token will be freeze.
//      * @param _amount Amount of token to freeze.
//      * @param _until Release date, must be in future.
//      */
//     function freezeTo(address _to, uint _amount, uint64 _until) public {
//         require(_to != address(0));
//         require(_amount <= balances[msg.sender]);

//         balances[msg.sender] = balances[msg.sender].sub(_amount);

//         bytes32 currentKey = toKey(_to, _until);
//         freezings[currentKey] = freezings[currentKey].add(_amount);
//         freezingBalance[_to] = freezingBalance[_to].add(_amount);

//         freeze(_to, _until);
//         emit Transfer(msg.sender, _to, _amount);
//         emit Freezed(_to, _until, _amount);
//     }

//     /**
//      * @dev release first available freezing tokens.
//      */
//     function releaseOnce() public {
//         bytes32 headKey = toKey(msg.sender, 0);
//         uint64 head = chains[headKey];
//         require(head != 0);
//         require(uint64(block.timestamp) > head);
//         bytes32 currentKey = toKey(msg.sender, head);

//         uint64 next = chains[currentKey];

//         uint amount = freezings[currentKey];
//         delete freezings[currentKey];

//         balances[msg.sender] = balances[msg.sender].add(amount);
//         freezingBalance[msg.sender] = freezingBalance[msg.sender].sub(amount);

//         if (next == 0) {
//             delete chains[headKey];
//         } else {
//             chains[headKey] = next;
//             delete chains[currentKey];
//         }
//         emit Released(msg.sender, amount);
//     }

//     /**
//      * @dev release all available for release freezing tokens. Gas usage is not deterministic!
//      * @return tokens How many tokens was released
//      */
//     function releaseAll() public returns (uint tokens) {
//         uint release;
//         uint balance;
//         (release, balance) = getFreezing(msg.sender, 0);
//         while (release != 0 && block.timestamp > release) {
//             releaseOnce();
//             tokens += balance;
//             (release, balance) = getFreezing(msg.sender, 0);
//         }
//     }

//     function toKey(address _addr, uint _release) internal pure returns (bytes32 result) {
//         // WISH masc to increase entropy
//         result = 0x5749534800000000000000000000000000000000000000000000000000000000;
//         assembly {
//             result := or(result, mul(_addr, 0x10000000000000000))
//             result := or(result, _release)
//         }
//     }

//     function freeze(address _to, uint64 _until) internal {
//         require(_until > block.timestamp);
//         bytes32 key = toKey(_to, _until);
//         bytes32 parentKey = toKey(_to, uint64(0));
//         uint64 next = chains[parentKey];

//         if (next == 0) {
//             chains[parentKey] = _until;
//             return;
//         }

//         bytes32 nextKey = toKey(_to, next);
//         uint parent;

//         while (next != 0 && _until > next) {
//             parent = next;
//             parentKey = nextKey;

//             next = chains[nextKey];
//             nextKey = toKey(_to, next);
//         }

//         if (_until == next) {
//             return;
//         }

//         if (next != 0) {
//             chains[key] = next;
//         }

//         chains[parentKey] = _until;
//     }
// }


// /**
//  * @title Burnable Token
//  * @dev Token that can be irreversibly burned (destroyed).
//  */
// contract BurnableToken is BasicToken {

//   event Burn(address indexed burner, uint256 value);

//   /**
//    * @dev Burns a specific amount of tokens.
//    * @param _value The amount of token to be burned.
//    */
//   function burn(uint256 _value) public {
//     _burn(msg.sender, _value);
//   }

//   function _burn(address _who, uint256 _value) internal {
//     require(_value <= balances[_who]);
//     // no need to require value <= totalSupply, since that would imply the
//     // sender's balance is greater than the totalSupply, which *should* be an assertion failure

//     balances[_who] = balances[_who].sub(_value);
//     totalSupply_ = totalSupply_.sub(_value);
//     emit Burn(_who, _value);
//     emit Transfer(_who, address(0), _value);
//   }
// }



// /**
//  * @title Pausable
//  * @dev Base contract which allows children to implement an emergency stop mechanism.
//  */
// contract Pausable is Ownable {
//   event Pause();
//   event Unpause();

//   bool public paused = false;


//   /**
//    * @dev Modifier to make a function callable only when the contract is not paused.
//    */
//   modifier whenNotPaused() {
//     require(!paused);
//     _;
//   }

//   /**
//    * @dev Modifier to make a function callable only when the contract is paused.
//    */
//   modifier whenPaused() {
//     require(paused);
//     _;
//   }

//   /**
//    * @dev called by the owner to pause, triggers stopped state
//    */
//   function pause() onlyOwner whenNotPaused public {
//     paused = true;
//     emit Pause();
//   }

//   /**
//    * @dev called by the owner to unpause, returns to normal state
//    */
//   function unpause() onlyOwner whenPaused public {
//     paused = false;
//     emit Unpause();
//   }
// }


// contract FreezableMintableToken is FreezableToken, MintableToken {
//     /**
//      * @dev Mint the specified amount of token to the specified address and freeze it until the specified date.
//      *      Be careful, gas usage is not deterministic,
//      *      and depends on how many freezes _to address already has.
//      * @param _to Address to which token will be freeze.
//      * @param _amount Amount of token to mint and freeze.
//      * @param _until Release date, must be in future.
//      * @return A boolean that indicates if the operation was successful.
//      */
//     function mintAndFreeze(address _to, uint _amount, uint64 _until) public onlyOwner canMint returns (bool) {
//         totalSupply_ = totalSupply_.add(_amount);

//         bytes32 currentKey = toKey(_to, _until);
//         freezings[currentKey] = freezings[currentKey].add(_amount);
//         freezingBalance[_to] = freezingBalance[_to].add(_amount);

//         freeze(_to, _until);
//         emit Mint(_to, _amount);
//         emit Freezed(_to, _until, _amount);
//         emit Transfer(msg.sender, _to, _amount);
//         return true;
//     }
// }



// contract Consts {
//     uint public constant TOKEN_DECIMALS = 18;
//     uint8 public constant TOKEN_DECIMALS_UINT8 = 18;
//     uint public constant TOKEN_DECIMAL_MULTIPLIER = 10 ** TOKEN_DECIMALS;

//     string public constant TOKEN_NAME = "Offshift";
//     string public constant TOKEN_SYMBOL = "XFT";
//     bool public constant PAUSED = false;
//     address public constant TARGET_USER = 0x7f3B46E1E7d0E60fE496C41e8f0D21d7e962D37d;
    
//     bool public constant CONTINUE_MINTING = false;
// }




// contract MainToken is Consts, FreezableMintableToken, BurnableToken, Pausable
    
// {
    
//     event Initialized();
//     bool public initialized = false;

//     constructor() public {
//         init();
//         transferOwnership(TARGET_USER);
//     }
    

//     function name() public pure returns (string memory _name) {
//         return TOKEN_NAME;
//     }

//     function symbol() public pure returns (string memory _symbol) {
//         return TOKEN_SYMBOL;
//     }

//     function decimals() public pure returns (uint8 _decimals) {
//         return TOKEN_DECIMALS_UINT8;
//     }

//     function transferFrom(address _from, address _to, uint256 _value) public returns (bool _success) {
//         require(!paused);
//         return super.transferFrom(_from, _to, _value);
//     }

//     function transfer(address _to, uint256 _value) public returns (bool _success) {
//         require(!paused);
//         return super.transfer(_to, _value);
//     }

    
//     function init() private {
//         require(!initialized);
//         initialized = true;

//         if (PAUSED) {
//             pause();
//         }

        
//         address[1] memory addresses = [address(0x7f3b46e1e7d0e60fe496c41e8f0d21d7e962d37d)];
//         uint[1] memory amounts = [uint(10000000000000000000000000)];
//         uint64[1] memory freezes = [uint64(0)];

//         for (uint i = 0; i < addresses.length; i++) {
//             if (freezes[i] == 0) {
//                 mint(addresses[i], amounts[i]);
//             } else {
//                 mintAndFreeze(addresses[i], amounts[i], freezes[i]);
//             }
//         }
        

//         if (!CONTINUE_MINTING) {
//             finishMinting();
//         }

//         emit Initialized();
//     }
    
// }