ETH Price: $3,254.97 (+3.61%)
Gas: 4 Gwei

Contract

0x196E5f240d26969CFEf464e80C6e423620cc7E40
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Early End Stake ...202425532024-07-05 19:59:5920 days ago1720209599IN
0x196E5f24...620cc7E40
0 ETH0.000291142.99364877
Early End Stake ...193596882024-03-04 5:23:59144 days ago1709529839IN
0x196E5f24...620cc7E40
0 ETH0.0053587347.99459033
Early End Stake ...191694542024-02-06 13:20:23171 days ago1707225623IN
0x196E5f24...620cc7E40
0 ETH0.0038749838.40989429
Extend Stake191694412024-02-06 13:17:35171 days ago1707225455IN
0x196E5f24...620cc7E40
0 ETH0.003321846.55320731
Early End Stake ...191290612024-01-31 21:12:11176 days ago1706735531IN
0x196E5f24...620cc7E40
0 ETH0.0016138920.13815722
Early End Stake ...187537042023-12-10 5:23:59229 days ago1702185839IN
0x196E5f24...620cc7E40
0 ETH0.0024376725.06837639
Early End Stake ...183997582023-10-21 16:04:59278 days ago1697904299IN
0x196E5f24...620cc7E40
0 ETH0.001653317
Join Club183522742023-10-15 0:43:11285 days ago1697330591IN
0x196E5f24...620cc7E40
0 ETH0.001041634.81800613
Join Club183147362023-10-09 18:35:11290 days ago1696876511IN
0x196E5f24...620cc7E40
0 ETH0.0027419312.68398422
Early End Stake ...182863782023-10-05 19:25:47294 days ago1696533947IN
0x196E5f24...620cc7E40
0 ETH0.0014398614.8090536
Early End Stake ...182751212023-10-04 5:38:47296 days ago1696397927IN
0x196E5f24...620cc7E40
0 ETH0.000577055.9335279
Extend Stake182590462023-10-01 23:44:35298 days ago1696203875IN
0x196E5f24...620cc7E40
0 ETH0.000693269.71565993
Extend Stake182540482023-10-01 6:58:11299 days ago1696143491IN
0x196E5f24...620cc7E40
0 ETH0.000476616.67947591
Join Club181378982023-09-14 23:53:59315 days ago1694735639IN
0x196E5f24...620cc7E40
0 ETH0.002077799.61116976
Extend Stake180867302023-09-07 19:47:35322 days ago1694116055IN
0x196E5f24...620cc7E40
0 ETH0.0019397527.18457685
Join Club180684292023-09-05 6:15:59325 days ago1693894559IN
0x196E5f24...620cc7E40
0 ETH0.0023780610.99951218
Join Club178331442023-08-03 8:00:23358 days ago1691049623IN
0x196E5f24...620cc7E40
0 ETH0.0031603215.87331317
Early End Stake ...174926582023-06-16 13:20:59406 days ago1686921659IN
0x196E5f24...620cc7E40
0 ETH0.001632816.79131449
Join Club174435392023-06-09 15:23:59413 days ago1686324239IN
0x196E5f24...620cc7E40
0 ETH0.0019813424.6454376
Early End Stake ...174032282023-06-03 22:52:23418 days ago1685832743IN
0x196E5f24...620cc7E40
0 ETH0.0020500721.08498738
Join Club173898562023-06-02 1:39:11420 days ago1685669951IN
0x196E5f24...620cc7E40
0 ETH0.0020426122.69722281
Early End Stake ...173734122023-05-30 18:06:35422 days ago1685469995IN
0x196E5f24...620cc7E40
0 ETH0.005492256.48032582
Early End Stake ...172983722023-05-20 4:50:23433 days ago1684558223IN
0x196E5f24...620cc7E40
0 ETH0.0026894431.78294506
Extend Stake172983622023-05-20 4:48:23433 days ago1684558103IN
0x196E5f24...620cc7E40
0 ETH0.0020883129.26661333
Join Club172708832023-05-16 7:46:23437 days ago1684223183IN
0x196E5f24...620cc7E40
0 ETH0.0090505741.86726619
View all transactions

Latest 2 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
155939452022-09-23 5:25:59672 days ago1663910759
0x196E5f24...620cc7E40
 Contract Creation0 ETH
