Contract 0x15205e92ce6e14ca2d720fe0f931d06def32a87d

 

Contract Overview

Balance:
0 BNB

BNB Value:
$0.00

Token:
Txn Hash
Block
From
To
Value [Txn Fee]
0xe66d0b0d99de14c695dc35f3d70a4f8a3717046b5e6093666382038a919c6afc96816462021-08-02 8:35:1011 hrs 25 mins ago0xab9aff41c68247d1214a60f638140530710eb3ad IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00212491
0x059c8951e3160b8d48dcb518ddfbd849bc3042b47946685f6705059df20e9c5196761392021-08-02 3:54:1516 hrs 6 mins ago0xaca121a0e508855cee592d13f4807769428e742b IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00215791
0x9b42f87d6bf2c0175d447f955101ab1c14a565433698de952a65de959f5a29ba96717042021-08-02 0:06:1619 hrs 54 mins ago0x5ca1f73cbbb477d3e91266dadb9a8c1379e439ef IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002359135
0x0529d9328c7877e88fce02595bbe0a486c3bf44cd6636f4b220b446e10b2935a96629962021-08-01 16:38:201 day 3 hrs ago0x62e185b1c13728d9802380d8518762b9a2ae4227 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002122135
0x2f0492dbaa569b64704ef3afa283a0aaaaf3c7823c73864f7c07770cba4b2c8b95949512021-07-30 6:23:313 days 13 hrs ago0xa26233e82b32002db78d58f72ad30dd9b1bc0bfc IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002005075
0x3386f90d696c431c6ca73eb3beb61c0323976af2834aca68b74219514948b1a195924402021-07-30 4:16:433 days 15 hrs ago0x77eaf2ca7cfe62390f18adcf169b274e6d9bec16 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002355335
0xbd1a9d0784ee25f37c2ad368359b9db747b93245a862c9e4ae9ecd6f4f2d037c95922462021-07-30 4:06:433 days 15 hrs ago0x3a678a763ccae90a459db03a93ca37bddb0a527b IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00202511
0x0ef09247d4a7aa85c116d3dcc55672340b44abebc995a851d0409df47dc23ac295902432021-07-30 2:22:513 days 17 hrs ago0x000fe4cd429c6655528b5a73f317239358441c43 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.001932265
0x6923157bcff1a6269dfd4470927f25ad25aabf3e8557cf252d21cfb06e3dc26695457332021-07-28 10:40:185 days 9 hrs ago0xbb1129ab715efb1e869ccb9a6a9ad643488d232f IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002155535
0xabc78818860dc3ec1b9dbe02cc0c5c8e4d33bef2cd737981bb9611efd68231f795448072021-07-28 9:51:525 days 10 hrs ago0x5f346b8a6116ab2724f09bbcf66c2c9ef3cf33f3 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00213731
0xd10876124a6629f44f88b3663731436ced4aa6f57030ccf6f1162b1b4dfed09d95169272021-07-27 8:17:436 days 11 hrs ago0xfe6e83c927941010c63df65aa7fa33c897b1092c IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002134535
0xf9164f00297a7c5a59cc22e8257ba2da3934f82156acce8c6ced6912d8b3a3ee95065422021-07-26 23:27:426 days 20 hrs ago0x18ba8c033bd9d535f3ddd15f85ae3e1ae4c2ae22 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00110924
0x1967ed88f178c391cb1b4ece036e77609768561c708832bbe04f5b974f9e9cb095064242021-07-26 23:21:486 days 20 hrs ago0x18ba8c033bd9d535f3ddd15f85ae3e1ae4c2ae22 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.000149785
0x62802dc5462d10ffeddc9e719e9900275f0a18222806851d1a0acea4524cd95994925592021-07-26 11:26:207 days 8 hrs ago0x1ed8448e0d2ce83a3635773e06b90ba422004ad7 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002359475
0x2b7f52092ccbda9c158d0031fbca2931b648ac56924500cd8122cd48920782fc94810172021-07-26 1:36:527 days 18 hrs ago0x7084015fecde023937d2012717ff93f92d5658b6 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002155535
0x61318318758db4d26fec9c9e381c8bee2c4533e1f722fb091ddb99e8d648bfbe94602922021-07-25 8:06:378 days 11 hrs ago0x000fe4cd429c6655528b5a73f317239358441c43 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002080475
0x3b8231544002db6190a9a0ce406528cfdec87e25c18f0f8cc4721bca071b847f94041502021-07-23 8:59:0810 days 11 hrs ago0xcc0fde5161f44c5c0b9b6633c63b2818b6dca18f IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00206231
0x756c0c77d7aeb5fdfbacbfbd8072695e6ed8e3a989189c1d477785a30973a9a894010052021-07-23 6:21:5210 days 13 hrs ago0xa26233e82b32002db78d58f72ad30dd9b1bc0bfc IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002350875
0xb639f1db166d100418ee4a57bf5ceebecbf1c5a19edce541d81f1a229f1240e793964032021-07-23 2:31:4210 days 17 hrs ago0x000fe4cd429c6655528b5a73f317239358441c43 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.002263875
0x07d01c6cc71e2c1fc821b8677161049b235b68cdc113a1c69bc5f7dcbe7da8d492815012021-07-19 2:43:1514 days 17 hrs ago0xa7f4d68fadc35af6a875713e9a49b0506c3f015a IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.0010971
0x34bb96fe90a6b1736061de44872cd2e336b8f5bc05a408538a6109e201ed2d0c91465192021-07-14 10:10:0019 days 9 hrs ago0x88ce38eacd3d584c661017ffc8eace4350cd6421 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.001411205
0x42e2f96b041ca104f0e645e1cc15969cddb6480bb95a0a7f8965147c087944dc87145892021-06-29 8:36:3534 days 11 hrs ago0xa7f4d68fadc35af6a875713e9a49b0506c3f015a IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.00109698
0x28e5e3730df52caffbe6c3bff51c259917c39f5fa20ac52246e88d54ce285f2c87143302021-06-29 8:23:3634 days 11 hrs ago0x000fe4cd429c6655528b5a73f317239358441c43 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.001453145
0xe6bc95714d69c620a36a97798f72b90f481dcc5153d63f468b71e20ac43f3dfe87075602021-06-29 2:41:3034 days 17 hrs ago0x3a678a763ccae90a459db03a93ca37bddb0a527b IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.001432205
0x09a2228ba44e7130cd5a5581de48afff96ac8ccafb8c8dfc09922145fc79358f86893162021-06-28 11:21:2935 days 8 hrs ago0x7084015fecde023937d2012717ff93f92d5658b6 IN  0x15205e92ce6e14ca2d720fe0f931d06def32a87d0 BNB0.001453205
[ Download CSV Export 
Latest 13 internal transactions
Parent Txn Hash Block From To Value
0x07d01c6cc71e2c1fc821b8677161049b235b68cdc113a1c69bc5f7dcbe7da8d492815012021-07-19 2:43:1514 days 17 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x42e2f96b041ca104f0e645e1cc15969cddb6480bb95a0a7f8965147c087944dc87145892021-06-29 8:36:3534 days 11 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x66a09cfcb7a71af584c43398564c7292f840a5c285f594af50177f8f9b28abaa81435682021-06-09 9:48:2754 days 10 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x90e158abdccddd86c665821034b3eb27edefb57c56ca798c8ff9a2ff4f86c08779713212021-06-03 9:56:1160 days 10 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0xbfdd4d7a4da19929be33e8fb6e6dc466c7dbe162ef3c240bab2db464abd24b6b79441962021-06-02 11:14:2961 days 8 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0xb7ae0f9d0aed66eaa022886f39c00b16d352088b1f641911c67961b8cbca406775972912021-05-21 8:51:1673 days 11 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x27edbf90483fa923ec8e59b7eba3397c6d40d52f9ecdfca65619b9317e6d9c2375972612021-05-21 8:49:4673 days 11 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x4c802ba02723c380017e7f4372a4b1a1dc43d4b2a6ef6f20c0972965e398780375754022021-05-20 14:33:0574 days 5 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0xfe9a78ad0cfa4d43718444eb62b1392e86b6cdc52e370a617542a4aa160f4d0175753292021-05-20 14:29:0874 days 5 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x7bf7f33880254e2b2d898400f8a366bffcdb610d3e4d015074adf747d647301f75732662021-05-20 12:45:0774 days 7 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x09b1c68e990b510dc167a25cf146fa6bb8014b73033edcf27516c7495ad874d474066612021-05-14 15:41:3880 days 4 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x2a72c20b64deff0829209cc49104ce6efc83ead8876c59e84feb6b18eda62cab74065322021-05-14 15:33:5480 days 4 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
0x125ee9827a8907bf9dda08c1744da4316421ebee3b14c6a8d7411804919078cc74052922021-05-14 14:30:3080 days 5 hrs ago 0x15205e92ce6e14ca2d720fe0f931d06def32a87d  Contract Creation0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenFaucetProxyFactory

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 19 : OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/ContextUpgradeable.sol";
import "../proxy/Initializable.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal initializer {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
    uint256[49] private __gap;
}

