false
true
0

Contract Address Details

0x5A9780Bfe63f3ec57f01b087cD65BD656C9034A8

Token
Communis (COM)
Creator
0x3def17–5136b9 at 0xa5b669–96d2f3
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
62,478 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25883277
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Communis




Optimization enabled
true
Compiler version
v0.8.16+commit.07a7930e




Optimization runs
200
EVM Version
petersburg




Verified at
2024-01-29T06:53:10.974928Z

Contract source code

/**
 *Submitted for verification at Etherscan.io on 2023-01-09
*/

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

// SPDX-License-Identifier: MIT
// 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\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\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: @openzeppelin\contracts\token\ERC20\extensions\ERC20Burnable.sol

// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

// File: contracts\COM.sol

// Codeak
pragma solidity ^0.8.4;
interface _HEX { 
   function currentDay() external view returns (uint256);
   function stakeLists(address owner, uint256 stakeIndex) external view returns (uint40, uint72, uint72, uint16, uint16, uint16, bool);
   function stakeGoodAccounting(address stakerAddr, uint256 stakeIndex, uint40 stakeIdParam) external;
   function globals() external view returns (
             uint72 lockedHeartsTotal
            ,uint72 nextStakeSharesTotal
            ,uint40 shareRate
            ,uint72 stakePenaltyTotal
            ,uint16 dailyDataCount
            ,uint72 stakeSharesTotal
            ,uint40 latestStakeId
            ,uint128 claimStats
            );
}

