ETH Price: $2,633.54 (+1.16%)
Gas: 3 Gwei

Contract

0x791D406B20A7d93C0945b0D9D7AbF323772397C9
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x519e6269bf05c25ba6d72c403273f5d31adf3569ac5dc91ec59ee27f494257b3 Get Tokens With ...(pending)2024-08-11 3:31:1715 hrs ago1723347077IN
0x791D406B...3772397C9
0 ETH(Pending)(Pending)
Get Tokens With ...204087162024-07-29 0:44:1113 days ago1722213851IN
0x791D406B...3772397C9
0 ETH0.000067691
Get Tokens With ...127649072021-07-05 2:52:301133 days ago1625453550IN
0x791D406B...3772397C9
0 ETH0.0017982110
Get Tokens With ...127508222021-07-02 22:08:521135 days ago1625263732IN
0x791D406B...3772397C9
0 ETH0.001618389
Get Tokens With ...126386602021-06-15 11:02:101153 days ago1623754930IN
0x791D406B...3772397C9
0 ETH0.0018521510.3
Get Tokens With ...123443292021-04-30 21:51:071198 days ago1619819467IN
0x791D406B...3772397C9
0 ETH0.0071928440
Recover ERC20119392392021-02-27 12:04:281261 days ago1614427468IN
0x791D406B...3772397C9
0 ETH0.00411165103
Get Tokens With ...113823132020-12-03 22:15:241346 days ago1607033724IN
0x791D406B...3772397C9
0 ETH0.0032170919
Get Tokens With ...112718632020-11-16 23:20:481363 days ago1605568848IN
0x791D406B...3772397C9
0 ETH0.0017596922.40535
Get Tokens With ...111818912020-11-03 3:53:531377 days ago1604375633IN
0x791D406B...3772397C9
0 ETH0.0029108237
Get Tokens With ...111285422020-10-25 23:21:251385 days ago1603668085IN
0x791D406B...3772397C9
0 ETH0.0023148115.00000145
Get Tokens With ...111238472020-10-25 6:04:181386 days ago1603605858IN
0x791D406B...3772397C9
0 ETH0.0017761722.1
Get Tokens With ...110824282020-10-18 21:45:321392 days ago1603057532IN
0x791D406B...3772397C9
0 ETH0.0013100316.3
Get Tokens With ...110720952020-10-17 7:29:231394 days ago1602919763IN
0x791D406B...3772397C9
0 ETH0.0017478323
Get Tokens With ...109990352020-10-06 0:42:381405 days ago1601944958IN
0x791D406B...3772397C9
0 ETH0.0081493787
Get Tokens With ...109901932020-10-04 15:31:271407 days ago1601825487IN
0x791D406B...3772397C9
0 ETH0.0063616581
Get Tokens With ...109709832020-10-01 15:36:571410 days ago1601566617IN
0x791D406B...3772397C9
0 ETH0.01711475101
Get Tokens With ...109413832020-09-27 0:16:071414 days ago1601165767IN
0x791D406B...3772397C9
0 ETH0.0086353751
Get Tokens With ...109348592020-09-25 23:54:371415 days ago1601078077IN
0x791D406B...3772397C9
0 ETH0.0097096658
Get Tokens With ...104498912020-07-13 7:41:501490 days ago1594626110IN
0x791D406B...3772397C9
0 ETH0.0031415640
Get Tokens With ...104426672020-07-12 4:55:081491 days ago1594529708IN
0x791D406B...3772397C9
0 ETH0.0067728440
Get Tokens With ...103366042020-06-25 18:32:201508 days ago1593109940IN
0x791D406B...3772397C9
0 ETH0.0031415640
Get Tokens With ...102716812020-06-15 17:27:341518 days ago1592242054IN
0x791D406B...3772397C9
0 ETH0.0023557831
Get Tokens With ...102716782020-06-15 17:27:221518 days ago1592242042IN
0x791D406B...3772397C9
0 ETH0.002438831
Get Tokens With ...102703502020-06-15 12:38:181518 days ago1592224698IN
0x791D406B...3772397C9
0 ETH0.000987913
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenFaucet

Compiler Version
v0.5.10+commit.5a6ea5b1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-07-23
*/

pragma solidity ^0.5.10;

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @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 SafeMath {
    /**
     * @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");
        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-solidity/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) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */
interface IERC20 {
    /**
     * @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.
     *
     * > 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: openzeppelin-solidity/contracts/utils/Address.sol

/**
 * @dev Collection of functions related to the address type,
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * > It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in 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;
    }
}

// File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: openzeppelin-solidity/contracts/ownership/Ownable.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.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be aplied to your functions to restrict their use to
 * the owner.
 */
contract Ownable {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

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

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

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _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 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: eth-token-recover/contracts/TokenRecover.sol

/**
 * @title TokenRecover
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Allow to recover any ERC20 sent into the contract for error
 */
contract TokenRecover is Ownable {

    /**
     * @dev Remember that only owner can call so be careful when use on contracts generated from other contracts.
     * @param tokenAddress The token contract address
     * @param tokenAmount Number of tokens to be sent
     */
    function recoverERC20(address tokenAddress, uint256 tokenAmount) public onlyOwner {
        IERC20(tokenAddress).transfer(owner(), tokenAmount);
    }
}

// File: openzeppelin-solidity/contracts/introspection/ERC165Checker.sol

/**
 * @dev Library used to query support of an interface declared via `IERC165`.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Returns true if `account` supports the `IERC165` interface,
     */
    function _supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) &&
            !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for `IERC165` itself is queried automatically.
     *
     * See `IERC165.supportsInterface`.
     */
    function _supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return _supportsERC165(account) &&
            _supportsERC165Interface(account, interfaceId);
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for `IERC165` itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * `IERC165` support.
     *
     * See `IERC165.supportsInterface`.
     */
    function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!_supportsERC165(account)) {
            return false;
        }

        // query support of each interface in _interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!_supportsERC165Interface(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with the `supportsERC165` method in this library.
     * Interface identification is specified in ERC-165.
     */
    function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
        // success determines whether the staticcall succeeded and result determines
        // whether the contract at account indicates support of _interfaceId
        (bool success, bool result) = _callERC165SupportsInterface(account, interfaceId);

        return (success && result);
    }

    /**
     * @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return success true if the STATICCALL succeeded, false otherwise
     * @return result true if the STATICCALL succeeded and the contract at account
     * indicates support of the interface with identifier interfaceId, false otherwise
     */
    function _callERC165SupportsInterface(address account, bytes4 interfaceId)
        private
        view
        returns (bool success, bool result)
    {
        bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);

        // solhint-disable-next-line no-inline-assembly
        assembly {
            let encodedParams_data := add(0x20, encodedParams)
            let encodedParams_size := mload(encodedParams)

            let output := mload(0x40)    // Find empty storage location using "free memory pointer"
            mstore(output, 0x0)

            success := staticcall(
                30000,                   // 30k gas
                account,                 // To addr
                encodedParams_data,
                encodedParams_size,
                output,
                0x20                     // Outputs are 32 bytes long
            )

            result := mload(output)      // Load the result
        }
    }
}

