{
  "address": "0xa6C165E3539A2bE6d55e2935EC9979D8C850A21b",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address[]",
          "name": "accounts",
          "type": "address[]"
        },
        {
          "internalType": "address[]",
          "name": "tokens",
          "type": "address[]"
        }
      ],
      "name": "getBalances",
      "outputs": [
        {
          "internalType": "uint256[]",
          "name": "",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0xf2e7114faf41eb9d50b18e3c9e7337830f04fa26b6103062e87efda0d306fb02",
  "receipt": {
    "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
    "from": "0x09FD4F6088f2025427AB1e89257A44747081Ed59",
    "contractAddress": null,
    "transactionIndex": 80,
    "gasUsed": "420418",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xb3af837d4dee68daf03ac65594b3e074bd57f7177b840bbb33b1886f96686e6c",
    "transactionHash": "0xf2e7114faf41eb9d50b18e3c9e7337830f04fa26b6103062e87efda0d306fb02",
    "logs": [],
    "blockNumber": 11922086,
    "cumulativeGasUsed": "3975679",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "553eed465bd8155b17258758c560dc9d",
  "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getBalances\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Jegor Sidorenko <jegor@pillarproject.io>Stanis\\u0142aw G\\u0142ogowski <stan@pillarproject.io>\",\"kind\":\"dev\",\"methods\":{\"getBalances(address[],address[])\":{\"details\":\"Pass 0x0 as a \\\"token\\\" address to get ETH balance. Possible error throws: - extremely large arrays for account and or tokens (gas cost too high)\",\"params\":{\"accounts\":\"array of accounts addresses\",\"tokens\":\"array of tokens addresses\"},\"returns\":{\"_0\":\"a one-dimensional that's user.length * tokens.length long. The array is ordered by all of the 0th accounts token balances, then the 1th user, and so on.\"}}},\"title\":\"Balances helper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getBalances(address[],address[])\":{\"notice\":\"Checks the token balances of accounts for multiple tokens.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/common/helpers/BalancesHelper.sol\":\"BalancesHelper\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"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\\u0142aw G\\u0142ogowski <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\",\"keccak256\":\"0x76a5729807b8581731967ea74fc5e16a2c5c9067457c9059da97f089ffff68b9\",\"license\":\"MIT\"},\"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\",\"keccak256\":\"0x6089f354ca754d9c5dd9e800ee5ed86717dbf8f9af470604e0be691ac57c0107\",\"license\":\"MIT\"},\"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\",\"keccak256\":\"0x6f2b0bd08da549c6c1f5ceee85766832d587dde62c56bebc3a14bd9ea407e03d\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b506106a2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ef5bfc3714610030575b600080fd5b6100fc6004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184602083028401116401000000008311171561009757600080fd5b9091929391929390803590602001906401000000008111156100b857600080fd5b8201836020820111156100ca57600080fd5b803590602001918460208302840111640100000000831117156100ec57600080fd5b9091929391929390505050610153565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b60608061016f848490508787905061035490919063ffffffff16565b67ffffffffffffffff8111801561018557600080fd5b506040519080825280602002602001820160405280156101b45781602001602082028036833780820191505090505b50905060005b868690508110156103475760005b858590508110156103395760006101fd6101ee848989905061035490919063ffffffff16565b836103da90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff1687878481811061022357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146102d2576102b589898581811061026a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1688888581811061029357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610462565b8482815181106102c157fe5b60200260200101818152505061032b565b8888848181106102de57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163184828151811061031e57fe5b6020026020010181815250505b5080806001019150506101c8565b5080806001019150506101ba565b5080915050949350505050565b60008083141561036757600090506103d4565b600082840290508284828161037857fe5b04146103cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806106726024913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015610458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600080600090506000833b905060008111156106665760008473ffffffffffffffffffffffffffffffffffffffff166370a0823160e01b87604051602401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610550578051825260208201915060208101905060208303925061052d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146105b0576040519150601f19603f3d011682016040523d82523d6000602084013e6105b5565b606091505b505090508015610664578473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561062657600080fd5b505afa15801561063a573d6000803e3d6000fd5b505050506040513d602081101561065057600080fd5b810190808051906020019092919050505092505b505b81925050509291505056fe536166654d6174684c69623a206d756c7469706c69636174696f6e206f766572666c6f77a164736f6c634300060c000a",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ef5bfc3714610030575b600080fd5b6100fc6004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184602083028401116401000000008311171561009757600080fd5b9091929391929390803590602001906401000000008111156100b857600080fd5b8201836020820111156100ca57600080fd5b803590602001918460208302840111640100000000831117156100ec57600080fd5b9091929391929390505050610153565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013f578082015181840152602081019050610124565b505050509050019250505060405180910390f35b60608061016f848490508787905061035490919063ffffffff16565b67ffffffffffffffff8111801561018557600080fd5b506040519080825280602002602001820160405280156101b45781602001602082028036833780820191505090505b50905060005b868690508110156103475760005b858590508110156103395760006101fd6101ee848989905061035490919063ffffffff16565b836103da90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff1687878481811061022357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146102d2576102b589898581811061026a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1688888581811061029357fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16610462565b8482815181106102c157fe5b60200260200101818152505061032b565b8888848181106102de57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163184828151811061031e57fe5b6020026020010181815250505b5080806001019150506101c8565b5080806001019150506101ba565b5080915050949350505050565b60008083141561036757600090506103d4565b600082840290508284828161037857fe5b04146103cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806106726024913960400191505060405180910390fd5b809150505b92915050565b600080828401905083811015610458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174684c69623a206164646974696f6e206f766572666c6f77000081525060200191505060405180910390fd5b8091505092915050565b600080600090506000833b905060008111156106665760008473ffffffffffffffffffffffffffffffffffffffff166370a0823160e01b87604051602401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610550578051825260208201915060208101905060208303925061052d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146105b0576040519150601f19603f3d011682016040523d82523d6000602084013e6105b5565b606091505b505090508015610664578473ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561062657600080fd5b505afa15801561063a573d6000803e3d6000fd5b505050506040513d602081101561065057600080fd5b810190808051906020019092919050505092505b505b81925050509291505056fe536166654d6174684c69623a206d756c7469706c69636174696f6e206f766572666c6f77a164736f6c634300060c000a",
  "devdoc": {
    "author": "Jegor Sidorenko <jegor@pillarproject.io>Stanisław Głogowski <stan@pillarproject.io>",
    "kind": "dev",
    "methods": {
      "getBalances(address[],address[])": {
        "details": "Pass 0x0 as a \"token\" address to get ETH balance. Possible error throws: - extremely large arrays for account and or tokens (gas cost too high)",
        "params": {
          "accounts": "array of accounts addresses",
          "tokens": "array of tokens addresses"
        },
        "returns": {
          "_0": "a one-dimensional that's user.length * tokens.length long. The array is ordered by all of the 0th accounts token balances, then the 1th user, and so on."
        }
      }
    },
    "title": "Balances helper",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "getBalances(address[],address[])": {
        "notice": "Checks the token balances of accounts for multiple tokens."
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}