contract Communis is ERC20, ERC20Burnable {

    _HEX private HEX;

    address internal constant contract_creator = 0x3dEF1720Ce2B04a56f0ee6BC9875C64A785136b9;

    constructor() ERC20("Communis", "COM") {
        HEX = _HEX(address(0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39));
    }

    function decimals() public view virtual override returns (uint8) {
        return 12;
    }

    enum BonusType {START, END, GOOD, RESTAKE}

    event newMint(
         uint256 data0
        ,uint256 data1
        ,uint256 indexed stakeId
        ,uint256 indexed bonusType
        ,address indexed senderAddr
        ,address referrer
    );

    event newDebtMint(
         uint256 data0
        ,address indexed senderAddr
    );

    event stakeDepositCodeak(
         uint256 data0
        ,address indexed senderAddr
    );

    event stakeWithdrawCodeak(
         uint256 data0
        ,address indexed senderAddr
    );

    struct PayoutResponse {
        uint256 recalculatedStakeShares;
        uint256 stakesOriginalShareRate;
        uint256 maxPayout;
    }

    struct Stake {
        uint256 stakeID;
        uint256 stakedHearts;
        uint256 stakeShares;
        uint256 lockedDay;
        uint256 stakedDays;
        uint256 unlockedDay;
    }

    struct RestakeEndDebt {
        uint16  stakedDays;
        uint16  endBonusPayoutDay;
        uint72  sharesDebt;
    }

    struct EndBonusDebt {
        uint16 nextPayoutDay;
        uint128 payoutDebt;
    }

    struct stakeIndexIdAmount {
        uint256 stakeIndex;
        uint256 stakeID;
        uint256 stakeAmount;
    }

    mapping(uint256 => uint256)                 public stakeIdStartBonusPayout;
    mapping(uint256 => uint256)                 public stakeIdEndBonusPayout;
    mapping(address => RestakeEndDebt)          public addressRestakeEndDebt;
    mapping(address => EndBonusDebt)            public addressEndBonusDebt;
    mapping(uint256 => uint256)                 public stakeIdGoodAccountingBonusPayout;
    mapping(address => uint256)                 public addressStakedCodeak;

    function memoryStake(address adr, uint256 stakeIndex, uint256 stakeID)
        internal view
        returns (Stake memory)
    {
        uint40 _stakeID;
        uint72 _stakedHearts;
        uint72 _stakeShares;
        uint16 _lockedDay;
        uint16 _stakedDays;
        uint16 _unlockedDay;

        (_stakeID, _stakedHearts, _stakeShares, _lockedDay, _stakedDays, _unlockedDay, ) = HEX.stakeLists(address(adr), stakeIndex);

        require(_stakeID == stakeID, "COM: Assure correct and current stake");

        return Stake(_stakeID, _stakedHearts, _stakeShares, _lockedDay, _stakedDays, _unlockedDay);
    }

    function getGlobalShareRate()
        internal view
        returns (uint256 shareRate)
    { 
        (, , shareRate, , , , , ) = HEX.globals(); 
    }

    function _emitNewMint(uint256 payout, uint256 stakedDays, uint256 recalculatedStakeShares, uint256 stakesOriginalShareRate, uint256 stakedHearts, uint256 stakeID, address referrer, BonusType bonusType)
        private
    {
        emit newMint(
            (uint256(uint128(payout)))
                | (uint256(uint128(recalculatedStakeShares)) << 128)
            ,uint256(uint40(block.timestamp))
                | (uint256(uint16(stakedDays))               << 40)
                | (uint256(uint40(stakesOriginalShareRate))  << 56)
                | (uint256(uint72(stakedHearts))             << 96)
            ,stakeID
            ,uint(bonusType)
            ,msg.sender
            ,referrer
        );
    }

    function _emitNewDebtMint(uint16 nextPayoutDay, uint256 payout, uint128 payoutDebt)
        private
    {
        emit newDebtMint(
             uint256(nextPayoutDay)
                | (uint256(uint112(payout)) << 16)
                | (uint256(payoutDebt)      << 128)
            ,msg.sender
        );
    }

    function _emitStakeDepositCodeak(uint256 amount, uint256 stakedCodeak)
        private
    {
        emit stakeDepositCodeak(
             uint256(uint128(amount))
                | (uint256(uint128(stakedCodeak)) << 128)
            ,msg.sender
        );
    }

    function _emitStakeWithdrawCodeak(uint256 amount, uint256 stakedCodeak)
        private
    {
        emit stakeWithdrawCodeak(
             uint256(uint128(amount))
                | (uint256(uint128(stakedCodeak)) << 128)
            ,msg.sender
        );
    }

    /**
     * 
     * @dev Reads current RestakeEndDebt
     * 
     * Maintains latest end bonus payout day
     * 
     * Maintains largest amount staked days
     * 
     * Accumulates stake's shares as total sharesDebt
     * 
     */
    function _updateRestakeEndDebt(uint256 currentDay, Stake memory s)
        private
    {
        RestakeEndDebt storage red = addressRestakeEndDebt[msg.sender];

        if(red.endBonusPayoutDay < currentDay) red.endBonusPayoutDay = uint16(currentDay);
        if(red.stakedDays < s.stakedDays) red.stakedDays = uint16(s.stakedDays);

        red.sharesDebt += uint72(s.stakeShares);
    }

    /**
     * 
     * @dev Reads current RestakeEndDebt
     * 
     * Assure new start stake (Stake Memory ss) meets requirements against RestakeEndDebt for Restake Bonus
     * 
     * Delete any restake debt if obligations are met
     * 
     */
    function _validateRestakeBonus(Stake memory ss)
        private
    {
        require(ss.stakedDays > 364, "COM: Minimum 365 staked days required");

        RestakeEndDebt storage red = addressRestakeEndDebt[msg.sender];

        require(red.endBonusPayoutDay != 0, "COM: No valid restake opportunity");
        require(ss.lockedDay > red.endBonusPayoutDay, "COM: Start Stake must be newer than previous stake");
        require(ss.stakedDays == 5555 || ss.stakedDays > red.stakedDays, "COM: New staked days must be greater than to previous");
        require(ss.stakeShares >= red.sharesDebt, "COM: Restake must at least maintain shares");     
        require(ss.stakeShares <= (red.sharesDebt * 2), "COM: Restake shares cannot be more than double");

        delete addressRestakeEndDebt[msg.sender];
    }

    /**
     * 
     * @dev Reverse engineer amount of bonus HEX hearts that were used in 
     * determining stake's HEX shares (this data is not kept in HEX storage)
     * 
     * Formula is derived from HEX smart contract
     * 
     */
    function getStakesBonusHearts(Stake memory s)
        internal pure
        returns (uint256 stakesBonusHearts)
    {
        uint256 cappedDays = 0;

        if (s.stakedDays > 1) cappedDays = s.stakedDays <= 3640 ? s.stakedDays - 1 : 3640;

        uint256 cappedHearts = s.stakedHearts <= (15 * (10 ** 15)) ? s.stakedHearts : (15 * (10 ** 15));

        stakesBonusHearts = s.stakedHearts * ((cappedDays * (15 * (10 ** 16))) + (cappedHearts * 1820)) / (273 * (10 ** 18)); 
    }

    /**
     * 
     * @dev Recalculate amount of bonus HEX hearts that would be applied if 
     * the cappedDays were not limited to 3640 days
     * 
     * Formula is derived from HEX smart contract
     * 
     */
    function getRecalculatedBonusHearts(Stake memory s)
        internal pure
        returns (uint256 recalculatedBonusHearts)
    {
        uint256 cappedDays = s.stakedDays - 1;

        uint256 cappedHearts = s.stakedHearts <= (15 * (10 ** 15)) ? s.stakedHearts : (15 * (10 ** 15));
 
        recalculatedBonusHearts = s.stakedHearts * ((cappedDays * (15 * (10 ** 16))) + (cappedHearts * 1820)) / (273 * (10 ** 18)); 
    }

    /**
     * 
     * @dev Creates a consistent PayoutResponse for any given Stake
     * 
     * Reverse engineer stakes original share rate as stakesOriginalShareRate using reverse engineered stakes bonus hearts
     * 
     * Recalculate Stake Shares with new Recalculated Bonus Hearts and using Reverse engineered stakesOriginalShareRate
     * 
     * Calculate penalty for amount days staked out of possible max length staked days of 5555, derived from HEX smart contract
     * 
     * Max payout represents the maximum possible value that can be minted for any given Stake
     * 
     */
    function getPayout(Stake memory s)
        public pure
        returns (PayoutResponse memory pr)
    {
        uint256 stakesOriginalShareRate = ((s.stakedHearts + getStakesBonusHearts(s)) * (10 ** 5)) / s.stakeShares;

        uint256 recalculatedStakeShares = (s.stakedHearts + getRecalculatedBonusHearts(s)) * (10 ** 17) / stakesOriginalShareRate;

        pr.stakesOriginalShareRate = stakesOriginalShareRate;
        pr.recalculatedStakeShares = recalculatedStakeShares;

        uint256 penalty = (s.stakedDays * (10 ** 15)) / 5555;
        pr.maxPayout = (recalculatedStakeShares * penalty) / (10 ** 15);
    }

    /**
     * 
     * @dev Creates a consistent payout for the Start Bonus given any Stake
     * 
     * If applyRestakeBonus, staked days range between 365 and 5555: 
     *      365 days gives bonusPercentage of 50000000000 and thus a 20% payout of maxPayout
     *      5555 days gives bonusPercentage of 20000000000 and thus a 50% payout of maxPayout
     * 
     * Else if staked days greater than 364, staked days range between 365 and 5555: 
     *      365 days gives bonusPercentage of 100000000000 and thus a 10% payout of maxPayout
     *      5555 days gives bonusPercentage of 40000000000 and thus a 25% payout of maxPayout
     * 
     * Else, staked days range between 180 and 364:
     *      180 days gives bonusPercentage of 200000000000 and thus a 5% payout of maxPayout
     *      364 days gives bonusPercentage of ~100540540540 and thus a ~9.946% payout of maxPayout
     * 
     * Penalty 
     *      global share rate is derived from HEX smart contract
     *      global share rate can only increase over time
     *      distance between current global share rate and reverse engineered stakes original share rate determine penalty
     * I.E.
     *      100,000 stakes share rate / 200,000 global share rate = you keep 50% of Start Bonus payout
     *      100,000 stakes share rate / 400,000 global share rate = you keep 25% of Start Bonus payout
     * 
     */
    function getStartBonusPayout(uint256 stakedDays, uint256 lockedDay, uint256 maxPayout, uint256 stakesOriginalShareRate, uint256 currentDay, uint256 globalShareRate, bool applyRestakeBonus)
        public pure
        returns (uint256 payout)
    {
        uint256 bonusPercentage;

        if(applyRestakeBonus == true) {
            bonusPercentage = (((stakedDays - 365) * (10 ** 10)) / 5190);
            bonusPercentage = ((3 * (10 ** 10)) * bonusPercentage) / (10 ** 10);
            bonusPercentage = (5 * (10 ** 10)) - bonusPercentage;
        }
        else if (stakedDays > 364) {
            bonusPercentage = ((stakedDays - 365) * (10 ** 10)) / 5190;
            bonusPercentage = ((6 * (10 ** 10)) * bonusPercentage) / (10 ** 10);
            bonusPercentage = (10 * (10 ** 10)) - bonusPercentage;
        }
        else {
            bonusPercentage = ((stakedDays - 180) * (10 ** 10)) / 185;
            bonusPercentage = ((10 * (10 ** 10)) * bonusPercentage) / (10 ** 10);
            bonusPercentage = (20 * (10 ** 10)) - bonusPercentage;
        }
 
        payout = (maxPayout * (10 ** 10)) / bonusPercentage;

        if(currentDay != lockedDay) {
            uint256 penalty = (stakesOriginalShareRate * (10 ** 15)) / globalShareRate;
            payout = (payout * penalty) / (10 ** 15);
        }
    }

    /**
     * 
     * @dev Allows withdraw of staked Codeak associated with msg.sender address
     * 
     */
    function withdrawStakedCodeak(uint256 withdrawAmount)
        external
    {
        require(withdrawAmount <= addressStakedCodeak[msg.sender], "COM: Requested withdraw amount is more than Address Staked Amount");

        addressStakedCodeak[msg.sender] -= withdrawAmount;

        _mint(msg.sender, withdrawAmount);
        _emitStakeWithdrawCodeak(withdrawAmount, addressStakedCodeak[msg.sender]);
    }

    /**
     * 
     * @dev External call to mint stake bonus for staking Codeak
     * 
     * Must have end bonus payout debt
     * 
     * Must have staked Codeak greater than or equal to end bonus payout debt
     * 
     */
    function mintStakeBonus()
        external
    {
        EndBonusDebt storage ebd = addressEndBonusDebt[msg.sender];
        if(ebd.payoutDebt != 0) {
            uint256 stakedCodeak = addressStakedCodeak[msg.sender];
            require(stakedCodeak >= ebd.payoutDebt, "COM: Address Staked Amount does not cover End Bonus Debt");
            _mintStakeBonus(ebd, HEX.currentDay(), stakedCodeak);
        }
    }

    /**
     * 
     * @dev Mints stake bonus for staking Codeak
     * 
     * Must have current day derived from HEX smart contract greater than next payout day
     * 
     * Calculates number of payouts based on distance between current day and next payout day
     * with no limit between the amount of days between them but in 91 day chunks
     *  
     * Sets next payout day depending on number of payouts minted
     * 
     */
    function _mintStakeBonus(EndBonusDebt storage ebd, uint256 currentDay, uint256 stakedCodeak)
        private
    {
        if(currentDay >= ebd.nextPayoutDay) {
            uint256 numberOfPayouts = ((currentDay - ebd.nextPayoutDay) / 91) + 1;
            uint256 payout = (stakedCodeak * numberOfPayouts) / 80;

            _mint(msg.sender, payout);

            ebd.nextPayoutDay += uint16(numberOfPayouts * 91);
            _emitNewDebtMint(ebd.nextPayoutDay, payout, ebd.payoutDebt);
        }
    }

    /**
     * 
     * @dev Allows batch minting of Start Bonuses to reduce gas costs
     * 
     */
    function mintStartBonusBatch(stakeIndexIdAmount[] calldata stakeIndexIdAmounts, address referrer)
        external
    {
        uint256 stakeIndexIdAmountsLength = stakeIndexIdAmounts.length;
        uint256 currentDay = HEX.currentDay();
        uint256 globalShareRate = getGlobalShareRate();

        for(uint256 i = 0; i < stakeIndexIdAmountsLength;){
            _mintStartBonus(stakeIndexIdAmounts[i].stakeIndex, stakeIndexIdAmounts[i].stakeID, false, referrer, currentDay, globalShareRate, stakeIndexIdAmounts[i].stakeAmount);
            unchecked {
                i++;
            }
        }
    }

    /**
     * 
     * @dev External call for single Start Bonuses
     * 
     */
    function mintStartBonus(uint256 stakeIndex, uint256 stakeID, bool applyRestakeBonus, address referrer, uint256 stakeAmount)
        external
    {
        _mintStartBonus(stakeIndex, stakeID, applyRestakeBonus, referrer, HEX.currentDay(), getGlobalShareRate(), stakeAmount);
    }

    /**
     * 
     * @dev Mints a bonus for starting a stake in HEX smart contract
     * 
     * Start bonus is only an upfront cut of the total max payout available for any given stake
     * 
     * Stake must not have its Start or End Bonus minted already
     * 
     * Stake shares must be at least 10000 to truncate low value edge cases
     * 
     * Start bonus forces minting Stake Bonus, if available, before staking new Codeak
     * 
     */
    function _mintStartBonus(uint256 stakeIndex, uint256 stakeID, bool applyRestakeBonus, address referrer, uint256 currentDay, uint256 globalShareRate, uint256 stakeAmount)
        private
    {
        require(stakeIdStartBonusPayout[stakeID] == 0, "COM: StakeID Start Bonus already minted");
        require(stakeIdEndBonusPayout[stakeID] == 0, "COM: StakeID End Bonus already minted");

        Stake memory s = memoryStake(address(msg.sender), stakeIndex, stakeID);

        require(s.stakeShares > 9999, "COM: Minimum 10000 shares required");
        require(s.stakedDays > 179, "COM: Minimum 180 staked days required");
        
        require(currentDay >= s.lockedDay, "COM: Stake not Active");

        BonusType bt = BonusType.START;
        if(applyRestakeBonus == true) {
            _validateRestakeBonus(s);
            bt = BonusType.RESTAKE;
        }

        PayoutResponse memory pr = getPayout(s);

        uint256 payout = getStartBonusPayout(s.stakedDays, s.lockedDay, pr.maxPayout, pr.stakesOriginalShareRate, currentDay, globalShareRate, applyRestakeBonus);

        if(referrer == msg.sender) {
            payout += (payout / 100);
        }
        else if(referrer != address(0)) {
            _mint(referrer, (payout / 100));
        }
        else {
            _mint(contract_creator, (payout / 100));
        }

        stakeIdStartBonusPayout[stakeID] = payout;

        EndBonusDebt storage ebd = addressEndBonusDebt[msg.sender];

        if(ebd.payoutDebt != 0 && addressStakedCodeak[msg.sender] >= ebd.payoutDebt) _mintStakeBonus(ebd, currentDay, addressStakedCodeak[msg.sender]);

        if(stakeAmount > 0) {
            require(stakeAmount <= payout, "COM: Stake amount is more than available payout");

            addressStakedCodeak[msg.sender] += stakeAmount;

            payout -= stakeAmount;

            _emitStakeDepositCodeak(stakeAmount, addressStakedCodeak[msg.sender]);
        }

        if(payout > 0) _mint(msg.sender, payout);
        _emitNewMint(payout, s.stakedDays, pr.recalculatedStakeShares, pr.stakesOriginalShareRate, s.stakedHearts, s.stakeID, referrer, bt);
    }

    /**
     * 
     * @dev Allows batch minting of End Bonuses to reduce gas costs
     * 
     */
    function mintEndBonusBatch(stakeIndexIdAmount[] calldata stakeIndexIdAmounts, address referrer)
        external
    {
        uint256 stakeIndexIdAmountsLength = stakeIndexIdAmounts.length;
        uint256 currentDay = HEX.currentDay();

        for(uint256 i = 0; i < stakeIndexIdAmountsLength;){
            _mintEndBonus(stakeIndexIdAmounts[i].stakeIndex, stakeIndexIdAmounts[i].stakeID, referrer, currentDay, stakeIndexIdAmounts[i].stakeAmount);
            unchecked {
                i++;
            }
        }
    }

    /**
     * 
     * @dev External call for single End Bonuses
     * 
     */
    function mintEndBonus(uint256 stakeIndex, uint256 stakeID, address referrer, uint256 stakeAmount)
        external
    {
        _mintEndBonus(stakeIndex, stakeID, referrer, HEX.currentDay(), stakeAmount);
    }

    /**
     * 
     * @dev Mints a bonus for fulfilling a stakes staked days commitment in HEX smart contract
     * 
     * End bonus is the remaining total max payout available for any given stake, reduced only based on previous Start Stake Bonus minted
     * 
     * Stake must not have its End Bonus minted already
     * 
     * Stake shares must be at least 10000 to truncate low value edge cases
     * 
     * 50% of End Bonus Payout is accumulated as End Bonus Debt
     * 
     * End bonus forces minting Stake Bonus, if available, before staking new Codeak
     * 
     * Allows staking new Codeak before checking if staked Codeak is less than End Bonus Debt
     * 
     */
    function _mintEndBonus(uint256 stakeIndex, uint256 stakeID, address referrer, uint256 currentDay, uint256 stakeAmount)
        private
    {
        require(stakeIdEndBonusPayout[stakeID] == 0, "COM: StakeID End Bonus already minted");

        Stake memory s = memoryStake(address(msg.sender), stakeIndex, stakeID);

        require(s.stakedDays > 364, "COM: Minimum 365 staked days required");
        require(s.stakeShares > 9999, "COM: Minimum 10000 shares required");

        uint256 dueDay = s.lockedDay + s.stakedDays;
        require(currentDay >= dueDay, "COM: Stake not due");
        require(currentDay <= dueDay + 37, "COM: Grace period ended");

        PayoutResponse memory pr = getPayout(s);

        uint256 payout = pr.maxPayout - stakeIdStartBonusPayout[stakeID];

        if(referrer == msg.sender) {
            payout += (payout / 100);
        }
        else if(referrer != address(0)) {
            _mint(referrer, (payout / 100));
        }
        else {
            _mint(contract_creator, (payout / 100));
        }

        stakeIdEndBonusPayout[stakeID] = payout;

        uint128 payoutDebt = uint128(payout / 2);

        EndBonusDebt storage ebd = addressEndBonusDebt[msg.sender];

        if(ebd.payoutDebt != 0) _mintStakeBonus(ebd, currentDay, addressStakedCodeak[msg.sender]);

        if(stakeAmount > 0) {
            require(stakeAmount <= payout, "COM: Stake amount is more than available payout");

            addressStakedCodeak[msg.sender] += stakeAmount;

            payout -= stakeAmount;
            
            _emitStakeDepositCodeak(stakeAmount, addressStakedCodeak[msg.sender]);
        }

        if(ebd.payoutDebt != 0) require(addressStakedCodeak[msg.sender] >= ebd.payoutDebt, "COM: Address Staked Amount does not cover End Bonus Debt");
        else ebd.nextPayoutDay = uint16(currentDay) + 91;

        if(payout > 0) _mint(msg.sender, payout);
        _emitNewMint(payout, s.stakedDays, pr.recalculatedStakeShares, pr.stakesOriginalShareRate, s.stakedHearts, s.stakeID, referrer, BonusType.END);

        _updateRestakeEndDebt(currentDay, s);
        ebd.payoutDebt += payoutDebt;
    }

    /**
     * 
     * @dev Mints a bonus for cleaning stale shares in the HEX smart contract
     * 
     * Stake must not already be unlocked 
     * 
     * Stake must not have its End or Good Accounting Bonus minted already
     * 
     */
    function mintGoodAccountingBonus(address stakeOwner, uint256 stakeIndex, uint256 stakeID)
        external
    {
        require(stakeIdGoodAccountingBonusPayout[stakeID] == 0, "COM: StakeID Good Accounting Bonus already minted");
        require(stakeIdEndBonusPayout[stakeID] == 0, "COM: StakeID End Bonus already minted");

        Stake memory s = memoryStake(address(stakeOwner), stakeIndex, stakeID);

        require(s.stakeShares > 9999, "COM: Minimum 10000 shares required");
        require(s.unlockedDay == 0, "COM: Stake already unlocked");
        require(HEX.currentDay() > s.lockedDay + s.stakedDays + 37, "COM: Grace period has not ended");

        HEX.stakeGoodAccounting(address(stakeOwner), stakeIndex, uint40(stakeID));

        Stake memory sga = memoryStake(address(stakeOwner), stakeIndex, stakeID);
        require(sga.unlockedDay != 0, "COM: Stake did not have Good Accounting ran");

        PayoutResponse memory pr = getPayout(s);

        uint256 payout = pr.maxPayout / 100;

        stakeIdGoodAccountingBonusPayout[stakeID] = payout;

        _mint(msg.sender, payout);
        _emitNewMint(payout, s.stakedDays, pr.recalculatedStakeShares, pr.stakesOriginalShareRate, s.stakedHearts, s.stakeID, address(0), BonusType.GOOD);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"newDebtMint","inputs":[{"type":"uint256","name":"data0","internalType":"uint256","indexed":false},{"type":"address","name":"senderAddr","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"newMint","inputs":[{"type":"uint256","name":"data0","internalType":"uint256","indexed":false},{"type":"uint256","name":"data1","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakeId","internalType":"uint256","indexed":true},{"type":"uint256","name":"bonusType","internalType":"uint256","indexed":true},{"type":"address","name":"senderAddr","internalType":"address","indexed":true},{"type":"address","name":"referrer","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"stakeDepositCodeak","inputs":[{"type":"uint256","name":"data0","internalType":"uint256","indexed":false},{"type":"address","name":"senderAddr","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"stakeWithdrawCodeak","inputs":[{"type":"uint256","name":"data0","internalType":"uint256","indexed":false},{"type":"address","name":"senderAddr","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"nextPayoutDay","internalType":"uint16"},{"type":"uint128","name":"payoutDebt","internalType":"uint128"}],"name":"addressEndBonusDebt","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"stakedDays","internalType":"uint16"},{"type":"uint16","name":"endBonusPayoutDay","internalType":"uint16"},{"type":"uint72","name":"sharesDebt","internalType":"uint72"}],"name":"addressRestakeEndDebt","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"addressStakedCodeak","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burnFrom","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"tuple","name":"pr","internalType":"struct Communis.PayoutResponse","components":[{"type":"uint256","name":"recalculatedStakeShares","internalType":"uint256"},{"type":"uint256","name":"stakesOriginalShareRate","internalType":"uint256"},{"type":"uint256","name":"maxPayout","internalType":"uint256"}]}],"name":"getPayout","inputs":[{"type":"tuple","name":"s","internalType":"struct Communis.Stake","components":[{"type":"uint256","name":"stakeID","internalType":"uint256"},{"type":"uint256","name":"stakedHearts","internalType":"uint256"},{"type":"uint256","name":"stakeShares","internalType":"uint256"},{"type":"uint256","name":"lockedDay","internalType":"uint256"},{"type":"uint256","name":"stakedDays","internalType":"uint256"},{"type":"uint256","name":"unlockedDay","internalType":"uint256"}]}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"payout","internalType":"uint256"}],"name":"getStartBonusPayout","inputs":[{"type":"uint256","name":"stakedDays","internalType":"uint256"},{"type":"uint256","name":"lockedDay","internalType":"uint256"},{"type":"uint256","name":"maxPayout","internalType":"uint256"},{"type":"uint256","name":"stakesOriginalShareRate","internalType":"uint256"},{"type":"uint256","name":"currentDay","internalType":"uint256"},{"type":"uint256","name":"globalShareRate","internalType":"uint256"},{"type":"bool","name":"applyRestakeBonus","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintEndBonus","inputs":[{"type":"uint256","name":"stakeIndex","internalType":"uint256"},{"type":"uint256","name":"stakeID","internalType":"uint256"},{"type":"address","name":"referrer","internalType":"address"},{"type":"uint256","name":"stakeAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintEndBonusBatch","inputs":[{"type":"tuple[]","name":"stakeIndexIdAmounts","internalType":"struct Communis.stakeIndexIdAmount[]","components":[{"type":"uint256","name":"stakeIndex","internalType":"uint256"},{"type":"uint256","name":"stakeID","internalType":"uint256"},{"type":"uint256","name":"stakeAmount","internalType":"uint256"}]},{"type":"address","name":"referrer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintGoodAccountingBonus","inputs":[{"type":"address","name":"stakeOwner","internalType":"address"},{"type":"uint256","name":"stakeIndex","internalType":"uint256"},{"type":"uint256","name":"stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintStakeBonus","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintStartBonus","inputs":[{"type":"uint256","name":"stakeIndex","internalType":"uint256"},{"type":"uint256","name":"stakeID","internalType":"uint256"},{"type":"bool","name":"applyRestakeBonus","internalType":"bool"},{"type":"address","name":"referrer","internalType":"address"},{"type":"uint256","name":"stakeAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintStartBonusBatch","inputs":[{"type":"tuple[]","name":"stakeIndexIdAmounts","internalType":"struct Communis.stakeIndexIdAmount[]","components":[{"type":"uint256","name":"stakeIndex","internalType":"uint256"},{"type":"uint256","name":"stakeID","internalType":"uint256"},{"type":"uint256","name":"stakeAmount","internalType":"uint256"}]},{"type":"address","name":"referrer","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeIdEndBonusPayout","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeIdGoodAccountingBonusPayout","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeIdStartBonusPayout","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawStakedCodeak","inputs":[{"type":"uint256","name":"withdrawAmount","internalType":"uint256"}]}]
              

Contract Creation Code

Verify & Publish
0x60806040523480156200001157600080fd5b506040518060400160405280600881526020017f436f6d6d756e69730000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f434f4d000000000000000000000000000000000000000000000000000000000081525081600390816200008f9190620001a4565b5060046200009e8282620001a4565b5050600580546001600160a01b031916732b591e99afe9f32eaa6214f7b7629768c40eeb391790555062000270565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600181811c908216806200011157607f821691505b6020821081036200014b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156200019f57600081815260208120601f850160051c810160208610156200017a5750805b601f850160051c820191505b818110156200019b5782815560010162000186565b5050505b505050565b81516001600160401b03811115620001c057620001c0620000cd565b620001d881620001d18454620000fc565b8462000151565b602080601f831160018114620002105760008415620001f75750858301515b600019600386901b1c1916600185901b1785556200019b565b600085815260208120601f198616915b82811015620002415788860151825594840194600190910190840162000220565b5085821015620002605787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612f0f80620002806000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806379cc6790116100f9578063b2d9bf8011610097578063c031e1df11610071578063c031e1df1461046d578063dd62ed3e146104a2578063e107625d146104b5578063ea98ed9a146104c857600080fd5b8063b2d9bf801461043f578063b4f98bed14610452578063bf607ab81461046557600080fd5b80638efd25c3116100d35780638efd25c3146103fe57806395d89b4114610411578063a457c2d714610419578063a9059cbb1461042c57600080fd5b806379cc6790146103b85780637b4296db146103cb5780638c58e047146103eb57600080fd5b80633b665f9c1161016657806367350ffe1161014057806367350ffe1461033c5780636c03c39c1461034f57806370a082311461036f578063741bf9211461039857600080fd5b80633b665f9c1461026657806342966c68146102bd57806360bc0be8146102d057600080fd5b806323b872dd116101a257806323b872dd1461021c578063313ce5671461022f578063395093511461023e57806339d6e5671461025157600080fd5b806306fdde03146101c9578063095ea7b3146101e757806318160ddd1461020a575b600080fd5b6101d16104e8565b6040516101de91906126fd565b60405180910390f35b6101fa6101f5366004612767565b61057a565b60405190151581526020016101de565b6002545b6040519081526020016101de565b6101fa61022a366004612791565b610594565b604051600c81526020016101de565b6101fa61024c366004612767565b6105b8565b61026461025f3660046127cd565b6105da565b005b61029b610274366004612800565b60096020526000908152604090205461ffff8116906201000090046001600160801b031682565b6040805161ffff90931683526001600160801b039091166020830152016101de565b6102646102cb366004612822565b610940565b6103126102de366004612800565b60086020526000908152604090205461ffff808216916201000081049091169064010000000090046001600160481b031683565b6040805161ffff94851681529390921660208401526001600160481b0316908201526060016101de565b61026461034a366004612849565b61094d565b61020e61035d366004612822565b600a6020526000908152604090205481565b61020e61037d366004612800565b6001600160a01b031660009081526020819052604090205490565b61020e6103a6366004612822565b60066020526000908152604090205481565b6102646103c6366004612767565b6109e0565b61020e6103d9366004612800565b600b6020526000908152604090205481565b6102646103f9366004612899565b6109f9565b61026461040c366004612822565b610aee565b6101d1610bc7565b6101fa610427366004612767565b610bd6565b6101fa61043a366004612767565b610c51565b61026461044d366004612899565b610c5f565b61020e61046036600461291d565b610d4d565b610264610ee9565b61048061047b36600461297d565b610fcf565b60408051825181526020808401519082015291810151908201526060016101de565b61020e6104b0366004612a05565b6110c2565b6102646104c3366004612a38565b6110ed565b61020e6104d6366004612822565b60076020526000908152604090205481565b6060600380546104f790612a75565b80601f016020809104026020016040519081016040528092919081815260200182805461052390612a75565b80156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b5050505050905090565b600033610588818585611176565b60019150505b92915050565b6000336105a285828561129b565b6105ad85858561130f565b506001949350505050565b6000336105888185856105cb83836110c2565b6105d59190612ac5565b611176565b6000818152600a6020526040902054156106555760405162461bcd60e51b815260206004820152603160248201527f434f4d3a205374616b65494420476f6f64204163636f756e74696e6720426f6e6044820152701d5cc8185b1c9958591e481b5a5b9d1959607a1b60648201526084015b60405180910390fd5b600081815260076020526040902054156106815760405162461bcd60e51b815260040161064c90612ad8565b600061068e8484846114dd565b905061270f8160400151116106b55760405162461bcd60e51b815260040161064c90612b1d565b60a0810151156107075760405162461bcd60e51b815260206004820152601b60248201527f434f4d3a205374616b6520616c726561647920756e6c6f636b65640000000000604482015260640161064c565b8060800151816060015161071b9190612ac5565b610726906025612ac5565b600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610779573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079d9190612b5f565b116107ea5760405162461bcd60e51b815260206004820152601f60248201527f434f4d3a20477261636520706572696f6420686173206e6f7420656e64656400604482015260640161064c565b6005546040516332e7b8d960e11b81526001600160a01b0386811660048301526024820186905264ffffffffff85166044830152909116906365cf71b290606401600060405180830381600087803b15801561084557600080fd5b505af1158015610859573d6000803e3d6000fd5b50505050600061086a8585856114dd565b90508060a001516000036108d45760405162461bcd60e51b815260206004820152602b60248201527f434f4d3a205374616b6520646964206e6f74206861766520476f6f642041636360448201526a37bab73a34b733903930b760a91b606482015260840161064c565b60006108df83610fcf565b90506000606482604001516108f49190612b78565b6000868152600a602052604090208190559050610911338261165e565b61093781856080015184600001518560200151886020015189600001516000600261173d565b50505050505050565b61094a33826117f5565b50565b6109d985858585600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cb9190612b5f565b6109d3611940565b876119c4565b5050505050565b6109eb82338361129b565b6109f582826117f5565b5050565b60055460408051635c9302c960e01b8152905184926000926001600160a01b0390911691635c9302c9916004808201926020929091908290030181865afa158015610a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6c9190612b5f565b90506000610a78611940565b905060005b8381101561093757610ae6878783818110610a9a57610a9a612b9a565b90506060020160000135888884818110610ab657610ab6612b9a565b9050606002016020013560008887878d8d89818110610ad757610ad7612b9a565b905060600201604001356119c4565b600101610a7d565b336000908152600b6020526040902054811115610b7d5760405162461bcd60e51b815260206004820152604160248201527f434f4d3a2052657175657374656420776974686472617720616d6f756e74206960448201527f73206d6f7265207468616e2041646472657373205374616b656420416d6f756e6064820152601d60fa1b608482015260a40161064c565b336000908152600b602052604081208054839290610b9c908490612bb0565b90915550610bac9050338261165e565b336000908152600b602052604090205461094a908290611d32565b6060600480546104f790612a75565b60003381610be482866110c2565b905083811015610c445760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161064c565b6105ad8286868403611176565b60003361058881858561130f565b60055460408051635c9302c960e01b8152905184926000926001600160a01b0390911691635c9302c9916004808201926020929091908290030181865afa158015610cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd29190612b5f565b905060005b82811015610d4557610d3d868683818110610cf457610cf4612b9a565b90506060020160000135878784818110610d1057610d10612b9a565b9050606002016020013586858a8a87818110610d2e57610d2e612b9a565b90506060020160400135611d85565b600101610cd7565b505050505050565b600080821515600103610dbb57611446610d6961016d8b612bb0565b610d78906402540be400612bc3565b610d829190612b78565b90506402540be400610d99826406fc23ac00612bc3565b610da39190612b78565b9050610db481640ba43b7400612bb0565b9050610e7a565b61016c891115610e1f57611446610dd461016d8b612bb0565b610de3906402540be400612bc3565b610ded9190612b78565b90506402540be400610e0482640df8475800612bc3565b610e0e9190612b78565b9050610db48164174876e800612bb0565b60b9610e2c60b48b612bb0565b610e3b906402540be400612bc3565b610e459190612b78565b90506402540be400610e5c8264174876e800612bc3565b610e669190612b78565b9050610e7781642e90edd000612bb0565b90505b80610e8a886402540be400612bc3565b610e949190612b78565b9150878514610edd57600084610eb18866038d7ea4c68000612bc3565b610ebb9190612b78565b905066038d7ea4c68000610ecf8285612bc3565b610ed99190612b78565b9250505b50979650505050505050565b33600090815260096020526040902080546201000090046001600160801b03161561094a57336000908152600b602052604090205481546201000090046001600160801b0316811015610f4e5760405162461bcd60e51b815260040161064c90612be2565b6109f582600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc99190612b5f565b83612143565b610ff360405180606001604052806000815260200160008152602001600081525090565b60008260400151611003846121fd565b84602001516110129190612ac5565b61101f90620186a0612bc3565b6110299190612b78565b9050600081611037856122b8565b85602001516110469190612ac5565b6110589067016345785d8a0000612bc3565b6110629190612b78565b6020840183905280845260808501519091506000906115b39061108c9066038d7ea4c68000612bc3565b6110969190612b78565b905066038d7ea4c680006110aa8284612bc3565b6110b49190612b78565b604085015250919392505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b611170848484600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116a9190612b5f565b85611d85565b50505050565b6001600160a01b0383166111d85760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161064c565b6001600160a01b0382166112395760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161064c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006112a784846110c2565b9050600019811461117057818110156113025760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161064c565b6111708484848403611176565b6001600160a01b0383166113735760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161064c565b6001600160a01b0382166113d55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161064c565b6001600160a01b0383166000908152602081905260409020548181101561144d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161064c565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611484908490612ac5565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114d091815260200190565b60405180910390a3611170565b6115166040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600554604051632607443b60e01b81526001600160a01b038681166004830152602482018690526000928392839283928392839290911690632607443b9060440160e060405180830381865afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115989190612c7d565b50949a5092985090965094509250905064ffffffffff8616881461160c5760405162461bcd60e51b815260206004820152602560248201527f434f4d3a2041737375726520636f727265637420616e642063757272656e74206044820152647374616b6560d81b606482015260840161064c565b6040805160c08101825264ffffffffff90971687526001600160481b039586166020880152939094169285019290925261ffff908116606085015290811660808401521660a082015290509392505050565b6001600160a01b0382166116b45760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161064c565b80600260008282546116c69190612ac5565b90915550506001600160a01b038216600090815260208190526040812080548392906116f3908490612ac5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b3381600381111561175057611750612cf7565b847fafc22f2a1b7c8423cb392f3fe7711c08b38f98246adb12e5a041c2fba455ef2a60808a6001600160801b0316901b8c6001600160801b0316176060896001600160481b0316901b60388b64ffffffffff16901b60288e61ffff16901b4264ffffffffff16171717876040516117e39392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a45050505050505050565b6001600160a01b0382166118555760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161064c565b6001600160a01b038216600090815260208190526040902054818110156118c95760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161064c565b6001600160a01b03831660009081526020819052604081208383039055600280548492906118f8908490612bb0565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161128e565b505050565b6005546040805163c312452560e01b815290516000926001600160a01b03169163c3124525916004808301926101009291908290030181865afa15801561198b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119af9190612d0d565b505064ffffffffff9093169695505050505050565b60008681526006602052604090205415611a305760405162461bcd60e51b815260206004820152602760248201527f434f4d3a205374616b65494420537461727420426f6e757320616c7265616479604482015266081b5a5b9d195960ca1b606482015260840161064c565b60008681526007602052604090205415611a5c5760405162461bcd60e51b815260040161064c90612ad8565b6000611a693389896114dd565b905061270f816040015111611a905760405162461bcd60e51b815260040161064c90612b1d565b60b3816080015111611af25760405162461bcd60e51b815260206004820152602560248201527f434f4d3a204d696e696d756d20313830207374616b65642064617973207265716044820152641d5a5c995960da1b606482015260840161064c565b8060600151841015611b3e5760405162461bcd60e51b8152602060048201526015602482015274434f4d3a205374616b65206e6f742041637469766560581b604482015260640161064c565b6000861515600103611b5757611b53826122cc565b5060035b6000611b6283610fcf565b90506000611b8584608001518560600151846040015185602001518b8b8f610d4d565b9050336001600160a01b03891603611bb357611ba2606482612b78565b611bac9082612ac5565b9050611bfe565b6001600160a01b03881615611bdb57611bd688611bd1606484612b78565b61165e565b611bfe565b611bfe733def1720ce2b04a56f0ee6bc9875c64a785136b9611bd1606484612b78565b60008a81526006602090815260408083208490553383526009909152902080546201000090046001600160801b031615801590611c5b57508054336000908152600b6020526040902054620100009091046001600160801b031611155b15611c7d57336000908152600b6020526040902054611c7d9082908a90612143565b8515611cf05781861115611ca35760405162461bcd60e51b815260040161064c90612db4565b336000908152600b602052604081208054889290611cc2908490612ac5565b90915550611cd290508683612bb0565b336000908152600b6020526040902054909250611cf090879061259b565b8115611d0057611d00338361165e565b611d248286608001518560000151866020015189602001518a600001518f8b61173d565b505050505050505050505050565b6040516001600160801b0383166001600160801b0319608084901b1617815233907f4cbbb1897a82fabe5c208fdda8b9787408442e9e6f9263068465e228a5f906c4906020015b60405180910390a25050565b60008481526007602052604090205415611db15760405162461bcd60e51b815260040161064c90612ad8565b6000611dbe3387876114dd565b905061016c816080015111611de55760405162461bcd60e51b815260040161064c90612e03565b61270f816040015111611e0a5760405162461bcd60e51b815260040161064c90612b1d565b600081608001518260600151611e209190612ac5565b905080841015611e675760405162461bcd60e51b8152602060048201526012602482015271434f4d3a205374616b65206e6f742064756560701b604482015260640161064c565b611e72816025612ac5565b841115611ec15760405162461bcd60e51b815260206004820152601760248201527f434f4d3a20477261636520706572696f6420656e646564000000000000000000604482015260640161064c565b6000611ecc83610fcf565b60008881526006602052604080822054908301519293509091611eef9190612bb0565b9050336001600160a01b03881603611f1d57611f0c606482612b78565b611f169082612ac5565b9050611f63565b6001600160a01b03871615611f4057611f3b87611bd1606484612b78565b611f63565b611f63733def1720ce2b04a56f0ee6bc9875c64a785136b9611bd1606484612b78565b6000888152600760205260408120829055611f7f600283612b78565b3360009081526009602052604090208054919250906201000090046001600160801b031615611fc557336000908152600b6020526040902054611fc59082908a90612143565b86156120385782871115611feb5760405162461bcd60e51b815260040161064c90612db4565b336000908152600b60205260408120805489929061200a908490612ac5565b9091555061201a90508784612bb0565b336000908152600b602052604090205490935061203890889061259b565b80546201000090046001600160801b031615612093578054336000908152600b6020526040902054620100009091046001600160801b0316111561208e5760405162461bcd60e51b815260040161064c90612be2565b6120b0565b61209e88605b612e48565b815461ffff191661ffff919091161781555b82156120c0576120c0338461165e565b6120e5838760800151866000015187602001518a602001518b600001518f600161173d565b6120ef88876125e6565b8054829082906002906121129084906201000090046001600160801b0316612e6a565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505050505050505050505050565b825461ffff16821061193b578254600090605b906121659061ffff1685612bb0565b61216f9190612b78565b61217a906001612ac5565b90506000605061218a8385612bc3565b6121949190612b78565b90506121a0338261165e565b6121ab82605b612bc3565b855486906000906121c190849061ffff16612e48565b82546101009290920a61ffff81810219909316918316021790915586546109d992509081169083906201000090046001600160801b0316612697565b6000806000905060018360800151111561223b57610e388360800151111561222757610e38612238565b600183608001516122389190612bb0565b90505b600066354a6ba7a180008460200151111561225d5766354a6ba7a18000612263565b83602001515b9050680ecca2d59581a4000061227b8261071c612bc3565b61228d84670214e8348c4f0000612bc3565b6122979190612ac5565b85602001516122a69190612bc3565b6122b09190612b78565b949350505050565b600080600183608001516122389190612bb0565b61016c8160800151116122f15760405162461bcd60e51b815260040161064c90612e03565b336000908152600860205260408120805490916201000090910461ffff1690036123675760405162461bcd60e51b815260206004820152602160248201527f434f4d3a204e6f2076616c69642072657374616b65206f70706f7274756e69746044820152607960f81b606482015260840161064c565b805460608301516201000090910461ffff16106123e15760405162461bcd60e51b815260206004820152603260248201527f434f4d3a205374617274205374616b65206d757374206265206e65776572207460448201527168616e2070726576696f7573207374616b6560701b606482015260840161064c565b81608001516115b314806123ff57508054608083015161ffff909116105b6124695760405162461bcd60e51b815260206004820152603560248201527f434f4d3a204e6577207374616b65642064617973206d7573742062652067726560448201527461746572207468616e20746f2070726576696f757360581b606482015260840161064c565b805460408301516401000000009091046001600160481b031611156124e35760405162461bcd60e51b815260206004820152602a60248201527f434f4d3a2052657374616b65206d757374206174206c65617374206d61696e7460448201526961696e2073686172657360b01b606482015260840161064c565b80546125019064010000000090046001600160481b03166002612e8a565b6001600160481b0316826040015111156125745760405162461bcd60e51b815260206004820152602e60248201527f434f4d3a2052657374616b65207368617265732063616e6e6f74206265206d6f60448201526d7265207468616e20646f75626c6560901b606482015260840161064c565b505033600090815260086020526040902080546cffffffffffffffffffffffffff19169055565b6040516001600160801b0383166001600160801b0319608084901b1617815233907fa8f21c07a94b82da90d177f9b2b3a25e91a969ac251d1601fa387a831c951ad890602001611d79565b336000908152600860205260409020805462010000900461ffff1683111561261f57805463ffff000019166201000061ffff8516021781555b6080820151815461ffff161015612646576080820151815461ffff191661ffff9091161781555b60408201518154829060049061266e90849064010000000090046001600160481b0316612eb9565b92506101000a8154816001600160481b0302191690836001600160481b03160217905550505050565b60405161ffff84166fffffffffffffffffffffffffffff0000601085901b16176001600160801b0319608084901b1617815233907f3a4343c9c29638775b0d0acbd8fcb6ec75cf77284a520b2f4b41357b86f4900c9060200160405180910390a2505050565b600060208083528351808285015260005b8181101561272a5785810183015185820160400152820161270e565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461276257600080fd5b919050565b6000806040838503121561277a57600080fd5b6127838361274b565b946020939093013593505050565b6000806000606084860312156127a657600080fd5b6127af8461274b565b92506127bd6020850161274b565b9150604084013590509250925092565b6000806000606084860312156127e257600080fd5b6127eb8461274b565b95602085013595506040909401359392505050565b60006020828403121561281257600080fd5b61281b8261274b565b9392505050565b60006020828403121561283457600080fd5b5035919050565b801515811461094a57600080fd5b600080600080600060a0868803121561286157600080fd5b8535945060208601359350604086013561287a8161283b565b92506128886060870161274b565b949793965091946080013592915050565b6000806000604084860312156128ae57600080fd5b833567ffffffffffffffff808211156128c657600080fd5b818601915086601f8301126128da57600080fd5b8135818111156128e957600080fd5b8760206060830285010111156128fe57600080fd5b602092830195509350612914918601905061274b565b90509250925092565b600080600080600080600060e0888a03121561293857600080fd5b873596506020880135955060408801359450606088013593506080880135925060a0880135915060c088013561296d8161283b565b8091505092959891949750929550565b600060c0828403121561298f57600080fd5b60405160c0810181811067ffffffffffffffff821117156129c057634e487b7160e01b600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b60008060408385031215612a1857600080fd5b612a218361274b565b9150612a2f6020840161274b565b90509250929050565b60008060008060808587031215612a4e57600080fd5b8435935060208501359250612a656040860161274b565b9396929550929360600135925050565b600181811c90821680612a8957607f821691505b602082108103612aa957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561058e5761058e612aaf565b60208082526025908201527f434f4d3a205374616b65494420456e6420426f6e757320616c7265616479206d6040820152641a5b9d195960da1b606082015260800190565b60208082526022908201527f434f4d3a204d696e696d756d2031303030302073686172657320726571756972604082015261195960f21b606082015260800190565b600060208284031215612b7157600080fd5b5051919050565b600082612b9557634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b8181038181111561058e5761058e612aaf565b6000816000190483118215151615612bdd57612bdd612aaf565b500290565b60208082526038908201527f434f4d3a2041646472657373205374616b656420416d6f756e7420646f65732060408201527f6e6f7420636f76657220456e6420426f6e757320446562740000000000000000606082015260800190565b805164ffffffffff8116811461276257600080fd5b80516001600160481b038116811461276257600080fd5b805161ffff8116811461276257600080fd5b600080600080600080600060e0888a031215612c9857600080fd5b612ca188612c3f565b9650612caf60208901612c54565b9550612cbd60408901612c54565b9450612ccb60608901612c6b565b9350612cd960808901612c6b565b9250612ce760a08901612c6b565b915060c088015161296d8161283b565b634e487b7160e01b600052602160045260246000fd5b600080600080600080600080610100898b031215612d2a57600080fd5b612d3389612c54565b9750612d4160208a01612c54565b9650612d4f60408a01612c3f565b9550612d5d60608a01612c54565b9450612d6b60808a01612c6b565b9350612d7960a08a01612c54565b9250612d8760c08a01612c3f565b915060e08901516001600160801b0381168114612da357600080fd5b809150509295985092959890939650565b6020808252602f908201527f434f4d3a205374616b6520616d6f756e74206973206d6f7265207468616e206160408201526e1d985a5b18589b19481c185e5bdd5d608a1b606082015260800190565b60208082526025908201527f434f4d3a204d696e696d756d20333635207374616b65642064617973207265716040820152641d5a5c995960da1b606082015260800190565b61ffff818116838216019080821115612e6357612e63612aaf565b5092915050565b6001600160801b03818116838216019080821115612e6357612e63612aaf565b60006001600160481b0380831681851681830481118215151615612eb057612eb0612aaf565b02949350505050565b6001600160481b03818116838216019080821115612e6357612e63612aaf56fea264697066735822122061a13278b51a7e83d610fe88bde393134b6eef7699d4c59c7a88088a0cba7ed664736f6c63430008100033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806379cc6790116100f9578063b2d9bf8011610097578063c031e1df11610071578063c031e1df1461046d578063dd62ed3e146104a2578063e107625d146104b5578063ea98ed9a146104c857600080fd5b8063b2d9bf801461043f578063b4f98bed14610452578063bf607ab81461046557600080fd5b80638efd25c3116100d35780638efd25c3146103fe57806395d89b4114610411578063a457c2d714610419578063a9059cbb1461042c57600080fd5b806379cc6790146103b85780637b4296db146103cb5780638c58e047146103eb57600080fd5b80633b665f9c1161016657806367350ffe1161014057806367350ffe1461033c5780636c03c39c1461034f57806370a082311461036f578063741bf9211461039857600080fd5b80633b665f9c1461026657806342966c68146102bd57806360bc0be8146102d057600080fd5b806323b872dd116101a257806323b872dd1461021c578063313ce5671461022f578063395093511461023e57806339d6e5671461025157600080fd5b806306fdde03146101c9578063095ea7b3146101e757806318160ddd1461020a575b600080fd5b6101d16104e8565b6040516101de91906126fd565b60405180910390f35b6101fa6101f5366004612767565b61057a565b60405190151581526020016101de565b6002545b6040519081526020016101de565b6101fa61022a366004612791565b610594565b604051600c81526020016101de565b6101fa61024c366004612767565b6105b8565b61026461025f3660046127cd565b6105da565b005b61029b610274366004612800565b60096020526000908152604090205461ffff8116906201000090046001600160801b031682565b6040805161ffff90931683526001600160801b039091166020830152016101de565b6102646102cb366004612822565b610940565b6103126102de366004612800565b60086020526000908152604090205461ffff808216916201000081049091169064010000000090046001600160481b031683565b6040805161ffff94851681529390921660208401526001600160481b0316908201526060016101de565b61026461034a366004612849565b61094d565b61020e61035d366004612822565b600a6020526000908152604090205481565b61020e61037d366004612800565b6001600160a01b031660009081526020819052604090205490565b61020e6103a6366004612822565b60066020526000908152604090205481565b6102646103c6366004612767565b6109e0565b61020e6103d9366004612800565b600b6020526000908152604090205481565b6102646103f9366004612899565b6109f9565b61026461040c366004612822565b610aee565b6101d1610bc7565b6101fa610427366004612767565b610bd6565b6101fa61043a366004612767565b610c51565b61026461044d366004612899565b610c5f565b61020e61046036600461291d565b610d4d565b610264610ee9565b61048061047b36600461297d565b610fcf565b60408051825181526020808401519082015291810151908201526060016101de565b61020e6104b0366004612a05565b6110c2565b6102646104c3366004612a38565b6110ed565b61020e6104d6366004612822565b60076020526000908152604090205481565b6060600380546104f790612a75565b80601f016020809104026020016040519081016040528092919081815260200182805461052390612a75565b80156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b5050505050905090565b600033610588818585611176565b60019150505b92915050565b6000336105a285828561129b565b6105ad85858561130f565b506001949350505050565b6000336105888185856105cb83836110c2565b6105d59190612ac5565b611176565b6000818152600a6020526040902054156106555760405162461bcd60e51b815260206004820152603160248201527f434f4d3a205374616b65494420476f6f64204163636f756e74696e6720426f6e6044820152701d5cc8185b1c9958591e481b5a5b9d1959607a1b60648201526084015b60405180910390fd5b600081815260076020526040902054156106815760405162461bcd60e51b815260040161064c90612ad8565b600061068e8484846114dd565b905061270f8160400151116106b55760405162461bcd60e51b815260040161064c90612b1d565b60a0810151156107075760405162461bcd60e51b815260206004820152601b60248201527f434f4d3a205374616b6520616c726561647920756e6c6f636b65640000000000604482015260640161064c565b8060800151816060015161071b9190612ac5565b610726906025612ac5565b600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610779573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079d9190612b5f565b116107ea5760405162461bcd60e51b815260206004820152601f60248201527f434f4d3a20477261636520706572696f6420686173206e6f7420656e64656400604482015260640161064c565b6005546040516332e7b8d960e11b81526001600160a01b0386811660048301526024820186905264ffffffffff85166044830152909116906365cf71b290606401600060405180830381600087803b15801561084557600080fd5b505af1158015610859573d6000803e3d6000fd5b50505050600061086a8585856114dd565b90508060a001516000036108d45760405162461bcd60e51b815260206004820152602b60248201527f434f4d3a205374616b6520646964206e6f74206861766520476f6f642041636360448201526a37bab73a34b733903930b760a91b606482015260840161064c565b60006108df83610fcf565b90506000606482604001516108f49190612b78565b6000868152600a602052604090208190559050610911338261165e565b61093781856080015184600001518560200151886020015189600001516000600261173d565b50505050505050565b61094a33826117f5565b50565b6109d985858585600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cb9190612b5f565b6109d3611940565b876119c4565b5050505050565b6109eb82338361129b565b6109f582826117f5565b5050565b60055460408051635c9302c960e01b8152905184926000926001600160a01b0390911691635c9302c9916004808201926020929091908290030181865afa158015610a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6c9190612b5f565b90506000610a78611940565b905060005b8381101561093757610ae6878783818110610a9a57610a9a612b9a565b90506060020160000135888884818110610ab657610ab6612b9a565b9050606002016020013560008887878d8d89818110610ad757610ad7612b9a565b905060600201604001356119c4565b600101610a7d565b336000908152600b6020526040902054811115610b7d5760405162461bcd60e51b815260206004820152604160248201527f434f4d3a2052657175657374656420776974686472617720616d6f756e74206960448201527f73206d6f7265207468616e2041646472657373205374616b656420416d6f756e6064820152601d60fa1b608482015260a40161064c565b336000908152600b602052604081208054839290610b9c908490612bb0565b90915550610bac9050338261165e565b336000908152600b602052604090205461094a908290611d32565b6060600480546104f790612a75565b60003381610be482866110c2565b905083811015610c445760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161064c565b6105ad8286868403611176565b60003361058881858561130f565b60055460408051635c9302c960e01b8152905184926000926001600160a01b0390911691635c9302c9916004808201926020929091908290030181865afa158015610cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd29190612b5f565b905060005b82811015610d4557610d3d868683818110610cf457610cf4612b9a565b90506060020160000135878784818110610d1057610d10612b9a565b9050606002016020013586858a8a87818110610d2e57610d2e612b9a565b90506060020160400135611d85565b600101610cd7565b505050505050565b600080821515600103610dbb57611446610d6961016d8b612bb0565b610d78906402540be400612bc3565b610d829190612b78565b90506402540be400610d99826406fc23ac00612bc3565b610da39190612b78565b9050610db481640ba43b7400612bb0565b9050610e7a565b61016c891115610e1f57611446610dd461016d8b612bb0565b610de3906402540be400612bc3565b610ded9190612b78565b90506402540be400610e0482640df8475800612bc3565b610e0e9190612b78565b9050610db48164174876e800612bb0565b60b9610e2c60b48b612bb0565b610e3b906402540be400612bc3565b610e459190612b78565b90506402540be400610e5c8264174876e800612bc3565b610e669190612b78565b9050610e7781642e90edd000612bb0565b90505b80610e8a886402540be400612bc3565b610e949190612b78565b9150878514610edd57600084610eb18866038d7ea4c68000612bc3565b610ebb9190612b78565b905066038d7ea4c68000610ecf8285612bc3565b610ed99190612b78565b9250505b50979650505050505050565b33600090815260096020526040902080546201000090046001600160801b03161561094a57336000908152600b602052604090205481546201000090046001600160801b0316811015610f4e5760405162461bcd60e51b815260040161064c90612be2565b6109f582600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc99190612b5f565b83612143565b610ff360405180606001604052806000815260200160008152602001600081525090565b60008260400151611003846121fd565b84602001516110129190612ac5565b61101f90620186a0612bc3565b6110299190612b78565b9050600081611037856122b8565b85602001516110469190612ac5565b6110589067016345785d8a0000612bc3565b6110629190612b78565b6020840183905280845260808501519091506000906115b39061108c9066038d7ea4c68000612bc3565b6110969190612b78565b905066038d7ea4c680006110aa8284612bc3565b6110b49190612b78565b604085015250919392505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b611170848484600560009054906101000a90046001600160a01b03166001600160a01b0316635c9302c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116a9190612b5f565b85611d85565b50505050565b6001600160a01b0383166111d85760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161064c565b6001600160a01b0382166112395760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161064c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006112a784846110c2565b9050600019811461117057818110156113025760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161064c565b6111708484848403611176565b6001600160a01b0383166113735760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161064c565b6001600160a01b0382166113d55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161064c565b6001600160a01b0383166000908152602081905260409020548181101561144d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161064c565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611484908490612ac5565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114d091815260200190565b60405180910390a3611170565b6115166040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600554604051632607443b60e01b81526001600160a01b038681166004830152602482018690526000928392839283928392839290911690632607443b9060440160e060405180830381865afa158015611574573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115989190612c7d565b50949a5092985090965094509250905064ffffffffff8616881461160c5760405162461bcd60e51b815260206004820152602560248201527f434f4d3a2041737375726520636f727265637420616e642063757272656e74206044820152647374616b6560d81b606482015260840161064c565b6040805160c08101825264ffffffffff90971687526001600160481b039586166020880152939094169285019290925261ffff908116606085015290811660808401521660a082015290509392505050565b6001600160a01b0382166116b45760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161064c565b80600260008282546116c69190612ac5565b90915550506001600160a01b038216600090815260208190526040812080548392906116f3908490612ac5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b3381600381111561175057611750612cf7565b847fafc22f2a1b7c8423cb392f3fe7711c08b38f98246adb12e5a041c2fba455ef2a60808a6001600160801b0316901b8c6001600160801b0316176060896001600160481b0316901b60388b64ffffffffff16901b60288e61ffff16901b4264ffffffffff16171717876040516117e39392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a45050505050505050565b6001600160a01b0382166118555760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161064c565b6001600160a01b038216600090815260208190526040902054818110156118c95760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161064c565b6001600160a01b03831660009081526020819052604081208383039055600280548492906118f8908490612bb0565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161128e565b505050565b6005546040805163c312452560e01b815290516000926001600160a01b03169163c3124525916004808301926101009291908290030181865afa15801561198b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119af9190612d0d565b505064ffffffffff9093169695505050505050565b60008681526006602052604090205415611a305760405162461bcd60e51b815260206004820152602760248201527f434f4d3a205374616b65494420537461727420426f6e757320616c7265616479604482015266081b5a5b9d195960ca1b606482015260840161064c565b60008681526007602052604090205415611a5c5760405162461bcd60e51b815260040161064c90612ad8565b6000611a693389896114dd565b905061270f816040015111611a905760405162461bcd60e51b815260040161064c90612b1d565b60b3816080015111611af25760405162461bcd60e51b815260206004820152602560248201527f434f4d3a204d696e696d756d20313830207374616b65642064617973207265716044820152641d5a5c995960da1b606482015260840161064c565b8060600151841015611b3e5760405162461bcd60e51b8152602060048201526015602482015274434f4d3a205374616b65206e6f742041637469766560581b604482015260640161064c565b6000861515600103611b5757611b53826122cc565b5060035b6000611b6283610fcf565b90506000611b8584608001518560600151846040015185602001518b8b8f610d4d565b9050336001600160a01b03891603611bb357611ba2606482612b78565b611bac9082612ac5565b9050611bfe565b6001600160a01b03881615611bdb57611bd688611bd1606484612b78565b61165e565b611bfe565b611bfe733def1720ce2b04a56f0ee6bc9875c64a785136b9611bd1606484612b78565b60008a81526006602090815260408083208490553383526009909152902080546201000090046001600160801b031615801590611c5b57508054336000908152600b6020526040902054620100009091046001600160801b031611155b15611c7d57336000908152600b6020526040902054611c7d9082908a90612143565b8515611cf05781861115611ca35760405162461bcd60e51b815260040161064c90612db4565b336000908152600b602052604081208054889290611cc2908490612ac5565b90915550611cd290508683612bb0565b336000908152600b6020526040902054909250611cf090879061259b565b8115611d0057611d00338361165e565b611d248286608001518560000151866020015189602001518a600001518f8b61173d565b505050505050505050505050565b6040516001600160801b0383166001600160801b0319608084901b1617815233907f4cbbb1897a82fabe5c208fdda8b9787408442e9e6f9263068465e228a5f906c4906020015b60405180910390a25050565b60008481526007602052604090205415611db15760405162461bcd60e51b815260040161064c90612ad8565b6000611dbe3387876114dd565b905061016c816080015111611de55760405162461bcd60e51b815260040161064c90612e03565b61270f816040015111611e0a5760405162461bcd60e51b815260040161064c90612b1d565b600081608001518260600151611e209190612ac5565b905080841015611e675760405162461bcd60e51b8152602060048201526012602482015271434f4d3a205374616b65206e6f742064756560701b604482015260640161064c565b611e72816025612ac5565b841115611ec15760405162461bcd60e51b815260206004820152601760248201527f434f4d3a20477261636520706572696f6420656e646564000000000000000000604482015260640161064c565b6000611ecc83610fcf565b60008881526006602052604080822054908301519293509091611eef9190612bb0565b9050336001600160a01b03881603611f1d57611f0c606482612b78565b611f169082612ac5565b9050611f63565b6001600160a01b03871615611f4057611f3b87611bd1606484612b78565b611f63565b611f63733def1720ce2b04a56f0ee6bc9875c64a785136b9611bd1606484612b78565b6000888152600760205260408120829055611f7f600283612b78565b3360009081526009602052604090208054919250906201000090046001600160801b031615611fc557336000908152600b6020526040902054611fc59082908a90612143565b86156120385782871115611feb5760405162461bcd60e51b815260040161064c90612db4565b336000908152600b60205260408120805489929061200a908490612ac5565b9091555061201a90508784612bb0565b336000908152600b602052604090205490935061203890889061259b565b80546201000090046001600160801b031615612093578054336000908152600b6020526040902054620100009091046001600160801b0316111561208e5760405162461bcd60e51b815260040161064c90612be2565b6120b0565b61209e88605b612e48565b815461ffff191661ffff919091161781555b82156120c0576120c0338461165e565b6120e5838760800151866000015187602001518a602001518b600001518f600161173d565b6120ef88876125e6565b8054829082906002906121129084906201000090046001600160801b0316612e6a565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505050505050505050505050565b825461ffff16821061193b578254600090605b906121659061ffff1685612bb0565b61216f9190612b78565b61217a906001612ac5565b90506000605061218a8385612bc3565b6121949190612b78565b90506121a0338261165e565b6121ab82605b612bc3565b855486906000906121c190849061ffff16612e48565b82546101009290920a61ffff81810219909316918316021790915586546109d992509081169083906201000090046001600160801b0316612697565b6000806000905060018360800151111561223b57610e388360800151111561222757610e38612238565b600183608001516122389190612bb0565b90505b600066354a6ba7a180008460200151111561225d5766354a6ba7a18000612263565b83602001515b9050680ecca2d59581a4000061227b8261071c612bc3565b61228d84670214e8348c4f0000612bc3565b6122979190612ac5565b85602001516122a69190612bc3565b6122b09190612b78565b949350505050565b600080600183608001516122389190612bb0565b61016c8160800151116122f15760405162461bcd60e51b815260040161064c90612e03565b336000908152600860205260408120805490916201000090910461ffff1690036123675760405162461bcd60e51b815260206004820152602160248201527f434f4d3a204e6f2076616c69642072657374616b65206f70706f7274756e69746044820152607960f81b606482015260840161064c565b805460608301516201000090910461ffff16106123e15760405162461bcd60e51b815260206004820152603260248201527f434f4d3a205374617274205374616b65206d757374206265206e65776572207460448201527168616e2070726576696f7573207374616b6560701b606482015260840161064c565b81608001516115b314806123ff57508054608083015161ffff909116105b6124695760405162461bcd60e51b815260206004820152603560248201527f434f4d3a204e6577207374616b65642064617973206d7573742062652067726560448201527461746572207468616e20746f2070726576696f757360581b606482015260840161064c565b805460408301516401000000009091046001600160481b031611156124e35760405162461bcd60e51b815260206004820152602a60248201527f434f4d3a2052657374616b65206d757374206174206c65617374206d61696e7460448201526961696e2073686172657360b01b606482015260840161064c565b80546125019064010000000090046001600160481b03166002612e8a565b6001600160481b0316826040015111156125745760405162461bcd60e51b815260206004820152602e60248201527f434f4d3a2052657374616b65207368617265732063616e6e6f74206265206d6f60448201526d7265207468616e20646f75626c6560901b606482015260840161064c565b505033600090815260086020526040902080546cffffffffffffffffffffffffff19169055565b6040516001600160801b0383166001600160801b0319608084901b1617815233907fa8f21c07a94b82da90d177f9b2b3a25e91a969ac251d1601fa387a831c951ad890602001611d79565b336000908152600860205260409020805462010000900461ffff1683111561261f57805463ffff000019166201000061ffff8516021781555b6080820151815461ffff161015612646576080820151815461ffff191661ffff9091161781555b60408201518154829060049061266e90849064010000000090046001600160481b0316612eb9565b92506101000a8154816001600160481b0302191690836001600160481b03160217905550505050565b60405161ffff84166fffffffffffffffffffffffffffff0000601085901b16176001600160801b0319608084901b1617815233907f3a4343c9c29638775b0d0acbd8fcb6ec75cf77284a520b2f4b41357b86f4900c9060200160405180910390a2505050565b600060208083528351808285015260005b8181101561272a5785810183015185820160400152820161270e565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461276257600080fd5b919050565b6000806040838503121561277a57600080fd5b6127838361274b565b946020939093013593505050565b6000806000606084860312156127a657600080fd5b6127af8461274b565b92506127bd6020850161274b565b9150604084013590509250925092565b6000806000606084860312156127e257600080fd5b6127eb8461274b565b95602085013595506040909401359392505050565b60006020828403121561281257600080fd5b61281b8261274b565b9392505050565b60006020828403121561283457600080fd5b5035919050565b801515811461094a57600080fd5b600080600080600060a0868803121561286157600080fd5b8535945060208601359350604086013561287a8161283b565b92506128886060870161274b565b949793965091946080013592915050565b6000806000604084860312156128ae57600080fd5b833567ffffffffffffffff808211156128c657600080fd5b818601915086601f8301126128da57600080fd5b8135818111156128e957600080fd5b8760206060830285010111156128fe57600080fd5b602092830195509350612914918601905061274b565b90509250925092565b600080600080600080600060e0888a03121561293857600080fd5b873596506020880135955060408801359450606088013593506080880135925060a0880135915060c088013561296d8161283b565b8091505092959891949750929550565b600060c0828403121561298f57600080fd5b60405160c0810181811067ffffffffffffffff821117156129c057634e487b7160e01b600052604160045260246000fd5b8060405250823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b60008060408385031215612a1857600080fd5b612a218361274b565b9150612a2f6020840161274b565b90509250929050565b60008060008060808587031215612a4e57600080fd5b8435935060208501359250612a656040860161274b565b9396929550929360600135925050565b600181811c90821680612a8957607f821691505b602082108103612aa957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561058e5761058e612aaf565b60208082526025908201527f434f4d3a205374616b65494420456e6420426f6e757320616c7265616479206d6040820152641a5b9d195960da1b606082015260800190565b60208082526022908201527f434f4d3a204d696e696d756d2031303030302073686172657320726571756972604082015261195960f21b606082015260800190565b600060208284031215612b7157600080fd5b5051919050565b600082612b9557634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b8181038181111561058e5761058e612aaf565b6000816000190483118215151615612bdd57612bdd612aaf565b500290565b60208082526038908201527f434f4d3a2041646472657373205374616b656420416d6f756e7420646f65732060408201527f6e6f7420636f76657220456e6420426f6e757320446562740000000000000000606082015260800190565b805164ffffffffff8116811461276257600080fd5b80516001600160481b038116811461276257600080fd5b805161ffff8116811461276257600080fd5b600080600080600080600060e0888a031215612c9857600080fd5b612ca188612c3f565b9650612caf60208901612c54565b9550612cbd60408901612c54565b9450612ccb60608901612c6b565b9350612cd960808901612c6b565b9250612ce760a08901612c6b565b915060c088015161296d8161283b565b634e487b7160e01b600052602160045260246000fd5b600080600080600080600080610100898b031215612d2a57600080fd5b612d3389612c54565b9750612d4160208a01612c54565b9650612d4f60408a01612c3f565b9550612d5d60608a01612c54565b9450612d6b60808a01612c6b565b9350612d7960a08a01612c54565b9250612d8760c08a01612c3f565b915060e08901516001600160801b0381168114612da357600080fd5b809150509295985092959890939650565b6020808252602f908201527f434f4d3a205374616b6520616d6f756e74206973206d6f7265207468616e206160408201526e1d985a5b18589b19481c185e5bdd5d608a1b606082015260800190565b60208082526025908201527f434f4d3a204d696e696d756d20333635207374616b65642064617973207265716040820152641d5a5c995960da1b606082015260800190565b61ffff818116838216019080821115612e6357612e63612aaf565b5092915050565b6001600160801b03818116838216019080821115612e6357612e63612aaf565b60006001600160481b0380831681851681830481118215151615612eb057612eb0612aaf565b02949350505050565b6001600160481b03818116838216019080821115612e6357612e63612aaf56fea264697066735822122061a13278b51a7e83d610fe88bde393134b6eef7699d4c59c7a88088a0cba7ed664736f6c63430008100033