contract IXTPaymentContract is Ownable, EmergencySafe, Upgradeable{

  event IXTPayment(address indexed from, address indexed to, uint value, string indexed action);

  ERC20Interface public tokenContract;

  mapping(string => uint) private actionPrices;
  mapping(address => bool) private allowed;

  /**
   * @dev Throws if called by non-allowed contract
   */
  modifier allowedOnly() {
    require(allowed[msg.sender] || msg.sender == owner);
    _;
  }

  /**
   * @dev sets up token address of IXT token
   * adds owner to allowds, if owner is changed in the future, remember to remove old
   * owner if desired
   * @param tokenAddress IXT token address
   */
  function IXTPaymentContract(address tokenAddress) public {
    tokenContract = ERC20Interface(tokenAddress);
    allowed[owner] = true;
  }

  /**
   * @dev transfers IXT 
   * @param from User address
   * @param to Recipient
   * @param action Service the user is paying for 
   */
  function transferIXT(address from, address to, string action) public allowedOnly isNotPaused returns (bool) {
    if (isOldVersion) {
      IXTPaymentContract newContract = IXTPaymentContract(nextContract);
      return newContract.transferIXT(from, to, action);
    } else {
      uint price = actionPrices[action];

      if(price != 0 && !tokenContract.transferFrom(from, to, price)){
        return false;
      } else {
        emit IXTPayment(from, to, price, action);     
        return true;
      }
    }
  }

  /**
   * @dev sets new token address in case of update
   * @param erc20Token Token address
   */
  function setTokenAddress(address erc20Token) public ownerOnly isNotPaused {
    tokenContract = ERC20Interface(erc20Token);
  }

  /**
   * @dev creates/updates action
   * @param action Action to be paid for 
   * @param price Price (in units * 10 ^ (<decimal places of token>))
   */
  function setAction(string action, uint price) public ownerOnly isNotPaused {
    actionPrices[action] = price;
  }

  /**
   * @dev retrieves price for action
   * @param action Name of action, e.g. 'create_insurance_contract'
   */
  function getActionPrice(string action) public view returns (uint) {
    return actionPrices[action];
  }


  /**
   * @dev add account to allow calling of transferIXT
   * @param allowedAddress Address of account 
   */
  function setAllowed(address allowedAddress) public ownerOnly {
    allowed[allowedAddress] = true;
  }

  /**
   * @dev remove account from allowed accounts
   * @param allowedAddress Address of account 
   */
  function removeAllowed(address allowedAddress) public ownerOnly {
    allowed[allowedAddress] = false;
  }
}
/**
 * @title IXT payment contract in charge of administaring IXT payments 
 * @dev contract looks up price for appropriate tasks and sends transferFrom() for user,
 * user must approve this contract to spend IXT for them before being able to use it
 */
function transferIXT(address from, address to, string action) public allowedOnly isNotPaused returns (bool) {
    if (isOldVersion) {
      IXTPaymentContract newContract = IXTPaymentContract(nextContract);
      return newContract.transferIXT(from, to, action);
    } else {
      uint price = actionPrices[action];

      if(price != 0 && !tokenContract.transferFrom(from, to, price)){
        return false;
      } else {
        emit IXTPayment(from, to, price, action);     
        return true;
      }
    }
  }
/**
 * @dev transfers IXT 
 * @param from User address
 * @param to Recipient
 * @param action Service the user is paying for 
 */