File 2 of 19 : IERC165Upgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165Upgradeable {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 3 of 19 : IERC1820RegistryUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the global ERC1820 Registry, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
 * implementers for interfaces in this registry, as well as query support.
 *
 * Implementers may be shared by multiple accounts, and can also implement more
 * than a single interface for each account. Contracts can implement interfaces
 * for themselves, but externally-owned accounts (EOA) must delegate this to a
 * contract.
 *
 * {IERC165} interfaces can also be queried via the registry.
 *
 * For an in-depth explanation and source code analysis, see the EIP text.
 */
interface IERC1820RegistryUpgradeable {
    /**
     * @dev Sets `newManager` as the manager for `account`. A manager of an
     * account is able to set interface implementers for it.
     *
     * By default, each account is its own manager. Passing a value of `0x0` in
     * `newManager` will reset the manager to this initial state.
     *
     * Emits a {ManagerChanged} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     */
    function setManager(address account, address newManager) external;

    /**
     * @dev Returns the manager for `account`.
     *
     * See {setManager}.
     */
    function getManager(address account) external view returns (address);

    /**
     * @dev Sets the `implementer` contract as ``account``'s implementer for
     * `interfaceHash`.
     *
     * `account` being the zero address is an alias for the caller's address.
     * The zero address can also be used in `implementer` to remove an old one.
     *
     * See {interfaceHash} to learn how these are created.
     *
     * Emits an {InterfaceImplementerSet} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
     * end in 28 zeroes).
     * - `implementer` must implement {IERC1820Implementer} and return true when
     * queried for support, unless `implementer` is the caller. See
     * {IERC1820Implementer-canImplementInterfaceForAddress}.
     */
    function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external;

    /**
     * @dev Returns the implementer of `interfaceHash` for `account`. If no such
     * implementer is registered, returns the zero address.
     *
     * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
     * zeroes), `account` will be queried for support of it.
     *
     * `account` being the zero address is an alias for the caller's address.
     */
    function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address);

    /**
     * @dev Returns the interface hash for an `interfaceName`, as defined in the
     * corresponding
     * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
     */
    function interfaceHash(string calldata interfaceName) external pure returns (bytes32);

    /**
     *  @notice Updates the cache with whether the contract implements an ERC165 interface or not.
     *  @param account Address of the contract for which to update the cache.
     *  @param interfaceId ERC165 interface for which to update the cache.
     */
    function updateERC165Cache(address account, bytes4 interfaceId) external;

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not.
     *  If the result is not cached a direct lookup on the contract address is performed.
     *  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
     *  {updateERC165Cache} with the contract address.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);

    event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);

    event ManagerChanged(address indexed account, address indexed newManager);
}

