{
  "language": "Solidity",
  "sources": {
    "src/common/helpers/BalancesHelper.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../token/ERC20Token.sol\";\nimport \"../libs/SafeMathLib.sol\";\n\n\n/**\n * @title Balances helper\n *\n * @author Jegor Sidorenko <jegor@pillarproject.io>\n * @author Stanisław Głogowski <stan@pillarproject.io>\n */\ncontract BalancesHelper {\n  using SafeMathLib for uint256;\n\n  // external functions\n\n  /**\n   * @notice Checks the token balances of accounts for multiple tokens.\n   * @dev Pass 0x0 as a \"token\" address to get ETH balance.\n   *\n   * Possible error throws:\n   * - extremely large arrays for account and or tokens (gas cost too high)\n   *\n   * @param accounts array of accounts addresses\n   * @param tokens array of tokens addresses\n   * @return a one-dimensional that's user.length * tokens.length long. The\n   * array is ordered by all of the 0th accounts token balances, then the 1th\n   * user, and so on.\n   */\n  function getBalances(\n    address[] calldata accounts,\n    address[] calldata tokens\n  )\n    external\n    view\n    returns (uint[] memory)\n  {\n    uint[] memory result = new uint[](accounts.length.mul(tokens.length));\n\n    for (uint i = 0; i < accounts.length; i++) {\n      for (uint j = 0; j < tokens.length; j++) {\n        uint index = j.add(tokens.length.mul(i));\n\n        if (tokens[j] != address(0x0)) {\n          result[index] = _getBalance(accounts[i], tokens[j]);\n        } else {\n          result[index] = accounts[i].balance;\n        }\n      }\n    }\n\n    return result;\n  }\n\n  // private functions\n\n  function _getBalance(\n    address account,\n    address token\n  )\n    private\n    view\n    returns (uint256)\n  {\n    uint256 result = 0;\n    uint256 tokenCode;\n\n    /// @dev check if token is actually a contract\n    // solhint-disable-next-line no-inline-assembly\n    assembly { tokenCode := extcodesize(token) } // contract code size\n\n    if (tokenCode > 0) {\n      /// @dev is it a contract and does it implement balanceOf\n      // solhint-disable-next-line avoid-low-level-calls\n      (bool methodExists,) = token.staticcall(abi.encodeWithSelector(\n        ERC20Token(token).balanceOf.selector,\n        account\n      ));\n\n      if (methodExists) {\n        result = ERC20Token(token).balanceOf(account);\n      }\n    }\n\n    return result;\n  }\n}\n"
    },
    "src/common/token/ERC20Token.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\nimport \"../libs/SafeMathLib.sol\";\n\n\n/**\n * @title ERC20 token\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol\n */\ncontract ERC20Token {\n  using SafeMathLib for uint256;\n\n  string public name;\n  string public symbol;\n  uint8 public decimals;\n  uint256 public totalSupply;\n\n  mapping(address => uint256) internal balances;\n  mapping(address => mapping(address => uint256)) internal allowances;\n\n  // events\n\n  event Transfer(\n    address indexed from,\n    address indexed to,\n    uint256 value\n  );\n\n  event Approval(\n    address indexed owner,\n    address indexed spender,\n    uint256 value\n  );\n\n  /**\n   * @dev internal constructor\n   */\n  constructor() internal {}\n\n  // external functions\n\n  function transfer(\n    address to,\n    uint256 value\n  )\n    external\n    returns (bool)\n  {\n    _transfer(_getSender(), to, value);\n\n    return true;\n  }\n\n  function transferFrom(\n    address from,\n    address to,\n    uint256 value\n  )\n    virtual\n    external\n    returns (bool)\n  {\n    address sender = _getSender();\n\n    _transfer(from, to, value);\n    _approve(from, sender, allowances[from][sender].sub(value));\n\n    return true;\n  }\n\n  function approve(\n    address spender,\n    uint256 value\n  )\n    virtual\n    external\n    returns (bool)\n  {\n    _approve(_getSender(), spender, value);\n\n    return true;\n  }\n\n  // external functions (views)\n\n  function balanceOf(\n    address owner\n  )\n    virtual\n    external\n    view\n    returns (uint256)\n  {\n    return balances[owner];\n  }\n\n  function allowance(\n    address owner,\n    address spender\n  )\n    virtual\n    external\n    view\n    returns (uint256)\n  {\n    return allowances[owner][spender];\n  }\n\n  // internal functions\n\n  function _transfer(\n    address from,\n    address to,\n    uint256 value\n  )\n    virtual\n    internal\n  {\n    require(\n      from != address(0),\n      \"ERC20Token: cannot transfer from 0x0 address\"\n    );\n    require(\n      to != address(0),\n      \"ERC20Token: cannot transfer to 0x0 address\"\n    );\n\n    balances[from] = balances[from].sub(value);\n    balances[to] = balances[to].add(value);\n\n    emit Transfer(from, to, value);\n  }\n\n  function _approve(\n    address owner,\n    address spender,\n    uint256 value\n  )\n    virtual\n    internal\n  {\n    require(\n      owner != address(0),\n      \"ERC20Token: cannot approve from 0x0 address\"\n    );\n    require(\n      spender != address(0),\n      \"ERC20Token: cannot approve to 0x0 address\"\n    );\n\n    allowances[owner][spender] = value;\n\n    emit Approval(owner, spender, value);\n  }\n\n  function _mint(\n    address owner,\n    uint256 value\n  )\n    virtual\n    internal\n  {\n    require(\n      owner != address(0),\n      \"ERC20Token: cannot mint to 0x0 address\"\n    );\n    require(\n      value > 0,\n      \"ERC20Token: cannot mint 0 value\"\n    );\n\n    balances[owner] = balances[owner].add(value);\n    totalSupply = totalSupply.add(value);\n\n    emit Transfer(address(0), owner, value);\n  }\n\n  function _burn(\n    address owner,\n    uint256 value\n  )\n    virtual\n    internal\n  {\n    require(\n      owner != address(0),\n      \"ERC20Token: cannot burn from 0x0 address\"\n    );\n\n    balances[owner] = balances[owner].sub(\n      value,\n      \"ERC20Token: burn value exceeds balance\"\n    );\n\n    totalSupply = totalSupply.sub(value);\n\n    emit Transfer(owner, address(0), value);\n  }\n\n  // internal functions (views)\n\n  function _getSender()\n    virtual\n    internal\n    view\n    returns (address)\n  {\n    return msg.sender;\n  }\n}\n"
    },
    "src/common/libs/SafeMathLib.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.12;\n\n/**\n * @title Safe math library\n *\n * @dev Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol\n */\nlibrary SafeMathLib {\n  function add(uint256 a, uint256 b) internal pure returns (uint256) {\n    uint256 c = a + b;\n\n    require(c >= a, \"SafeMathLib: addition overflow\");\n\n    return c;\n  }\n\n  function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n    return sub(a, b, \"SafeMathLib: subtraction overflow\");\n  }\n\n  function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b <= a, errorMessage);\n\n    return a - b;\n  }\n\n  function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a == 0) {\n      return 0;\n    }\n\n    uint256 c = a * b;\n\n    require(c / a == b, \"SafeMathLib: multiplication overflow\");\n\n    return c;\n  }\n\n  function div(uint256 a, uint256 b) internal pure returns (uint256) {\n    return div(a, b, \"SafeMathLib: division by zero\");\n  }\n\n  function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b > 0, errorMessage);\n\n    return a / b;\n  }\n\n  function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n    return mod(a, b, \"SafeMathLib: modulo by zero\");\n  }\n\n  function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b != 0, errorMessage);\n\n    return a % b;\n  }\n}\n"
    }
  },
  "settings": {
    "evmVersion": "istanbul",
    "metadata": {
      "bytecodeHash": "none",
      "useLiteralContent": true
    },
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    }
  }
}