// File: openzeppelin-solidity/contracts/introspection/IERC165.sol

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * [EIP](https://eips.ethereum.org/EIPS/eip-165).
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others (`ERC165Checker`).
 *
 * For an implementation, see `ERC165`.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * 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: openzeppelin-solidity/contracts/introspection/ERC165.sol

/**
 * @dev Implementation of the `IERC165` interface.
 *
 * Contracts may inherit from this and call `_registerInterface` to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See `IERC165.supportsInterface`.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See `IERC165.supportsInterface`.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: erc-payable-token/contracts/token/ERC1363/IERC1363.sol

/**
 * @title IERC1363 Interface
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Interface for a Payable Token contract as defined in
 *  https://github.com/ethereum/EIPs/issues/1363
 */
contract IERC1363 is IERC20, ERC165 {
    /*
     * Note: the ERC-165 identifier for this interface is 0x4bbee2df.
     * 0x4bbee2df ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)'))
     */

    /*
     * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce.
     * 0xfb9ec8ce ===
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */

    /**
     * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
     * @param to address The address which you want to transfer to
     * @param value uint256 The amount of tokens to be transferred
     * @return true unless throwing
     */
    function transferAndCall(address to, uint256 value) public returns (bool);

    /**
     * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver
     * @param to address The address which you want to transfer to
     * @param value uint256 The amount of tokens to be transferred
     * @param data bytes Additional data with no specified format, sent in call to `to`
     * @return true unless throwing
     */
    function transferAndCall(address to, uint256 value, bytes memory data) public returns (bool);

    /**
     * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver
     * @param from address The address which you want to send tokens from
     * @param to address The address which you want to transfer to
     * @param value uint256 The amount of tokens to be transferred
     * @return true unless throwing
     */
    function transferFromAndCall(address from, address to, uint256 value) public returns (bool);


    /**
     * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver
     * @param from address The address which you want to send tokens from
     * @param to address The address which you want to transfer to
     * @param value uint256 The amount of tokens to be transferred
     * @param data bytes Additional data with no specified format, sent in call to `to`
     * @return true unless throwing
     */
    function transferFromAndCall(address from, address to, uint256 value, bytes memory data) public returns (bool);

    /**
     * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
     * and then call `onApprovalReceived` on spender.
     * 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
     * @param spender address The address which will spend the funds
     * @param value uint256 The amount of tokens to be spent
     */
    function approveAndCall(address spender, uint256 value) public returns (bool);

    /**
     * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender
     * and then call `onApprovalReceived` on spender.
     * 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
     * @param spender address The address which will spend the funds
     * @param value uint256 The amount of tokens to be spent
     * @param data bytes Additional data with no specified format, sent in call to `spender`
     */
    function approveAndCall(address spender, uint256 value, bytes memory data) public returns (bool);
}

// File: erc-payable-token/contracts/token/ERC1363/IERC1363Receiver.sol

/**
 * @title IERC1363Receiver Interface
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Interface for any contract that wants to support transferAndCall or transferFromAndCall
 *  from ERC1363 token contracts as defined in
 *  https://github.com/ethereum/EIPs/issues/1363
 */
contract IERC1363Receiver {
    /*
     * Note: the ERC-165 identifier for this interface is 0x88a7ca5c.
     * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))
     */

    /**
     * @notice Handle the receipt of ERC1363 tokens
     * @dev Any ERC1363 smart contract calls this function on the recipient
     * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the
     * transfer. Return of other than the magic value MUST result in the
     * transaction being reverted.
     * Note: the token contract address is always the message sender.
     * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
     * @param from address The address which are token transferred from
     * @param value uint256 The amount of tokens transferred
     * @param data bytes Additional data with no specified format
     * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`
     *  unless throwing
     */
    function onTransferReceived(address operator, address from, uint256 value, bytes memory data) public returns (bytes4); // solhint-disable-line  max-line-length
}

// File: erc-payable-token/contracts/token/ERC1363/IERC1363Spender.sol

/**
 * @title IERC1363Spender Interface
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Interface for any contract that wants to support approveAndCall
 *  from ERC1363 token contracts as defined in
 *  https://github.com/ethereum/EIPs/issues/1363
 */
contract IERC1363Spender {
    /*
     * Note: the ERC-165 identifier for this interface is 0x7b04a2d0.
     * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))
     */

    /**
     * @notice Handle the approval of ERC1363 tokens
     * @dev Any ERC1363 smart contract calls this function on the recipient
     * after an `approve`. This function MAY throw to revert and reject the
     * approval. Return of other than the magic value MUST result in the
     * transaction being reverted.
     * Note: the token contract address is always the message sender.
     * @param owner address The address which called `approveAndCall` function
     * @param value uint256 The amount of tokens to be spent
     * @param data bytes Additional data with no specified format
     * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`
     *  unless throwing
     */
    function onApprovalReceived(address owner, uint256 value, bytes memory data) public returns (bytes4);
}

// File: erc-payable-token/contracts/payment/ERC1363Payable.sol

/**
 * @title ERC1363Payable
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Implementation proposal of a contract that wants to accept ERC1363 payments
 */
contract ERC1363Payable is IERC1363Receiver, IERC1363Spender, ERC165 {
    using ERC165Checker for address;

    /**
     * @dev Magic value to be returned upon successful reception of ERC1363 tokens
     *  Equals to `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`,
     *  which can be also obtained as `IERC1363Receiver(0).onTransferReceived.selector`
     */
    bytes4 internal constant _INTERFACE_ID_ERC1363_RECEIVER = 0x88a7ca5c;

    /**
     * @dev Magic value to be returned upon successful approval of ERC1363 tokens.
     * Equals to `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`,
     * which can be also obtained as `IERC1363Spender(0).onApprovalReceived.selector`
     */
    bytes4 internal constant _INTERFACE_ID_ERC1363_SPENDER = 0x7b04a2d0;

    /*
     * Note: the ERC-165 identifier for the ERC1363 token transfer
     * 0x4bbee2df ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)'))
     */
    bytes4 private constant _INTERFACE_ID_ERC1363_TRANSFER = 0x4bbee2df;

    /*
     * Note: the ERC-165 identifier for the ERC1363 token approval
     * 0xfb9ec8ce ===
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */
    bytes4 private constant _INTERFACE_ID_ERC1363_APPROVE = 0xfb9ec8ce;

    event TokensReceived(
        address indexed operator,
        address indexed from,
        uint256 value,
        bytes data
    );

    event TokensApproved(
        address indexed owner,
        uint256 value,
        bytes data
    );

    // The ERC1363 token accepted
    IERC1363 private _acceptedToken;

    /**
     * @param acceptedToken Address of the token being accepted
     */
    constructor(IERC1363 acceptedToken) public {
        require(address(acceptedToken) != address(0));
        require(
            acceptedToken.supportsInterface(_INTERFACE_ID_ERC1363_TRANSFER) &&
            acceptedToken.supportsInterface(_INTERFACE_ID_ERC1363_APPROVE)
        );

        _acceptedToken = acceptedToken;

        // register the supported interface to conform to IERC1363Receiver and IERC1363Spender via ERC165
        _registerInterface(_INTERFACE_ID_ERC1363_RECEIVER);
        _registerInterface(_INTERFACE_ID_ERC1363_SPENDER);
    }

    /*
     * @dev Note: remember that the token contract address is always the message sender.
     * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
     * @param from address The address which are token transferred from
     * @param value uint256 The amount of tokens transferred
     * @param data bytes Additional data with no specified format
     */
    function onTransferReceived(address operator, address from, uint256 value, bytes memory data) public returns (bytes4) { // solhint-disable-line  max-line-length
        require(msg.sender == address(_acceptedToken));

        emit TokensReceived(operator, from, value, data);

        _transferReceived(operator, from, value, data);

        return _INTERFACE_ID_ERC1363_RECEIVER;
    }

    /*
     * @dev Note: remember that the token contract address is always the message sender.
     * @param owner address The address which called `approveAndCall` function
     * @param value uint256 The amount of tokens to be spent
     * @param data bytes Additional data with no specified format
     */
    function onApprovalReceived(address owner, uint256 value, bytes memory data) public returns (bytes4) {
        require(msg.sender == address(_acceptedToken));

        emit TokensApproved(owner, value, data);

        _approvalReceived(owner, value, data);

        return _INTERFACE_ID_ERC1363_SPENDER;
    }

    /**
     * @dev The ERC1363 token accepted
     */
    function acceptedToken() public view returns (IERC1363) {
        return _acceptedToken;
    }

    /**
     * @dev Called after validating a `onTransferReceived`. Override this method to
     * make your stuffs within your contract.
     * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
     * @param from address The address which are token transferred from
     * @param value uint256 The amount of tokens transferred
     * @param data bytes Additional data with no specified format
     */
    function _transferReceived(address operator, address from, uint256 value, bytes memory data) internal {
        // solhint-disable-previous-line no-empty-blocks

        // optional override
    }

    /**
     * @dev Called after validating a `onApprovalReceived`. Override this method to
     * make your stuffs within your contract.
     * @param owner address The address which called `approveAndCall` function
     * @param value uint256 The amount of tokens to be spent
     * @param data bytes Additional data with no specified format
     */
    function _approvalReceived(address owner, uint256 value, bytes memory data) internal {
        // solhint-disable-previous-line no-empty-blocks

        // optional override
    }
}

// File: openzeppelin-solidity/contracts/access/Roles.sol

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

// File: dao-smartcontracts/contracts/access/roles/DAORoles.sol

/**
 * @title DAORoles
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev It identifies the DAO roles
 */
contract DAORoles is Ownable {
    using Roles for Roles.Role;

    event OperatorAdded(address indexed account);
    event OperatorRemoved(address indexed account);

    event DappAdded(address indexed account);
    event DappRemoved(address indexed account);

    Roles.Role private _operators;
    Roles.Role private _dapps;

    constructor () internal {} // solhint-disable-line no-empty-blocks

    modifier onlyOperator() {
        require(isOperator(msg.sender));
        _;
    }

    modifier onlyDapp() {
        require(isDapp(msg.sender));
        _;
    }

    /**
     * @dev Check if an address has the `operator` role
     * @param account Address you want to check
     */
    function isOperator(address account) public view returns (bool) {
        return _operators.has(account);
    }

    /**
     * @dev Check if an address has the `dapp` role
     * @param account Address you want to check
     */
    function isDapp(address account) public view returns (bool) {
        return _dapps.has(account);
    }

    /**
     * @dev Add the `operator` role from address
     * @param account Address you want to add role
     */
    function addOperator(address account) public onlyOwner {
        _addOperator(account);
    }

    /**
     * @dev Add the `dapp` role from address
     * @param account Address you want to add role
     */
    function addDapp(address account) public onlyOperator {
        _addDapp(account);
    }

    /**
     * @dev Remove the `operator` role from address
     * @param account Address you want to remove role
     */
    function removeOperator(address account) public onlyOwner {
        _removeOperator(account);
    }

    /**
     * @dev Remove the `operator` role from address
     * @param account Address you want to remove role
     */
    function removeDapp(address account) public onlyOperator {
        _removeDapp(account);
    }

    function _addOperator(address account) internal {
        _operators.add(account);
        emit OperatorAdded(account);
    }

    function _addDapp(address account) internal {
        _dapps.add(account);
        emit DappAdded(account);
    }

    function _removeOperator(address account) internal {
        _operators.remove(account);
        emit OperatorRemoved(account);
    }

    function _removeDapp(address account) internal {
        _dapps.remove(account);
        emit DappRemoved(account);
    }
}

// File: dao-smartcontracts/contracts/dao/Organization.sol

/**
 * @title Organization
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Library for managing organization
 */
library Organization {
    using SafeMath for uint256;

    // structure defining a member
    struct Member {
        uint256 id;
        address account;
        bytes9 fingerprint;
        uint256 creationDate;
        uint256 stakedTokens;
        uint256 usedTokens;
        bytes32 data;
        bool approved;
    }

    // structure defining members status
    struct Members {
        uint256 count;
        uint256 totalStakedTokens;
        uint256 totalUsedTokens;
        mapping(address => uint256) addressMap;
        mapping(uint256 => Member) list;
    }

    /**
     * @dev Returns if an address is member or not
     * @param members Current members struct
     * @param account Address of the member you are looking for
     * @return bool
     */
    function isMember(Members storage members, address account) internal view returns (bool) {
        return members.addressMap[account] != 0;
    }

    /**
     * @dev Get creation date of a member
     * @param members Current members struct
     * @param account Address you want to check
     * @return uint256 Member creation date, zero otherwise
     */
    function creationDateOf(Members storage members, address account) internal view returns (uint256) {
        Member storage member = members.list[members.addressMap[account]];

        return member.creationDate;
    }

    /**
     * @dev Check how many tokens staked for given address
     * @param members Current members struct
     * @param account Address you want to check
     * @return uint256 Member staked tokens
     */
    function stakedTokensOf(Members storage members, address account) internal view returns (uint256) {
        Member storage member = members.list[members.addressMap[account]];

        return member.stakedTokens;
    }

    /**
     * @dev Check how many tokens used for given address
     * @param members Current members struct
     * @param account Address you want to check
     * @return uint256 Member used tokens
     */
    function usedTokensOf(Members storage members, address account) internal view returns (uint256) {
        Member storage member = members.list[members.addressMap[account]];

        return member.usedTokens;
    }

    /**
     * @dev Check if an address has been approved
     * @param members Current members struct
     * @param account Address you want to check
     * @return bool
     */
    function isApproved(Members storage members, address account) internal view returns (bool) {
        Member storage member = members.list[members.addressMap[account]];

        return member.approved;
    }

    /**
     * @dev Returns the member structure
     * @param members Current members struct
     * @param memberId Id of the member you are looking for
     * @return Member
     */
    function getMember(Members storage members, uint256 memberId) internal view returns (Member storage) {
        Member storage structure = members.list[memberId];

        require(structure.account != address(0));

        return structure;
    }

    /**
     * @dev Generate a new member and the member structure
     * @param members Current members struct
     * @param account Address you want to make member
     * @return uint256 The new member id
     */
    function addMember(Members storage members, address account) internal returns (uint256) {
        require(account != address(0));
        require(!isMember(members, account));

        uint256 memberId = members.count.add(1);
        bytes9 fingerprint = getFingerprint(account, memberId);

        members.addressMap[account] = memberId;
        members.list[memberId] = Member(
            memberId,
            account,
            fingerprint,
            block.timestamp, // solhint-disable-line not-rely-on-time
            0,
            0,
            "",
            false
        );

        members.count = memberId;

        return memberId;
    }

    /**
     * @dev Add tokens to member stack
     * @param members Current members struct
     * @param account Address you want to stake tokens
     * @param amount Number of tokens to stake
     */
    function stake(Members storage members, address account, uint256 amount) internal {
        require(isMember(members, account));

        Member storage member = members.list[members.addressMap[account]];

        member.stakedTokens = member.stakedTokens.add(amount);
        members.totalStakedTokens = members.totalStakedTokens.add(amount);
    }

    /**
     * @dev Remove tokens from member stack
     * @param members Current members struct
     * @param account Address you want to unstake tokens
     * @param amount Number of tokens to unstake
     */
    function unstake(Members storage members, address account, uint256 amount) internal {
        require(isMember(members, account));

        Member storage member = members.list[members.addressMap[account]];

        require(member.stakedTokens >= amount);

        member.stakedTokens = member.stakedTokens.sub(amount);
        members.totalStakedTokens = members.totalStakedTokens.sub(amount);
    }

    /**
     * @dev Use tokens from member stack
     * @param members Current members struct
     * @param account Address you want to use tokens
     * @param amount Number of tokens to use
     */
    function use(Members storage members, address account, uint256 amount) internal {
        require(isMember(members, account));

        Member storage member = members.list[members.addressMap[account]];

        require(member.stakedTokens >= amount);

        member.stakedTokens = member.stakedTokens.sub(amount);
        members.totalStakedTokens = members.totalStakedTokens.sub(amount);

        member.usedTokens = member.usedTokens.add(amount);
        members.totalUsedTokens = members.totalUsedTokens.add(amount);
    }

    /**
     * @dev Set the approved status for a member
     * @param members Current members struct
     * @param account Address you want to update
     * @param status Bool the new status for approved
     */
    function setApproved(Members storage members, address account, bool status) internal {
        require(isMember(members, account));

        Member storage member = members.list[members.addressMap[account]];

        member.approved = status;
    }

    /**
     * @dev Set data for a member
     * @param members Current members struct
     * @param account Address you want to update
     * @param data bytes32 updated data
     */
    function setData(Members storage members, address account, bytes32 data) internal {
        require(isMember(members, account));

        Member storage member = members.list[members.addressMap[account]];

        member.data = data;
    }

    /**
     * @dev Generate a member fingerprint
     * @param account Address you want to make member
     * @param memberId The member id
     * @return bytes9 It represents member fingerprint
     */
    function getFingerprint(address account, uint256 memberId) private pure returns (bytes9) {
        return bytes9(keccak256(abi.encodePacked(account, memberId)));
    }
}

// File: dao-smartcontracts/contracts/dao/DAO.sol

/**
 * @title DAO
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev It identifies the DAO and Organization logic
 */
contract DAO is ERC1363Payable, DAORoles {
    using SafeMath for uint256;

    using Organization for Organization.Members;
    using Organization for Organization.Member;

    event MemberAdded(
        address indexed account,
        uint256 id
    );

    event MemberStatusChanged(
        address indexed account,
        bool approved
    );

    event TokensStaked(
        address indexed account,
        uint256 value
    );

    event TokensUnstaked(
        address indexed account,
        uint256 value
    );

    event TokensUsed(
        address indexed account,
        address indexed dapp,
        uint256 value
    );

    Organization.Members private _members;

    constructor (IERC1363 acceptedToken) public ERC1363Payable(acceptedToken) {} // solhint-disable-line no-empty-blocks

    /**
     * @dev fallback. This function will create a new member
     */
    function () external payable { // solhint-disable-line no-complex-fallback
        require(msg.value == 0);

        _newMember(msg.sender);
    }

    /**
     * @dev Generate a new member and the member structure
     */
    function join() external {
        _newMember(msg.sender);
    }

    /**
     * @dev Generate a new member and the member structure
     * @param account Address you want to make member
     */
    function newMember(address account) external onlyOperator {
        _newMember(account);
    }

    /**
     * @dev Set the approved status for a member
     * @param account Address you want to update
     * @param status Bool the new status for approved
     */
    function setApproved(address account, bool status) external onlyOperator {
        _members.setApproved(account, status);

        emit MemberStatusChanged(account, status);
    }

    /**
     * @dev Set data for a member
     * @param account Address you want to update
     * @param data bytes32 updated data
     */
    function setData(address account, bytes32 data) external onlyOperator {
        _members.setData(account, data);
    }

    /**
     * @dev Use tokens from a specific account
     * @param account Address to use the tokens from
     * @param amount Number of tokens to use
     */
    function use(address account, uint256 amount) external onlyDapp {
        _members.use(account, amount);

        IERC20(acceptedToken()).transfer(msg.sender, amount);

        emit TokensUsed(account, msg.sender, amount);
    }

    /**
     * @dev Remove tokens from member stack
     * @param amount Number of tokens to unstake
     */
    function unstake(uint256 amount) public {
        _members.unstake(msg.sender, amount);

        IERC20(acceptedToken()).transfer(msg.sender, amount);

        emit TokensUnstaked(msg.sender, amount);
    }

    /**
     * @dev Returns the members number
     * @return uint256
     */
    function membersNumber() public view returns (uint256) {
        return _members.count;
    }

    /**
     * @dev Returns the total staked tokens number
     * @return uint256
     */
    function totalStakedTokens() public view returns (uint256) {
        return _members.totalStakedTokens;
    }

    /**
     * @dev Returns the total used tokens number
     * @return uint256
     */
    function totalUsedTokens() public view returns (uint256) {
        return _members.totalUsedTokens;
    }

    /**
     * @dev Returns if an address is member or not
     * @param account Address of the member you are looking for
     * @return bool
     */
    function isMember(address account) public view returns (bool) {
        return _members.isMember(account);
    }

    /**
     * @dev Get creation date of a member
     * @param account Address you want to check
     * @return uint256 Member creation date, zero otherwise
     */
    function creationDateOf(address account) public view returns (uint256) {
        return _members.creationDateOf(account);
    }

    /**
     * @dev Check how many tokens staked for given address
     * @param account Address you want to check
     * @return uint256 Member staked tokens
     */
    function stakedTokensOf(address account) public view returns (uint256) {
        return _members.stakedTokensOf(account);
    }

    /**
     * @dev Check how many tokens used for given address
     * @param account Address you want to check
     * @return uint256 Member used tokens
     */
    function usedTokensOf(address account) public view returns (uint256) {
        return _members.usedTokensOf(account);
    }

    /**
     * @dev Check if an address has been approved
     * @param account Address you want to check
     * @return bool
     */
    function isApproved(address account) public view returns (bool) {
        return _members.isApproved(account);
    }

    /**
     * @dev Returns the member structure
     * @param memberAddress Address of the member you are looking for
     * @return array
     */
    function getMemberByAddress(address memberAddress)
        public
        view
        returns (
            uint256 id,
            address account,
            bytes9 fingerprint,
            uint256 creationDate,
            uint256 stakedTokens,
            uint256 usedTokens,
            bytes32 data,
            bool approved
        )
    {
        return getMemberById(_members.addressMap[memberAddress]);
    }

    /**
     * @dev Returns the member structure
     * @param memberId Id of the member you are looking for
     * @return array
     */
    function getMemberById(uint256 memberId)
        public
        view
        returns (
            uint256 id,
            address account,
            bytes9 fingerprint,
            uint256 creationDate,
            uint256 stakedTokens,
            uint256 usedTokens,
            bytes32 data,
            bool approved
        )
    {
        Organization.Member storage structure = _members.getMember(memberId);

        id = structure.id;
        account = structure.account;
        fingerprint = structure.fingerprint;
        creationDate = structure.creationDate;
        stakedTokens = structure.stakedTokens;
        usedTokens = structure.usedTokens;
        data = structure.data;
        approved = structure.approved;
    }

    /**
     * @dev Allow to recover tokens from contract
     * @param tokenAddress address The token contract address
     * @param tokenAmount uint256 Number of tokens to be sent
     */
    function recoverERC20(address tokenAddress, uint256 tokenAmount) public onlyOwner {
        if (tokenAddress == address(acceptedToken())) {
            uint256 currentBalance = IERC20(acceptedToken()).balanceOf(address(this));
            require(currentBalance.sub(_members.totalStakedTokens) >= tokenAmount);
        }

        IERC20(tokenAddress).transfer(owner(), tokenAmount);
    }

    /**
     * @dev Called after validating a `onTransferReceived`
     * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function
     * @param from address The address which are token transferred from
     * @param value uint256 The amount of tokens transferred
     * @param data bytes Additional data with no specified format
     */
    function _transferReceived(
        address operator, // solhint-disable-line no-unused-vars
        address from,
        uint256 value,
        bytes memory data // solhint-disable-line no-unused-vars
    )
        internal
    {
        _stake(from, value);
    }

    /**
     * @dev Called after validating a `onApprovalReceived`
     * @param owner address The address which called `approveAndCall` function
     * @param value uint256 The amount of tokens to be spent
     * @param data bytes Additional data with no specified format
     */
    function _approvalReceived(
        address owner,
        uint256 value,
        bytes memory data // solhint-disable-line no-unused-vars
    )
        internal
    {
        IERC20(acceptedToken()).transferFrom(owner, address(this), value);

        _stake(owner, value);
    }

    /**
     * @dev Generate a new member and the member structure
     * @param account Address you want to make member
     * @return uint256 The new member id
     */
    function _newMember(address account) internal {
        uint256 memberId = _members.addMember(account);

        emit MemberAdded(account, memberId);
    }

    /**
     * @dev Add tokens to member stack
     * @param account Address you want to stake tokens
     * @param amount Number of tokens to stake
     */
    function _stake(address account, uint256 amount) internal {
        if (!isMember(account)) {
            _newMember(account);
        }

        _members.stake(account, amount);

        emit TokensStaked(account, amount);
    }
}

// File: contracts/faucet/TokenFaucet.sol

/**
 * @title TokenFaucet
 * @author Vittorio Minacori (https://github.com/vittominacori)
 * @dev Implementation of a TokenFaucet
 */
contract TokenFaucet is TokenRecover {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    event FaucetCreated(address indexed token);

    // struct representing the enabled faucet
    struct FaucetDetail {
        bool exists;
        bool enabled;
        uint256 dailyRate;
        uint256 referralRate;
        uint256 totalDistributedTokens;
    }

    // struct representing the faucet status for an account
    struct RecipientDetail {
        bool exists;
        mapping(address => uint256) tokens;
        mapping(address => uint256) lastUpdate;
        address referral;
    }

    // struct representing the referral status
    struct ReferralDetail {
        mapping(address => uint256) tokens;
        address[] recipients;
    }

    // the time between two tokens claim
    uint256 private _pauseTime = 1 days;

    // the DAO smart contract
    DAO private _dao;

    // list of addresses who received tokens
    address[] private _recipients;

    // map of address and faucet details
    mapping(address => FaucetDetail) private _faucetList;

    // map of address and received token amount
    mapping(address => RecipientDetail) private _recipientList;

    // map of address and referred addresses
    mapping(address => ReferralDetail) private _referralList;

    /**
     * @param dao DAO the decentralized organization address
     */
    constructor(address payable dao) public {
        require(dao != address(0), "TokenFaucet: dao is the zero address");

        _dao = DAO(dao);
    }

    /**
     * @return the DAO smart contract
     */
    function dao() public view returns (DAO) {
        return _dao;
    }

    /**
     * @param token The token address to check
     * @return if faucet is enabled or not
     */
    function isEnabled(address token) public view returns (bool) {
        return _faucetList[token].enabled;
    }

    /**
     * @param token The token address to check
     * @return the daily rate of tokens distributed
     */
    function getDailyRate(address token) public view returns (uint256) {
        return _faucetList[token].dailyRate;
    }

    /**
     * @param token The token address to check
     * @return the value earned by referral for each recipient
     */
    function getReferralRate(address token) public view returns (uint256) {
        return _faucetList[token].referralRate;
    }

    /**
     * @param token The token address to check
     * @return the sum of distributed tokens
     */
    function totalDistributedTokens(address token) public view returns (uint256) {
        return _faucetList[token].totalDistributedTokens;
    }

    /**
     * @dev return the number of remaining tokens to distribute
     * @param token The token address to check
     * @return uint256
     */
    function remainingTokens(address token) public view returns (uint256) {
        return IERC20(token).balanceOf(address(this));
    }

    /**
     * @return address of a recipient by list index
     */
    function getRecipientAddress(uint256 index) public view returns (address) {
        return _recipients[index];
    }

    /**
     * @dev return the recipients length
     * @return uint
     */
    function getRecipientsLength() public view returns (uint) {
        return _recipients.length;
    }

    /**
     * @param account The address to check
     * @param token The token address to check
     * @return received token amount for the given address
     */
    function receivedTokens(address account, address token) public view returns (uint256) {
        return _recipientList[account].tokens[token];
    }

    /**
     * @param account The address to check
     * @param token The token address to check
     * @return last tokens received timestamp
     */
    function lastUpdate(address account, address token) public view returns (uint256) {
        return _recipientList[account].lastUpdate[token];
    }

    /**
     * @param account The address to check
     * @return referral for given address
     */
    function getReferral(address account) public view returns (address) {
        return _recipientList[account].referral;
    }

    /**
     * @param account The address to check
     * @param token The token address to check
     * @return earned tokens by referrals
     */
    function earnedByReferral(address account, address token) public view returns (uint256) {
        return _referralList[account].tokens[token];
    }

    /**
     * @param account The address to check
     * @return referred addresses for given address
     */
    function getReferredAddresses(address account) public view returns (address[] memory) {
        return _referralList[account].recipients;
    }

    /**
     * @param account The address to check
     * @return referred addresses for given address
     */
    function getReferredAddressesLength(address account) public view returns (uint) {
        return _referralList[account].recipients.length;
    }

    /**
     * @param account The address to check
     * @param token The token address to check
     * @return time of next available claim or zero
     */
    function nextClaimTime(address account, address token) public view returns (uint256) {
        return lastUpdate(account, token) == 0 ? 0 : lastUpdate(account, token) + _pauseTime;
    }

    /**
     * @param token Address of the token being distributed
     * @param dailyRate Daily rate of tokens distributed
     * @param referralRate The value earned by referral
     */
    function createFaucet(address token, uint256 dailyRate, uint256 referralRate) public onlyOwner {
        require(!_faucetList[token].exists, "TokenFaucet: token faucet already exists");
        require(token != address(0), "TokenFaucet: token is the zero address");
        require(dailyRate > 0, "TokenFaucet: dailyRate is 0");
        require(referralRate > 0, "TokenFaucet: referralRate is 0");

        _faucetList[token].exists = true;
        _faucetList[token].enabled = true;
        _faucetList[token].dailyRate = dailyRate;
        _faucetList[token].referralRate = referralRate;

        emit FaucetCreated(token);
    }

    /**
     * @dev change daily referral rate
     * @param token Address of tokens being updated
     * @param newDailyRate Daily rate of tokens distributed
     * @param newReferralRate The value earned by referral
     */
    function setFaucetRates(address token, uint256 newDailyRate, uint256 newReferralRate) public onlyOwner {
        require(_faucetList[token].exists, "TokenFaucet: token faucet does not exist");
        require(newDailyRate > 0, "TokenFaucet: dailyRate is 0");
        require(newReferralRate > 0, "TokenFaucet: referralRate is 0");

        _faucetList[token].dailyRate = newDailyRate;
        _faucetList[token].referralRate = newReferralRate;
    }

    /**
     * @dev disable a faucet
     * @param token Address of tokens being updated
     */
    function disableFaucet(address token) public onlyOwner {
        require(_faucetList[token].exists, "TokenFaucet: token faucet does not exist");

        _faucetList[token].enabled = false;
    }

    /**
     * @dev enable a faucet
     * @param token Address of tokens being updated
     */
    function enableFaucet(address token) public onlyOwner {
        require(_faucetList[token].exists, "TokenFaucet: token faucet does not exist");

        _faucetList[token].enabled = true;
    }

    /**
     * @dev function to be called to receive tokens
     * @param token The token address to distribute
     */
    function getTokens(address token) public {
        require(_faucetList[token].exists, "TokenFaucet: token faucet does not exist");
        require(_dao.isMember(msg.sender), "TokenFaucet: message sender is not dao member");

        // distribute tokens
        _distributeTokens(token, msg.sender, address(0));
    }

    /**
     * @dev function to be called to receive tokens
     * @param token The token address to distribute
     * @param referral Address to an account that is referring
     */
    function getTokensWithReferral(address token, address referral) public {
        require(_faucetList[token].exists, "TokenFaucet: token faucet does not exist");
        require(_dao.isMember(msg.sender), "TokenFaucet: message sender is not dao member");
        require(referral != msg.sender, "TokenFaucet: referral cannot be message sender");

        // distribute tokens
        _distributeTokens(token, msg.sender, referral);
    }

    /**
     * @dev The way in which faucet tokens rate is calculated for recipient
     * @param token Address of tokens being distributed
     * @param account Address receiving the tokens
     * @return Number of tokens that can be received
     */
    function _getRecipientTokenAmount(address token, address account) internal view returns (uint256) {
        uint256 tokenAmount = getDailyRate(token);

        if (_dao.stakedTokensOf(account) > 0) {
            tokenAmount = tokenAmount.mul(2);
        }

        if (_dao.usedTokensOf(account) > 0) {
            tokenAmount = tokenAmount.mul(2);
        }

        return tokenAmount;
    }

    /**
     * @dev The way in which faucet tokens rate is calculated for referral
     * @param token Address of tokens being distributed
     * @param account Address receiving the tokens
     * @return Number of tokens that can be received
     */
    function _getReferralTokenAmount(address token, address account) internal view returns (uint256) {
        uint256 tokenAmount = 0;

        if (_dao.isMember(account)) {
            tokenAmount = getReferralRate(token);

            if (_dao.stakedTokensOf(account) > 0) {
                tokenAmount = tokenAmount.mul(2);
            }

            if (_dao.usedTokensOf(account) > 0) {
                tokenAmount = tokenAmount.mul(2);
            }
        }

        return tokenAmount;
    }

    /**
     * @dev distribute tokens
     * @param token The token being distributed
     * @param account Address being distributing
     * @param referral Address to an account that is referring
     */
    function _distributeTokens(address token, address account, address referral) internal {
        // solhint-disable-next-line not-rely-on-time
        require(nextClaimTime(account, token) <= block.timestamp, "TokenFaucet: next claim date is not passed");

        // check if recipient exists
        if (!_recipientList[account].exists) {
            _recipients.push(account);
            _recipientList[account].exists = true;

            // check if valid referral
            if (referral != address(0)) {
                _recipientList[account].referral = referral;
                _referralList[referral].recipients.push(account);
            }
        }

        uint256 recipientTokenAmount = _getRecipientTokenAmount(token, account);

        // update recipient status

        // solhint-disable-next-line not-rely-on-time
        _recipientList[account].lastUpdate[token] = block.timestamp;
        _recipientList[account].tokens[token] = _recipientList[account].tokens[token].add(recipientTokenAmount);

        // update faucet status
        _faucetList[token].totalDistributedTokens = _faucetList[token].totalDistributedTokens.add(recipientTokenAmount);

        // transfer tokens to recipient
        IERC20(token).safeTransfer(account, recipientTokenAmount);

        // check referral

        if (_recipientList[account].referral != address(0)) {
            // referral is only the first one referring
            address firstReferral = _recipientList[account].referral;

            uint256 referralTokenAmount = _getReferralTokenAmount(token, firstReferral);

            // referral can earn only if it is dao member
            if (referralTokenAmount > 0) {
                // update referral status
                _referralList[firstReferral].tokens[token] = _referralList[firstReferral].tokens[token].add(referralTokenAmount);

                // update faucet status
                _faucetList[token].totalDistributedTokens = _faucetList[token].totalDistributedTokens.add(referralTokenAmount);

                // transfer tokens to referral
                IERC20(token).safeTransfer(firstReferral, referralTokenAmount);
            }
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"token","type":"address"}],"name":"earnedByReferral","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"getRecipientAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"remainingTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getReferral","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"token","type":"address"}],"name":"nextClaimTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dao","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"totalDistributedTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"getTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getDailyRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getReferredAddresses","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"referral","type":"address"}],"name":"getTokensWithReferral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getReferredAddressesLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"dailyRate","type":"uint256"},{"name":"referralRate","type":"uint256"}],"name":"createFaucet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"token","type":"address"}],"name":"receivedTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"disableFaucet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"token","type":"address"}],"name":"lastUpdate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"isEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"newDailyRate","type":"uint256"},{"name":"newReferralRate","type":"uint256"}],"name":"setFaucetRates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getReferralRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecipientsLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"enableFaucet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"dao","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token","type":"address"}],"name":"FaucetCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

