contract Requestable {
  using RequestHelper for Types.Request;

  mapping(address => uint) nonces;

  function validateRequest(Types.Request memory request) internal {
    require(request.target == address(this), "INVALID_TARGET");
    require(request.getSigner() == request.owner, "INVALID_SIGNATURE");
    require(nonces[request.owner] + 1 == request.nonce, "INVALID_NONCE");
    
    if (request.fee.feeAmount > 0) {
      require(balanceOf(request.owner, request.fee.feeToken) >= request.fee.feeAmount, "INSUFFICIENT_FEE_BALANCE");
    }

    nonces[request.owner] += 1;
  }

  function completeRequest(Types.Request memory request) internal {
    if (request.fee.feeAmount > 0) {
      _payRequestFee(request.owner, request.fee.feeToken, request.fee.feeRecipient, request.fee.feeAmount);
    }
  }

  function nonceOf(address owner) public view returns (uint) {
    return nonces[owner];
  }

  // Abtract functions
  function balanceOf(address owner, address token) public view returns (uint);
  function _payRequestFee(address owner, address feeToken, address feeRecipient, uint feeAmount) internal;
}
/**
 * @title Requestable
 *
 * Enables contracts to easily accept signed requests and verify
 * their signer. Employs a nonce-pattern where requests must contain
 * a nonce (specific to their owner) that is one above the last nonce.
 * This can be verified by calling `validateRequest` at the start of a function
 *
 * Requests contain fee information (feeRecipient, feeToken & feeAmount)
 * which will be paid upon calling `completeRequest`. In order for this to
 * be possible, abstract functions `balanceOf` and `_payRequestFee` must
 * be implemented
 */
function balanceOf(address owner, address token) public view returns (uint);

// Abtract functions