contract PayFair is SafeMath, ERC223, Ownable {
 string public name = "PayFair Token";
 string public symbol = "PFR";
 uint public constant decimals = 8;
 uint public constant FROZEN_TOKENS = 11109031;
 uint public constant MULTIPLIER = 10 ** decimals;
 ERC223 public oldToken;
 
 /// approve() allowances
 mapping (address => mapping (address => uint)) allowed;
 /// holder balances
 mapping(address => uint) balances;
 
 /// @dev Fix for the ERC20 short address attack http://vessenes.com/the-erc20-short-address-attack-explained/
 /// @param size payload size
 modifier onlyPayloadSize(uint size) {
    require(msg.data.length >= size + 4);
    _;
 }

 /// @dev Constructor
 constructor (address oldTokenAdddress) public {   
   oldToken = ERC223(oldTokenAdddress);
   
   totalSupply = convertToDecimal(FROZEN_TOKENS);
   balances[owner] = convertToDecimal(FROZEN_TOKENS);
 }

 /// Fallback method will buyout tokens
 function() external payable {
   revert();
 }

 function upgradeTokens(uint amountToUpgrade) public {  
    require(amountToUpgrade <= oldToken.balanceOf(msg.sender));
    require(amountToUpgrade <= oldToken.allowance(msg.sender, address(this)));   
    
    emit Transfer(address(0), msg.sender, amountToUpgrade);
    totalSupply = safeAdd(totalSupply, amountToUpgrade);
    balances[msg.sender] = safeAdd(balances[msg.sender], amountToUpgrade);
    oldToken.transferFrom(msg.sender, address(0x0), amountToUpgrade);
 }

 /// @dev Converts token value to value with decimal places
 /// @param amount Source token value
 function convertToDecimal(uint amount) private pure returns (uint) {
   return safeMul(amount, MULTIPLIER);
 }

 /// @dev Tranfer tokens to address
 /// @param _to dest address
 /// @param _value tokens amount
 /// @return transfer result
 function transfer(address _to, uint _value) public returns (bool success) {
   bytes memory empty;
   return transfer(_to, _value, empty);
 }

 /// @dev Tranfer tokens from one address to other
 /// @param _from source address
 /// @param _to dest address
 /// @param _value tokens amount
 /// @return transfer result
 function transferFrom(address _from, address _to, uint _value) public returns (bool success) {
    bytes memory empty;
    return transferFrom(_from, _to, _value, empty);
 }
 
 /// @dev Tranfer tokens to address
 /// @param _to dest address
 /// @param _value tokens amount
 /// @param _data data
 /// @return transfer result
 function transfer(address _to, uint _value, bytes memory _data) public onlyPayloadSize(2 * 32) returns (bool success) {
   balances[msg.sender] = safeSub(balances[msg.sender], _value);
   balances[_to] = safeAdd(balances[_to], _value);
   
   if (isContract(_to)) return contractFallback(msg.sender, _to, _value, _data);
   emit Transfer(msg.sender, _to, _value);
   return true;
 }

 /// @dev Tranfer tokens from one address to other
 /// @param _from source address
 /// @param _to dest address
 /// @param _value tokens amount
 /// @param _data data
 /// @return transfer result
 function transferFrom(address _from, address _to, uint _value, bytes memory _data) public onlyPayloadSize(2 * 32) returns (bool success) {
    uint256 _allowance = allowed[_from][msg.sender];

    balances[_to] = safeAdd(balances[_to], _value);
    balances[_from] = safeSub(balances[_from], _value);
    allowed[_from][msg.sender] = safeSub(_allowance, _value);
    
    if (isContract(_to)) return contractFallback(msg.sender, _to, _value, _data);
    emit Transfer(_from, _to, _value);
    return true;
 }
 /// @dev Tokens balance
 /// @param _owner holder address
 /// @return balance amount
 function balanceOf(address _owner) public view returns (uint balance) {
   return balances[_owner];
 }

 /// @dev Approve transfer
 /// @param _spender holder address
 /// @param _value tokens amount
 /// @return result
 function approve(address _spender, uint _value) public returns (bool success) {
   // 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;
   emit Approval(msg.sender, _spender, _value);
   return true;
 }

 /// @dev Token allowance
 /// @param _owner holder address
 /// @param _spender spender address
 /// @return remain amount
 function allowance(address _owner, address _spender) public view returns (uint remaining) {
   return allowed[_owner][_spender];
 }
 
 /// @dev Called when transaction target is a contract
 /// @param _origin holder origin address
 /// @param _to address
 /// @param _value value
 /// @param _data data
 /// @return success result
 function contractFallback(address _origin, address _to, uint _value, bytes memory _data) private returns (bool success) {
    ERC223Receiver reciever = ERC223Receiver(_to);
    return reciever.tokenFallback(msg.sender, _origin, _value, _data);
 }
  
 /// @dev Assemble the given address bytecode. If bytecode exists then the _addr is a contract.
 /// @param _addr address
 /// @return is_contract result
 function isContract(address _addr) private returns (bool is_contract) {
   // retrieve the size of the code on target address, this needs assembly
    uint length;
    assembly { length := extcodesize(_addr) }
    return length > 0;
 }
}
/// @title PayFair contract - standard ERC20 token with Short Hand Attack and approve() race condition mitigation.
function allowance(address _owner, address _spender) public view returns (uint remaining) {
  return allowed[_owner][_spender];
}

/// @dev Token allowance
/// @param _owner holder address
/// @param _spender spender address
/// @return remain amount