155939412022-09-23 5:25:11672 days ago1663910711
0x196E5f24...620cc7E40
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DiamondHandsClub

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 201 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-09-23
*/

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

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

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

    /**
     * @dev Moves `amount` tokens from `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: contracts/diamondhands.sol

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.2;







contract TEAMContract {
    function getPoolAddresses(string memory ticker) public view returns (address) {}
}
contract PerpetualContract {
    function getCurrentPeriod() external view returns (uint256){}
    uint256 public STAKE_START_DAY; // the day when the current stake starts, is updated as each stake starts
    uint256 public STAKE_END_DAY; // the day when the current stake ends, is updated as each stake starts
    uint256 public STAKE_LENGTH;
    function getHexDay() external view returns (uint256){}

}
/*
Diamond Hands Club is a contract that allows holders of the Maximus Perpetual Pool tokens to 
timelock their tokens for the duration of the corresponding HEX stake pool and earn additional rewards. 
This contract is deployed for each of the Perpetual Pools and runs on that pool's stake schedule.
Joining the Diamond Hands Club is fully voluntary and there is a penalty applied to any amount that is unlocked early.
Penalty = amount* 0.0369 * 3696 / stake length

How it works
1. Choose amount you want to lock.
2. Lock in before the Perpetual Pool stake starts by running joinClub(amount) which transfers your Perpetual Pool tokens to the Diamond Hand Contract.
3. If you unlock before the Perpetual Pool stake ends, the penalty applied to the amount early unlocked goes into the Reward Bucket Contract. 
4. After the stake ends, The contents of the Reward Bucket are sent to the Stake Reward Distribution contract and you can reclaim your pool tokens from the DH contract and claim your portion of the rewards from that period from the Stake Reward Distribution Contract containing:
    1. Pool tokens from early unlock penalty
    2. Any TEAM or MAXI that happens to be mysteriously airdropped to the Reward Bucket by motivated TEAM members trying to incentivize perpetual pool participation.


Period 0: Perpetual Pool Minting Phase - ends September 26
What Happens? Users can enter the first timelock period.
Functions available:
- joinClub(amount) commits them into the upcoming stake period
- earlyEndStake(amount) if they have already joined the upcoming stake period

Period 1: Stake Phase
What Happens? Users are locked in, and if they unlock early they experience a penalty that is redistributed to the people that stay locked the whole period.
Functions available:
- joinClub(amount) commits them into the next stake period
- earlyEndStake(amount, stakeID) if they are currently locked into the current stake period or have already joined the upcoming stake period
- extendStake(stakeID) rolls their existing stake into the next stake period

Period 2: Reload Phase
What Happens? After the corresponding perpetual pool stake ends users can reclaim their locked tokens and claim rewards from the prior period. They can also enter the next timelock period.
- joinClub(amount) commits them into the next stake period
- earlyEndStake(amount, stakeID) if they are currently locked into the current stake period or have already joined the upcoming stake period
- restakeExpiredStake(stakeID) rolls their existing stake into the next stake period
- endExpiredStake(stakeID) closes out their existing stake and returns their timelocked tokens.

Period 3:Stake Phase
Period 4: Reload Phase
REPEAT FOREVER

*/
contract DiamondHandsClub is ReentrancyGuard {
    /*
    Post-deployment instructions: 
    1. run deployStakeRewardDistributionContract()
    2. run deployRewardBucketContract()
    */
    event Stake(
        address indexed staker,
        uint256 amount, 
        uint256 current_period,
        uint256 stakeID, 
        bool is_initial);
    event ExtendStake(
        address indexed staker,
        uint256 amount, 
        uint256 staking_period, 
        uint256 stakeID);
    event EarlyEndStake(address indexed staker,
        uint256 amount, 
        uint256 staking_period, 
        uint256 stakeID);
    event EndExpiredStake(address indexed staker,
        uint256 amount, 
        uint256 staking_period, 
        uint256 stakeID);
    event RestakeExpiredStake(address indexed staker,
        uint256 amount, 
        uint256 staking_period, 
        uint256 stakeID);
    address public PERPETUAL_POOL_ADDRESS;
    address public constant TEAM_CONTRACT_ADDRESS=0xB7c9E99Da8A857cE576A830A9c19312114d9dE02;
    TEAMContract TeamContract = TEAMContract(TEAM_CONTRACT_ADDRESS);  
    PerpetualContract PoolContract;
    IERC20 PoolERC;
    uint256 public GLOBAL_AMOUNT_STAKED;  // Running total number of Pool tokens staked by all users. Incremented when any user stakes Pool tokens and decremented when any user end-stakes Pool Tokens.
    mapping (address=> uint256) public USER_AMOUNT_STAKED;// Running total number of Tokens staked per user. Incremented when user stakes Tokens and decremented when user end-stakes Tokens.
    address public STAKE_REWARD_DISTRIBUTION_ADDRESS; // Contract that the reward bucket sends funds to as a staking period ends. Contract that user claims their rewards from.
    address public REWARD_BUCKET_ADDRESS; // Reward Bucket is the address that stores the stake rewards. Penalties are sent from DH Contract to the Reward Bucket. 
    string public TICKER_SYMBOL;
    constructor(string memory ticker) ReentrancyGuard() {
        TICKER_SYMBOL=ticker; // symbol of the Perpetual Pool contract this is deployed for.
        PERPETUAL_POOL_ADDRESS = TeamContract.getPoolAddresses(ticker);
        PoolContract = PerpetualContract(PERPETUAL_POOL_ADDRESS); // used for getCurrentPeriod, etc.
        PoolERC = IERC20(PERPETUAL_POOL_ADDRESS); // used for transfer, balanceOf, etc
    }
    // Supporting Contract Deployment
    // @notice Run this immediately after deployment of the DH Contract.
    function deployStakeRewardDistributionContract() public nonReentrant {
        require(STAKE_REWARD_DISTRIBUTION_ADDRESS==address(0), "already deployed");
        DHStakeRewardDistribution srd = new DHStakeRewardDistribution(address(this));
        STAKE_REWARD_DISTRIBUTION_ADDRESS = address(srd);
    }
    // @notice Run this immediately after deployment of the DH Contract.
    function deployRewardBucketContract() public nonReentrant  {
        require(REWARD_BUCKET_ADDRESS==address(0), "already deployed");
        RewardBucket rb = new RewardBucket(address(this));
        REWARD_BUCKET_ADDRESS = address(rb);
    }
    
   
    /// Staking
    // A StakeRecord is created for each user when they stake into a new period.
    // If a stake record for a user has already been created for a particular period, the existing one will be updated.
    struct StakeRecord {
        address staker; // staker
        uint256 balance; // the remaining balance of the stake.
        uint stakeID; // how a user identifies their stakes. Each period stake increments stakeID.
        uint256 stake_expiry_period; // what period this stake is scheduled to serve through. May be extended to the next staking period during the stake_expiry_period.
        mapping(uint => uint256) stakedTokensPerPeriod; // A record of the number of Tokens that successfully served each staking period during this stake. This number crystallizes as each staking period ends and is used to claim rewards.
        bool initiated;
    }
    mapping (uint => uint256) public globalStakedTokensPerPeriod; // A record of the number of Tokens that are successfully staked for each stake period. Value crystallizes in each period as period ends.
    mapping (address =>mapping(uint => StakeRecord)) public stakes; // Mapping of all users stake records.
    /*
    @notice joinClub(amount) User facing function for staking Tokens. 
    @dev 1) Checks if user balance exceeds input stake amount. 2) Saves stake data via newStakeRecord(). 3) Transfers the staked Tokens to the Diamond Hand Club Contract. 4) Update global and user stake tally.
    @param amount number of Tokens staked, include enough zeros to support 8 decimal units. to stake 1 Token, enter amount = 100000000
    */
    function joinClub(uint256 amount) external nonReentrant {
        require(amount>0, "You must join with more than zero pool tokens");
        require(PoolERC.allowance(msg.sender, address(this))>=amount);
        newStakeRecord(amount); // updates the stake record
        PoolERC.transferFrom(msg.sender, address(this), amount); // sends pool token to Diamond Hand Club contract
        GLOBAL_AMOUNT_STAKED = GLOBAL_AMOUNT_STAKED + amount;
        USER_AMOUNT_STAKED[msg.sender]=USER_AMOUNT_STAKED[msg.sender] + amount;
    }
        /*
        @dev Function that determines which is the next staking period, and creates or updates the users stake record for that period.
        */
        function newStakeRecord(uint256 amount) private {
            uint256 next_staking_period = getNextStakingPeriod(); // the contract period number for each staking period is used as a unique identifier for a stake. 
            StakeRecord storage stake = stakes[msg.sender][next_staking_period]; // retrieves the existing stake record for this upcoming staking period, or render a new one if this is the first time.
            bool is_initial;
            if (stake.initiated==false){ // first time setup. values that should not change if this user stakes again in this period.
                stake.stakeID = next_staking_period;
                stake.initiated = true;
                stake.staker = msg.sender;
                stake.stake_expiry_period = next_staking_period;
                is_initial = true;
            }
            stake.balance = amount + stake.balance;
            stake.stakedTokensPerPeriod[next_staking_period] = amount + stake.stakedTokensPerPeriod[next_staking_period];
            globalStakedTokensPerPeriod[next_staking_period] = amount + globalStakedTokensPerPeriod[next_staking_period];
            emit Stake(msg.sender, amount, getCurrentPeriod(), stake.stakeID, is_initial);
        }
  
    /*
    @notice Calculates the 20% penalty for early end staking an amount.
    */
    function calculatePenalty(uint256 amount) public view returns(uint256) {
        uint256 penalty = amount/5; // 20% penalty = 1/5 of the amount
        return penalty;
    } 
/*
    @notice earlyEndStakeToken(stakeID, amount) User facing function for ending a part or all of a stake either before or during its expiry period. A scaled% penalty is applied to the amount returned to the user and the penalized amount goes to the Reward Bucket.
    @dev checks that they have this stake, updates the stake record via earlyEndStakeRecord() function, updates the global tallies, calculates the early end stake penalty, and returns back the amount requested minus penalty.
    @param stakeID the ID of the stake the user wants to early end stake
    @param amount number of Tokens early end staked, include enough zeros to support 8 decimal units. to end stake 1 Tokens, enter amount = 100000000
    */
    function earlyEndStakeToken(uint256 stakeID, uint256 amount) external nonReentrant {
        earlyEndStakeRecord(stakeID, amount); // update the stake record
        uint256 penalty = calculatePenalty(amount); 
        GLOBAL_AMOUNT_STAKED = GLOBAL_AMOUNT_STAKED - amount;
        USER_AMOUNT_STAKED[msg.sender]=USER_AMOUNT_STAKED[msg.sender] - amount;
        PoolERC.transfer(msg.sender,amount-penalty);
        PoolERC.transfer(REWARD_BUCKET_ADDRESS,penalty);
    }
         /*
        @dev Determines if stake is pending, or in progress and updates the record to reflect the amount of Tokens that remains actively staked from that particular stake.
        @param stakeID the ID of the stake the user wants to early end stake
        @param amount number of Tokens early end staked, include enough zeros to support 8 decimal units. to end stake 1 Tokens, enter amount = 100000000
        */
        function earlyEndStakeRecord(uint256 stakeID, uint256 amount) private {
            uint256 current_period = getCurrentPeriod();
            uint256 next_staking_period = getNextStakingPeriod();
            StakeRecord storage stake = stakes[msg.sender][stakeID];
            require(stake.initiated==true, "You must enter an existing stake period");
            require(stake.stake_expiry_period>=current_period, "The stake period must be active."); // must be before the stake has expired
            require(stake.balance>=amount);
            stake.balance = stake.balance - amount;
            // Decrement staked Tokens from next staking period
            if (stake.stakedTokensPerPeriod[next_staking_period]>0){
                globalStakedTokensPerPeriod[next_staking_period]=globalStakedTokensPerPeriod[next_staking_period]-amount;
                stake.stakedTokensPerPeriod[next_staking_period]=stake.stakedTokensPerPeriod[next_staking_period]-amount;
            }
            // Decrement staked Tokens from current staking period.
            if (stake.stakedTokensPerPeriod[current_period]>0) {
                globalStakedTokensPerPeriod[current_period]=globalStakedTokensPerPeriod[current_period]-amount;
                stake.stakedTokensPerPeriod[current_period]=stake.stakedTokensPerPeriod[current_period]-amount;
            }
            emit EarlyEndStake(msg.sender, amount, stake.stake_expiry_period, stakeID);
        }
    /*
    @notice End a stake which has already served its full staking period. This function updates your stake record and returns your staked Tokens back into your address.
    @param stakeID the ID of the stake the user wants to end stake
    @param amount number of Tokens end staked, include enough zeros to support 8 decimal units. to end stake 1 Tokens, enter amount = 100000000
            
    */
    function endCompletedStake(uint256 stakeID, uint256 amount) external nonReentrant {
        endExpiredStake(stakeID, amount);
        GLOBAL_AMOUNT_STAKED = GLOBAL_AMOUNT_STAKED - amount;
        USER_AMOUNT_STAKED[msg.sender]=USER_AMOUNT_STAKED[msg.sender] - amount;
        PoolERC.transfer(msg.sender, amount);
    }
        function endExpiredStake(uint256 stakeID, uint256 amount) private {
            uint256 current_period=getCurrentPeriod();
            StakeRecord storage stake = stakes[msg.sender][stakeID];
            require(stake.stake_expiry_period<current_period);
            require(stake.balance>=amount);
            stake.balance = stake.balance-amount;
            emit EndExpiredStake(msg.sender, amount, stake.stake_expiry_period, stakeID);
        }

    /*
    @notice This function extends a currently active stake into the next staking period. It can only be run during the expiry period of a stake. This extends the entire stake into the next period.
    @param stakeID the ID of the stake the user wants to extend into the next staking period.
        */
        function extendStake(uint256 stakeID) external nonReentrant {
            uint256 current_period=getCurrentPeriod();
            uint256 next_staking_period = getNextStakingPeriod();
            StakeRecord storage stake = stakes[msg.sender][stakeID];
            require(isStakingPeriod());
            require(stake.stake_expiry_period==current_period);
            stake.stake_expiry_period=next_staking_period;
            stake.stakedTokensPerPeriod[next_staking_period] = stake.stakedTokensPerPeriod[next_staking_period] + stake.balance;
            globalStakedTokensPerPeriod[next_staking_period] = globalStakedTokensPerPeriod[next_staking_period] + stake.balance;
            emit ExtendStake(msg.sender, stake.balance, next_staking_period, stakeID);
        }
    /*
    @notice This function ends and restakes a stake which has been completed (if current period is greater than stake expiry period). It ends the stake but does not return your Tokens, instead it rolls those Tokens into a brand new stake record starting in the next staking period.
    @param stakeID the ID of the stake the user wants to extend into the next staking period.
    */
    function restakeExpiredStake(uint256 stakeID) public nonReentrant {
        uint256 current_period=getCurrentPeriod();
        StakeRecord storage stake = stakes[msg.sender][stakeID];
        require(stake.stake_expiry_period<current_period);
        require(stake.balance > 0);
        newStakeRecord(stake.balance);
        uint256 amount = stake.balance;
        stake.balance = 0;
        emit RestakeExpiredStake(msg.sender, amount, stake.stake_expiry_period, stakeID);
    }
    function getAddressPeriodEndTotal(address staker_address, uint256 period, uint stakeID) public view returns (uint256) {
        StakeRecord storage stake = stakes[staker_address][stakeID];
        return stake.stakedTokensPerPeriod[period]; 
    }
    function getglobalStakedTokensPerPeriod(uint256 period) public view returns(uint256){
        return globalStakedTokensPerPeriod[period];
    }
   
    /// Utilities
    /*
    @notice The current period of the Diamond Hands Contract is the current period of the corresponding Perpetual Pool Contract.
    */
    function getCurrentPeriod() public view returns (uint current_period){
        return PoolContract.getCurrentPeriod(); 
    }
    
    function isStakingPeriod() public view returns (bool) {
        uint remainder = getCurrentPeriod()%2;
        if(remainder==0){
            return false;
        }
        else {
            return true;
        }
    }

    function getNextStakingPeriod() private view returns(uint256) {
        uint256 current_period=getCurrentPeriod();
        uint256 next_staking_period;
        if (isStakingPeriod()==true) {
            next_staking_period = current_period+2;
        }
        else {
            next_staking_period=current_period+1;
        }
        return next_staking_period;
    }
}
contract RewardBucket is ReentrancyGuard {
    /*
    Deployment instructions: 
    1. run activate()
    */
    address public PERPETUAL_POOL_ADDRESS;
    address public constant TEAM_CONTRACT_ADDRESS=0xB7c9E99Da8A857cE576A830A9c19312114d9dE02;
    PerpetualContract PoolContract;
    IERC20 PoolERC;
    TEAMContract TeamContract = TEAMContract(TEAM_CONTRACT_ADDRESS);
    address public STAKE_REWARD_DISTRIBUTION_ADDRESS;
    DiamondHandsClub DHContract;
    constructor(address dhc_address) ReentrancyGuard() {
        DHContract = DiamondHandsClub(dhc_address);
    } 
    /*
    @notice This function must be run right after deployment
    */
    function activate() public nonReentrant {
        require(PERPETUAL_POOL_ADDRESS==address(0)); 
        PERPETUAL_POOL_ADDRESS=DHContract.PERPETUAL_POOL_ADDRESS();
        PoolContract = PerpetualContract(PERPETUAL_POOL_ADDRESS); // used for getCurrentPeriod, etc.
        PoolERC = IERC20(PERPETUAL_POOL_ADDRESS); // used for transfer, balanceOf, etc
        STAKE_REWARD_DISTRIBUTION_ADDRESS=DHContract.STAKE_REWARD_DISTRIBUTION_ADDRESS();
        require(STAKE_REWARD_DISTRIBUTION_ADDRESS!=address(0));
        declareSupportedTokens();
    }
    /// Rewards Allocation   
    // Income received by the TEAM Contract in tokens from the below declared supported tokens list are split up and claimable
    mapping (string => address) supportedTokens;
    /*
    @dev Declares which tokens that will be supported by the reward distribution contract.
    */
    address constant MAXI_ADDRESS = 0x0d86EB9f43C57f6FF3BC9E23D8F9d82503f0e84b;
    address constant HEX_ADDRESS  = 0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39; // "2b, 5 9 1e? that is the question..."
    address constant HEDRON_ADDRESS = 0x3819f64f282bf135d62168C1e513280dAF905e06; 
    
    function declareSupportedTokens() private {
        supportedTokens["HEX"] = HEX_ADDRESS;
        supportedTokens["MAXI"]=MAXI_ADDRESS;
        supportedTokens["HDRN"]=HEDRON_ADDRESS;
        supportedTokens["BASE"]=TeamContract.getPoolAddresses("BASE");
        supportedTokens["TRIO"]=TeamContract.getPoolAddresses("TRIO");
        supportedTokens["LUCKY"]=TeamContract.getPoolAddresses("LUCKY");
        supportedTokens["DECI"]=TeamContract.getPoolAddresses("DECI");
        supportedTokens["TEAM"]=TEAM_CONTRACT_ADDRESS;
        supportedTokens["ICSA"]=0xfc4913214444aF5c715cc9F7b52655e788A569ed;
        
    }
    mapping (string => mapping (uint => bool)) public didRecordPeriodEndBalance; // didRecordPeriodEndBalance[TICKER][period]
    mapping (string =>mapping (uint => uint256)) public periodEndBalance; //periodEndBalance[TICKER][period]
    mapping (string => mapping (uint => uint256)) public periodRedemptionRates; //periodRedemptionRates[TICKER][period] Number of coins claimable per team staked 
    /*
    @notice This function checks to make sure that a staking period just ended, and then measures and saves the Tokens Contracts balance of the designated token.
    @param ticker is the ticker that is to be 
    */ 
    function prepareClaim(string memory ticker) external nonReentrant {
        require(DHContract.isStakingPeriod()==false);
        uint256 latest_staking_period = DHContract.getCurrentPeriod()-1;
        require(didRecordPeriodEndBalance[ticker][latest_staking_period]==false);
        periodEndBalance[ticker][latest_staking_period] = IERC20(supportedTokens[ticker]).balanceOf(address(this)); //measures how many of the designated token are in the Tokens contract address
        IERC20(supportedTokens[ticker]).transfer(STAKE_REWARD_DISTRIBUTION_ADDRESS, periodEndBalance[ticker][latest_staking_period]);
        didRecordPeriodEndBalance[ticker][latest_staking_period]=true;
        uint256 scaled_rate = periodEndBalance[ticker][latest_staking_period] *(10**8)/DHContract.getglobalStakedTokensPerPeriod(latest_staking_period);
        periodRedemptionRates[ticker][latest_staking_period] = scaled_rate;
    }
    
    function getPeriodRedemptionRates(string memory ticker, uint256 period) public view returns (uint256) {
        return periodRedemptionRates[ticker][period];
    }
    
    function getSupportedTokens(string memory ticker) public view returns(address) {
            return supportedTokens[ticker];
        }

    function getClaimableAmount(address user, uint256 period, string memory ticker, uint stakeID) public view returns (uint256, address) {
        uint256 total_amount_succesfully_staked = DHContract.getAddressPeriodEndTotal(user, period, stakeID);
        uint256 redeemable_amount = getPeriodRedemptionRates(ticker,period) * total_amount_succesfully_staked / (10**8);
        return (redeemable_amount, getSupportedTokens(ticker));
    }
    
}
contract DHStakeRewardDistribution is ReentrancyGuard {
    /*
    Deployment insttructions: 
    1. run activate()
    2. run prepareSupportedTokens()
    */
    address public REWARD_BUCKET_ADDRESS;
    RewardBucket RewardBucketContract;
    address public DHC_ADDRESS;
    DiamondHandsClub DHContract; 
    mapping (string => address) public supportedTokens;
    mapping (address => mapping(uint => mapping(uint => mapping (string => bool)))) public didUserStakeClaimFromPeriod; // log which periods and which tokens a user's stake has claimed rewards from
    constructor(address dhc_address) ReentrancyGuard(){
      DHC_ADDRESS=dhc_address;
      DHContract = DiamondHandsClub(DHC_ADDRESS); 
    }
    /*
    Upon deployment we must collect the Reward bucket address from the DH Contract
    */
    function activate() public nonReentrant {
        require(REWARD_BUCKET_ADDRESS==address(0));
        REWARD_BUCKET_ADDRESS = DHContract.REWARD_BUCKET_ADDRESS();
        require(REWARD_BUCKET_ADDRESS!=address(0));
        RewardBucketContract = RewardBucket(REWARD_BUCKET_ADDRESS);
        
    }
    /*
    @notice Claim Rewards in the designated ticker for a period served by a stake record designated by stake ID. You can only run this function if you have not already claimed and if you have redeemable rewards for that coin from that period.
    @param period is the period you want to claim rewards from
    @param ticker is the ticker symbol for the token you want to claim
    @param stakeID is the stakeID of the stake record that contains Tokens that was succesfully staked during the period you input.
    */
    function claimRewards(uint256 period, string memory ticker, uint stakeID) nonReentrant external {
        (uint256 redeemable_amount, address token_address) = RewardBucketContract.getClaimableAmount(msg.sender,period, ticker, stakeID);
        require(didUserStakeClaimFromPeriod[msg.sender][stakeID][period][ticker]==false, "You must not have already claimed from this stake on this period.");
        require(redeemable_amount>0, "No rewards from this period.");
        IERC20(token_address).transfer(msg.sender, redeemable_amount);
        didUserStakeClaimFromPeriod[msg.sender][stakeID][period][ticker]=true;
    }

    /*
    @notice Run this function to retrieve and save all of the supported token addresses from the Tokens contract into the Stake Reward Distribution contract. This should be run once after the supported tokens are declared in the team contract.
    */
    function prepareSupportedTokens() nonReentrant public {
        collectSupportedTokenAddress("HEX");
        collectSupportedTokenAddress("MAXI");
        collectSupportedTokenAddress("HDRN");
        collectSupportedTokenAddress("BASE");
        collectSupportedTokenAddress("TRIO");
        collectSupportedTokenAddress("LUCKY");
        collectSupportedTokenAddress("DECI");
        collectSupportedTokenAddress("TEAM");
        collectSupportedTokenAddress("ICSA");
    }
    function collectSupportedTokenAddress(string memory ticker) private {
        require(supportedTokens[ticker]==address(0));
        supportedTokens[ticker]=RewardBucketContract.getSupportedTokens(ticker);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"ticker","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staking_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"EarlyEndStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staking_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"EndExpiredStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staking_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"ExtendStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staking_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"RestakeExpiredStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"current_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"},{"indexed":false,"internalType":"bool","name":"is_initial","type":"bool"}],"name":"Stake","type":"event"},{"inputs":[],"name":"GLOBAL_AMOUNT_STAKED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERPETUAL_POOL_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_BUCKET_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKE_REWARD_DISTRIBUTION_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TEAM_CONTRACT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKER_SYMBOL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"USER_AMOUNT_STAKED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculatePenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployRewardBucketContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployStakeRewardDistributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"earlyEndStakeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"endCompletedStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"extendStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker_address","type":"address"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"getAddressPeriodEndTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentPeriod","outputs":[{"internalType":"uint256","name":"current_period","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"period","type":"uint256"}],"name":"getglobalStakedTokensPerPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"globalStakedTokensPerPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStakingPeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"joinClub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"restakeExpiredStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakes","outputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"stakeID","type":"uint256"},{"internalType":"uint256","name":"stake_expiry_period","type":"uint256"},{"internalType":"bool","name":"initiated","type":"bool"}],"stateMutability":"view","type":"function"}]