60806040526201518060015534801561001757600080fd5b50604051611cb8380380611cb88339818101604052602081101561003a57600080fd5b5051600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600160a01b0381166100e4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180611c946024913960400191505060405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055611b81806101136000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c806373f2888c116100de5780638f32d59b11610097578063d24a1c9811610071578063d24a1c9814610530578063dbc3e35b14610556578063e4596dc41461055e578063f2fde38b146105845761018e565b80638f32d59b146104bc5780639015d371146104d857806392dae580146104fe5761018e565b806373f2888c146103d457806384513a111461040657806387a8af4e1461043457806388ad7a611461045a5780638980f11f146104885780638da5cb5b146104b45761018e565b8063438752f51161014b578063661f905b11610125578063661f905b146103025780636ce11d95146103785780636f1bfbb6146103a6578063715018a6146103cc5761018e565b8063438752f51461028e578063450efe21146102b45780634ad99662146102dc5761018e565b8063108444891461019357806318337012146101d3578063236f86a11461020c5780633b0f0f2f146102325780633cd4aa8d146102585780634162169f14610286575b600080fd5b6101c1600480360360408110156101a957600080fd5b506001600160a01b03813581169160200135166105aa565b60408051918252519081900360200190f35b6101f0600480360360208110156101e957600080fd5b50356105d7565b604080516001600160a01b039092168252519081900360200190f35b6101c16004803603602081101561022257600080fd5b50356001600160a01b0316610601565b6101f06004803603602081101561024857600080fd5b50356001600160a01b031661067d565b6101c16004803603604081101561026e57600080fd5b506001600160a01b038135811691602001351661069e565b6101f06106cc565b6101c1600480360360208110156102a457600080fd5b50356001600160a01b03166106db565b6102da600480360360208110156102ca57600080fd5b50356001600160a01b03166106f9565b005b6101c1600480360360208110156102f257600080fd5b50356001600160a01b0316610811565b6103286004803603602081101561031857600080fd5b50356001600160a01b031661082f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561036457818101518382015260200161034c565b505050509050019250505060405180910390f35b6102da6004803603604081101561038e57600080fd5b506001600160a01b03813581169160200135166108a8565b6101c1600480360360208110156103bc57600080fd5b50356001600160a01b0316610a08565b6102da610a26565b6102da600480360360608110156103ea57600080fd5b506001600160a01b038135169060208101359060400135610ab7565b6101c16004803603604081101561041c57600080fd5b506001600160a01b0381358116916020013516610caa565b6102da6004803603602081101561044a57600080fd5b50356001600160a01b0316610cd9565b6101c16004803603604081101561047057600080fd5b506001600160a01b0381358116916020013516610d99565b6102da6004803603604081101561049e57600080fd5b506001600160a01b038135169060200135610dc8565b6101f0610ea6565b6104c4610eb5565b604080519115158252519081900360200190f35b6104c4600480360360208110156104ee57600080fd5b50356001600160a01b0316610ec6565b6102da6004803603606081101561051457600080fd5b506001600160a01b038135169060208101359060400135610ee9565b6101c16004803603602081101561054657600080fd5b50356001600160a01b0316611058565b6101c1611076565b6102da6004803603602081101561057457600080fd5b50356001600160a01b031661107c565b6102da6004803603602081101561059a57600080fd5b50356001600160a01b0316611140565b6001600160a01b038083166000908152600660209081526040808320938516835292905220545b92915050565b6000600382815481106105e657fe5b6000918252602090912001546001600160a01b031692915050565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b15801561064b57600080fd5b505afa15801561065f573d6000803e3d6000fd5b505050506040513d602081101561067557600080fd5b505192915050565b6001600160a01b039081166000908152600560205260409020600301541690565b60006106aa8383610d99565b156106c2576001546106bc8484610d99565b016106c5565b60005b9392505050565b6002546001600160a01b031690565b6001600160a01b031660009081526004602052604090206003015490565b6001600160a01b03811660009081526004602052604090205460ff166107505760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6002546040805163288c314960e21b815233600482015290516001600160a01b039092169163a230c52491602480820192602092909190829003018186803b15801561079b57600080fd5b505afa1580156107af573d6000803e3d6000fd5b505050506040513d60208110156107c557600080fd5b50516108025760405162461bcd60e51b815260040180806020018281038252602d815260200180611a7a602d913960400191505060405180910390fd5b61080e81336000611190565b50565b6001600160a01b031660009081526004602052604090206001015490565b6001600160a01b03811660009081526006602090815260409182902060010180548351818402810184019094528084526060939283018282801561089c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161087e575b50505050509050919050565b6001600160a01b03821660009081526004602052604090205460ff166108ff5760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6002546040805163288c314960e21b815233600482015290516001600160a01b039092169163a230c52491602480820192602092909190829003018186803b15801561094a57600080fd5b505afa15801561095e573d6000803e3d6000fd5b505050506040513d602081101561097457600080fd5b50516109b15760405162461bcd60e51b815260040180806020018281038252602d815260200180611a7a602d913960400191505060405180910390fd5b6001600160a01b0381163314156109f95760405162461bcd60e51b815260040180806020018281038252602e815260200180611af9602e913960400191505060405180910390fd5b610a04823383611190565b5050565b6001600160a01b031660009081526006602052604090206001015490565b610a2e610eb5565b610a6d576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b610abf610eb5565b610afe576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526004602052604090205460ff1615610b565760405162461bcd60e51b8152600401808060200182810382526028815260200180611ad16028913960400191505060405180910390fd5b6001600160a01b038316610b9b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b276026913960400191505060405180910390fd5b60008211610bf0576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e4661756365743a206461696c795261746520697320300000000000604482015290519081900360640190fd5b60008111610c45576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e4661756365743a20726566657272616c5261746520697320300000604482015290519081900360640190fd5b6001600160a01b0383166000818152600460205260408082208054610100600160ff19909216821761ff0019161782558101869055600201849055517f9684f028e9a5f8e59dea680f5dddf7e9e11b4827702d5ab6ca4d5c6cf874567f9190a2505050565b6001600160a01b0391821660009081526005602090815260408083209390941682526001909201909152205490565b610ce1610eb5565b610d20576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205460ff16610d775760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6001600160a01b03166000908152600460205260409020805461ff0019169055565b6001600160a01b0391821660009081526005602090815260408083209390941682526002909201909152205490565b610dd0610eb5565b610e0f576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b816001600160a01b031663a9059cbb610e26610ea6565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610e7657600080fd5b505af1158015610e8a573d6000803e3d6000fd5b505050506040513d6020811015610ea057600080fd5b50505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6001600160a01b0316600090815260046020526040902054610100900460ff1690565b610ef1610eb5565b610f30576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526004602052604090205460ff16610f875760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b60008211610fdc576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e4661756365743a206461696c795261746520697320300000000000604482015290519081900360640190fd5b60008111611031576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e4661756365743a20726566657272616c5261746520697320300000604482015290519081900360640190fd5b6001600160a01b039092166000908152600460205260409020600181019190915560020155565b6001600160a01b031660009081526004602052604090206002015490565b60035490565b611084610eb5565b6110c3576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205460ff1661111a5760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6001600160a01b03166000908152600460205260409020805461ff001916610100179055565b611148610eb5565b611187576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b61080e8161148e565b4261119b838561069e565b11156111d85760405162461bcd60e51b815260040180806020018281038252602a8152602001806119e7602a913960400191505060405180910390fd5b6001600160a01b03821660009081526005602052604090205460ff166112bb576003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b038581169182179092556000908152600560205260409020805460ff19169092179091558116156112bb576001600160a01b03808316600081815260056020908152604080832060030180549587166001600160a01b031996871681179091558352600682528220600190810180549182018155835291200180549092161790555b60006112c7848461152e565b6001600160a01b038481166000908152600560209081526040808320938916835260028401825280832042905560019093019052205490915061130a908261166f565b6001600160a01b038085166000908152600560209081526040808320938916835260019093018152828220939093556004909252902060030154611354908263ffffffff61166f16565b6001600160a01b03851660008181526004602052604090206003019190915561138490848363ffffffff6116c916565b6001600160a01b038381166000908152600560205260409020600301541615610ea0576001600160a01b03808416600090815260056020526040812060030154909116906113d28683611720565b90508015611486576001600160a01b038083166000908152600660209081526040808320938a1683529290522054611410908263ffffffff61166f16565b6001600160a01b038084166000908152600660209081526040808320938b168352928152828220939093556004909252902060030154611456908263ffffffff61166f16565b6001600160a01b03871660008181526004602052604090206003019190915561148690838363ffffffff6116c916565b505050505050565b6001600160a01b0381166114d35760405162461bcd60e51b81526004018080602001828103825260268152602001806119c16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008061153a84610811565b60025460408051632ac2353f60e21b81526001600160a01b0387811660048301529151939450600093919092169163ab08d4fc916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505111156115d3576115d081600263ffffffff6117a916565b90505b6002546040805163d658197560e01b81526001600160a01b0386811660048301529151600093929092169163d658197591602480820192602092909190829003018186803b15801561162457600080fd5b505afa158015611638573d6000803e3d6000fd5b505050506040513d602081101561164e57600080fd5b505111156106c55761166781600263ffffffff6117a916565b949350505050565b6000828201838110156106c5576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261171b908490611802565b505050565b6002546040805163288c314960e21b81526001600160a01b03848116600483015291516000938493169163a230c524916024808301926020929190829003018186803b15801561176f57600080fd5b505afa158015611783573d6000803e3d6000fd5b505050506040513d602081101561179957600080fd5b5051156106c55761153a84611058565b6000826117b8575060006105d1565b828202828482816117c557fe5b04146106c55760405162461bcd60e51b8152600401808060200182810382526021815260200180611a396021913960400191505060405180910390fd5b611814826001600160a01b03166119ba565b611865576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106118a35780518252601f199092019160209182019101611884565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611905576040519150601f19603f3d011682016040523d82523d6000602084013e61190a565b606091505b509150915081611961576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610ea05780806020019051602081101561197d57600080fd5b5051610ea05760405162461bcd60e51b815260040180806020018281038252602a815260200180611aa7602a913960400191505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4661756365743a206e65787420636c61696d2064617465206973206e6f7420706173736564546f6b656e4661756365743a20746f6b656e2066617563657420646f6573206e6f74206578697374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4661756365743a206d6573736167652073656e646572206973206e6f742064616f206d656d6265725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564546f6b656e4661756365743a20746f6b656e2066617563657420616c726561647920657869737473546f6b656e4661756365743a20726566657272616c2063616e6e6f74206265206d6573736167652073656e646572546f6b656e4661756365743a20746f6b656e20697320746865207a65726f2061646472657373a265627a7a72305820e29718aa0e34d218a98ff09797ef5de29b843a17802d6e6e60cf26740df7739964736f6c634300050a0032546f6b656e4661756365743a2064616f20697320746865207a65726f2061646472657373000000000000000000000000a042c9143c8758d2ad5a3fcc08dec39f6964453e

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018e5760003560e01c806373f2888c116100de5780638f32d59b11610097578063d24a1c9811610071578063d24a1c9814610530578063dbc3e35b14610556578063e4596dc41461055e578063f2fde38b146105845761018e565b80638f32d59b146104bc5780639015d371146104d857806392dae580146104fe5761018e565b806373f2888c146103d457806384513a111461040657806387a8af4e1461043457806388ad7a611461045a5780638980f11f146104885780638da5cb5b146104b45761018e565b8063438752f51161014b578063661f905b11610125578063661f905b146103025780636ce11d95146103785780636f1bfbb6146103a6578063715018a6146103cc5761018e565b8063438752f51461028e578063450efe21146102b45780634ad99662146102dc5761018e565b8063108444891461019357806318337012146101d3578063236f86a11461020c5780633b0f0f2f146102325780633cd4aa8d146102585780634162169f14610286575b600080fd5b6101c1600480360360408110156101a957600080fd5b506001600160a01b03813581169160200135166105aa565b60408051918252519081900360200190f35b6101f0600480360360208110156101e957600080fd5b50356105d7565b604080516001600160a01b039092168252519081900360200190f35b6101c16004803603602081101561022257600080fd5b50356001600160a01b0316610601565b6101f06004803603602081101561024857600080fd5b50356001600160a01b031661067d565b6101c16004803603604081101561026e57600080fd5b506001600160a01b038135811691602001351661069e565b6101f06106cc565b6101c1600480360360208110156102a457600080fd5b50356001600160a01b03166106db565b6102da600480360360208110156102ca57600080fd5b50356001600160a01b03166106f9565b005b6101c1600480360360208110156102f257600080fd5b50356001600160a01b0316610811565b6103286004803603602081101561031857600080fd5b50356001600160a01b031661082f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561036457818101518382015260200161034c565b505050509050019250505060405180910390f35b6102da6004803603604081101561038e57600080fd5b506001600160a01b03813581169160200135166108a8565b6101c1600480360360208110156103bc57600080fd5b50356001600160a01b0316610a08565b6102da610a26565b6102da600480360360608110156103ea57600080fd5b506001600160a01b038135169060208101359060400135610ab7565b6101c16004803603604081101561041c57600080fd5b506001600160a01b0381358116916020013516610caa565b6102da6004803603602081101561044a57600080fd5b50356001600160a01b0316610cd9565b6101c16004803603604081101561047057600080fd5b506001600160a01b0381358116916020013516610d99565b6102da6004803603604081101561049e57600080fd5b506001600160a01b038135169060200135610dc8565b6101f0610ea6565b6104c4610eb5565b604080519115158252519081900360200190f35b6104c4600480360360208110156104ee57600080fd5b50356001600160a01b0316610ec6565b6102da6004803603606081101561051457600080fd5b506001600160a01b038135169060208101359060400135610ee9565b6101c16004803603602081101561054657600080fd5b50356001600160a01b0316611058565b6101c1611076565b6102da6004803603602081101561057457600080fd5b50356001600160a01b031661107c565b6102da6004803603602081101561059a57600080fd5b50356001600160a01b0316611140565b6001600160a01b038083166000908152600660209081526040808320938516835292905220545b92915050565b6000600382815481106105e657fe5b6000918252602090912001546001600160a01b031692915050565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b15801561064b57600080fd5b505afa15801561065f573d6000803e3d6000fd5b505050506040513d602081101561067557600080fd5b505192915050565b6001600160a01b039081166000908152600560205260409020600301541690565b60006106aa8383610d99565b156106c2576001546106bc8484610d99565b016106c5565b60005b9392505050565b6002546001600160a01b031690565b6001600160a01b031660009081526004602052604090206003015490565b6001600160a01b03811660009081526004602052604090205460ff166107505760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6002546040805163288c314960e21b815233600482015290516001600160a01b039092169163a230c52491602480820192602092909190829003018186803b15801561079b57600080fd5b505afa1580156107af573d6000803e3d6000fd5b505050506040513d60208110156107c557600080fd5b50516108025760405162461bcd60e51b815260040180806020018281038252602d815260200180611a7a602d913960400191505060405180910390fd5b61080e81336000611190565b50565b6001600160a01b031660009081526004602052604090206001015490565b6001600160a01b03811660009081526006602090815260409182902060010180548351818402810184019094528084526060939283018282801561089c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161087e575b50505050509050919050565b6001600160a01b03821660009081526004602052604090205460ff166108ff5760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6002546040805163288c314960e21b815233600482015290516001600160a01b039092169163a230c52491602480820192602092909190829003018186803b15801561094a57600080fd5b505afa15801561095e573d6000803e3d6000fd5b505050506040513d602081101561097457600080fd5b50516109b15760405162461bcd60e51b815260040180806020018281038252602d815260200180611a7a602d913960400191505060405180910390fd5b6001600160a01b0381163314156109f95760405162461bcd60e51b815260040180806020018281038252602e815260200180611af9602e913960400191505060405180910390fd5b610a04823383611190565b5050565b6001600160a01b031660009081526006602052604090206001015490565b610a2e610eb5565b610a6d576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b610abf610eb5565b610afe576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526004602052604090205460ff1615610b565760405162461bcd60e51b8152600401808060200182810382526028815260200180611ad16028913960400191505060405180910390fd5b6001600160a01b038316610b9b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b276026913960400191505060405180910390fd5b60008211610bf0576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e4661756365743a206461696c795261746520697320300000000000604482015290519081900360640190fd5b60008111610c45576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e4661756365743a20726566657272616c5261746520697320300000604482015290519081900360640190fd5b6001600160a01b0383166000818152600460205260408082208054610100600160ff19909216821761ff0019161782558101869055600201849055517f9684f028e9a5f8e59dea680f5dddf7e9e11b4827702d5ab6ca4d5c6cf874567f9190a2505050565b6001600160a01b0391821660009081526005602090815260408083209390941682526001909201909152205490565b610ce1610eb5565b610d20576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205460ff16610d775760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6001600160a01b03166000908152600460205260409020805461ff0019169055565b6001600160a01b0391821660009081526005602090815260408083209390941682526002909201909152205490565b610dd0610eb5565b610e0f576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b816001600160a01b031663a9059cbb610e26610ea6565b836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610e7657600080fd5b505af1158015610e8a573d6000803e3d6000fd5b505050506040513d6020811015610ea057600080fd5b50505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6001600160a01b0316600090815260046020526040902054610100900460ff1690565b610ef1610eb5565b610f30576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526004602052604090205460ff16610f875760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b60008211610fdc576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e4661756365743a206461696c795261746520697320300000000000604482015290519081900360640190fd5b60008111611031576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e4661756365743a20726566657272616c5261746520697320300000604482015290519081900360640190fd5b6001600160a01b039092166000908152600460205260409020600181019190915560020155565b6001600160a01b031660009081526004602052604090206002015490565b60035490565b611084610eb5565b6110c3576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205460ff1661111a5760405162461bcd60e51b8152600401808060200182810382526028815260200180611a116028913960400191505060405180910390fd5b6001600160a01b03166000908152600460205260409020805461ff001916610100179055565b611148610eb5565b611187576040805162461bcd60e51b81526020600482018190526024820152600080516020611a5a833981519152604482015290519081900360640190fd5b61080e8161148e565b4261119b838561069e565b11156111d85760405162461bcd60e51b815260040180806020018281038252602a8152602001806119e7602a913960400191505060405180910390fd5b6001600160a01b03821660009081526005602052604090205460ff166112bb576003805460018082019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b038581169182179092556000908152600560205260409020805460ff19169092179091558116156112bb576001600160a01b03808316600081815260056020908152604080832060030180549587166001600160a01b031996871681179091558352600682528220600190810180549182018155835291200180549092161790555b60006112c7848461152e565b6001600160a01b038481166000908152600560209081526040808320938916835260028401825280832042905560019093019052205490915061130a908261166f565b6001600160a01b038085166000908152600560209081526040808320938916835260019093018152828220939093556004909252902060030154611354908263ffffffff61166f16565b6001600160a01b03851660008181526004602052604090206003019190915561138490848363ffffffff6116c916565b6001600160a01b038381166000908152600560205260409020600301541615610ea0576001600160a01b03808416600090815260056020526040812060030154909116906113d28683611720565b90508015611486576001600160a01b038083166000908152600660209081526040808320938a1683529290522054611410908263ffffffff61166f16565b6001600160a01b038084166000908152600660209081526040808320938b168352928152828220939093556004909252902060030154611456908263ffffffff61166f16565b6001600160a01b03871660008181526004602052604090206003019190915561148690838363ffffffff6116c916565b505050505050565b6001600160a01b0381166114d35760405162461bcd60e51b81526004018080602001828103825260268152602001806119c16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008061153a84610811565b60025460408051632ac2353f60e21b81526001600160a01b0387811660048301529151939450600093919092169163ab08d4fc916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505111156115d3576115d081600263ffffffff6117a916565b90505b6002546040805163d658197560e01b81526001600160a01b0386811660048301529151600093929092169163d658197591602480820192602092909190829003018186803b15801561162457600080fd5b505afa158015611638573d6000803e3d6000fd5b505050506040513d602081101561164e57600080fd5b505111156106c55761166781600263ffffffff6117a916565b949350505050565b6000828201838110156106c5576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261171b908490611802565b505050565b6002546040805163288c314960e21b81526001600160a01b03848116600483015291516000938493169163a230c524916024808301926020929190829003018186803b15801561176f57600080fd5b505afa158015611783573d6000803e3d6000fd5b505050506040513d602081101561179957600080fd5b5051156106c55761153a84611058565b6000826117b8575060006105d1565b828202828482816117c557fe5b04146106c55760405162461bcd60e51b8152600401808060200182810382526021815260200180611a396021913960400191505060405180910390fd5b611814826001600160a01b03166119ba565b611865576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106118a35780518252601f199092019160209182019101611884565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611905576040519150601f19603f3d011682016040523d82523d6000602084013e61190a565b606091505b509150915081611961576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610ea05780806020019051602081101561197d57600080fd5b5051610ea05760405162461bcd60e51b815260040180806020018281038252602a815260200180611aa7602a913960400191505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4661756365743a206e65787420636c61696d2064617465206973206e6f7420706173736564546f6b656e4661756365743a20746f6b656e2066617563657420646f6573206e6f74206578697374536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4661756365743a206d6573736167652073656e646572206973206e6f742064616f206d656d6265725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564546f6b656e4661756365743a20746f6b656e2066617563657420616c726561647920657869737473546f6b656e4661756365743a20726566657272616c2063616e6e6f74206265206d6573736167652073656e646572546f6b656e4661756365743a20746f6b656e20697320746865207a65726f2061646472657373a265627a7a72305820e29718aa0e34d218a98ff09797ef5de29b843a17802d6e6e60cf26740df7739964736f6c634300050a0032

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000a042c9143c8758d2ad5a3fcc08dec39f6964453e

