UNPKG

@etherspot/contracts

Version:

Etherspot Solidity contracts

43 lines 8.52 kB
{ "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" ] } } } }