File 4 of 19 : SafeMathUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMathUpgradeable {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 5 of 19 : Initializable.sol
// SPDX-License-Identifier: MIT

// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;

import "../utils/AddressUpgradeable.sol";

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {

    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /// @dev Returns true if and only if the function is running in the constructor
    function _isConstructor() private view returns (bool) {
        return !AddressUpgradeable.isContract(address(this));
    }
}

File 6 of 19 : IERC20Upgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Upgradeable {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 7 of 19 : AddressUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 8 of 19 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract ContextUpgradeable is Initializable {
    function __Context_init() internal initializer {
        __Context_init_unchained();
    }

    function __Context_init_unchained() internal initializer {
    }
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
    uint256[50] private __gap;
}

File 9 of 19 : SafeCastUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;


/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCastUpgradeable {

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        require(value < 2**255, "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 10 of 19 : FixedPoint.sol
/**
Copyright 2020 PoolTogether Inc.

This file is part of PoolTogether.

PoolTogether is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation under version 3 of the License.

PoolTogether is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PoolTogether.  If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.6.0 <0.8.0;

import "./external/openzeppelin/OpenZeppelinSafeMath_V3_3_0.sol";

/**
 * @author Brendan Asselstine
 * @notice Provides basic fixed point math calculations.
 *
 * This library calculates integer fractions by scaling values by 1e18 then performing standard integer math.
 */
library FixedPoint {
    using OpenZeppelinSafeMath_V3_3_0 for uint256;

    // The scale to use for fixed point numbers.  Same as Ether for simplicity.
    uint256 internal constant SCALE = 1e18;

    /**
        * Calculates a Fixed18 mantissa given the numerator and denominator
        *
        * The mantissa = (numerator * 1e18) / denominator
        *
        * @param numerator The mantissa numerator
        * @param denominator The mantissa denominator
        * @return The mantissa of the fraction
        */
    function calculateMantissa(uint256 numerator, uint256 denominator) internal pure returns (uint256) {
        uint256 mantissa = numerator.mul(SCALE);
        mantissa = mantissa.div(denominator);
        return mantissa;
    }

    /**
        * Multiplies a Fixed18 number by an integer.
        *
        * @param b The whole integer to multiply
        * @param mantissa The Fixed18 number
        * @return An integer that is the result of multiplying the params.
        */
    function multiplyUintByMantissa(uint256 b, uint256 mantissa) internal pure returns (uint256) {
        uint256 result = mantissa.mul(b);
        result = result.div(SCALE);
        return result;
    }

    /**
    * Divides an integer by a fixed point 18 mantissa
    *
    * @param dividend The integer to divide
    * @param mantissa The fixed point 18 number to serve as the divisor
    * @return An integer that is the result of dividing an integer by a fixed point 18 mantissa
    */
    function divideUintByMantissa(uint256 dividend, uint256 mantissa) internal pure returns (uint256) {
        uint256 result = SCALE.mul(dividend);
        result = result.div(mantissa);
        return result;
    }
}

File 11 of 19 : OpenZeppelinSafeMath_V3_3_0.sol
// SPDX-License-Identifier: MIT

// NOTE: Copied from OpenZeppelin Contracts version 3.3.0

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library OpenZeppelinSafeMath_V3_3_0 {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 12 of 19 : Constants.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.6.0 <0.7.0;

import "@openzeppelin/contracts-upgradeable/introspection/IERC1820RegistryUpgradeable.sol";

library Constants {
  IERC1820RegistryUpgradeable public constant REGISTRY = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

  // keccak256("ERC777TokensSender")
  bytes32 public constant TOKENS_SENDER_INTERFACE_HASH =
  0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;

  // keccak256("ERC777TokensRecipient")
  bytes32 public constant TOKENS_RECIPIENT_INTERFACE_HASH =
  0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;

  // keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC"));
  bytes32 public constant ACCEPT_MAGIC =
  0xa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b4;

  bytes4 public constant ERC165_INTERFACE_ID_ERC165 = 0x01ffc9a7;
  bytes4 public constant ERC165_INTERFACE_ID_ERC721 = 0x80ac58cd;
}

File 13 of 19 : ProxyFactory.sol
pragma solidity >=0.6.0 <0.7.0;

// solium-disable security/no-inline-assembly
// solium-disable security/no-low-level-calls
contract ProxyFactory {

  event ProxyCreated(address proxy);

  function deployMinimal(address _logic, bytes memory _data) public returns (address proxy) {
    // Adapted from https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol
    bytes20 targetBytes = bytes20(_logic);
    assembly {
      let clone := mload(0x40)
      mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
      mstore(add(clone, 0x14), targetBytes)
      mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
      proxy := create(0, clone, 0x37)
    }

    emit ProxyCreated(address(proxy));

    if(_data.length > 0) {
      (bool success,) = proxy.call(_data);
      require(success, "ProxyFactory/constructor-call-failed");
    }
  }
}

File 14 of 19 : TokenFaucet.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.6.0 <0.7.0;

import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/SafeCastUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@pooltogether/fixed-point/contracts/FixedPoint.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

import "../utils/ExtendedSafeCast.sol";
import "../token/TokenListener.sol";

/// @title Disburses a token at a fixed rate per second to holders of another token.
/// @notice The tokens are dripped at a "drip rate per second".  This is the number of tokens that
/// are dripped each second.  A user's share of the dripped tokens is based on how many 'measure' tokens they hold.
/* solium-disable security/no-block-members */
contract TokenFaucet is OwnableUpgradeable, TokenListener {
  using SafeMathUpgradeable for uint256;
  using SafeCastUpgradeable for uint256;
  using ExtendedSafeCast for uint256;

  event Initialized(
    IERC20Upgradeable indexed asset,
    IERC20Upgradeable indexed measure,
    uint256 dripRatePerSecond
  );

  event Dripped(
    uint256 newTokens
  );

  event Deposited(
    address indexed user,
    uint256 amount
  );

  event Withdrawn(
    address indexed to,
    uint256 amount
  );

  event Claimed(
    address indexed user,
    uint256 newTokens
  );

  event DripRateChanged(
    uint256 dripRatePerSecond
  );

  struct UserState {
    uint128 lastExchangeRateMantissa;
    uint128 balance;
  }

  /// @notice The token that is being disbursed
  IERC20Upgradeable public asset;

  /// @notice The token that is user to measure a user's portion of disbursed tokens
  IERC20Upgradeable public measure;

  /// @notice The total number of tokens that are disbursed each second
  uint256 public dripRatePerSecond;

  /// @notice The cumulative exchange rate of measure token supply : dripped tokens
  uint112 public exchangeRateMantissa;

  /// @notice The total amount of tokens that have been dripped but not claimed
  uint112 public totalUnclaimed;

  /// @notice The timestamp at which the tokens were last dripped
  uint32 public lastDripTimestamp;

  /// @notice The data structure that tracks when a user last received tokens
  mapping(address => UserState) public userStates;

  /// @notice Initializes a new Comptroller V2
  /// @param _asset The asset to disburse to users
  /// @param _measure The token to use to measure a users portion
  /// @param _dripRatePerSecond The amount of the asset to drip each second
  function initialize (
    IERC20Upgradeable _asset,
    IERC20Upgradeable _measure,
    uint256 _dripRatePerSecond
  ) public initializer {
    __Ownable_init();
    lastDripTimestamp = _currentTime();
    asset = _asset;
    measure = _measure;
    setDripRatePerSecond(_dripRatePerSecond);

    emit Initialized(
      asset,
      measure,
      dripRatePerSecond
    );
  }

  /// @notice Safely deposits asset tokens into the faucet.  Must be pre-approved
  /// This should be used instead of transferring directly because the drip function must
  /// be called before receiving new assets.
  /// @param amount The amount of asset tokens to add (must be approved already)
  function deposit(uint256 amount) external {
    drip();
    asset.transferFrom(msg.sender, address(this), amount);

    emit Deposited(msg.sender, amount);
  }

  /// @notice Allows the owner to withdraw tokens that have not been dripped yet.
  /// @param to The address to withdraw to
  /// @param amount The amount to withdraw
  function withdrawTo(address to, uint256 amount) external onlyOwner {
    drip();
    uint256 assetTotalSupply = asset.balanceOf(address(this));
    uint256 availableTotalSupply = assetTotalSupply.sub(totalUnclaimed);
    require(amount <= availableTotalSupply, "TokenFaucet/insufficient-funds");
    asset.transfer(to, amount);

    emit Withdrawn(to, amount);
  }

  /// @notice Transfers all unclaimed tokens to the user
  /// @param user The user to claim tokens for
  /// @return The amount of tokens that were claimed.
  function claim(address user) external returns (uint256) {
    drip();
    _captureNewTokensForUser(user);
    uint256 balance = userStates[user].balance;
    userStates[user].balance = 0;
    totalUnclaimed = uint256(totalUnclaimed).sub(balance).toUint112();
    asset.transfer(user, balance);

    emit Claimed(user, balance);

    return balance;
  }

  /// @notice Drips new tokens.
  /// @dev Should be called immediately before any measure token mints/transfers/burns
  /// @return The number of new tokens dripped.
  function drip() public returns (uint256) {
    uint256 currentTimestamp = _currentTime();

    // this should only run once per block.
    if (lastDripTimestamp == uint32(currentTimestamp)) {
      return 0;
    }

    uint256 assetTotalSupply = asset.balanceOf(address(this));
    uint256 availableTotalSupply = assetTotalSupply.sub(totalUnclaimed);
    uint256 newSeconds = currentTimestamp.sub(lastDripTimestamp);
    uint256 nextExchangeRateMantissa = exchangeRateMantissa;
    uint256 newTokens;
    uint256 measureTotalSupply = measure.totalSupply();


    if (measureTotalSupply > 0 && availableTotalSupply > 0) {
      newTokens = newSeconds.mul(dripRatePerSecond);
      if (newTokens > availableTotalSupply) {
        newTokens = availableTotalSupply;
      }
      uint256 indexDeltaMantissa = FixedPoint.calculateMantissa(newTokens, measureTotalSupply);
      nextExchangeRateMantissa = nextExchangeRateMantissa.add(indexDeltaMantissa);

      emit Dripped(
        newTokens
      );
    }

    exchangeRateMantissa = nextExchangeRateMantissa.toUint112();
    totalUnclaimed = uint256(totalUnclaimed).add(newTokens).toUint112();
    lastDripTimestamp = currentTimestamp.toUint32();

    return newTokens;
  }

  /// @notice Allows the owner to set the drip rate per second.  This is the number of tokens that are dripped each second.
  /// @param _dripRatePerSecond The new drip rate in tokens per second
  function setDripRatePerSecond(uint256 _dripRatePerSecond) public onlyOwner {
    require(_dripRatePerSecond > 0, "TokenFaucet/dripRate-gt-zero");

    // ensure we're all caught up
    drip();

    dripRatePerSecond = _dripRatePerSecond;

    emit DripRateChanged(dripRatePerSecond);
  }

  /// @notice Captures new tokens for a user
  /// @dev This must be called before changes to the user's balance (i.e. before mint, transfer or burns)
  /// @param user The user to capture tokens for
  /// @return The number of new tokens
  function _captureNewTokensForUser(
    address user
  ) private returns (uint128) {
    UserState storage userState = userStates[user];
    if (exchangeRateMantissa == userState.lastExchangeRateMantissa) {
      // ignore if exchange rate is same
      return 0;
    }
    uint256 deltaExchangeRateMantissa = uint256(exchangeRateMantissa).sub(userState.lastExchangeRateMantissa);
    uint256 userMeasureBalance = measure.balanceOf(user);
    uint128 newTokens = FixedPoint.multiplyUintByMantissa(userMeasureBalance, deltaExchangeRateMantissa).toUint128();

    userStates[user] = UserState({
      lastExchangeRateMantissa: exchangeRateMantissa,
      balance: uint256(userState.balance).add(newTokens).toUint128()
    });

    return newTokens;
  }

  /// @notice Should be called before a user mints new "measure" tokens.
  /// @param to The user who is minting the tokens
  /// @param token The token they are minting
  function beforeTokenMint(
    address to,
    uint256,
    address token,
    address
  )
    external
    override
  {
    if (token == address(measure)) {
      drip();
      _captureNewTokensForUser(to);
    }
  }

  /// @notice Should be called before "measure" tokens are transferred or burned
  /// @param from The user who is sending the tokens
  /// @param to The user who is receiving the tokens
  /// @param token The token token they are burning
  function beforeTokenTransfer(
    address from,
    address to,
    uint256,
    address token
  )
    external
    override
  {
    // must be measure and not be minting
    if (token == address(measure) && from != address(0)) {
      drip();
      _captureNewTokensForUser(to);
      _captureNewTokensForUser(from);
    }
  }

  /// @notice returns the current time.  Allows for override in testing.
  /// @return The current time (block.timestamp)
  function _currentTime() internal virtual view returns (uint32) {
    return block.timestamp.toUint32();
  }

}

File 15 of 19 : TokenFaucetProxyFactory.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.6.0 <0.7.0;

import "./TokenFaucet.sol";
import "../external/openzeppelin/ProxyFactory.sol";

/// @title Stake Prize Pool Proxy Factory
/// @notice Minimal proxy pattern for creating new TokenFaucet contracts
contract TokenFaucetProxyFactory is ProxyFactory {

  /// @notice Contract template for deploying proxied Comptrollers
  TokenFaucet public instance;

  /// @notice Initializes the Factory with an instance of the TokenFaucet
  constructor () public {
    instance = new TokenFaucet();
  }

  /// @notice Creates a new TokenFaucet
  /// @param _asset The asset to disburse to users
  /// @param _measure The token to use to measure a users portion
  /// @param _dripRatePerSecond The amount of the asset to drip each second
  /// @return A reference to the new proxied TokenFaucet
  function create(
    IERC20Upgradeable _asset,
    IERC20Upgradeable _measure,
    uint256 _dripRatePerSecond
  ) public returns (TokenFaucet) {
    TokenFaucet tokenFaucet = TokenFaucet(deployMinimal(address(instance), ""));
    tokenFaucet.initialize(
      _asset, _measure, _dripRatePerSecond
    );
    tokenFaucet.transferOwnership(msg.sender);
    return tokenFaucet;
  }

  /// @notice Creates a new TokenFaucet and immediately deposits funds
  /// @param _asset The asset to disburse to users
  /// @param _measure The token to use to measure a users portion
  /// @param _dripRatePerSecond The amount of the asset to drip each second
  /// @param _amount The amount of assets to deposit into the faucet
  /// @return A reference to the new proxied TokenFaucet
  function createAndDeposit(
    IERC20Upgradeable _asset,
    IERC20Upgradeable _measure,
    uint256 _dripRatePerSecond,
    uint256 _amount
  ) external returns (TokenFaucet) {
    TokenFaucet faucet = create(_asset, _measure, _dripRatePerSecond);
    _asset.transferFrom(msg.sender, address(faucet), _amount);
  }

  /// @notice Runs claim on all passed comptrollers for a user.
  /// @param user The user to claim for
  /// @param tokenFaucets The tokenFaucets to call claim on.
  function claimAll(address user, TokenFaucet[] calldata tokenFaucets) external {
    for (uint256 i = 0; i < tokenFaucets.length; i++) {
      tokenFaucets[i].claim(user);
    }
  }
}

File 16 of 19 : TokenListener.sol
pragma solidity ^0.6.4;

import "./TokenListenerInterface.sol";
import "./TokenListenerLibrary.sol";
import "../Constants.sol";

abstract contract TokenListener is TokenListenerInterface {
  function supportsInterface(bytes4 interfaceId) external override view returns (bool) {
    return (
      interfaceId == Constants.ERC165_INTERFACE_ID_ERC165 || 
      interfaceId == TokenListenerLibrary.ERC165_INTERFACE_ID_TOKEN_LISTENER
    );
  }
}

File 17 of 19 : TokenListenerInterface.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.0 <0.7.0;

import "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol";

/// @title An interface that allows a contract to listen to token mint, transfer and burn events.
interface TokenListenerInterface is IERC165Upgradeable {
  /// @notice Called when tokens are minted.
  /// @param to The address of the receiver of the minted tokens.
  /// @param amount The amount of tokens being minted
  /// @param controlledToken The address of the token that is being minted
  /// @param referrer The address that referred the minting.
  function beforeTokenMint(address to, uint256 amount, address controlledToken, address referrer) external;

  /// @notice Called when tokens are transferred or burned.
  /// @param from The address of the sender of the token transfer
  /// @param to The address of the receiver of the token transfer.  Will be the zero address if burning.
  /// @param amount The amount of tokens transferred
  /// @param controlledToken The address of the token that was transferred
  function beforeTokenTransfer(address from, address to, uint256 amount, address controlledToken) external;
}

File 18 of 19 : TokenListenerLibrary.sol
pragma solidity ^0.6.12;

library TokenListenerLibrary {
  /*
    *     bytes4(keccak256('beforeTokenMint(address,uint256,address,address)')) == 0x4d7f3db0
    *     bytes4(keccak256('beforeTokenTransfer(address,address,uint256,address)')) == 0xb2210957
    *
    *     => 0x4d7f3db0 ^ 0xb2210957 == 0xff5e34e7
    */
  bytes4 public constant ERC165_INTERFACE_ID_TOKEN_LISTENER = 0xff5e34e7;
}

File 19 of 19 : ExtendedSafeCast.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.6.0 <0.7.0;

library ExtendedSafeCast {

  /**
    * @dev Converts an unsigned uint256 into a unsigned uint112.
    *
    * Requirements:
    *
    * - input must be less than or equal to maxUint112.
    */
  function toUint112(uint256 value) internal pure returns (uint112) {
    require(value < 2 ** 112, "SafeCast: value doesn't fit in an uint112");
    return uint112(value);
  }

  /**
    * @dev Converts an unsigned uint256 into a unsigned uint96.
    *
    * Requirements:
    *
    * - input must be less than or equal to maxUint96.
    */
  function toUint96(uint256 value) internal pure returns (uint96) {
    require(value < 2 ** 96, "SafeCast: value doesn't fit in an uint96");
    return uint96(value);
  }

}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proxy","type":"address"}],"name":"ProxyCreated","type":"event"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"contract TokenFaucet[]","name":"tokenFaucets","type":"address[]"}],"name":"claimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"_asset","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"_measure","type":"address"},{"internalType":"uint256","name":"_dripRatePerSecond","type":"uint256"}],"name":"create","outputs":[{"internalType":"contract TokenFaucet","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"_asset","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"_measure","type":"address"},{"internalType":"uint256","name":"_dripRatePerSecond","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"createAndDeposit","outputs":[{"internalType":"contract TokenFaucet","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"deployMinimal","outputs":[{"internalType":"address","name":"proxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"instance","outputs":[{"internalType":"contract TokenFaucet","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5060405161001d9061005f565b604051809103906000f080158015610039573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b039290921691909117905561006c565b611886806106ec83390190565b6106718061007b6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063022ec0951461005c57806313e7e05814610080578063244a79d614610102578063b3eeb5e21461013e578063ffe5725f146101f4575b600080fd5b61006461022a565b604080516001600160a01b039092168252519081900360200190f35b6101006004803603604081101561009657600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100c157600080fd5b8201836020820111156100d357600080fd5b803590602001918460208302840111640100000000831117156100f557600080fd5b509092509050610239565b005b6100646004803603608081101561011857600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356102e8565b6100646004803603604081101561015457600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561017f57600080fd5b82018360208201111561019157600080fd5b803590602001918460018302840111640100000000831117156101b357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610388945050505050565b6100646004803603606081101561020a57600080fd5b506001600160a01b03813581169160208101359091169060400135610504565b6000546001600160a01b031681565b60005b818110156102e25782828281811061025057fe5b905060200201356001600160a01b03166001600160a01b0316631e83409a856040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050506040513d60208110156102d857600080fd5b505060010161023c565b50505050565b6000806102f6868686610504565b604080516323b872dd60e01b81523360048201526001600160a01b038084166024830152604482018790529151929350908816916323b872dd916064808201926020929091908290030181600087803b15801561035257600080fd5b505af1158015610366573d6000803e3d6000fd5b505050506040513d602081101561037c57600080fd5b50919695505050505050565b6000808360601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0604080516001600160a01b038316815290519194507efffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349925081900360200190a18251156104fd576000826001600160a01b0316846040518082805190602001908083835b602083106104545780518252601f199092019160209182019101610435565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146104b6576040519150601f19603f3d011682016040523d82523d6000602084013e6104bb565b606091505b50509050806104fb5760405162461bcd60e51b81526004018080602001828103825260248152602001806106186024913960400191505060405180910390fd5b505b5092915050565b600080546040805160208101909152828152829161052d916001600160a01b0390911690610388565b9050806001600160a01b0316631794bb3c8686866040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561059757600080fd5b505af11580156105ab573d6000803e3d6000fd5b50506040805163f2fde38b60e01b815233600482015290516001600160a01b038516935063f2fde38b9250602480830192600092919082900301818387803b1580156105f657600080fd5b505af115801561060a573d6000803e3d6000fd5b509297965050505050505056fe50726f7879466163746f72792f636f6e7374727563746f722d63616c6c2d6661696c6564a2646970667358221220db6b670ea1ad6d64186168999ed5e69248d10e1fd763e357eebc0387adafe60664736f6c634300060c0033608060405234801561001057600080fd5b50611866806100206000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c80638da5cb5b116100ad578063ca5baafc11610071578063ca5baafc1461034f578063d9772a251461036c578063e318613e1461038d578063efa9a1ad14610395578063f2fde38b1461039d57610121565b80638da5cb5b146102c25780639f678cca146102ca578063b2210957146102d2578063b6b55f251461030e578063c96f14b81461032b57610121565b80631e83409a116100f45780631e83409a14610208578063205c28781461022e57806338d52e0f1461025a5780634d7f3db01461027e578063715018a6146102ba57610121565b806301ffc9a7146101265780630ecc535f146101615780631794bb3c146101b6578063187f3334146101ee575b600080fd5b61014d6004803603602081101561013c57600080fd5b50356001600160e01b0319166103c3565b604080519115158252519081900360200190f35b6101876004803603602081101561017757600080fd5b50356001600160a01b03166103ff565b60405180836001600160801b03168152602001826001600160801b031681526020019250505060405180910390f35b6101ec600480360360608110156101cc57600080fd5b506001600160a01b03813581169160208101359091169060400135610425565b005b6101f6610583565b60408051918252519081900360200190f35b6101f66004803603602081101561021e57600080fd5b50356001600160a01b0316610589565b6101ec6004803603604081101561024457600080fd5b506001600160a01b0381351690602001356106f1565b610262610915565b604080516001600160a01b039092168252519081900360200190f35b6101ec6004803603608081101561029457600080fd5b506001600160a01b03813581169160208101359160408201358116916060013516610924565b6101ec610953565b6102626109ff565b6101f6610a0f565b6101ec600480360360808110156102e857600080fd5b506001600160a01b03813581169160208101358216916040820135916060013516610cab565b6101ec6004803603602081101561032457600080fd5b5035610ce7565b610333610daf565b604080516001600160701b039092168252519081900360200190f35b6101ec6004803603602081101561036557600080fd5b5035610dc5565b610374610ec0565b6040805163ffffffff9092168252519081900360200190f35b610333610ed3565b610262610ee2565b6101ec600480360360208110156103b357600080fd5b50356001600160a01b0316610ef1565b60006001600160e01b031982166301ffc9a760e01b14806103f757506001600160e01b03198216600162a1cb1960e01b0319145b90505b919050565b6069602052600090815260409020546001600160801b0380821691600160801b90041682565b600054610100900460ff168061043e575061043e610ff4565b8061044c575060005460ff16155b6104875760405162461bcd60e51b815260040180806020018281038252602e815260200180611773602e913960400191505060405180910390fd5b600054610100900460ff161580156104b2576000805460ff1961ff0019909116610100171660011790555b6104ba611005565b6104c26110b7565b6068805463ffffffff92909216600160e01b026001600160e01b03909216919091179055606580546001600160a01b038087166001600160a01b031992831617909255606680549286169290911691909117905561051f82610dc5565b60665460655460675460408051918252516001600160a01b039384169392909216917f10f27652c1015195ca7e6bc9b4c724cbf18e91c42117d92124703a3f49bb240f9181900360200190a3801561057d576000805461ff00191690555b50505050565b60675481565b6000610593610a0f565b5061059d826110c7565b506001600160a01b038216600090815260696020526040902080546001600160801b03808216909255606854600160801b909104909116906105f8906105f390600160701b90046001600160701b03168361126c565b6112ce565b606880546001600160701b0392909216600160701b026dffffffffffffffffffffffffffff60701b199092169190911790556065546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561068057600080fd5b505af1158015610694573d6000803e3d6000fd5b505050506040513d60208110156106aa57600080fd5b50506040805182815290516001600160a01b038516917fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a919081900360200190a292915050565b6106f9611316565b6001600160a01b031661070a6109ff565b6001600160a01b031614610753576040805162461bcd60e51b815260206004820181905260248201526000805160206117c2833981519152604482015290519081900360640190fd5b61075b610a0f565b50606554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156107a757600080fd5b505afa1580156107bb573d6000803e3d6000fd5b505050506040513d60208110156107d157600080fd5b50516068549091506000906107f7908390600160701b90046001600160701b031661126c565b90508083111561084e576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e4661756365742f696e73756666696369656e742d66756e64730000604482015290519081900360640190fd5b6065546040805163a9059cbb60e01b81526001600160a01b038781166004830152602482018790529151919092169163a9059cbb9160448083019260209291908290030181600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b505050506040513d60208110156108ce57600080fd5b50506040805184815290516001600160a01b038616917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a250505050565b6065546001600160a01b031681565b6066546001600160a01b038381169116141561057d57610942610a0f565b5061094c846110c7565b5050505050565b61095b611316565b6001600160a01b031661096c6109ff565b6001600160a01b0316146109b5576040805162461bcd60e51b815260206004820181905260248201526000805160206117c2833981519152604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b03165b90565b600080610a1a6110b7565b60685463ffffffff9182169250600160e01b900416811415610a40576000915050610a0c565b606554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610a8b57600080fd5b505afa158015610a9f573d6000803e3d6000fd5b505050506040513d6020811015610ab557600080fd5b5051606854909150600090610adb908390600160701b90046001600160701b031661126c565b606854909150600090610b0090859063ffffffff600160e01b90910481169061126c16565b606854606654604080516318160ddd60e01b815290519394506001600160701b039092169260009283926001600160a01b0316916318160ddd91600480820192602092909190829003018186803b158015610b5a57600080fd5b505afa158015610b6e573d6000803e3d6000fd5b505050506040513d6020811015610b8457600080fd5b505190508015801590610b975750600085115b15610c0957606754610baa90859061131a565b915084821115610bb8578491505b6000610bc4838361137a565b9050610bd084826113a3565b6040805185815290519195507f7de59a92c9386255180c28ede4b61edb9b7b2ac96855ac634151489cef21bad6919081900360200190a1505b610c12836112ce565b606880546dffffffffffffffffffffffffffff19166001600160701b039283161790819055610c4d916105f391600160701b900416846113a3565b6068600e6101000a8154816001600160701b0302191690836001600160701b03160217905550610c7c876113fd565b6068805463ffffffff92909216600160e01b026001600160e01b03909216919091179055509550505050505090565b6066546001600160a01b038281169116148015610cd057506001600160a01b03841615155b1561057d57610cdd610a0f565b50610942836110c7565b610cef610a0f565b50606554604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b158015610d4a57600080fd5b505af1158015610d5e573d6000803e3d6000fd5b505050506040513d6020811015610d7457600080fd5b505060408051828152905133917f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4919081900360200190a250565b606854600160701b90046001600160701b031681565b610dcd611316565b6001600160a01b0316610dde6109ff565b6001600160a01b031614610e27576040805162461bcd60e51b815260206004820181905260248201526000805160206117c2833981519152604482015290519081900360640190fd5b60008111610e7c576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e4661756365742f64726970526174652d67742d7a65726f00000000604482015290519081900360640190fd5b610e84610a0f565b5060678190556040805182815290517f3d38e7cd2e029035006f9977a727c8724cd41dffb6d2a40d9f66bd4c26836a329181900360200190a150565b606854600160e01b900463ffffffff1681565b6068546001600160701b031681565b6066546001600160a01b031681565b610ef9611316565b6001600160a01b0316610f0a6109ff565b6001600160a01b031614610f53576040805162461bcd60e51b815260206004820181905260248201526000805160206117c2833981519152604482015290519081900360640190fd5b6001600160a01b038116610f985760405162461bcd60e51b81526004018080602001828103825260268152602001806117266026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6000610fff30611442565b15905090565b600054610100900460ff168061101e575061101e610ff4565b8061102c575060005460ff16155b6110675760405162461bcd60e51b815260040180806020018281038252602e815260200180611773602e913960400191505060405180910390fd5b600054610100900460ff16158015611092576000805460ff1961ff0019909116610100171660011790555b61109a611448565b6110a26114e8565b80156110b4576000805461ff00191690555b50565b60006110c2426113fd565b905090565b6001600160a01b038116600090815260696020526040812080546068546001600160701b03166001600160801b0390911614156111085760009150506103fa565b805460685460009161112c916001600160701b0316906001600160801b031661126c565b606654604080516370a0823160e01b81526001600160a01b038881166004830152915193945060009391909216916370a08231916024808301926020929190829003018186803b15801561117f57600080fd5b505afa158015611193573d6000803e3d6000fd5b505050506040513d60208110156111a957600080fd5b5051905060006111c16111bc83856115e1565b611602565b604080518082019091526068546001600160701b031681528554919250906020820190611206906111bc90600160801b90046001600160801b039081169086166113a3565b6001600160801b039081169091526001600160a01b03881660009081526069602090815260409091208351815494909201518316600160801b029183166fffffffffffffffffffffffffffffffff19909416939093179091161790559350505050919050565b6000828211156112c3576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000600160701b82106113125760405162461bcd60e51b81526004018080602001828103825260298152602001806117e26029913960400191505060405180910390fd5b5090565b3390565b600082611329575060006112c8565b8282028284828161133657fe5b04146113735760405162461bcd60e51b81526004018080602001828103825260218152602001806117a16021913960400191505060405180910390fd5b9392505050565b60008061138f84670de0b6b3a764000061131a565b905061139b8184611646565b949350505050565b600082820183811015611373576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600064010000000082106113125760405162461bcd60e51b815260040180806020018281038252602681526020018061180b6026913960400191505060405180910390fd5b3b151590565b600054610100900460ff16806114615750611461610ff4565b8061146f575060005460ff16155b6114aa5760405162461bcd60e51b815260040180806020018281038252602e815260200180611773602e913960400191505060405180910390fd5b600054610100900460ff161580156110a2576000805460ff1961ff00199091166101001716600117905580156110b4576000805461ff001916905550565b600054610100900460ff16806115015750611501610ff4565b8061150f575060005460ff16155b61154a5760405162461bcd60e51b815260040180806020018281038252602e815260200180611773602e913960400191505060405180910390fd5b600054610100900460ff16158015611575576000805460ff1961ff0019909116610100171660011790555b600061157f611316565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156110b4576000805461ff001916905550565b6000806115ee838561131a565b905061139b81670de0b6b3a7640000611646565b6000600160801b82106113125760405162461bcd60e51b815260040180806020018281038252602781526020018061174c6027913960400191505060405180910390fd5b600061137383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506000818361170f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156116d45781810151838201526020016116bc565b50505050905090810190601f1680156117015780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161171b57fe5b049594505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737353616665436173743a2076616c756520646f65736e27742066697420696e203132382062697473496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657253616665436173743a2076616c756520646f65736e27742066697420696e20616e2075696e7431313253616665436173743a2076616c756520646f65736e27742066697420696e2033322062697473a2646970667358221220327c0fecbfd7201d6e646ef92cc6a086b3870725bf6eb6168b54a7b834c517bc64736f6c634300060c0033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.