-----Decoded View---------------
Arg [0] : dao (address): 0xa042c9143c8758d2Ad5A3FCc08dEc39F6964453E

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a042c9143c8758d2ad5a3fcc08dec39f6964453e


Deployed Bytecode Sourcemap

56243:12656:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56243:12656:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60698:150;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;60698:150:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;59348:118;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59348:118:0;;:::i;:::-;;;;-1:-1:-1;;;;;59348:118:0;;;;;;;;;;;;;;59135:134;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59135:134:0;-1:-1:-1;;;;;59135:134:0;;:::i;60411:126::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60411:126:0;-1:-1:-1;;;;;60411:126:0;;:::i;61556:188::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;61556:188:0;;;;;;;;;;:::i;57893:71::-;;;:::i;58828:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58828:144:0;-1:-1:-1;;;;;58828:144:0;;:::i;64029:323::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64029:323:0;-1:-1:-1;;;;;64029:323:0;;:::i;:::-;;58322:121;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58322:121:0;-1:-1:-1;;;;;58322:121:0;;:::i;60971:145::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60971:145:0;-1:-1:-1;;;;;60971:145:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;60971:145:0;;;;;;;;;;;;;;;;;64548:443;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;64548:443:0;;;;;;;;;;:::i;61239:146::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61239:146:0;-1:-1:-1;;;;;61239:146:0;;:::i;13008:140::-;;;:::i;61945:643::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;61945:643:0;;;;;;;;;;;;;:::i;59835:149::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;59835:149:0;;;;;;;;;;:::i;63393:199::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63393:199:0;-1:-1:-1;;;;;63393:199:0;;:::i;60149:149::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;60149:149:0;;;;;;;;;;:::i;14264:152::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;14264:152:0;;;;;;;;:::i;12197:79::-;;;:::i;12563:92::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;58082:113;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58082:113:0;-1:-1:-1;;;;;58082:113:0;;:::i;62828:456::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;62828:456:0;;;;;;;;;;;;;:::i;58581:127::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58581:127:0;-1:-1:-1;;;;;58581:127:0;;:::i;59555:102::-;;;:::i;63700:197::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63700:197:0;-1:-1:-1;;;;;63700:197:0;;:::i;13303:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13303:109:0;-1:-1:-1;;;;;13303:109:0;;:::i;60698:150::-;-1:-1:-1;;;;;60804:22:0;;;60777:7;60804:22;;;:13;:22;;;;;;;;:36;;;;;;;;;;60698:150;;;;;:::o;59348:118::-;59413:7;59440:11;59452:5;59440:18;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59440:18:0;;59348:118;-1:-1:-1;;59348:118:0:o;59135:134::-;59223:38;;;-1:-1:-1;;;59223:38:0;;59255:4;59223:38;;;;;;59196:7;;-1:-1:-1;;;;;59223:23:0;;;;;:38;;;;;;;;;;;;;;;:23;:38;;;5:2:-1;;;;30:1;27;20:12;5:2;59223:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59223:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59223:38:0;;59135:134;-1:-1:-1;;59135:134:0:o;60411:126::-;-1:-1:-1;;;;;60497:23:0;;;60470:7;60497:23;;;:14;:23;;;;;:32;;;;;60411:126::o;61556:188::-;61632:7;61659:26;61670:7;61679:5;61659:10;:26::i;:::-;:31;:77;;61726:10;;61697:26;61708:7;61717:5;61697:10;:26::i;:::-;:39;61659:77;;;61693:1;61659:77;61652:84;61556:188;-1:-1:-1;;;61556:188:0:o;57893:71::-;57952:4;;-1:-1:-1;;;;;57952:4:0;57893:71;:::o;58828:144::-;-1:-1:-1;;;;;58923:18:0;58896:7;58923:18;;;:11;:18;;;;;:41;;;;58828:144::o;64029:323::-;-1:-1:-1;;;;;64089:18:0;;;;;;:11;:18;;;;;:25;;;64081:78;;;;-1:-1:-1;;;64081:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64178:4;;:25;;;-1:-1:-1;;;64178:25:0;;64192:10;64178:25;;;;;;-1:-1:-1;;;;;64178:4:0;;;;:13;;:25;;;;;;;;;;;;;;;:4;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;64178:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64178:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64178:25:0;64170:83;;;;-1:-1:-1;;;64170:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64296:48;64314:5;64321:10;64341:1;64296:17;:48::i;:::-;64029:323;:::o;58322:121::-;-1:-1:-1;;;;;58407:18:0;58380:7;58407:18;;;:11;:18;;;;;:28;;;;58322:121::o;60971:145::-;-1:-1:-1;;;;;61075:22:0;;;;;;:13;:22;;;;;;;;;:33;;61068:40;;;;;;;;;;;;;;;;;61039:16;;61068:40;;;61075:33;61068:40;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61068:40:0;;;;;;;;;;;;;;;;;;;;;;;60971:145;;;:::o;64548:443::-;-1:-1:-1;;;;;64638:18:0;;;;;;:11;:18;;;;;:25;;;64630:78;;;;-1:-1:-1;;;64630:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64727:4;;:25;;;-1:-1:-1;;;64727:25:0;;64741:10;64727:25;;;;;;-1:-1:-1;;;;;64727:4:0;;;;:13;;:25;;;;;;;;;;;;;;;:4;:25;;;5:2:-1;;;;30:1;27;20:12;5:2;64727:25:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64727:25:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64727:25:0;64719:83;;;;-1:-1:-1;;;64719:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64821:22:0;;64833:10;64821:22;;64813:81;;;;-1:-1:-1;;;64813:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64937:46;64955:5;64962:10;64974:8;64937:17;:46::i;:::-;64548:443;;:::o;61239:146::-;-1:-1:-1;;;;;61337:22:0;61313:4;61337:22;;;:13;:22;;;;;:33;;:40;;61239:146::o;13008:140::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;13107:1;13091:6;;13070:40;;-1:-1:-1;;;;;13091:6:0;;;;13070:40;;13107:1;;13070:40;13138:1;13121:19;;-1:-1:-1;;;;;;13121:19:0;;;13008:140::o;61945:643::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;62060:18:0;;;;;;:11;:18;;;;;:25;;;62059:26;62051:79;;;;-1:-1:-1;;;62051:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62149:19:0;;62141:70;;;;-1:-1:-1;;;62141:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62242:1;62230:9;:13;62222:53;;;;;-1:-1:-1;;;62222:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;62309:1;62294:12;:16;62286:59;;;;;-1:-1:-1;;;62286:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62358:18:0;;;;;;:11;:18;;;;;;:32;;;62386:4;-1:-1:-1;;62358:32:0;;;;;-1:-1:-1;;62401:33:0;;;;62445:28;;:40;;;62496:31;;:46;;;62560:20;;;62358:18;62560:20;61945:643;;;:::o;59835:149::-;-1:-1:-1;;;;;59939:23:0;;;59912:7;59939:23;;;:14;:23;;;;;;;;:37;;;;;;:30;;;;:37;;;;;;59835:149::o;63393:199::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63467:18:0;;;;;;:11;:18;;;;;:25;;;63459:78;;;;-1:-1:-1;;;63459:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63550:18:0;63579:5;63550:18;;;:11;:18;;;;;:34;;-1:-1:-1;;63550:34:0;;;63393:199::o;60149:149::-;-1:-1:-1;;;;;60249:23:0;;;60222:7;60249:23;;;:14;:23;;;;;;;;:41;;;;;;:34;;;;:41;;;;;;60149:149::o;14264:152::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;14364:12;-1:-1:-1;;;;;14357:29:0;;14387:7;:5;:7::i;:::-;14396:11;14357:51;;;;;;;;;;;;;-1:-1:-1;;;;;14357:51:0;-1:-1:-1;;;;;14357:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14357:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;14357:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;14264:152:0:o;12197:79::-;12235:7;12262:6;-1:-1:-1;;;;;12262:6:0;12197:79;:::o;12563:92::-;12603:4;12641:6;-1:-1:-1;;;;;12641:6:0;12627:10;:20;;12563:92::o;58082:113::-;-1:-1:-1;;;;;58161:18:0;58137:4;58161:18;;;:11;:18;;;;;:26;;;;;;;58082:113::o;62828:456::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;62950:18:0;;;;;;:11;:18;;;;;:25;;;62942:78;;;;-1:-1:-1;;;62942:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63054:1;63039:12;:16;63031:56;;;;;-1:-1:-1;;;63031:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63124:1;63106:15;:19;63098:62;;;;;-1:-1:-1;;;63098:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63173:18:0;;;;;;;:11;:18;;;;;:28;;;:43;;;;63227:31;;:49;62828:456::o;58581:127::-;-1:-1:-1;;;;;58669:18:0;58642:7;58669:18;;;:11;:18;;;;;:31;;;;58581:127::o;59555:102::-;59631:11;:18;59555:102;:::o;63700:197::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;63773:18:0;;;;;;:11;:18;;;;;:25;;;63765:78;;;;-1:-1:-1;;;63765:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63856:18:0;;;;;:11;:18;;;;;:33;;-1:-1:-1;;63856:33:0;;;;;63700:197::o;13303:109::-;12409:9;:7;:9::i;:::-;12401:54;;;;;-1:-1:-1;;;12401:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;12401:54:0;;;;;;;;;;;;;;;13376:28;13395:8;13376:18;:28::i;66660:2236::-;66853:15;66820:29;66834:7;66843:5;66820:13;:29::i;:::-;:48;;66812:103;;;;-1:-1:-1;;;66812:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66971:23:0;;;;;;:14;:23;;;;;:30;;;66966:370;;67018:11;27:10:-1;;39:1;23:18;;;45:23;;;67018:25:0;;;;-1:-1:-1;;;;;;67018:25:0;-1:-1:-1;;;;;67018:25:0;;;;;;;;;-1:-1:-1;67058:23:0;;;:14;67018:25;67058:23;;;;:37;;-1:-1:-1;;67058:37:0;;;;;;;67156:22;;;67152:173;;-1:-1:-1;;;;;67199:23:0;;;;;;;:14;:23;;;;;;;;:32;;:43;;;;;-1:-1:-1;;;;;;67199:43:0;;;;;;;;67261:23;;:13;:23;;;;67199:43;67261:34;;;27:10:-1;;23:18;;;45:23;;67261:48:0;;;;;;;;;;;;;67152:173;67348:28;67379:40;67404:5;67411:7;67379:24;:40::i;:::-;-1:-1:-1;;;;;67525:23:0;;;;;;;:14;:23;;;;;;;;:41;;;;;:34;;;:41;;;;;67569:15;67525:59;;67635:30;;;;:37;;;;67348:71;;-1:-1:-1;67635:63:0;;67348:71;67635:41;:63::i;:::-;-1:-1:-1;;;;;67595:23:0;;;;;;;:14;:23;;;;;;;;:37;;;;;:30;;;;:37;;;;;:103;;;;67788:11;:18;;;;;:41;;;:67;;67834:20;67788:67;:45;:67;:::i;:::-;-1:-1:-1;;;;;67744:18:0;;;;;;:11;:18;;;;;:41;;:111;;;;67909:57;;67936:7;67945:20;67909:57;:26;:57;:::i;:::-;-1:-1:-1;;;;;68012:23:0;;;68056:1;68012:23;;;:14;:23;;;;;:32;;;;:46;68008:881;;-1:-1:-1;;;;;68156:23:0;;;68132:21;68156:23;;;:14;:23;;;;;:32;;;;;;;68235:45;68259:5;68156:32;68235:23;:45::i;:::-;68205:75;-1:-1:-1;68360:23:0;;68356:522;;-1:-1:-1;;;;;68492:28:0;;;;;;;:13;:28;;;;;;;;:42;;;;;;;;;;:67;;68539:19;68492:67;:46;:67;:::i;:::-;-1:-1:-1;;;;;68447:28:0;;;;;;;:13;:28;;;;;;;;:42;;;;;;;;;;;:112;;;;68665:11;:18;;;;;:41;;;:66;;68711:19;68665:66;:45;:66;:::i;:::-;-1:-1:-1;;;;;68621:18:0;;;;;;:11;:18;;;;;:41;;:110;;;;68800:62;;68827:13;68842:19;68800:62;:26;:62;:::i;:::-;68008:881;;66660:2236;;;;:::o;13518:229::-;-1:-1:-1;;;;;13592:22:0;;13584:73;;;;-1:-1:-1;;;13584:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13694:6;;;13673:38;;-1:-1:-1;;;;;13673:38:0;;;;13694:6;;;13673:38;;;13722:6;:17;;-1:-1:-1;;;;;;13722:17:0;-1:-1:-1;;;;;13722:17:0;;;;;;;;;;13518:229::o;65257:405::-;65346:7;65366:19;65388;65401:5;65388:12;:19::i;:::-;65424:4;;:28;;;-1:-1:-1;;;65424:28:0;;-1:-1:-1;;;;;65424:28:0;;;;;;;;;65366:41;;-1:-1:-1;65455:1:0;;65424:4;;;;;:19;;:28;;;;;;;;;;;;;;:4;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;65424:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65424:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65424:28:0;:32;65420:97;;;65487:18;:11;65503:1;65487:18;:15;:18;:::i;:::-;65473:32;;65420:97;65533:4;;:26;;;-1:-1:-1;;;65533:26:0;;-1:-1:-1;;;;;65533:26:0;;;;;;;;;65562:1;;65533:4;;;;;:17;;:26;;;;;;;;;;;;;;;:4;:26;;;5:2:-1;;;;30:1;27;20:12;5:2;65533:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65533:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65533:26:0;:30;65529:95;;;65594:18;:11;65610:1;65594:18;:15;:18;:::i;:::-;65580:32;65643:11;-1:-1:-1;;;;65257:405:0:o;922:181::-;980:7;1012:5;;;1036:6;;;;1028:46;;;;;-1:-1:-1;;;1028:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;8202:176;8311:58;;;-1:-1:-1;;;;;8311:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;8311:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;8285:85:0;;8304:5;;8285:18;:85::i;:::-;8202:176;;;:::o;65927:513::-;66075:4;;:22;;;-1:-1:-1;;;66075:22:0;;-1:-1:-1;;;;;66075:22:0;;;;;;;;;66015:7;;;;66075:4;;:13;;:22;;;;;;;;;;;;;;:4;:22;;;5:2:-1;;;;30:1;27;20:12;5:2;66075:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66075:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66075:22:0;66071:331;;;66128:22;66144:5;66128:15;:22::i;1813:470::-;1871:7;2115:6;2111:47;;-1:-1:-1;2145:1:0;2138:8;;2111:47;2182:5;;;2186:1;2182;:5;:1;2206:5;;;;;:10;2198:56;;;;-1:-1:-1;;;2198:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10196:1114;10800:27;10808:5;-1:-1:-1;;;;;10800:25:0;;:27::i;:::-;10792:71;;;;;-1:-1:-1;;;10792:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;10937:12;10951:23;10986:5;-1:-1:-1;;;;;10978:19:0;10998:4;10978:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;10978:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;10936:67:0;;;;11022:7;11014:52;;;;;-1:-1:-1;;;11014:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11083:17;;:21;11079:224;;11225:10;11214:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11214:30:0;11206:85;;;;-1:-1:-1;;;11206:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7145:422;7512:20;7551:8;;;7145:422::o

Swarm Source

bzzr://e29718aa0e34d218a98ff09797ef5de29b843a17802d6e6e60cf26740df77399

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.