6080604052600280546001600160a01b03191673b7c9e99da8a857ce576a830a9c19312114d9de021790553480156200003757600080fd5b5060405162003435380380620034358339810160408190526200005a916200015c565b600160005560096200006d8282620002a3565b50600254604051633eb01cd360e11b81526001600160a01b0390911690637d6039a690620000a09084906004016200036f565b602060405180830381865afa158015620000be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e49190620003a4565b600180546001600160a01b03929092166001600160a01b03199283168117909155600380548316821790556004805490921617905550620003d6565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200015357818101518382015260200162000139565b50506000910152565b6000602082840312156200016f57600080fd5b81516001600160401b03808211156200018757600080fd5b818401915084601f8301126200019c57600080fd5b815181811115620001b157620001b162000120565b604051601f8201601f19908116603f01168101908382118183101715620001dc57620001dc62000120565b81604052828152876020848701011115620001f657600080fd5b6200020983602083016020880162000136565b979650505050505050565b600181811c908216806200022957607f821691505b6020821081036200024a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029e57600081815260208120601f850160051c81016020861015620002795750805b601f850160051c820191505b818110156200029a5782815560010162000285565b5050505b505050565b81516001600160401b03811115620002bf57620002bf62000120565b620002d781620002d0845462000214565b8462000250565b602080601f8311600181146200030f5760008415620002f65750858301515b600019600386901b1c1916600185901b1785556200029a565b600085815260208120601f198616915b8281101562000340578886015182559484019460019091019084016200031f565b50858210156200035f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082518060208401526200039081604085016020870162000136565b601f01601f19169190910160400192915050565b600060208284031215620003b757600080fd5b81516001600160a01b0381168114620003cf57600080fd5b9392505050565b61304f80620003e66000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c8063690ae3d6116100b857806380ff34731161007c57806380ff347314610335578063813f4db4146103485780638d2fe35d146103605780639a0dfcf31461037b578063c57ab80114610384578063e15427421461039757600080fd5b8063690ae3d6146102b0578063694f8022146102c35780636b406b6d146102cb5780637e0e00cf146102de5780637e49627d1461032257600080fd5b8063301c8c6a116100ff578063301c8c6a146101cc57806344fcdd14146101ec5780634ecce45114610201578063584b62a1146102145780636065f9d61461029d57600080fd5b8063019cca4b1461013c578063086146d21461016f5780632851092d146101775780632a9217b5146101a25780632d9ba1cd146101ac575b600080fd5b61015c61014a36600461118b565b60066020526000908152604090205481565b6040519081526020015b60405180910390f35b61015c6103aa565b60015461018a906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b6101aa61041d565b005b61015c6101ba3660046111a6565b6000908152600a602052604090205490565b61015c6101da3660046111a6565b600a6020526000908152604090205481565b6101f46104fd565b60405161016691906111bf565b61015c61020f3660046111a6565b61058b565b61026961022236600461120d565b600b602090815260009283526040808420909152908252902080546001820154600283015460038401546005909401546001600160a01b0390931693919290919060ff1685565b604080516001600160a01b03909616865260208601949094529284019190915260608301521515608082015260a001610166565b6101aa6102ab366004611237565b6105a0565b6101aa6102be366004611237565b610692565b6101aa610822565b60075461018a906001600160a01b031681565b61015c6102ec366004611259565b6001600160a01b0383166000908152600b6020908152604080832084845282528083208584526004019091529020549392505050565b6101aa6103303660046111a6565b6108f9565b6101aa6103433660046111a6565b610a30565b610350610afd565b6040519015158152602001610166565b61018a73b7c9e99da8a857ce576a830a9c19312114d9de0281565b61015c60055481565b60085461018a906001600160a01b031681565b6101aa6103a53660046111a6565b610b2e565b60035460408051630430a36960e11b815290516000926001600160a01b03169163086146d29160048083019260209291908290030181865afa1580156103f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610418919061128c565b905090565b6002600054036104485760405162461bcd60e51b815260040161043f906112a5565b60405180910390fd5b60026000556007546001600160a01b0316156104995760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e4819195c1b1bde595960821b604482015260640161043f565b6000306040516104a890611155565b6001600160a01b039091168152602001604051809103906000f0801580156104d4573d6000803e3d6000fd5b50600780546001600160a01b0319166001600160a01b0392909216919091179055506001600055565b6009805461050a906112dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610536906112dc565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b600080610599600584611342565b9392505050565b6002600054036105c25760405162461bcd60e51b815260040161043f906112a5565b60026000556105d18282610d06565b806005546105df9190611356565b600555336000908152600660205260409020546105fd908290611356565b33600081815260066020526040908190209290925560048054925163a9059cbb60e01b815290810191909152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611369565b5050600160005550565b6002600054036106b45760405162461bcd60e51b815260040161043f906112a5565b60026000556106c38282610db3565b60006106ce8261058b565b9050816005546106de9190611356565b600555336000908152600660205260409020546106fc908390611356565b336000818152600660205260409020919091556004546001600160a01b03169063a9059cbb9061072c8486611356565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079b9190611369565b506004805460085460405163a9059cbb60e01b81526001600160a01b039182169381019390935260248301849052169063a9059cbb906044016020604051808303816000875af11580156107f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108179190611369565b505060016000555050565b6002600054036108445760405162461bcd60e51b815260040161043f906112a5565b60026000556008546001600160a01b0316156108955760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e4819195c1b1bde595960821b604482015260640161043f565b6000306040516108a490611162565b6001600160a01b039091168152602001604051809103906000f0801580156108d0573d6000803e3d6000fd5b50600880546001600160a01b0319166001600160a01b0392909216919091179055506001600055565b60026000540361091b5760405162461bcd60e51b815260040161043f906112a5565b6002600090815561092a6103aa565b90506000610936610fed565b336000908152600b60209081526040808320878452909152902090915061095b610afd565b61096457600080fd5b8281600301541461097457600080fd5b600381018290556001810154600083815260048301602052604090205461099b919061138b565b60008381526004830160209081526040808320939093556001840154600a909152919020546109ca919061138b565b6000838152600a60209081526040918290209290925560018301548151908152918201849052810185905233907fa8066869490ef421f05bad45cd697329771b6cf22e60b0fbfebc1f6dbee85679906060015b60405180910390a2505060016000555050565b600260005403610a525760405162461bcd60e51b815260040161043f906112a5565b60026000908155610a616103aa565b336000908152600b6020908152604080832086845290915290206003810154919250908211610a8f57600080fd5b6000816001015411610aa057600080fd5b610aad8160010154611033565b60018101805460009091556003820154604080518381526020810192909252810185905233907f6c6afda2278fafa8f9f636cdf4af81f3ffc6ff41d12bea3b731cf924126fdcfa90606001610a1d565b6000806002610b0a6103aa565b610b14919061139e565b905080600003610b2657600091505090565b600191505090565b600260005403610b505760405162461bcd60e51b815260040161043f906112a5565b600260005580610bb85760405162461bcd60e51b815260206004820152602d60248201527f596f75206d757374206a6f696e2077697468206d6f7265207468616e207a657260448201526c6f20706f6f6c20746f6b656e7360981b606482015260840161043f565b60048054604051636eb1769f60e11b8152339281019290925230602483015282916001600160a01b039091169063dd62ed3e90604401602060405180830381865afa158015610c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2f919061128c565b1015610c3a57600080fd5b610c4381611033565b600480546040516323b872dd60e01b81523392810192909252306024830152604482018390526001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610c9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbf9190611369565b5080600554610cce919061138b565b60055533600090815260066020526040902054610cec90829061138b565b336000908152600660205260408120919091556001905550565b6000610d106103aa565b336000908152600b6020908152604080832087845290915290206003810154919250908211610d3e57600080fd5b8281600101541015610d4f57600080fd5b828160010154610d5f9190611356565b60018201556003810154604080518581526020810192909252810185905233907f7fca7f23e28ab4ea8ec17e674c7e959ed9737ce4930613fb69d59b09b1c78b73906060015b60405180910390a250505050565b6000610dbd6103aa565b90506000610dc9610fed565b336000908152600b60209081526040808320888452909152902060058101549192509060ff161515600114610e505760405162461bcd60e51b815260206004820152602760248201527f596f75206d75737420656e74657220616e206578697374696e67207374616b65604482015266081c195c9a5bd960ca1b606482015260840161043f565b8281600301541015610ea45760405162461bcd60e51b815260206004820181905260248201527f546865207374616b6520706572696f64206d757374206265206163746976652e604482015260640161043f565b8381600101541015610eb557600080fd5b838160010154610ec59190611356565b6001820155600082815260048201602052604090205415610f34576000828152600a6020526040902054610efa908590611356565b6000838152600a60209081526040808320939093556004840190522054610f22908590611356565b60008381526004830160205260409020555b600083815260048201602052604090205415610f9e576000838152600a6020526040902054610f64908590611356565b6000848152600a60209081526040808320939093556004840190522054610f8c908590611356565b60008481526004830160205260409020555b6003810154604080518681526020810192909252810186905233907fd024fb5309d60d56df8339015fd653666f4e9f5eec9985b62bdeb4c38be456239060600160405180910390a25050505050565b600080610ff86103aa565b90506000611004610afd565b151560010361101f5761101882600261138b565b905061102d565b61102a82600161138b565b90505b92915050565b600061103d610fed565b336000908152600b60209081526040808320848452909152812060058101549293509160ff161515810361109d57506002810182905560058101805460ff1916600190811790915581546001600160a01b03191633178255600382018390555b60018201546110ac908561138b565b600183015560008381526004830160205260409020546110cc908561138b565b6000848152600484016020908152604080832093909355600a905220546110f3908561138b565b6000848152600a6020526040902055337f9427353240d93cb4f15e429717c3e4e45b6f499959900935e731d6c0d2f110148561112d6103aa565b6002860154604080519384526020840192909252908201528315156060820152608001610da5565b610b5a806113b383390190565b61110d80611f0d83390190565b80356001600160a01b038116811461118657600080fd5b919050565b60006020828403121561119d57600080fd5b6105998261116f565b6000602082840312156111b857600080fd5b5035919050565b600060208083528351808285015260005b818110156111ec578581018301518582016040015282016111d0565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561122057600080fd5b6112298361116f565b946020939093013593505050565b6000806040838503121561124a57600080fd5b50508035926020909101359150565b60008060006060848603121561126e57600080fd5b6112778461116f565b95602085013595506040909401359392505050565b60006020828403121561129e57600080fd5b5051919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600181811c908216806112f057607f821691505b60208210810361131057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008261135157611351611316565b500490565b8181038181111561102d5761102d61132c565b60006020828403121561137b57600080fd5b8151801515811461059957600080fd5b8082018082111561102d5761102d61132c565b6000826113ad576113ad611316565b50069056fe608060405234801561001057600080fd5b50604051610b5a380380610b5a83398101604081905261002f91610063565b6001600055600380546001600160a01b039092166001600160a01b0319928316811790915560048054909216179055610093565b60006020828403121561007557600080fd5b81516001600160a01b038116811461008c57600080fd5b9392505050565b610ab8806100a26000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a1e9f2851161005b578063a1e9f285146100f0578063c49c1270146100f8578063c57ab80114610158578063f1d927d41461016b57600080fd5b80630f15f4c01461008257806389919cdd1461008c5780639b80238a146100dd575b600080fd5b61008a61017e565b005b6100c061009a366004610816565b80516020818301810180516005825292820191909301209152546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6003546100c0906001600160a01b031681565b61008a61027f565b61014861010636600461086b565b60066020908152600094855260408086208252938552838520815291845291909220815180830184018051928152908401929093019190912091525460ff1681565b60405190151581526020016100d4565b6001546100c0906001600160a01b031681565b61008a6101793660046108ce565b6103f9565b6002600054036101a95760405162461bcd60e51b81526004016101a09061091e565b60405180910390fd5b60026000556001546001600160a01b0316156101c457600080fd5b600480546040805163c57ab80160e01b815290516001600160a01b039092169263c57ab8019282820192602092908290030181865afa15801561020b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610955565b600180546001600160a01b0319166001600160a01b0392909216918217905561025757600080fd5b60018054600280546001600160a01b0319166001600160a01b03909216919091179055600055565b6002600054036102a15760405162461bcd60e51b81526004016101a09061091e565b60026000556040805180820190915260038152620908ab60eb1b60208201526102c990610682565b6102ee604051806040016040528060048152602001634d41584960e01b815250610682565b610313604051806040016040528060048152602001632422292760e11b815250610682565b610338604051806040016040528060048152602001634241534560e01b815250610682565b61035d604051806040016040528060048152602001635452494f60e01b815250610682565b610383604051806040016040528060058152602001644c55434b5960d81b815250610682565b6103a8604051806040016040528060048152602001634445434960e01b815250610682565b6103cd604051806040016040528060048152602001635445414d60e01b815250610682565b6103f2604051806040016040528060048152602001634943534160e01b815250610682565b6001600055565b60026000540361041b5760405162461bcd60e51b81526004016101a09061091e565b6002600081815590546040516369c966a360e01b815282916001600160a01b0316906369c966a3906104579033908990899089906004016109c9565b6040805180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104979190610a01565b33600090815260066020908152604080832088845282528083208a8452909152908190209051929450909250906104cf908690610a31565b9081526040519081900360200190205460ff161561055f5760405162461bcd60e51b815260206004820152604160248201527f596f75206d757374206e6f74206861766520616c726561647920636c61696d6560448201527f642066726f6d2074686973207374616b65206f6e207468697320706572696f646064820152601760f91b608482015260a4016101a0565b600082116105af5760405162461bcd60e51b815260206004820152601c60248201527f4e6f20726577617264732066726f6d207468697320706572696f642e0000000060448201526064016101a0565b60405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0382169063a9059cbb906044016020604051808303816000875af11580156105fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106209190610a4d565b50336000908152600660209081526040808320868452825280832088845290915290819020905160019190610656908790610a31565b908152604051908190036020019020805491151560ff1990921691909117905550506001600055505050565b60006001600160a01b031660058260405161069d9190610a31565b908152604051908190036020019020546001600160a01b0316146106c057600080fd5b6002546040516344e6f28b60e01b81526001600160a01b03909116906344e6f28b906106f0908490600401610a6f565b602060405180830381865afa15801561070d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107319190610955565b6005826040516107419190610a31565b90815260405190819003602001902080546001600160a01b03929092166001600160a01b031990921691909117905550565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261079a57600080fd5b813567ffffffffffffffff808211156107b5576107b5610773565b604051601f8301601f19908116603f011681019082821181831017156107dd576107dd610773565b816040528381528660208588010111156107f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561082857600080fd5b813567ffffffffffffffff81111561083f57600080fd5b61084b84828501610789565b949350505050565b6001600160a01b038116811461086857600080fd5b50565b6000806000806080858703121561088157600080fd5b843561088c81610853565b93506020850135925060408501359150606085013567ffffffffffffffff8111156108b657600080fd5b6108c287828801610789565b91505092959194509250565b6000806000606084860312156108e357600080fd5b83359250602084013567ffffffffffffffff81111561090157600080fd5b61090d86828701610789565b925050604084013590509250925092565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561096757600080fd5b815161097281610853565b9392505050565b60005b8381101561099457818101518382015260200161097c565b50506000910152565b600081518084526109b5816020860160208601610979565b601f01601f19169290920160200192915050565b60018060a01b03851681528360208201526080604082015260006109f0608083018561099d565b905082606083015295945050505050565b60008060408385031215610a1457600080fd5b825191506020830151610a2681610853565b809150509250929050565b60008251610a43818460208701610979565b9190910192915050565b600060208284031215610a5f57600080fd5b8151801515811461097257600080fd5b602081526000610972602083018461099d56fea264697066735822122081faefd22fff813ce75f7891995cc2975c43efce510cfa6a593afae016df12ea64736f6c634300081000336080604052600480546001600160a01b03191673b7c9e99da8a857ce576a830a9c19312114d9de0217905534801561003657600080fd5b5060405161110d38038061110d8339810160408190526100559161007f565b6001600055600680546001600160a01b0319166001600160a01b03929092169190911790556100af565b60006020828403121561009157600080fd5b81516001600160a01b03811681146100a857600080fd5b9392505050565b61104f806100be6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80636b406b6d116100715780636b406b6d1461017457806370f283b1146101875780638d2fe35d1461019a578063e096c258146101b5578063f20a25b2146101f0578063f8f469e61461020357600080fd5b80630d4d77f4146100ae5780630f15f4c0146100fc5780632851092d1461010657806344e6f28b1461013157806369c966a314610144575b600080fd5b6100e96100bc366004610e26565b8151602081840181018051600a825292820194820194909420919093529091526000908152604090205481565b6040519081526020015b60405180910390f35b610104610251565b005b600154610119906001600160a01b031681565b6040516001600160a01b0390911681526020016100f3565b61011961013f366004610e6b565b61040d565b610157610152366004610ec0565b61043e565b604080519283526001600160a01b039091166020830152016100f3565b600554610119906001600160a01b031681565b610104610195366004610e6b565b610504565b61011973b7c9e99da8a857ce576a830a9c19312114d9de0281565b6100e96101c3366004610e26565b81516020818401810180516009825292820194820194909420919093529091526000908152604090205481565b6100e96101fe366004610e26565b610937565b610241610211366004610e26565b81516020818401810180516008825292820194820194909420919093529091526000908152604090205460ff1681565b60405190151581526020016100f3565b6002600054036102a85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000556001546001600160a01b0316156102c357600080fd5b600660009054906101000a90046001600160a01b03166001600160a01b0316632851092d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033a9190610f21565b600180546001600160a01b039283166001600160a01b031991821681179092556002805482168317905560038054909116909117905560065460408051636b406b6d60e01b815290519190921691636b406b6d9160048083019260209291908290030181865afa1580156103b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d69190610f21565b600580546001600160a01b0319166001600160a01b039290921691821790556103fe57600080fd5b610406610972565b6001600055565b600060078260405161041f9190610f45565b908152604051908190036020019020546001600160a01b031692915050565b600654604051637e0e00cf60e01b81526001600160a01b03868116600483015260248201869052604482018490526000928392839290911690637e0e00cf90606401602060405180830381865afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610f74565b905060006305f5e100826104d5888a610937565b6104df9190610fa3565b6104e99190610fc2565b9050806104f58761040d565b93509350505094509492505050565b6002600054036105565760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161029f565b60026000556006546040805163204fd36d60e21b815290516001600160a01b039092169163813f4db4916004808201926020929091908290030181865afa1580156105a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c99190610fe4565b156105d357600080fd5b60006001600660009054906101000a90046001600160a01b03166001600160a01b031663086146d26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561062a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064e9190610f74565b6106589190611006565b905060088260405161066a9190610f45565b90815260408051602092819003830190206000848152925290205460ff161561069257600080fd5b6007826040516106a29190610f45565b908152604051908190036020018120546370a0823160e01b82523060048301526001600160a01b0316906370a0823190602401602060405180830381865afa1580156106f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107169190610f74565b6009836040516107269190610f45565b908152604080519182900360209081018320600086815291522091909155600790610752908490610f45565b908152604051908190036020018120546005546001600160a01b039182169263a9059cbb92919091169060099061078a908790610f45565b90815260408051602092819003830181206000888152935291205460e084901b6001600160e01b03191682526001600160a01b03909216600482015260248101919091526044016020604051808303816000875af11580156107f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108149190610fe4565b5060016008836040516108279190610f45565b90815260408051918290036020908101832060008681529152908120805493151560ff1990941693909317909255600654632d9ba1cd60e01b8252600482018490526001600160a01b031690632d9ba1cd90602401602060405180830381865afa158015610899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bd9190610f74565b6009846040516108cd9190610f45565b9081526040805160209281900383019020600086815292529020546108f6906305f5e100610fa3565b6109009190610fc2565b905080600a846040516109139190610f45565b90815260408051602092819003830190206000958652909152832055506001905550565b6000600a836040516109499190610f45565b908152602001604051809103902060008381526020019081526020016000205490505b92915050565b732b591e99afe9f32eaa6214f7b7629768c40eeb39600760405161099f90620908ab60eb1b815260030190565b908152604080516020928190038301812080546001600160a01b03199081166001600160a01b0396871617909155634d41584960e01b82526007600480840182905284516024948190038501812080548516730d86eb9f43c57f6ff3bc9e23d8f9d82503f0e84b179055632422292760e11b815280820192909252845191829003840182208054909316733819f64f282bf135d62168c1e513280daf905e06179092558154633eb01cd360e11b825281830186905292810191909152634241534560e01b60448201529151931692637d6039a6926064808401939192918290030181865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610f21565b604051634241534560e01b81526007906004019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b8352818301939093526024820152635452494f60e01b6044820152911690637d6039a690606401602060405180830381865afa158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190610f21565b604051635452494f60e01b81526007906004019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b83529082019290925260056024820152644c55434b5960d81b6044820152911690637d6039a690606401602060405180830381865afa158015610bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1e9190610f21565b604051644c55434b5960d81b81526007906005019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b8352818301939093526024820152634445434960e01b6044820152911690637d6039a690606401602060405180830381865afa158015610cac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd09190610f21565b60408051634445434960e01b81526007600480830182905283516024938190038401812080546001600160a01b03199081166001600160a01b0398909816979097179055635445414d60e01b8152808201839052845190819003840181208054871673b7c9e99da8a857ce576a830a9c19312114d9de02179055634943534160e01b815290810191909152915191829003019020805490911673fc4913214444af5c715cc9f7b52655e788a569ed179055565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610daa57600080fd5b813567ffffffffffffffff80821115610dc557610dc5610d83565b604051601f8301601f19908116603f01168101908282118183101715610ded57610ded610d83565b81604052838152866020858801011115610e0657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610e3957600080fd5b823567ffffffffffffffff811115610e5057600080fd5b610e5c85828601610d99565b95602094909401359450505050565b600060208284031215610e7d57600080fd5b813567ffffffffffffffff811115610e9457600080fd5b610ea084828501610d99565b949350505050565b6001600160a01b0381168114610ebd57600080fd5b50565b60008060008060808587031215610ed657600080fd5b8435610ee181610ea8565b935060208501359250604085013567ffffffffffffffff811115610f0457600080fd5b610f1087828801610d99565b949793965093946060013593505050565b600060208284031215610f3357600080fd5b8151610f3e81610ea8565b9392505050565b6000825160005b81811015610f665760208186018101518583015201610f4c565b506000920191825250919050565b600060208284031215610f8657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610fbd57610fbd610f8d565b500290565b600082610fdf57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215610ff657600080fd5b81518015158114610f3e57600080fd5b8181038181111561096c5761096c610f8d56fea264697066735822122033193495db6f0796ee8be33bc1af30f06e0dd5edd23d9407ce1f0b598625d36164736f6c63430008100033a2646970667358221220010e3ed52e817669188c43af0ca3ab96664e519fba7f12e2faff6349d043aa8064736f6c63430008100033000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000044445434900000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101375760003560e01c8063690ae3d6116100b857806380ff34731161007c57806380ff347314610335578063813f4db4146103485780638d2fe35d146103605780639a0dfcf31461037b578063c57ab80114610384578063e15427421461039757600080fd5b8063690ae3d6146102b0578063694f8022146102c35780636b406b6d146102cb5780637e0e00cf146102de5780637e49627d1461032257600080fd5b8063301c8c6a116100ff578063301c8c6a146101cc57806344fcdd14146101ec5780634ecce45114610201578063584b62a1146102145780636065f9d61461029d57600080fd5b8063019cca4b1461013c578063086146d21461016f5780632851092d146101775780632a9217b5146101a25780632d9ba1cd146101ac575b600080fd5b61015c61014a36600461118b565b60066020526000908152604090205481565b6040519081526020015b60405180910390f35b61015c6103aa565b60015461018a906001600160a01b031681565b6040516001600160a01b039091168152602001610166565b6101aa61041d565b005b61015c6101ba3660046111a6565b6000908152600a602052604090205490565b61015c6101da3660046111a6565b600a6020526000908152604090205481565b6101f46104fd565b60405161016691906111bf565b61015c61020f3660046111a6565b61058b565b61026961022236600461120d565b600b602090815260009283526040808420909152908252902080546001820154600283015460038401546005909401546001600160a01b0390931693919290919060ff1685565b604080516001600160a01b03909616865260208601949094529284019190915260608301521515608082015260a001610166565b6101aa6102ab366004611237565b6105a0565b6101aa6102be366004611237565b610692565b6101aa610822565b60075461018a906001600160a01b031681565b61015c6102ec366004611259565b6001600160a01b0383166000908152600b6020908152604080832084845282528083208584526004019091529020549392505050565b6101aa6103303660046111a6565b6108f9565b6101aa6103433660046111a6565b610a30565b610350610afd565b6040519015158152602001610166565b61018a73b7c9e99da8a857ce576a830a9c19312114d9de0281565b61015c60055481565b60085461018a906001600160a01b031681565b6101aa6103a53660046111a6565b610b2e565b60035460408051630430a36960e11b815290516000926001600160a01b03169163086146d29160048083019260209291908290030181865afa1580156103f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610418919061128c565b905090565b6002600054036104485760405162461bcd60e51b815260040161043f906112a5565b60405180910390fd5b60026000556007546001600160a01b0316156104995760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e4819195c1b1bde595960821b604482015260640161043f565b6000306040516104a890611155565b6001600160a01b039091168152602001604051809103906000f0801580156104d4573d6000803e3d6000fd5b50600780546001600160a01b0319166001600160a01b0392909216919091179055506001600055565b6009805461050a906112dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610536906112dc565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b600080610599600584611342565b9392505050565b6002600054036105c25760405162461bcd60e51b815260040161043f906112a5565b60026000556105d18282610d06565b806005546105df9190611356565b600555336000908152600660205260409020546105fd908290611356565b33600081815260066020526040908190209290925560048054925163a9059cbb60e01b815290810191909152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611369565b5050600160005550565b6002600054036106b45760405162461bcd60e51b815260040161043f906112a5565b60026000556106c38282610db3565b60006106ce8261058b565b9050816005546106de9190611356565b600555336000908152600660205260409020546106fc908390611356565b336000818152600660205260409020919091556004546001600160a01b03169063a9059cbb9061072c8486611356565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079b9190611369565b506004805460085460405163a9059cbb60e01b81526001600160a01b039182169381019390935260248301849052169063a9059cbb906044016020604051808303816000875af11580156107f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108179190611369565b505060016000555050565b6002600054036108445760405162461bcd60e51b815260040161043f906112a5565b60026000556008546001600160a01b0316156108955760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e4819195c1b1bde595960821b604482015260640161043f565b6000306040516108a490611162565b6001600160a01b039091168152602001604051809103906000f0801580156108d0573d6000803e3d6000fd5b50600880546001600160a01b0319166001600160a01b0392909216919091179055506001600055565b60026000540361091b5760405162461bcd60e51b815260040161043f906112a5565b6002600090815561092a6103aa565b90506000610936610fed565b336000908152600b60209081526040808320878452909152902090915061095b610afd565b61096457600080fd5b8281600301541461097457600080fd5b600381018290556001810154600083815260048301602052604090205461099b919061138b565b60008381526004830160209081526040808320939093556001840154600a909152919020546109ca919061138b565b6000838152600a60209081526040918290209290925560018301548151908152918201849052810185905233907fa8066869490ef421f05bad45cd697329771b6cf22e60b0fbfebc1f6dbee85679906060015b60405180910390a2505060016000555050565b600260005403610a525760405162461bcd60e51b815260040161043f906112a5565b60026000908155610a616103aa565b336000908152600b6020908152604080832086845290915290206003810154919250908211610a8f57600080fd5b6000816001015411610aa057600080fd5b610aad8160010154611033565b60018101805460009091556003820154604080518381526020810192909252810185905233907f6c6afda2278fafa8f9f636cdf4af81f3ffc6ff41d12bea3b731cf924126fdcfa90606001610a1d565b6000806002610b0a6103aa565b610b14919061139e565b905080600003610b2657600091505090565b600191505090565b600260005403610b505760405162461bcd60e51b815260040161043f906112a5565b600260005580610bb85760405162461bcd60e51b815260206004820152602d60248201527f596f75206d757374206a6f696e2077697468206d6f7265207468616e207a657260448201526c6f20706f6f6c20746f6b656e7360981b606482015260840161043f565b60048054604051636eb1769f60e11b8152339281019290925230602483015282916001600160a01b039091169063dd62ed3e90604401602060405180830381865afa158015610c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2f919061128c565b1015610c3a57600080fd5b610c4381611033565b600480546040516323b872dd60e01b81523392810192909252306024830152604482018390526001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610c9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbf9190611369565b5080600554610cce919061138b565b60055533600090815260066020526040902054610cec90829061138b565b336000908152600660205260408120919091556001905550565b6000610d106103aa565b336000908152600b6020908152604080832087845290915290206003810154919250908211610d3e57600080fd5b8281600101541015610d4f57600080fd5b828160010154610d5f9190611356565b60018201556003810154604080518581526020810192909252810185905233907f7fca7f23e28ab4ea8ec17e674c7e959ed9737ce4930613fb69d59b09b1c78b73906060015b60405180910390a250505050565b6000610dbd6103aa565b90506000610dc9610fed565b336000908152600b60209081526040808320888452909152902060058101549192509060ff161515600114610e505760405162461bcd60e51b815260206004820152602760248201527f596f75206d75737420656e74657220616e206578697374696e67207374616b65604482015266081c195c9a5bd960ca1b606482015260840161043f565b8281600301541015610ea45760405162461bcd60e51b815260206004820181905260248201527f546865207374616b6520706572696f64206d757374206265206163746976652e604482015260640161043f565b8381600101541015610eb557600080fd5b838160010154610ec59190611356565b6001820155600082815260048201602052604090205415610f34576000828152600a6020526040902054610efa908590611356565b6000838152600a60209081526040808320939093556004840190522054610f22908590611356565b60008381526004830160205260409020555b600083815260048201602052604090205415610f9e576000838152600a6020526040902054610f64908590611356565b6000848152600a60209081526040808320939093556004840190522054610f8c908590611356565b60008481526004830160205260409020555b6003810154604080518681526020810192909252810186905233907fd024fb5309d60d56df8339015fd653666f4e9f5eec9985b62bdeb4c38be456239060600160405180910390a25050505050565b600080610ff86103aa565b90506000611004610afd565b151560010361101f5761101882600261138b565b905061102d565b61102a82600161138b565b90505b92915050565b600061103d610fed565b336000908152600b60209081526040808320848452909152812060058101549293509160ff161515810361109d57506002810182905560058101805460ff1916600190811790915581546001600160a01b03191633178255600382018390555b60018201546110ac908561138b565b600183015560008381526004830160205260409020546110cc908561138b565b6000848152600484016020908152604080832093909355600a905220546110f3908561138b565b6000848152600a6020526040902055337f9427353240d93cb4f15e429717c3e4e45b6f499959900935e731d6c0d2f110148561112d6103aa565b6002860154604080519384526020840192909252908201528315156060820152608001610da5565b610b5a806113b383390190565b61110d80611f0d83390190565b80356001600160a01b038116811461118657600080fd5b919050565b60006020828403121561119d57600080fd5b6105998261116f565b6000602082840312156111b857600080fd5b5035919050565b600060208083528351808285015260005b818110156111ec578581018301518582016040015282016111d0565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561122057600080fd5b6112298361116f565b946020939093013593505050565b6000806040838503121561124a57600080fd5b50508035926020909101359150565b60008060006060848603121561126e57600080fd5b6112778461116f565b95602085013595506040909401359392505050565b60006020828403121561129e57600080fd5b5051919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600181811c908216806112f057607f821691505b60208210810361131057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008261135157611351611316565b500490565b8181038181111561102d5761102d61132c565b60006020828403121561137b57600080fd5b8151801515811461059957600080fd5b8082018082111561102d5761102d61132c565b6000826113ad576113ad611316565b50069056fe608060405234801561001057600080fd5b50604051610b5a380380610b5a83398101604081905261002f91610063565b6001600055600380546001600160a01b039092166001600160a01b0319928316811790915560048054909216179055610093565b60006020828403121561007557600080fd5b81516001600160a01b038116811461008c57600080fd5b9392505050565b610ab8806100a26000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a1e9f2851161005b578063a1e9f285146100f0578063c49c1270146100f8578063c57ab80114610158578063f1d927d41461016b57600080fd5b80630f15f4c01461008257806389919cdd1461008c5780639b80238a146100dd575b600080fd5b61008a61017e565b005b6100c061009a366004610816565b80516020818301810180516005825292820191909301209152546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6003546100c0906001600160a01b031681565b61008a61027f565b61014861010636600461086b565b60066020908152600094855260408086208252938552838520815291845291909220815180830184018051928152908401929093019190912091525460ff1681565b60405190151581526020016100d4565b6001546100c0906001600160a01b031681565b61008a6101793660046108ce565b6103f9565b6002600054036101a95760405162461bcd60e51b81526004016101a09061091e565b60405180910390fd5b60026000556001546001600160a01b0316156101c457600080fd5b600480546040805163c57ab80160e01b815290516001600160a01b039092169263c57ab8019282820192602092908290030181865afa15801561020b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610955565b600180546001600160a01b0319166001600160a01b0392909216918217905561025757600080fd5b60018054600280546001600160a01b0319166001600160a01b03909216919091179055600055565b6002600054036102a15760405162461bcd60e51b81526004016101a09061091e565b60026000556040805180820190915260038152620908ab60eb1b60208201526102c990610682565b6102ee604051806040016040528060048152602001634d41584960e01b815250610682565b610313604051806040016040528060048152602001632422292760e11b815250610682565b610338604051806040016040528060048152602001634241534560e01b815250610682565b61035d604051806040016040528060048152602001635452494f60e01b815250610682565b610383604051806040016040528060058152602001644c55434b5960d81b815250610682565b6103a8604051806040016040528060048152602001634445434960e01b815250610682565b6103cd604051806040016040528060048152602001635445414d60e01b815250610682565b6103f2604051806040016040528060048152602001634943534160e01b815250610682565b6001600055565b60026000540361041b5760405162461bcd60e51b81526004016101a09061091e565b6002600081815590546040516369c966a360e01b815282916001600160a01b0316906369c966a3906104579033908990899089906004016109c9565b6040805180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104979190610a01565b33600090815260066020908152604080832088845282528083208a8452909152908190209051929450909250906104cf908690610a31565b9081526040519081900360200190205460ff161561055f5760405162461bcd60e51b815260206004820152604160248201527f596f75206d757374206e6f74206861766520616c726561647920636c61696d6560448201527f642066726f6d2074686973207374616b65206f6e207468697320706572696f646064820152601760f91b608482015260a4016101a0565b600082116105af5760405162461bcd60e51b815260206004820152601c60248201527f4e6f20726577617264732066726f6d207468697320706572696f642e0000000060448201526064016101a0565b60405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0382169063a9059cbb906044016020604051808303816000875af11580156105fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106209190610a4d565b50336000908152600660209081526040808320868452825280832088845290915290819020905160019190610656908790610a31565b908152604051908190036020019020805491151560ff1990921691909117905550506001600055505050565b60006001600160a01b031660058260405161069d9190610a31565b908152604051908190036020019020546001600160a01b0316146106c057600080fd5b6002546040516344e6f28b60e01b81526001600160a01b03909116906344e6f28b906106f0908490600401610a6f565b602060405180830381865afa15801561070d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107319190610955565b6005826040516107419190610a31565b90815260405190819003602001902080546001600160a01b03929092166001600160a01b031990921691909117905550565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261079a57600080fd5b813567ffffffffffffffff808211156107b5576107b5610773565b604051601f8301601f19908116603f011681019082821181831017156107dd576107dd610773565b816040528381528660208588010111156107f657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561082857600080fd5b813567ffffffffffffffff81111561083f57600080fd5b61084b84828501610789565b949350505050565b6001600160a01b038116811461086857600080fd5b50565b6000806000806080858703121561088157600080fd5b843561088c81610853565b93506020850135925060408501359150606085013567ffffffffffffffff8111156108b657600080fd5b6108c287828801610789565b91505092959194509250565b6000806000606084860312156108e357600080fd5b83359250602084013567ffffffffffffffff81111561090157600080fd5b61090d86828701610789565b925050604084013590509250925092565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60006020828403121561096757600080fd5b815161097281610853565b9392505050565b60005b8381101561099457818101518382015260200161097c565b50506000910152565b600081518084526109b5816020860160208601610979565b601f01601f19169290920160200192915050565b60018060a01b03851681528360208201526080604082015260006109f0608083018561099d565b905082606083015295945050505050565b60008060408385031215610a1457600080fd5b825191506020830151610a2681610853565b809150509250929050565b60008251610a43818460208701610979565b9190910192915050565b600060208284031215610a5f57600080fd5b8151801515811461097257600080fd5b602081526000610972602083018461099d56fea264697066735822122081faefd22fff813ce75f7891995cc2975c43efce510cfa6a593afae016df12ea64736f6c634300081000336080604052600480546001600160a01b03191673b7c9e99da8a857ce576a830a9c19312114d9de0217905534801561003657600080fd5b5060405161110d38038061110d8339810160408190526100559161007f565b6001600055600680546001600160a01b0319166001600160a01b03929092169190911790556100af565b60006020828403121561009157600080fd5b81516001600160a01b03811681146100a857600080fd5b9392505050565b61104f806100be6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80636b406b6d116100715780636b406b6d1461017457806370f283b1146101875780638d2fe35d1461019a578063e096c258146101b5578063f20a25b2146101f0578063f8f469e61461020357600080fd5b80630d4d77f4146100ae5780630f15f4c0146100fc5780632851092d1461010657806344e6f28b1461013157806369c966a314610144575b600080fd5b6100e96100bc366004610e26565b8151602081840181018051600a825292820194820194909420919093529091526000908152604090205481565b6040519081526020015b60405180910390f35b610104610251565b005b600154610119906001600160a01b031681565b6040516001600160a01b0390911681526020016100f3565b61011961013f366004610e6b565b61040d565b610157610152366004610ec0565b61043e565b604080519283526001600160a01b039091166020830152016100f3565b600554610119906001600160a01b031681565b610104610195366004610e6b565b610504565b61011973b7c9e99da8a857ce576a830a9c19312114d9de0281565b6100e96101c3366004610e26565b81516020818401810180516009825292820194820194909420919093529091526000908152604090205481565b6100e96101fe366004610e26565b610937565b610241610211366004610e26565b81516020818401810180516008825292820194820194909420919093529091526000908152604090205460ff1681565b60405190151581526020016100f3565b6002600054036102a85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000556001546001600160a01b0316156102c357600080fd5b600660009054906101000a90046001600160a01b03166001600160a01b0316632851092d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033a9190610f21565b600180546001600160a01b039283166001600160a01b031991821681179092556002805482168317905560038054909116909117905560065460408051636b406b6d60e01b815290519190921691636b406b6d9160048083019260209291908290030181865afa1580156103b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d69190610f21565b600580546001600160a01b0319166001600160a01b039290921691821790556103fe57600080fd5b610406610972565b6001600055565b600060078260405161041f9190610f45565b908152604051908190036020019020546001600160a01b031692915050565b600654604051637e0e00cf60e01b81526001600160a01b03868116600483015260248201869052604482018490526000928392839290911690637e0e00cf90606401602060405180830381865afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610f74565b905060006305f5e100826104d5888a610937565b6104df9190610fa3565b6104e99190610fc2565b9050806104f58761040d565b93509350505094509492505050565b6002600054036105565760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161029f565b60026000556006546040805163204fd36d60e21b815290516001600160a01b039092169163813f4db4916004808201926020929091908290030181865afa1580156105a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c99190610fe4565b156105d357600080fd5b60006001600660009054906101000a90046001600160a01b03166001600160a01b031663086146d26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561062a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064e9190610f74565b6106589190611006565b905060088260405161066a9190610f45565b90815260408051602092819003830190206000848152925290205460ff161561069257600080fd5b6007826040516106a29190610f45565b908152604051908190036020018120546370a0823160e01b82523060048301526001600160a01b0316906370a0823190602401602060405180830381865afa1580156106f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107169190610f74565b6009836040516107269190610f45565b908152604080519182900360209081018320600086815291522091909155600790610752908490610f45565b908152604051908190036020018120546005546001600160a01b039182169263a9059cbb92919091169060099061078a908790610f45565b90815260408051602092819003830181206000888152935291205460e084901b6001600160e01b03191682526001600160a01b03909216600482015260248101919091526044016020604051808303816000875af11580156107f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108149190610fe4565b5060016008836040516108279190610f45565b90815260408051918290036020908101832060008681529152908120805493151560ff1990941693909317909255600654632d9ba1cd60e01b8252600482018490526001600160a01b031690632d9ba1cd90602401602060405180830381865afa158015610899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bd9190610f74565b6009846040516108cd9190610f45565b9081526040805160209281900383019020600086815292529020546108f6906305f5e100610fa3565b6109009190610fc2565b905080600a846040516109139190610f45565b90815260408051602092819003830190206000958652909152832055506001905550565b6000600a836040516109499190610f45565b908152602001604051809103902060008381526020019081526020016000205490505b92915050565b732b591e99afe9f32eaa6214f7b7629768c40eeb39600760405161099f90620908ab60eb1b815260030190565b908152604080516020928190038301812080546001600160a01b03199081166001600160a01b0396871617909155634d41584960e01b82526007600480840182905284516024948190038501812080548516730d86eb9f43c57f6ff3bc9e23d8f9d82503f0e84b179055632422292760e11b815280820192909252845191829003840182208054909316733819f64f282bf135d62168c1e513280daf905e06179092558154633eb01cd360e11b825281830186905292810191909152634241534560e01b60448201529151931692637d6039a6926064808401939192918290030181865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610f21565b604051634241534560e01b81526007906004019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b8352818301939093526024820152635452494f60e01b6044820152911690637d6039a690606401602060405180830381865afa158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190610f21565b604051635452494f60e01b81526007906004019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b83529082019290925260056024820152644c55434b5960d81b6044820152911690637d6039a690606401602060405180830381865afa158015610bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1e9190610f21565b604051644c55434b5960d81b81526007906005019081526040516020918190038201812080546001600160a01b0319166001600160a01b0394851617905560048054633eb01cd360e11b8352818301939093526024820152634445434960e01b6044820152911690637d6039a690606401602060405180830381865afa158015610cac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd09190610f21565b60408051634445434960e01b81526007600480830182905283516024938190038401812080546001600160a01b03199081166001600160a01b0398909816979097179055635445414d60e01b8152808201839052845190819003840181208054871673b7c9e99da8a857ce576a830a9c19312114d9de02179055634943534160e01b815290810191909152915191829003019020805490911673fc4913214444af5c715cc9f7b52655e788a569ed179055565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610daa57600080fd5b813567ffffffffffffffff80821115610dc557610dc5610d83565b604051601f8301601f19908116603f01168101908282118183101715610ded57610ded610d83565b81604052838152866020858801011115610e0657600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610e3957600080fd5b823567ffffffffffffffff811115610e5057600080fd5b610e5c85828601610d99565b95602094909401359450505050565b600060208284031215610e7d57600080fd5b813567ffffffffffffffff811115610e9457600080fd5b610ea084828501610d99565b949350505050565b6001600160a01b0381168114610ebd57600080fd5b50565b60008060008060808587031215610ed657600080fd5b8435610ee181610ea8565b935060208501359250604085013567ffffffffffffffff811115610f0457600080fd5b610f1087828801610d99565b949793965093946060013593505050565b600060208284031215610f3357600080fd5b8151610f3e81610ea8565b9392505050565b6000825160005b81811015610f665760208186018101518583015201610f4c565b506000920191825250919050565b600060208284031215610f8657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615610fbd57610fbd610f8d565b500290565b600082610fdf57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215610ff657600080fd5b81518015158114610f3e57600080fd5b8181038181111561096c5761096c610f8d56fea264697066735822122033193495db6f0796ee8be33bc1af30f06e0dd5edd23d9407ce1f0b598625d36164736f6c63430008100033a2646970667358221220010e3ed52e817669188c43af0ca3ab96664e519fba7f12e2faff6349d043aa8064736f6c63430008100033

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

000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000044445434900000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : ticker (string): DECI

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [2] : 4445434900000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

30640:14658:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32032:53;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;529:25:1;;;517:2;502:18;32032:53:0;;;;;;;;44541:127;;;:::i;31561:37::-;;;;;-1:-1:-1;;;;;31561:37:0;;;;;;-1:-1:-1;;;;;729:32:1;;;711:51;;699:2;684:18;31561:37:0;565:203:1;33135:308:0;;;:::i;:::-;;44220:145;;;;;;:::i;:::-;44296:7;44322:35;;;:27;:35;;;;;;;44220:145;34674:60;;;;;;:::i;:::-;;;;;;;;;;;;;;32565:27;;;:::i;:::-;;;;;;;:::i;37465:176::-;;;;;;:::i;:::-;;:::i;34879:62::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34879:62:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2041:32:1;;;2023:51;;2105:2;2090:18;;2083:34;;;;2133:18;;;2126:34;;;;2191:2;2176:18;;2169:34;2247:14;2240:22;2234:3;2219:19;;2212:51;2010:3;1995:19;34879:62:0;1770:499:1;41176:324:0;;;;;;:::i;:::-;;:::i;38376:475::-;;;;;;:::i;:::-;;:::i;33523:246::-;;;:::i;32223:48::-;;;;;-1:-1:-1;;;;;32223:48:0;;;43964:250;;;;;;:::i;:::-;-1:-1:-1;;;;;44121:22:0;;44073:7;44121:22;;;:6;:22;;;;;;;;:31;;;;;;;;44170:35;;;:27;;:35;;;;;;43964:250;;;;;;42290:779;;;;;;:::i;:::-;;:::i;43469:489::-;;;;;;:::i;:::-;;:::i;44680:228::-;;;:::i;:::-;;;3019:14:1;;3012:22;2994:41;;2982:2;2967:18;44680:228:0;2854:187:1;31605:88:0;;31651:42;31605:88;;31830:35;;;;;;32400:36;;;;;-1:-1:-1;;;;;32400:36:0;;;35422:534;;;;;;:::i;:::-;;:::i;44541:127::-;44628:12;;:31;;;-1:-1:-1;;;44628:31:0;;;;44590:19;;-1:-1:-1;;;;;44628:12:0;;:29;;:31;;;;;;;;;;;;;;:12;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44621:38;;44541:127;:::o;33135:308::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;;;;;;;;;1812:1;2543:7;:18;33223:33:::1;::::0;-1:-1:-1;;;;;33223:33:0::1;:45:::0;33215:74:::1;;;::::0;-1:-1:-1;;;33215:74:0;;3797:2:1;33215:74:0::1;::::0;::::1;3779:21:1::0;3836:2;3816:18;;;3809:30;-1:-1:-1;;;3855:18:1;;;3848:46;3911:18;;33215:74:0::1;3595:340:1::0;33215:74:0::1;33300:29;33370:4;33332:44;;;;;:::i;:::-;-1:-1:-1::0;;;;;729:32:1;;;711:51;;699:2;684:18;33332:44:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;33387:33:0::1;:48:::0;;-1:-1:-1;;;;;;33387:48:0::1;-1:-1:-1::0;;;;;33387:48:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;2722:22:0;33135:308::o;32565:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;37465:176::-;37527:7;;37565:8;37572:1;37565:6;:8;:::i;:::-;37547:26;37465:176;-1:-1:-1;;;37465:176:0:o;41176:324::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;41269:32:::1;41285:7:::0;41294:6;41269:15:::1;:32::i;:::-;41358:6;41335:20;;:29;;;;:::i;:::-;41312:20;:52:::0;41425:10:::1;41406:30;::::0;;;:18:::1;:30;::::0;;;;;:39:::1;::::0;41439:6;;41406:39:::1;:::i;:::-;41394:10;41375:30;::::0;;;:18:::1;:30;::::0;;;;;;:70;;;;41456:7:::1;::::0;;:36;;-1:-1:-1;;;41456:36:0;;;;::::1;5021:51:1::0;;;;5088:18;;;5081:34;;;-1:-1:-1;;;;;41456:7:0;;::::1;::::0;:16:::1;::::0;4994:18:1;;41456:36:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;1768:1:0;2722:7;:22;-1:-1:-1;41176:324:0:o;38376:475::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;38470:36:::1;38490:7:::0;38499:6;38470:19:::1;:36::i;:::-;38544:15;38562:24;38579:6;38562:16;:24::i;:::-;38544:42;;38644:6;38621:20;;:29;;;;:::i;:::-;38598:20;:52:::0;38711:10:::1;38692:30;::::0;;;:18:::1;:30;::::0;;;;;:39:::1;::::0;38725:6;;38692:39:::1;:::i;:::-;38680:10;38661:30;::::0;;;:18:::1;:30;::::0;;;;:70;;;;38742:7:::1;::::0;-1:-1:-1;;;;;38742:7:0::1;::::0;:16:::1;::::0;38770:14:::1;38777:7:::0;38770:6;:14:::1;:::i;:::-;38742:43;::::0;-1:-1:-1;;;;;;38742:43:0::1;::::0;;;;;;-1:-1:-1;;;;;5039:32:1;;;38742:43:0::1;::::0;::::1;5021:51:1::0;5088:18;;;5081:34;4994:18;;38742:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;38796:7:0::1;::::0;;38813:21:::1;::::0;38796:47:::1;::::0;-1:-1:-1;;;38796:47:0;;-1:-1:-1;;;;;38813:21:0;;::::1;38796:47:::0;;::::1;5021:51:1::0;;;;5088:18;;;5081:34;;;38796:7:0::1;::::0;:16:::1;::::0;4994:18:1;;38796:47:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;1768:1:0;2722:7;:22;-1:-1:-1;;38376:475:0:o;33523:246::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;33601:21:::1;::::0;-1:-1:-1;;;;;33601:21:0::1;:33:::0;33593:62:::1;;;::::0;-1:-1:-1;;;33593:62:0;;3797:2:1;33593:62:0::1;::::0;::::1;3779:21:1::0;3836:2;3816:18;;;3809:30;-1:-1:-1;;;3855:18:1;;;3848:46;3911:18;;33593:62:0::1;3595:340:1::0;33593:62:0::1;33666:15;33709:4;33684:31;;;;;:::i;:::-;-1:-1:-1::0;;;;;729:32:1;;;711:51;;699:2;684:18;33684:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;33726:21:0::1;:35:::0;;-1:-1:-1;;;;;;33726:35:0::1;-1:-1:-1::0;;;;;33726:35:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;2722:22:0;33523:246::o;42290:779::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;;;42388::::1;:16;:18::i;:::-;42365:41;;42421:27;42451:22;:20;:22::i;:::-;42523:10;42488:25;42516:18:::0;;;:6:::1;:18;::::0;;;;;;;:27;;;;;;;;42421:52;;-1:-1:-1;42566:17:0::1;:15;:17::i;:::-;42558:26;;;::::0;::::1;;42634:14;42607:5;:25;;;:41;42599:50;;;::::0;::::1;;42664:25;::::0;::::1;:45:::0;;;42826:13:::1;::::0;::::1;::::0;42775:48:::1;::::0;;;:27:::1;::::0;::::1;:48;::::0;;;;;:64:::1;::::0;42826:13;42775:64:::1;:::i;:::-;42724:48;::::0;;;:27:::1;::::0;::::1;:48;::::0;;;;;;;:115;;;;42956:13:::1;::::0;::::1;::::0;42905:27:::1;:48:::0;;;;;;;:64:::1;::::0;42956:13;42905:64:::1;:::i;:::-;42854:48;::::0;;;:27:::1;:48;::::0;;;;;;;;:115;;;;43013:13:::1;::::0;::::1;::::0;42989:68;;5740:25:1;;;5781:18;;;5774:34;;;5824:18;;5817:34;;;43001:10:0::1;::::0;42989:68:::1;::::0;5728:2:1;5713:18;42989:68:0::1;;;;;;;;-1:-1:-1::0;;1768:1:0;2722:7;:22;-1:-1:-1;;42290:779:0:o;43469:489::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;;;43569::::1;:16;:18::i;:::-;43633:10;43598:25;43626:18:::0;;;:6:::1;:18;::::0;;;;;;;:27;;;;;;;;43672:25:::1;::::0;::::1;::::0;43546:41;;-1:-1:-1;43626:27:0;43672:40;-1:-1:-1;43664:49:0::1;;;::::0;::::1;;43748:1;43732:5;:13;;;:17;43724:26;;;::::0;::::1;;43761:29;43776:5;:13;;;43761:14;:29::i;:::-;43818:13;::::0;::::1;::::0;;43801:14:::1;43842:17:::0;;;43915:25:::1;::::0;::::1;::::0;43875:75:::1;::::0;;5740:25:1;;;5796:2;5781:18;;5774:34;;;;5824:18;;5817:34;;;43895:10:0::1;::::0;43875:75:::1;::::0;5728:2:1;5713:18;43875:75:0::1;5538:319:1::0;44680:228:0;44728:4;44745:14;44781:1;44762:18;:16;:18::i;:::-;:20;;;;:::i;:::-;44745:37;;44796:9;44807:1;44796:12;44793:108;;44831:5;44824:12;;;44680:228;:::o;44793:108::-;44885:4;44878:11;;;44680:228;:::o;35422:534::-;1812:1;2410:7;;:19;2402:63;;;;-1:-1:-1;;;2402:63:0;;;;;;;:::i;:::-;1812:1;2543:7;:18;35497:8;35489:66:::1;;;::::0;-1:-1:-1;;;35489:66:0;;6181:2:1;35489:66:0::1;::::0;::::1;6163:21:1::0;6220:2;6200:18;;;6193:30;6259:34;6239:18;;;6232:62;-1:-1:-1;;;6310:18:1;;;6303:43;6363:19;;35489:66:0::1;5979:409:1::0;35489:66:0::1;35574:7;::::0;;:44:::1;::::0;-1:-1:-1;;;35574:44:0;;35592:10:::1;35574:44:::0;;::::1;6605:34:1::0;;;;35612:4:0::1;6655:18:1::0;;;6648:43;35620:6:0;;-1:-1:-1;;;;;35574:7:0;;::::1;::::0;:17:::1;::::0;6540:18:1;;35574:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;35566:61;;;::::0;::::1;;35638:22;35653:6;35638:14;:22::i;:::-;35699:7;::::0;;:55:::1;::::0;-1:-1:-1;;;35699:55:0;;35720:10:::1;35699:55:::0;;::::1;6942:34:1::0;;;;35740:4:0::1;6992:18:1::0;;;6985:43;7044:18;;;7037:34;;;-1:-1:-1;;;;;35699:7:0::1;::::0;:20:::1;::::0;6877:18:1;;35699:55:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;35861:6;35838:20;;:29;;;;:::i;:::-;35815:20;:52:::0;35928:10:::1;35909:30;::::0;;;:18:::1;:30;::::0;;;;;:39:::1;::::0;35942:6;;35909:39:::1;:::i;:::-;35897:10;35878:30;::::0;;;:18:::1;:30;::::0;;;;:70;;;;1768:1;2722:22;;-1:-1:-1;35422:534:0:o;41510:455::-;41591:22;41614:18;:16;:18::i;:::-;41682:10;41647:25;41675:18;;;:6;:18;;;;;;;;:27;;;;;;;;41725:25;;;;41591:41;;-1:-1:-1;41675:27:0;41725:40;-1:-1:-1;41717:49:0;;;;;;41804:6;41789:5;:13;;;:21;;41781:30;;;;;;41856:6;41842:5;:13;;;:20;;;;:::i;:::-;41826:13;;;:36;41918:25;;;;41882:71;;;5740:25:1;;;5796:2;5781:18;;5774:34;;;;5824:18;;5817:34;;;41898:10:0;;41882:71;;5728:2:1;5713:18;41882:71:0;;;;;;;;41576:389;;41510:455;;:::o;39292:1465::-;39377:22;39402:18;:16;:18::i;:::-;39377:43;;39435:27;39465:22;:20;:22::i;:::-;39537:10;39502:25;39530:18;;;:6;:18;;;;;;;;:27;;;;;;;;39580:15;;;;39435:52;;-1:-1:-1;39530:27:0;39580:15;;:21;;:15;:21;39572:73;;;;-1:-1:-1;;;39572:73:0;;7284:2:1;39572:73:0;;;7266:21:1;7323:2;7303:18;;;7296:30;7362:34;7342:18;;;7335:62;-1:-1:-1;;;7413:18:1;;;7406:37;7460:19;;39572:73:0;7082:403:1;39572:73:0;39695:14;39668:5;:25;;;:41;;39660:86;;;;-1:-1:-1;;;39660:86:0;;7692:2:1;39660:86:0;;;7674:21:1;;;7711:18;;;7704:30;7770:34;7750:18;;;7743:62;7822:18;;39660:86:0;7490:356:1;39660:86:0;39824:6;39809:5;:13;;;:21;;39801:30;;;;;;39878:6;39862:5;:13;;;:22;;;;:::i;:::-;39846:13;;;:38;40017:1;39968:48;;;:27;;;:48;;;;;;:50;39964:317;;40087:48;;;;:27;:48;;;;;;:55;;40136:6;;40087:55;:::i;:::-;40038:48;;;;:27;:48;;;;;;;;:104;;;;40210:27;;;:48;;;;:55;;40259:6;;40210:55;:::i;:::-;40161:48;;;;:27;;;:48;;;;;:104;39964:317;40412:1;40368:43;;;:27;;;:43;;;;;;:45;40364:293;;40478:43;;;;:27;:43;;;;;;:50;;40522:6;;40478:50;:::i;:::-;40434:43;;;;:27;:43;;;;;;;;:94;;;;40591:27;;;:43;;;;:50;;40635:6;;40591:50;:::i;:::-;40547:43;;;;:27;;;:43;;;;;:94;40364:293;40710:25;;;;40676:69;;;5740:25:1;;;5796:2;5781:18;;5774:34;;;;5824:18;;5817:34;;;40690:10:0;;40676:69;;5728:2:1;5713:18;40676:69:0;;;;;;;39362:1395;;;39292:1465;;:::o;44916:379::-;44969:7;44989:22;45012:18;:16;:18::i;:::-;44989:41;;45041:27;45083:17;:15;:17::i;:::-;:23;;45102:4;45083:23;45079:172;;45145:16;:14;45160:1;45145:16;:::i;:::-;45123:38;;45079:172;;;45223:16;:14;45238:1;45223:16;:::i;:::-;45203:36;;45079:172;45268:19;44916:379;-1:-1:-1;;44916:379:0:o;36126:1240::-;36189:27;36219:22;:20;:22::i;:::-;36390:10;36355:25;36383:18;;;:6;:18;;;;;;;;:39;;;;;;;;36591:15;;;;36189:52;;-1:-1:-1;36383:39:0;36591:15;;:22;;;;36587:377;;-1:-1:-1;36726:13:0;;;:35;;;36780:15;;;:22;;-1:-1:-1;;36780:22:0;36798:4;36780:22;;;;;;36821:25;;-1:-1:-1;;;;;;36821:25:0;36836:10;36821:25;;;36865;;;:47;;;36587:377;37003:13;;;;36994:22;;:6;:22;:::i;:::-;36978:13;;;:38;37091:48;;;;:27;;;:48;;;;;;37082:57;;:6;:57;:::i;:::-;37031:48;;;;:27;;;:48;;;;;;;;:108;;;;37214:27;:48;;;;37205:57;;:6;:57;:::i;:::-;37154:48;;;;:27;:48;;;;;:108;37288:10;37282:72;37300:6;37308:18;:16;:18::i;:::-;37328:13;;;;37282:72;;;8076:25:1;;;8132:2;8117:18;;8110:34;;;;8160:18;;;8153:34;8230:14;;8223:22;8218:2;8203:18;;8196:50;8063:3;8048:19;37282:72:0;7851:401:1;-1:-1:-1;;;;;;;;:::o;:::-;;;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;773:180::-;832:6;885:2;873:9;864:7;860:23;856:32;853:52;;;901:1;898;891:12;853:52;-1:-1:-1;924:23:1;;773:180;-1:-1:-1;773:180:1:o;958:548::-;1070:4;1099:2;1128;1117:9;1110:21;1160:6;1154:13;1203:6;1198:2;1187:9;1183:18;1176:34;1228:1;1238:140;1252:6;1249:1;1246:13;1238:140;;;1347:14;;;1343:23;;1337:30;1313:17;;;1332:2;1309:26;1302:66;1267:10;;1238:140;;;1242:3;1427:1;1422:2;1413:6;1402:9;1398:22;1394:31;1387:42;1497:2;1490;1486:7;1481:2;1473:6;1469:15;1465:29;1454:9;1450:45;1446:54;1438:62;;;;958:548;;;;:::o;1511:254::-;1579:6;1587;1640:2;1628:9;1619:7;1615:23;1611:32;1608:52;;;1656:1;1653;1646:12;1608:52;1679:29;1698:9;1679:29;:::i;:::-;1669:39;1755:2;1740:18;;;;1727:32;;-1:-1:-1;;;1511:254:1:o;2274:248::-;2342:6;2350;2403:2;2391:9;2382:7;2378:23;2374:32;2371:52;;;2419:1;2416;2409:12;2371:52;-1:-1:-1;;2442:23:1;;;2512:2;2497:18;;;2484:32;;-1:-1:-1;2274:248:1:o;2527:322::-;2604:6;2612;2620;2673:2;2661:9;2652:7;2648:23;2644:32;2641:52;;;2689:1;2686;2679:12;2641:52;2712:29;2731:9;2712:29;:::i;:::-;2702:39;2788:2;2773:18;;2760:32;;-1:-1:-1;2839:2:1;2824:18;;;2811:32;;2527:322;-1:-1:-1;;;2527:322:1:o;3046:184::-;3116:6;3169:2;3157:9;3148:7;3144:23;3140:32;3137:52;;;3185:1;3182;3175:12;3137:52;-1:-1:-1;3208:16:1;;3046:184;-1:-1:-1;3046:184:1:o;3235:355::-;3437:2;3419:21;;;3476:2;3456:18;;;3449:30;3515:33;3510:2;3495:18;;3488:61;3581:2;3566:18;;3235:355::o;3940:380::-;4019:1;4015:12;;;;4062;;;4083:61;;4137:4;4129:6;4125:17;4115:27;;4083:61;4190:2;4182:6;4179:14;4159:18;4156:38;4153:161;;4236:10;4231:3;4227:20;4224:1;4217:31;4271:4;4268:1;4261:15;4299:4;4296:1;4289:15;4153:161;;3940:380;;;:::o;4325:127::-;4386:10;4381:3;4377:20;4374:1;4367:31;4417:4;4414:1;4407:15;4441:4;4438:1;4431:15;4457:127;4518:10;4513:3;4509:20;4506:1;4499:31;4549:4;4546:1;4539:15;4573:4;4570:1;4563:15;4589:120;4629:1;4655;4645:35;;4660:18;;:::i;:::-;-1:-1:-1;4694:9:1;;4589:120::o;4714:128::-;4781:9;;;4802:11;;;4799:37;;;4816:18;;:::i;5126:277::-;5193:6;5246:2;5234:9;5225:7;5221:23;5217:32;5214:52;;;5262:1;5259;5252:12;5214:52;5294:9;5288:16;5347:5;5340:13;5333:21;5326:5;5323:32;5313:60;;5369:1;5366;5359:12;5408:125;5473:9;;;5494:10;;;5491:36;;;5507:18;;:::i;5862:112::-;5894:1;5920;5910:35;;5925:18;;:::i;:::-;-1:-1:-1;5959:9:1;;5862:112::o

Swarm Source

ipfs://010e3ed52e817669188c43af0ca3ab96664e519fba7f12e2faff6349d043aa80

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  ]
[ 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.