ETH Price: $3,127.39 (+0.96%)

Token

TEXAN Token (TEXAN)
 

Overview

Max Total Supply

99,998,442,380,537.150846128775510502 TEXAN

Holders

19,955 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
1,000,000 TEXAN

Value
$0.00
0x3edd148ce72bdcba5984581d8f1b25894a8e8521
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The TEXAN Token is the endowment token on the blockchain. TEXAN is an immutable contract with NO admin keys. Stakers of TEXAN are rewarded with more TEXAN based on the length of their stake.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TEXAN

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity Multiple files format)

File 6 of 6: TEXAN.sol
/// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Address
// @notice This contract is proprietary and may not be copied or used without permission.

pragma solidity ^0.8.13;

import "./StakableEndowmentToken.sol";

contract TEXAN is StakableEndowmentToken {

    constructor() {
        setNameAndSymbol("TEXAN Token", "TEXAN");

        // NOTE: This has been modified so the original Owner Address does NOT hold
        // the supply. The Endowment Supply holds 97T stars for available rewards  
        // and is no longer held by the OA account.  We think this is good for security purposes.
        //
        //  These 3T tokens are for initial circulation.  (most will be staked)
        uint intitialTotalSupply = 3 * 1e30; // 3 Trillion Tokens ( 1e12 * decimals(1e18)) 

        _mint(msg.sender, intitialTotalSupply);
    }

    receive()
    payable
    external
    {
        uint256 fbfail = 1;
        require(fbfail == 0, string(abi.encodePacked(name(), ": You can not send ETH to this contract!")));
    }

    fallback() external {}
}

File 1 of 6: Context.sol
// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Addrress

pragma solidity ^0.8.13;

// @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 2 of 6: ERC20.sol
// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Addrress

pragma solidity ^0.8.13;

// Import Context
import "./IERC20Metadata.sol";

/**
 * @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}.
 *
 * 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 _tokenName;
    string private _tokenSymbol;

    function setNameAndSymbol(string memory nameOfToken, string memory symbolOfToken) internal {
        _tokenName = nameOfToken;
        _tokenSymbol = symbolOfToken;
    }


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

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

    /**
     * @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:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, 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}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), 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}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - 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) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][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) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * 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:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, 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 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 3 of 6: IERC20.sol
// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Addrress

pragma solidity ^0.8.13;

// Import Context
import "./Context.sol";

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

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

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

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

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

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

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

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

File 4 of 6: IERC20Metadata.sol
// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Addrress

pragma solidity ^0.8.13;

// Import Context
import "./IERC20.sol";

/**
 * @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 5 of 6: StakableEndowmentToken.sol
// SPDX-License-Identifier: UNLICENSED
// @title Stakeable Endowment Token
// @author Origin Addrress
// @notice This contract is proprietary and may not be copied or used without permission.
// @dev Stakable Endowment Main Functions for Staking, Scraping, and Ending Stakes
// @notice These are the main public functions for the token.

pragma solidity ^0.8.13;

import "./ERC20.sol";

abstract contract StakableEndowmentToken is ERC20 {
    // Launch timeTime 
    // Dec 22 12AM GMT
    uint256 internal constant LAUNCH_TIME = 1671667200;  //The time of launch
                                            
    // Global Constants Constants
    uint256 internal constant MIN_STAKE_DAYS = 1;
    uint256 internal constant MAX_STAKE_DAYS = 8036; // Approx 22 years and half a day
    uint256 internal constant MAX_STAKE_YEARS = 22; //

    uint256 internal constant MIN_STAKE_AMOUNT = 10000;
    uint256 internal constant MAX_STAKE_AMOUNT = 1e29; // 100B Stake is the max (100000000000000000000000000000)

    // This is the Endowment Supply. For security reasons we made this an 
    // internal variable that only this contract can change.
    
    // The initial supply is 97 Trillion locked in the contract
    uint256 internal _endowmentSupply = (97 * 1e30);

    // Global Variables
    uint256 g_latestStakeId = 0;     // the global stake id starting at zero so first take will be 1
    uint256 g_stakedStars = 0;      // the amount of wei that is already staked
    uint256 g_stakedPrincipleStars = 0;      // the amount of principle that is staked in wei
    uint256 g_penalizedStars = 0;  // these are the Stars that have been set aside from penalties
    uint256 g_stakedCount = 0;  // current count of active stakes based on + and - in startStake and endStake

    // For Calculations
    uint256 constant PRECISION = 1e18;   // 18 decimals
    uint256 constant YEARDIVIDER = 36525;  // must use yearprecision multiplier with this (100)
    uint256 constant YEARPRECISION = 100;  // because of integers only multiple by precision, divide by precision



    // @notice This contract has the utilities necessary for the Staking Endowment Token below
    event StartStake(
        address indexed stakeAddress,  // Address
        uint256 indexed stakeId,
        uint256 indexed eventName,
        uint256 startDay,
        uint256 stakedDays,
        uint256 principle,
        uint256 possibleInterest
    );

    event ScrapeStake(
        address indexed stakeAddress,
        uint256 indexed stakeId,
        uint256 indexed eventName,
        uint256 scrapeDay,
        uint256 previousScrapedInterest,
        uint256 oldPossibleInterest,
        uint256 scrapedInterest,
        uint possibleInterest
    );

    event EndStake(
        address indexed stakeAddress,
        uint256 indexed stakeId,
        uint256 indexed eventName,
        uint256 endStakeDay,
        uint256 principle,
        uint256 oldPossibleInterest,
        uint256 scrapedInterest,
        uint256 penalties,
        uint256 stakeTotal
    );

    // @dev Memory resident Stake for temporary use
    // @param uint256 _stakeId
    // @param uint256 _stakedPrinciple
    // @param uint256 _startDay
    // @param uint256 _scrapeDay
    // @param uint256 _stakedDays
    // @param uint256 _scrapedInterest
    // @param uint256 _possibleStars
    struct TempStake {
        uint256 _stakeId;
        uint256 _stakedPrinciple;
        uint256 _startDay;
        uint256 _scrapeDay;
        uint256 _stakedDays;
        uint256 _scrapedInterest;
        uint256 _possibleStars;
    }

    // @dev Permenant Stake for Storage
    // @param uint256 stakeId The stake ID
    // @param uint256 stakedPrinciple The initial principle staked
    // @param uint256 startDay The day the stake was started
    // @param uint256 scrapeDay The day the stake was scraped
    // @param uint256 stakedDays The days of the stake commitment
    // @param uint256 scrapedInterest The interest that has been scraped if any
    // @param uint256 possibleStars The potential amount of stars for this stake
    struct PermStake {
        uint256 stakeId;
        uint256 stakedPrinciple;
        uint256 startDay;
        uint256 scrapeDay;
        uint256 stakedDays;
        uint256 scrapedInterest;
        uint256 possibleStars;
    }

    // initialize the Store of Stakes.
    mapping(address => PermStake[]) public Stakes;

    // @dev Private: This emits the event
    // and was moved due to stack limits
    // @param uint256 stakeId - the stake id
    // @param uint256 interestDays the days of interest applied in this case
    // @param uint256 previousInterest - the amount of interest previously scraped
    // @param uint256 previousPossibleStars - what the previous amount of interest was before the scrape
    // @param uint256 scrapedInterest - the amount of interest scraped by this action
    // @param uint256 newPossibleIntest - the possible interest
    function emitScrapeEvent(uint256 stakeId, uint256 interestDays, uint256 previousInterest, uint256 previousPossibleStars, uint256 scrapedInterest, uint256 newPossibleInterest ) 
    internal 
    {
        // Emit the stake scrape event
        emit ScrapeStake(
            msg.sender,         // event Sender set here
            stakeId,            // stake Id
            uint(2),            // event id is 2
            interestDays,
            previousInterest,
            previousPossibleStars,
            scrapedInterest,
            newPossibleInterest
        );
    }

    // @dev Public Function: Open a stake.
    // @param uint256 stakedPrinciple Number of Stars to stake
    // @param uint256 stakedDays length of days in the stake
    function startStake(uint256 stakedPrinciple, uint256 stakedDays)
    external
    {
        // make sure the stake params are within guidelines or throw an error
        _assurePrincipleAndStakedDaysAreValid(stakedPrinciple, stakedDays);
        
        //Calculate possible payout
        uint256 possibleInterest = _calculateInterest(stakedPrinciple, stakedDays);
        
        // Create total possible stars
        uint256 possibleStars = possibleInterest + stakedPrinciple;  // ALL possible interest AND principle
        
        require(_endowmentSupply >  possibleInterest, "There is not enough to cover your stake");

        // Start the stake
        _startStake(stakedPrinciple, stakedDays, possibleStars);
        

        // the principle is burned from token supply, and the possible interest is pulled from the endowmentSupply
        _endowmentSupply = _endowmentSupply - possibleInterest; 
        
        
        // Add to global counter
        // Add principle only
        g_stakedPrincipleStars += stakedPrinciple;
        // Add all possible interest and principle to stakedStars.
        g_stakedStars += possibleStars;
        // Stake is official Ready to go
    }

    // @dev Public Function: Scrape stake
    // @dev This will calculate the eligible days since the previous stake
    // and mint the interest back to the user. This will also recalculate
    // the possible amount of interest.
    // @param uint256 stakeIndex  the index of the stake based on the order of active stakes
    // @param uint256 myStakeId The stake's id that is unique to the stake
    function scrapeStake(uint256 stakeIndex, uint256 myStakeId)
    external
    {
        PermStake[] storage permStakes = Stakes[msg.sender];
        require(permStakes.length != 0, "Empty stake list");
        require(stakeIndex < permStakes.length, "stakeIndex invalid");
        
        // load a copy of temporary stake 
        TempStake memory stake = TempStake(0,0,0,0,0,0,0);

        _loadStake(permStakes[stakeIndex], myStakeId, stake);
        // load up the stake reference also
        PermStake storage permStakeRef = Stakes[msg.sender][stakeIndex];
        // Defaults
        uint256 previousInterest = stake._scrapedInterest;
        uint256 previousPossibleStars = stake._possibleStars;
        // Calculate Days
        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);
        // Returns Calculated Days in an array like below
        // 0 curDay - Current Day
        // 1 startDay - Start Day
        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)
        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)
        // 4 interestDays - Days that are used to CALCULATE INTEREST
        // 5 possibleDays -  (endOfStakeDays - currentDay)
        // scrapeServedDays // days that are interest bearing days
        uint256 currentInterest = 0;
        uint256 lostInterest = 0;
        uint256 newPossibleInterest = 0;
        uint256 curDay = calcDays[0];
        // the stake start day must be < the currentDay
        require(curDay > stake._startDay, "Scraping is not allowed, stake must start first");
        // make sure the curDay is within the scope of "scrapeable days"
        require(curDay <= calcDays[3], "Scraping is not allowed, must end stake");

        
        // Scraping is allowed only if the curDay is greater than the scrapeDay
        //PER SEI-04 - to save possible gas for the user
        require(curDay > calcDays[2], "Scraping is not allowed until 1 or more staked days has completed");

        // we will require this check so it doesn't waste resource by running these other calcs
        // you can't scrape twice on the same day so current Day must greater than previous scraped day
        // will equal 0 or previous accumulated amount
        previousInterest = stake._scrapedInterest;
        // total possible interest that was reserved for your stake
        // previousPossibleStars = stake._possibleStars; //includes principle
        // Calculate total based on interestDays
        currentInterest = _calculateInterest(stake._stakedPrinciple, calcDays[4]);
        // Calculate NEW possibleInterest based on EndofStake Days - currentDay
        newPossibleInterest = _calculateInterest(stake._stakedPrinciple, (calcDays[3]-calcDays[0]));
        uint newPossibleInterestPlusPrinciple = newPossibleInterest + stake._stakedPrinciple;
        // Lost interest = the interest you could have had - what you have now
        // What I have: 
            // previousPossibleStars - (includes principle)
            // newPossibleInterestPlusPrinciple  - newPossibleInterest also include principle
            // currentInterest - what we are minting for interest
        // just in case the previous possible interest is less than the new possible interest
        uint previousStarsAndCurrentInterest = previousPossibleStars > currentInterest ? (previousPossibleStars - currentInterest) : 0;
        if (previousStarsAndCurrentInterest > newPossibleInterestPlusPrinciple) {
            // lost interest gets minted back to the OA
            lostInterest = previousStarsAndCurrentInterest - newPossibleInterestPlusPrinciple;
        }
        // Now do the work based on values above calculate actual payout
        // penalties do not happen here, because there is a force closed function.
        // If there is accrued interest, send this back to the user
        // If there is no accrued interest, then nothing changes and all stays the same.
        if (currentInterest != 0) {

            // Mint this back to message sender
            _mint(msg.sender, currentInterest);
            
            // Mint lost interest back to the endowment supply
            if (lostInterest > 0) {
                 _endowmentSupply = _endowmentSupply + lostInterest;
            }


            // Set the total amount of accrued interest
            stake._scrapedInterest = previousInterest + currentInterest;
            // set the new possible interest in the stake... should continually get smaller and smaller
            stake._possibleStars  = newPossibleInterestPlusPrinciple;
            // Set the Scrape day to today
            stake._scrapeDay = curDay;
            //update the current stake to the new values
            _updateStake(permStakeRef, stake);
            // Emit the stake scrape event
            emitScrapeEvent(
                stake._stakeId,
                uint256(calcDays[4]),
                uint256(previousInterest),
                previousPossibleStars,
                stake._scrapedInterest,
                newPossibleInterest
            );
            // update global values
            // Adds back previous possible interest to the global variable
            g_stakedStars -= previousPossibleStars;
            // Removes the new current possible interest 
            g_stakedStars += newPossibleInterestPlusPrinciple;
        }
    }

    // @dev Public Function: End the Stake: This will calculate the amount of
    // interest, mint it back to the user, and remove the stake from the stakeList Map
    // @param uint256 stakeIndex  the index of the stake based on order and may change based on active stakes
    // @param uint256 myStakeId The stake's id
    function endStake(uint256 stakeIndex, uint256 myStakeId)
    external
    {
        PermStake[] storage permStakes = Stakes[msg.sender];
        require(permStakes.length != 0, "Stake List is Empty");
        require(stakeIndex < permStakes.length, "not a valid stakeIndex");
        
        // get temporary stake into memory
        TempStake memory stake = TempStake(0,0,0,0,0,0,0);

        _loadStake(permStakes[stakeIndex], myStakeId, stake);
        // Defaults
        uint256 servedDays = 0;
        uint256 stakeTotal;
        uint256 interestAccrued = 0;
        uint256 penalty = 0;
        // Calculate Days - returns Calculated Days in an array like below
        // 0 curDay - Current Day
        // 1 startDay - Start Day
        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)
        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)
        // 4 interestDays - Days that are used to CALCULATE INTEREST
        // 5 possibleDays -  (endOfStakeDays - currentDay)
        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);
        // Stake Insurance - in case someone makes a mistake
        // if The stake has not started, then mint all possible back to the OA (removed)
        // if The stake has not started, then mint all possible back to the Endowment Supply
        if (calcDays[0] < calcDays[1]) {

            // Add the possible stars back to the endowment supply (minus the principle of course)
            _endowmentSupply = _endowmentSupply + (stake._possibleStars - stake._stakedPrinciple);

            
            // make sure that stakeTotal and penalty = 0 
            stakeTotal = 0;
            penalty = 0;
            // Add principle back to user
            _mint(msg.sender, stake._stakedPrinciple);
            // remove this from global stats
            g_stakedStars -= stake._possibleStars;
             

            // remove from the global principle stats
            g_stakedPrincipleStars -= stake._stakedPrinciple;
        
        } else {
            // served days is day from start day
            servedDays = calcDays[0] - calcDays[1];
            // calculate stake performance
            (stakeTotal, interestAccrued, penalty) = _calculateStakeTotal(stake);

            // Check for penalties
            if (penalty > 0) {
                // Zero interest gets returned
                // Possible Interest should get sent back to Endowment Supply
                _endowmentSupply += (stake._possibleStars - stake._stakedPrinciple);
                
                // Update global variables - to keep track of penalizedStars
                g_penalizedStars += penalty;

                // Remove possible stars from the global variable g_stakedStars
                if(g_stakedStars >= (stake._possibleStars)){
                    g_stakedStars -= (stake._possibleStars);
                }
                                
                // Remove the principle amount from global variable g_stakedPrincipleStars
                if(g_stakedPrincipleStars >= stake._stakedPrinciple){
                    g_stakedPrincipleStars -= stake._stakedPrinciple;
                }

            } else {
                // This is a good stake
                // There are no possible stars anymore
                // There is only interestAccrued, so remove that from global variable g_stakedStars

                // Remove all possible stars from g_stakedstars
                if (g_stakedStars >= interestAccrued){
                    g_stakedStars -= interestAccrued;    
                }
                // Possible Stars has Principle Included... InterestAccrued does not.
                // so we need to back out the principle also
                if (g_stakedStars >= stake._stakedPrinciple){
                    g_stakedStars -= stake._stakedPrinciple;    
                }

                // NOTE: Stake Total is Both the interestAccrued + Principle and that 
                // goes back to the user

                // Speaking of principle, let's also remove it from g_stakedPrincipleStars
                if(g_stakedPrincipleStars >= stake._stakedPrinciple){
                    g_stakedPrincipleStars -= stake._stakedPrinciple;    
                }
            }

            // Calculations are done, so let's mint back to the user,
            // Stake total could equal principle + stars, or principle - penalty
            if (stakeTotal != 0) {
                // We do not mint penalties back
                // This amount should be principle + any Interest Earned
                // OR if penalties, then this is principle minus penalties
                
                _mint(msg.sender, stakeTotal);
                
                // minted stake total back to user
                // ready to end the stake, so continue

            }
        } // end else
        
        // emit the stake end event and remove the stake from Stakes
        emit EndStake(
            msg.sender,
            stake._stakeId,
            uint256(3), // stake event id
            uint256(calcDays[3]),
            uint256(stake._stakedPrinciple),
            uint256(stake._possibleStars),
            uint256(stake._scrapedInterest),
            uint256(penalty),
            uint256(stakeTotal)
        );
        // Remove the Stake from your stake list
        uint256 lastIndex = permStakes.length - 1;
        // If it's the last element, then skip
        if (stakeIndex != lastIndex) {
            permStakes[stakeIndex] = permStakes[lastIndex];
        }
        permStakes.pop();
        // stake remove is finished - remove from the the global Active Stakes Count

        g_stakedCount = g_stakedCount - 1;
    }

    // @dev get the allocated supply of the token
    function allocatedSupply()
    external
    view
    returns (
        uint256
    )
    {
        return _allocatedSupply();
    }

    // @dev Public Function: Returns the current Day since the launch date
    // @return current day number
    function currentDay()
    external
    view
    returns (
        uint
    )
    {
        return _currentDay();
    }

    // @dev Reports Global gives a list of global variables for reporting
    // returns:
    // uint256 staked_stars,  sum of interest + principle
    // uint256 staked_principle_stars  // total staked based only on principle, what users actually staked,
    // uint256 total_supply, 
    // uint256 allocated_supply,
    // uint256 penalized_stars,
    // uint256 current_day,
    // uint256 latest_stake_id
    // uint256 staked_count total active stakes + and - at the end of startStake and endStake
    function reportGlobals()
    external
    view
    returns (
        uint256 staked_stars, 
        uint256 staked_principle_stars,
        uint256 total_supply,
        uint256 allocated_supply,
        uint256 penalized_stars,
        uint256 current_day,
        uint256 latest_stake_id,
        uint256 staked_count,
        uint256 endowment_supply
    )
    {
        staked_stars = g_stakedStars;
        staked_principle_stars = g_stakedPrincipleStars;
        

        total_supply = super.totalSupply() + g_stakedStars + _endowmentSupply;
        

        allocated_supply = _allocatedSupply();
        penalized_stars = g_penalizedStars;
        current_day = _currentDay();
        latest_stake_id = g_latestStakeId;
        staked_count = g_stakedCount;
        endowment_supply = _endowmentSupply;

        return (staked_stars, staked_principle_stars, total_supply, allocated_supply, penalized_stars, current_day, latest_stake_id, staked_count, endowment_supply);
    }

    // @dev Public Function: Return the count of stakes in the stakeList map
    // @param address userAddress - address of staker
    function countStakes(address userAddress)
    external
    view
    returns (
        uint256
    )
    {
        return Stakes[userAddress].length;
    }

    // Calculate Days
    // Returns Calculated Days in an array like below
    // 0 curDay - Current Day
    // 1 startDay - Start Day
    // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)
    // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)
    // 4 interestDays - Days that are used to CALCULATE INTEREST
    // 5 possibleDays -  (endOfStakeDays - currentDay)
    // @param uint256 tempStartDay
    // @param uint256 tempStakedDays
    // @param uint256 tempScrapeDay
    function calculateStakeDays(uint256 tempStartDay, uint256 tempStakedDays, uint256 tempScrapeDay)
    external
    view
    returns (
        uint[6] memory
    )
    {
        uint[6] memory calcDays = _calculateStakeDays(tempStartDay, tempStakedDays, tempScrapeDay);
        return (calcDays);
    }

    // @dev Calculate the interest of a scenario
    // @param uint256 stakedPrinciple The amount of principle for the stake
    // @param uint256 stakedDays the number of days to commit to a stake
    function calculateInterest(uint256 stakedPrinciple, uint256 stakedDays)
    external
    pure
    returns(
        uint256 interest
    )
    {
        _assurePrincipleAndStakedDaysAreValid(stakedPrinciple, stakedDays);
        interest = _calculateInterest(stakedPrinciple, stakedDays);

        return (interest);
    }

    // @dev This give the totalsupply plus the totalstaked.  Total staked also
    // includes the interest that may be accrued from time and principle.
    // @return Allocated Supply in Stars
    function _allocatedSupply()
    private
    view
    returns (
        uint256
    )
    {

        return super.totalSupply() + g_stakedStars;

    }

    // @dev Private function that calculates the current day from day 1
    // @return Current day number
    function _currentDay()
    internal
    view
    returns (
        uint256 temp_currentDay
    )
    {
        return (block.timestamp - LAUNCH_TIME) / 1 days;
    }

    // @dev Private Function to load the stake into memory
    // Takes stake store and pushes the values into it
    // @param PermStake stakeRef reference of values to get
    // @param uint256 myStakeId or the globalStakeId
    // @param TempStake stake to load into memory as st or current stake
    // Requirements:
    // `stakeId must exist in the list`, so both the position (zero index AND stakeID must be correct)
    function _loadStake(PermStake storage stakeRef, uint256 myStakeId, TempStake memory stake)
    internal
    view
    {
        //require current stake index is valid
        require(myStakeId == stakeRef.stakeId, "myStakeId not in stake");
        stake._stakeId = stakeRef.stakeId;
        stake._stakedPrinciple = stakeRef.stakedPrinciple;
        stake._startDay = stakeRef.startDay;
        stake._scrapeDay = stakeRef.scrapeDay;
        stake._stakedDays = stakeRef.stakedDays;
        stake._scrapedInterest = stakeRef.scrapedInterest;
        stake._possibleStars = stakeRef.possibleStars;
    }

    // @dev Private Function for updating the stake
    // returns nothing, it just updates the stake passed to it
    // @param PermStake stakeRef the reference to the original mapping of the stake store
    // @param TempStake stake the new instance to update from
    function _updateStake(PermStake storage stakeRef, TempStake memory stake)
    internal
    {
        stakeRef.stakeId = stake._stakeId;
        stakeRef.stakedPrinciple = uint256(stake._stakedPrinciple);
        stakeRef.startDay = uint256(stake._startDay);
        stakeRef.scrapeDay = uint256(stake._scrapeDay);
        stakeRef.stakedDays = uint256(stake._stakedDays);
        stakeRef.scrapedInterest = uint256(stake._scrapedInterest);
        stakeRef.possibleStars = uint256(stake._possibleStars);
    }

    // @dev Internal Function Start a Stake Internal Function
    // @param uint256 stakedPrinciple
    // @param uint256 stakedDays length of days in the stake
    // @param uint256 possibleStars allocated total for this stake
    function _startStake(
        uint256 stakedPrinciple,
        uint256 stakedDays,
        uint256 possibleStars
    )
    private
    {
        // Get the current day
        uint256 cday = _currentDay();
        // starts the next day
        uint256 startDay = cday + 1;
        // automaticall set scrape day to start day
        uint256 scrapeDay = startDay;
        // Burn the tokens from the sender
        _burn(msg.sender, stakedPrinciple);
        // Get the global stake id and create the stake
        uint256 newStakeId = ++g_latestStakeId;
        // push the new stake into the sender's stake list
        Stakes[msg.sender].push(
            PermStake(
                newStakeId,
                stakedPrinciple,
                startDay,
                scrapeDay,
                stakedDays,
                uint256(0),
                possibleStars
            )
        );
        // emit the stake start event
        emit StartStake(
            msg.sender,
            uint256(newStakeId),
            uint256(1),
            startDay,
            stakedDays,
            stakedPrinciple,
            possibleStars
        );
        // Add to the global Active Stakes
        g_stakedCount = g_stakedCount + 1;
    }

    // @dev Require and validate the basic min/max stake parameters
    // @param uint256 principle
    // @param uint256 servedDays
    function _assurePrincipleAndStakedDaysAreValid(uint256 principle, uint256 servedDays)
    internal
    pure
    {
        // validate the stake days and principle 
        require(servedDays >= MIN_STAKE_DAYS, "Stake length is too small");
        require(servedDays <= MAX_STAKE_DAYS, "Stake length is too large");
        require(principle >= MIN_STAKE_AMOUNT, "Principle is not high enough");
        require(principle <= MAX_STAKE_AMOUNT, "Principle is too high");
    }

    // @dev Calculate Interest Function
    // @notice This calculates the amount of interest for the number of servedDays.
    // This divides up served days into buckets of yearly increments based on 365.25 days
    // Then applies the rate of return based on the interestTable.
    // @param uint256 principle - the principle to apply
    // @param uint256 servedDays - the number of days to calculate.
    function _calculateInterest(uint256 principle, uint256 servedDays)
    internal
    pure
    returns(
        uint256 totalInterest
    )
    {
        // year is 365.25, but we need to multiply by 100 to keep it integer'istic
        uint256 workingDays = servedDays * YEARPRECISION;
        // This will fill up based on the days.
        // Daily Interest Table is based on 18 decimals so
        uint[23] memory dailyInterestTable = _getDailyInterestTable();
        // Set an index to increment for the while loops
        uint256 workingidx = 0;
        uint256 appliedInterestRate = 0;
        uint256 tempInterestAmount = 0;
        uint256 current = 0;

        while (workingidx < MAX_STAKE_YEARS) {
            if (workingDays > YEARDIVIDER) {
                current = YEARDIVIDER;
                workingDays -= YEARDIVIDER;
            } else {
                // x is less than than MaxStakeYears, so set the remainder to this.
                current = workingDays;  // this will give the days left over
                workingDays = 0;
            }
            // apply this years interest rate to the days inside that year
            appliedInterestRate = dailyInterestTable[workingidx];
            
            // days (36525) * interest for this year divided by 100 multiplied by principle then divide py precision
            
            // tempInterestAmount = (((current * appliedInterestRate) / YEARPRECISION) * principle) / (PRECISION * PRECISION); //36 decimals
            
            uint tempInterestAmountNumerator = 0;
            tempInterestAmountNumerator = ((current * appliedInterestRate) * principle) / YEARPRECISION;
            tempInterestAmount = tempInterestAmountNumerator / (PRECISION * PRECISION); //36

            // apply the principle and add it to the running total of interest
            totalInterest += tempInterestAmount;   // divide by 100 because of our days... days return as 36525 and not 365.25
            workingidx = workingidx + 1;  // keep running for the full 22 years.
            if (workingDays == 0) {
                break;
            }
        }

        return (totalInterest);
    }

    // @dev CalculatePenalty
    // @notice This calculates the penalty if there is one.
    // The rules for penalty:
    //     - if a stake is less than 50% complete, then you get 50% of your principle returned
    //     - if a stake is greater than 50%, you get the percentage back for each day from 100%
    //         example: Stake is 60% complete. You should receive 60% of your principle back.
    // @param TempStake stake the stake to calculate penalties for
    function _calculatePenalty(TempStake memory stake)
    internal
    view
    returns(
        uint256 penaltyAmount
    )
    {
        // calculate the penalty for forcing and end stake
        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);
        uint256 pct = 0;
        uint256 pctleft = 0;
        uint256 pctprecision = 100;
        uint256 daysSinceStart = 0;
        uint256 totalStakeDays = stake._stakedDays * pctprecision;
        // Check served days to make sure it's at least 1
        if (totalStakeDays <= 0) {
            totalStakeDays = 1 * pctprecision; //sets minimum amt for calculation        
        }
        if (calcDays[0] < calcDays[1]) {
            // should never happen... condition handled in parent
        } else if (calcDays[0] == calcDays[1]) {
            daysSinceStart = (1 * pctprecision);
        } else {
            // number of days since start day
            daysSinceStart = (calcDays[0] - calcDays[1]) * pctprecision;
        }
        // basic pct made here
        pct = (daysSinceStart * pctprecision) / totalStakeDays;
        // decision time - anything 50 or less is counted as 50
        if (pct <= 50) {
            pctleft = 50;
        } else if (pct > 50 && pct < 100) {
            pctleft = 100 - pct;
        } else {
            pctleft = 0;
        }
        // calculate penalties from pctleft
        penaltyAmount = (stake._stakedPrinciple * pctleft) / 100;
        // This cannot be less than zero
        if (penaltyAmount <= 0) {
            penaltyAmount = 0;
        }
        // this should never exceed the amount, but just in case lets test for it anyway
        if (penaltyAmount > stake._stakedPrinciple) {
            penaltyAmount = stake._stakedPrinciple;
        }

        return (penaltyAmount);
    }

    // @param TempStake stake
    function _calculateStakeTotal(TempStake memory stake)
    internal
    view
    returns (
        uint256 stakeTotal,
        uint256 currentInterest,
        uint256 penalty
    )
    {
        penalty = 0;
        stakeTotal = 0;  // total return of the stake
        currentInterest = 0;
        uint256 appliedPrinciple = 0;
        uint256 previousInterest = stake._scrapedInterest;
        uint[6] memory calcDays = _calculateStakeDays(stake._startDay, stake._stakedDays, stake._scrapeDay);
        // Returns Calculated Days in an array like below
        // 0 curDay - Current Day
        // 1 startDay - Start Day
        // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)
        // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)
        // 4 interestDays - Days that are used to CALCULATE INTEREST
        // 5 possibleDays -  (endOfStakeDays - currentDay)
        // if InterestDays is less than staked days
        // if (calcDays[4] < stake._stakedDays) {
        // if currentDay is less than endofstake day
        if (calcDays[0] < calcDays[3]) {
            // calculate the penalty if any
            penalty = _calculatePenalty(stake);
            if (penalty > stake._stakedPrinciple) {
                // this should never happen but if it does, then set to 50% of the principle
                appliedPrinciple = stake._stakedPrinciple / 2;
            } else {
                // this should return a "prorated" amount of principle from 51% to 99%
                appliedPrinciple = (stake._stakedPrinciple - penalty);
            }
            // A broken stake will only give you the portion of your principle back, not your interest.
            stakeTotal = appliedPrinciple;
            currentInterest = 0;
        } else {
            // There is no penalty if stake is completed
            currentInterest = _calculateInterest(stake._stakedPrinciple, calcDays[4]);
            // Set the total amount of accrued interest
            stake._scrapedInterest = previousInterest + currentInterest;
            // stake is finished, so we set this to zero
            stake._possibleStars = 0;
            // total amount of stake to be returned to user
            stakeTotal = currentInterest + stake._stakedPrinciple;
            penalty = 0;
        }
    }

    // This returns days in this order:
    // 0 curDay - Current Day
    // 1 startDay - Start Day
    // 2 scrapeDay - The previous day this was scraped - (default to startDay, and is set when scraped)
    // 3 endOfStakeDay - The final day of this stake (startDay + stakedDays or total days in stake)
    // 4 interestDays - Days that are used to CALCULATE INTEREST
    // 5 possibleDays -  (endOfStakeDays - currentDay)
    // @dev Calculate Days
    // @notice This returns an array of calculated days of your stake based on the current day.
    // @param uint256 startDay
    // @param uint256 stakedDays length of days in the stake
    // @param uint256 scrapeDay
    function _calculateStakeDays(uint256 startDay, uint256 stakedDays, uint256 scrapeDay)
    internal
    view
    returns (uint[6] memory)
    {
        // if the stakedDays is less than the minimum, throw an error
        require(stakedDays >= MIN_STAKE_DAYS, "stake days must be greater than 1");
        uint256 curDay = _currentDay();  //ex. day 25
        uint256 endOfStakeDay = startDay + stakedDays; //ex. Day 52
        // find the higher of the two days ( startDay or a more recent scrapeDay )
        uint256 targetStartDay = scrapeDay >= startDay ? scrapeDay : startDay;
        // the possible interest bearing days
        uint256 possibleDays = endOfStakeDay - targetStartDay;
        uint256 interestDays = 0;
        // if the currentDay is greater than the end stake day, we subtract:
        // targetStartDay from the endOfStakeDay giving us the interest days.
        // otherwise we take the currentDay and subtract the same targetStartDay because it's still an active stake.
        if (targetStartDay > curDay) {
            // probably a new stake so we'll default to zero
            // this also keeps this from subtracting current day from target day
            // and for the beginning of a stake, it will be a negative 1
            interestDays = 0;
        } else {
            interestDays = curDay >= endOfStakeDay ? (endOfStakeDay - targetStartDay) : (curDay - targetStartDay);
        }

        return [
            uint(curDay),
            startDay,
            scrapeDay,
            endOfStakeDay,
            interestDays,
            possibleDays
        ];
    }

    // @dev getDailyInterestTable
    // @notice This table has precalculated values for the 22 year buckets that calculate the interest
    // based on the number of days you have within each year.
    function _getDailyInterestTable()
    internal
    pure
    returns (uint[23] memory tableOfInterest)
    {
        // These values are precalculated and will never change once this is made live.
        // based on 36 decimals
        tableOfInterest = [
        uint(136892539356605065023956194387405), 
             164271047227926078028747433264887, 
             219028062970568104038329911019849, 
             301163586584531143052703627652292, 
             410677618069815195071868583162217, 
             547570157426420260095824777549623, 
             711841204654346338124572210814510, 
             903490759753593429158110882956878, 
             1122518822724161533196440793976728, 
             1368925393566050650239561943874058, 
             1642710472279260780287474332648870, 
             1943874058863791923340177960301163, 
             2272416153319644079397672826830937, 
             2628336755646817248459958932238193, 
             3011635865845311430527036276522929, 
             3422313483915126625598904859685147, 
             3860369609856262833675564681724845, 
             4325804243668720054757015742642026, 
             4818617385352498288843258042436687, 
             5338809034907597535934291581108829, 
             5886379192334017796030116358658453, 
             6461327857631759069130732375085557, 
             0
            ];

        return (tableOfInterest);
    }


    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.
        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply
        uint totSupply = super.totalSupply() + g_stakedStars + _endowmentSupply;

        return (totSupply);
    }
    /**
     * @dev Follows same convention as IERC20-totalsupply
     */
    function endowmentSupply() public view returns (uint256) {
        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.
        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply
        return _endowmentSupply;
    }    
    
    /**
     * @dev Follows same convention as IERC20-totalsupply
     */
    function originalSupply() public view returns (uint256) {
        // The Endowment Supply is the total amount of token available for staking rewards to the stakers.
        // A proper representation of Total Supply is the Endowment Supply + what is in the ERC20 total supply
        return (super.totalSupply());
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakeAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"eventName","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endStakeDay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"principle","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldPossibleInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scrapedInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalties","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeTotal","type":"uint256"}],"name":"EndStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakeAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"eventName","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scrapeDay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"previousScrapedInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldPossibleInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scrapedInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"possibleInterest","type":"uint256"}],"name":"ScrapeStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakeAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"eventName","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startDay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakedDays","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"principle","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"possibleInterest","type":"uint256"}],"name":"StartStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"Stakes","outputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"},{"internalType":"uint256","name":"stakedPrinciple","type":"uint256"},{"internalType":"uint256","name":"startDay","type":"uint256"},{"internalType":"uint256","name":"scrapeDay","type":"uint256"},{"internalType":"uint256","name":"stakedDays","type":"uint256"},{"internalType":"uint256","name":"scrapedInterest","type":"uint256"},{"internalType":"uint256","name":"possibleStars","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allocatedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakedPrinciple","type":"uint256"},{"internalType":"uint256","name":"stakedDays","type":"uint256"}],"name":"calculateInterest","outputs":[{"internalType":"uint256","name":"interest","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tempStartDay","type":"uint256"},{"internalType":"uint256","name":"tempStakedDays","type":"uint256"},{"internalType":"uint256","name":"tempScrapeDay","type":"uint256"}],"name":"calculateStakeDays","outputs":[{"internalType":"uint256[6]","name":"","type":"uint256[6]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"countStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint256","name":"myStakeId","type":"uint256"}],"name":"endStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endowmentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"originalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reportGlobals","outputs":[{"internalType":"uint256","name":"staked_stars","type":"uint256"},{"internalType":"uint256","name":"staked_principle_stars","type":"uint256"},{"internalType":"uint256","name":"total_supply","type":"uint256"},{"internalType":"uint256","name":"allocated_supply","type":"uint256"},{"internalType":"uint256","name":"penalized_stars","type":"uint256"},{"internalType":"uint256","name":"current_day","type":"uint256"},{"internalType":"uint256","name":"latest_stake_id","type":"uint256"},{"internalType":"uint256","name":"staked_count","type":"uint256"},{"internalType":"uint256","name":"endowment_supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeIndex","type":"uint256"},{"internalType":"uint256","name":"myStakeId","type":"uint256"}],"name":"scrapeStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakedPrinciple","type":"uint256"},{"internalType":"uint256","name":"stakedDays","type":"uint256"}],"name":"startStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526d04c84fe76aeab24e25c24000000060055560006006556000600755600060085560006009556000600a553480156200003c57600080fd5b506200008f6040518060400160405280600b81526020016a2a22ac20a7102a37b5b2b760a91b815250604051806040016040528060058152602001642a22ac20a760d91b815250620000b060201b60201c565b6c25dd85d670d35ec9bec0000000620000a93382620000e0565b50620002d1565b8151620000c5906003906020850190620001c8565b508051620000db906004906020840190620001c8565b505050565b6001600160a01b0382166200013b5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b80600260008282546200014f91906200026e565b90915550506001600160a01b038216600090815260208190526040812080548392906200017e9084906200026e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b828054620001d69062000295565b90600052602060002090601f016020900481019282620001fa576000855562000245565b82601f106200021557805160ff191683800117855562000245565b8280016001018555821562000245579182015b828111156200024557825182559160200191906001019062000228565b506200025392915062000257565b5090565b5b8082111562000253576000815560010162000258565b600082198211156200029057634e487b7160e01b600052601160045260246000fd5b500190565b600181811c90821680620002aa57607f821691505b602082108103620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b61247e80620002e16000396000f3fe6080604052600436106101445760003560e01c80633a70a5ca116100b657806395d89b411161006f57806395d89b4114610469578063a457c2d71461047e578063a9059cbb1461049e578063dd62ed3e146104be578063df28e78f14610504578063efdd7c07146105195761019d565b80633a70a5ca146103a757806343a033e1146103bc5780634b2ba0dd146103dc5780635c9302c9146103f157806370a0823114610406578063892080e81461043c5761019d565b806320e9ab121161010857806320e9ab12146102a057806323b872dd146102c05780632f3f9b46146102e0578063313ce5671461031657806335de32341461033257806339509351146103875761019d565b806306fdde03146101a9578063095ea7b3146101d4578063128bfcae1461020457806318160ddd146102245780631f545303146102475761019d565b3661019d5760016000610155610539565b604051602001610165919061216f565b6040516020818303038152906040529061019b5760405162461bcd60e51b815260040161019291906121c1565b60405180910390fd5b005b34801561019b57600080fd5b3480156101b557600080fd5b506101be610539565b6040516101cb91906121c1565b60405180910390f35b3480156101e057600080fd5b506101f46101ef366004612210565b6105cb565b60405190151581526020016101cb565b34801561021057600080fd5b5061019b61021f36600461223a565b6105e1565b34801561023057600080fd5b506102396106bd565b6040519081526020016101cb565b34801561025357600080fd5b5061025c6106e9565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016101cb565b3480156102ac57600080fd5b5061019b6102bb36600461223a565b610759565b3480156102cc57600080fd5b506101f46102db36600461225c565b610bd4565b3480156102ec57600080fd5b506102396102fb366004612298565b6001600160a01b03166000908152600b602052604090205490565b34801561032257600080fd5b50604051601281526020016101cb565b34801561033e57600080fd5b5061035261034d366004612210565b610c7e565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101cb565b34801561039357600080fd5b506101f46103a2366004612210565b610cd8565b3480156103b357600080fd5b50610239610d14565b3480156103c857600080fd5b5061019b6103d736600461223a565b610d23565b3480156103e857600080fd5b50610239611122565b3480156103fd57600080fd5b5061023961112d565b34801561041257600080fd5b50610239610421366004612298565b6001600160a01b031660009081526020819052604090205490565b34801561044857600080fd5b5061045c6104573660046122b3565b611137565b6040516101cb91906122df565b34801561047557600080fd5b506101be611155565b34801561048a57600080fd5b506101f4610499366004612210565b611164565b3480156104aa57600080fd5b506101f46104b9366004612210565b6111fd565b3480156104ca57600080fd5b506102396104d9366004612310565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561051057600080fd5b50600554610239565b34801561052557600080fd5b5061023961053436600461223a565b61120a565b60606003805461054890612343565b80601f016020809104026020016040519081016040528092919081815260200182805461057490612343565b80156105c15780601f10610596576101008083540402835291602001916105c1565b820191906000526020600020905b8154815290600101906020018083116105a457829003601f168201915b5050505050905090565b60006105d8338484611227565b50600192915050565b6105eb828261134c565b60006105f7838361149a565b905060006106058483612393565b905081600554116106685760405162461bcd60e51b815260206004820152602760248201527f5468657265206973206e6f7420656e6f75676820746f20636f76657220796f7560448201526672207374616b6560c81b6064820152608401610192565b61067384848361157f565b8160055461068191906123ab565b60058190555083600860008282546106999190612393565b9250508190555080600760008282546106b29190612393565b909155505050505050565b6000806005546007546106cf60025490565b6106d99190612393565b6106e39190612393565b92915050565b60008060008060008060008060006007549850600854975060055460075461071060025490565b61071a9190612393565b6107249190612393565b965061072e611702565b9550600954945061073d61171a565b93506006549250600a5491506005549050909192939495969798565b336000908152600b6020526040812080549091036107af5760405162461bcd60e51b81526020600482015260136024820152725374616b65204c69737420697320456d70747960681b6044820152606401610192565b805483106107f85760405162461bcd60e51b81526020600482015260166024820152750dcdee840c240ecc2d8d2c840e6e8c2d6ca92dcc8caf60531b6044820152606401610192565b60006040518060e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250905061086082858154811061084b5761084b6123c2565b90600052602060002090600702018483611738565b60008080600090506000806108828660400151876080015188606001516117c9565b60208101518151919250111561090a5785602001518660c001516108a691906123ab565b6005546108b39190612393565b6005556020860151600094508492506108cd9033906118d2565b8560c00151600760008282546108e391906123ab565b90915550506020860151600880546000906108ff9084906123ab565b90915550610a509050565b6020810151815161091b91906123ab565b9450610926866119b1565b9195509350915081156109cd5785602001518660c0015161094791906123ab565b600560008282546109589190612393565b9250508190555081600960008282546109719190612393565b909155505060c08601516007541061099f578560c001516007600082825461099991906123ab565b90915550505b8560200151600854106109c8578560200151600860008282546109c291906123ab565b90915550505b610a40565b82600754106109ee5782600760008282546109e891906123ab565b90915550505b856020015160075410610a1757856020015160076000828254610a1191906123ab565b90915550505b856020015160085410610a4057856020015160086000828254610a3a91906123ab565b90915550505b8315610a5057610a5033856118d2565b85516060808301516020808a015160c0808c015160a0808e0151604080519788529587019490945293850152938301526080820186905281018790526003929133917f599a340c142edf87d421bb7c191f9481e5762e2be20f5367d6e77e4c5bcdac15910160405180910390a48654600090610ace906001906123ab565b9050808a14610b6157878181548110610ae957610ae96123c2565b9060005260206000209060070201888b81548110610b0957610b096123c2565b9060005260206000209060070201600082015481600001556001820154816001015560028201548160020155600382015481600301556004820154816004015560058201548160050155600682015481600601559050505b87805480610b7157610b716123d8565b6000828152602081206007600019909301928302018181556001818101839055600282018390556003820183905560048201839055600582018390556006909101919091559155600a54610bc591906123ab565b600a5550505050505050505050565b6000610be1848484611a82565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610c665760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610192565b610c738533858403611227565b506001949350505050565b600b6020528160005260406000208181548110610c9a57600080fd5b600091825260209091206007909102018054600182015460028301546003840154600485015460058601546006909601549497509295509093909287565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105d8918590610d0f908690612393565b611227565b6000610d1e611702565b905090565b336000908152600b602052604081208054909103610d765760405162461bcd60e51b815260206004820152601060248201526f115b5c1d1e481cdd185ad9481b1a5cdd60821b6044820152606401610192565b80548310610dbb5760405162461bcd60e51b81526020600482015260126024820152711cdd185ad9525b99195e081a5b9d985b1a5960721b6044820152606401610192565b60006040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610e0e82858154811061084b5761084b6123c2565b336000908152600b60205260408120805486908110610e2f57610e2f6123c2565b9060005260206000209060070201905060008260a00151905060008360c0015190506000610e6a8560400151866080015187606001516117c9565b80516040870151919250600091829182918111610ee15760405162461bcd60e51b815260206004820152602f60248201527f5363726170696e67206973206e6f7420616c6c6f7765642c207374616b65206d60448201526e1d5cdd081cdd185c9d08199a5c9cdd608a1b6064820152608401610192565b6060850151811115610f455760405162461bcd60e51b815260206004820152602760248201527f5363726170696e67206973206e6f7420616c6c6f7765642c206d75737420656e60448201526664207374616b6560c81b6064820152608401610192565b60408501518111610fc85760405162461bcd60e51b815260206004820152604160248201527f5363726170696e67206973206e6f7420616c6c6f77656420756e74696c20312060448201527f6f72206d6f7265207374616b656420646179732068617320636f6d706c6574656064820152601960fa1b608482015260a401610192565b60a089015160208a0151909750610fe7908660045b602002015161149a565b60208a0151865160608801519296506110099261100491906123ab565b61149a565b9150600089602001518361101d9190612393565b9050600085881161102f576000611039565b61103986896123ab565b9050818111156110505761104d82826123ab565b94505b85156111125761106033876118d2565b841561107857846005546110749190612393565b6005555b611082868a612393565b60a08c0181905260c08c0183905260608c018490528b51808c5560208d015160018d015560408d015160028d015560038c018590556080808e015160048e015560058d0183905560068d018590558901516110e1928c908c9089611c52565b87600760008282546110f391906123ab565b92505081905550816007600082825461110c9190612393565b90915550505b5050505050505050505050505050565b6000610d1e60025490565b6000610d1e61171a565b61113f612106565b600061114c8585856117c9565b95945050505050565b60606004805461054890612343565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156111e65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610192565b6111f33385858403611227565b5060019392505050565b60006105d8338484611a82565b6000611216838361134c565b611220838361149a565b9392505050565b6001600160a01b0383166112895760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610192565b6001600160a01b0382166112ea5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610192565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600181101561139d5760405162461bcd60e51b815260206004820152601960248201527f5374616b65206c656e67746820697320746f6f20736d616c6c000000000000006044820152606401610192565b611f648111156113ef5760405162461bcd60e51b815260206004820152601960248201527f5374616b65206c656e67746820697320746f6f206c61726765000000000000006044820152606401610192565b6127108210156114415760405162461bcd60e51b815260206004820152601c60248201527f5072696e6369706c65206973206e6f74206869676820656e6f756768000000006044820152606401610192565b6c01431e0fae6d7217caa00000008211156114965760405162461bcd60e51b81526020600482015260156024820152740a0e4d2dcc6d2e0d8ca40d2e640e8dede40d0d2ced605b1b6044820152606401610192565b5050565b6000806114a86064846123ee565b905060006114b4611cb0565b90506000806000805b601684101561157357618ead8611156114e55750618ead6114de81876123ab565b95506114ea565b506000945b8484601781106114fc576114fc6123c2565b60200201519250600060648a61151286856123ee565b61151c91906123ee565b611526919061240d565b905061153a670de0b6b3a7640000806123ee565b611544908261240d565b92506115508389612393565b975061155d856001612393565b94508660000361156d5750611573565b506114bd565b50505050505092915050565b600061158961171a565b90506000611598826001612393565b9050806115a53387611e89565b60006006600081546115b69061242f565b9190508190559050600b6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060e0016040528083815260200189815260200185815260200184815260200188815260200160008152602001878152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050600181336001600160a01b03167f8fdc0cbd36b6db294b289125f705adcfb3320fb50626f3de2f09632811b2c458868a8c8b6040516116e0949392919093845260208401929092526040830152606082015260800190565b60405180910390a4600a546116f6906001612393565b600a5550505050505050565b600060075461171060025490565b610d1e9190612393565b60006201518061172e6363a39e00426123ab565b610d1e919061240d565b825482146117815760405162461bcd60e51b81526020600482015260166024820152756d795374616b654964206e6f7420696e207374616b6560501b6044820152606401610192565b8254815260018301546020820152600283015460408201526003830154606082015260048301546080820152600583015460a082015260069092015460c09092019190915250565b6117d1612106565b600183101561182c5760405162461bcd60e51b815260206004820152602160248201527f7374616b652064617973206d7573742062652067726561746572207468616e206044820152603160f81b6064820152608401610192565b600061183661171a565b905060006118448587612393565b90506000868510156118565786611858565b845b9050600061186682846123ab565b905060008483111561187a5750600061189e565b838510156118915761188c83866123ab565b61189b565b61189b83856123ab565b90505b6040805160c08101825295865260208601999099529784019590955250606082015260808101949094525060a08301525090565b6001600160a01b0382166119285760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610192565b806002600082825461193a9190612393565b90915550506001600160a01b03821660009081526020819052604081208054839290611967908490612393565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60a081015160408201516080830151606084015160009384938493849384926119db9290916117c9565b606081015181519192501115611a39576119f487611fcf565b93508660200151841115611a1a5760028760200151611a13919061240d565b9250611a2d565b838760200151611a2a91906123ab565b92505b82955060009450611a78565b6020870151611a4a90826004610fdd565b9450611a568583612393565b60a0880152600060c08801526020870151611a719086612393565b9550600093505b5050509193909250565b6001600160a01b038316611ae65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610192565b6001600160a01b038216611b485760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610192565b6001600160a01b03831660009081526020819052604090205481811015611bc05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610192565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611bf7908490612393565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c4391815260200190565b60405180910390a35b50505050565b60408051868152602081018690529081018490526060810183905260808101829052600290879033907f464fbd494c736696c02460d8c6c817142a314d106db57638db0977eedacbf1899060a00160405180910390a4505050505050565b611cb8612124565b604051806102e001604052806d06bfd3a68f166e7321aa1baf65cd81526020016d0819646178815156f532879f46f781526020016d0acc85d74b57171e9c435f7f094981526020016d0ed938080797bfca16dca34eacc481526020016d143f7af3ad434b5964fe530e316981526020016d1aff4e9a3c59b9cc86a86ebd973781526020016d2318b2fbb4db0b237bdaf65cde2e81526020016d2c8ba81816c73f5e4495e9ec064e81526020016d37582def621e567ce0d9496b0f9881526020016d437e448196e0507f50a514d9fa0a81526020016d50fdebceb50d2d6593f94c38c5a681526020016d5fd723d6bca4ed2faad5ef87726b81526020016d7009ec99ada78fdd953afec6005981526020016d819646178815156f532879f46f7181526020016d947c30504bed7de4e49e6112bfb181526020016da8bbab43f930c93e499cb420f11b81526020016dbe54b6f28fdef77b8223731f03ad81526020016dd547535c0ff8089c8e329e0cf76a81526020016ded938080797bfca16dca34eacc4f81526020016e0107393e5fcc6ad38a20ea37b8825d81526020016e0122388cfa08c48d56a792a676199581526020016e013e916c4f2e892a0701c3812391f581526020016000815250905090565b6001600160a01b038216611ee95760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610192565b6001600160a01b03821660009081526020819052604090205481811015611f5d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610192565b6001600160a01b0383166000908152602081905260408120838303905560028054849290611f8c9084906123ab565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161133f565b600080611fe98360400151846080015185606001516117c9565b905060008060006064905060008082886080015161200791906123ee565b90506000811161201f5761201c8360016123ee565b90505b6020860151865110612068576020860151865103612049576120428360016123ee565b9150612068565b60208601518651849161205b916123ab565b61206591906123ee565b91505b8061207384846123ee565b61207d919061240d565b94506032851161209057603293506120bc565b6032851180156120a05750606485105b156120b7576120b08560646123ab565b93506120bc565b600093505b60648489602001516120ce91906123ee565b6120d8919061240d565b9650600087116120e757600096505b87602001518711156120fb57876020015196505b505050505050919050565b6040518060c001604052806006906020820280368337509192915050565b604051806102e001604052806017906020820280368337509192915050565b60005b8381101561215e578181015183820152602001612146565b83811115611c4c5750506000910152565b60008251612181818460208701612143565b7f3a20596f752063616e206e6f742073656e642045544820746f20746869732063920191825250676f6e74726163742160c01b6020820152602801919050565b60208152600082518060208401526121e0816040850160208701612143565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461220b57600080fd5b919050565b6000806040838503121561222357600080fd5b61222c836121f4565b946020939093013593505050565b6000806040838503121561224d57600080fd5b50508035926020909101359150565b60008060006060848603121561227157600080fd5b61227a846121f4565b9250612288602085016121f4565b9150604084013590509250925092565b6000602082840312156122aa57600080fd5b611220826121f4565b6000806000606084860312156122c857600080fd5b505081359360208301359350604090920135919050565b60c08101818360005b60068110156123075781518352602092830192909101906001016122e8565b50505092915050565b6000806040838503121561232357600080fd5b61232c836121f4565b915061233a602084016121f4565b90509250929050565b600181811c9082168061235757607f821691505b60208210810361237757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156123a6576123a661237d565b500190565b6000828210156123bd576123bd61237d565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008160001904831182151516156124085761240861237d565b500290565b60008261242a57634e487b7160e01b600052601260045260246000fd5b500490565b6000600182016124415761244161237d565b506001019056fea2646970667358221220bd4db68575faa397f8921486bf919774ac268e61c6330d36e646e3b79f1dc5d764736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106101445760003560e01c80633a70a5ca116100b657806395d89b411161006f57806395d89b4114610469578063a457c2d71461047e578063a9059cbb1461049e578063dd62ed3e146104be578063df28e78f14610504578063efdd7c07146105195761019d565b80633a70a5ca146103a757806343a033e1146103bc5780634b2ba0dd146103dc5780635c9302c9146103f157806370a0823114610406578063892080e81461043c5761019d565b806320e9ab121161010857806320e9ab12146102a057806323b872dd146102c05780632f3f9b46146102e0578063313ce5671461031657806335de32341461033257806339509351146103875761019d565b806306fdde03146101a9578063095ea7b3146101d4578063128bfcae1461020457806318160ddd146102245780631f545303146102475761019d565b3661019d5760016000610155610539565b604051602001610165919061216f565b6040516020818303038152906040529061019b5760405162461bcd60e51b815260040161019291906121c1565b60405180910390fd5b005b34801561019b57600080fd5b3480156101b557600080fd5b506101be610539565b6040516101cb91906121c1565b60405180910390f35b3480156101e057600080fd5b506101f46101ef366004612210565b6105cb565b60405190151581526020016101cb565b34801561021057600080fd5b5061019b61021f36600461223a565b6105e1565b34801561023057600080fd5b506102396106bd565b6040519081526020016101cb565b34801561025357600080fd5b5061025c6106e9565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c084015260e0830152610100820152610120016101cb565b3480156102ac57600080fd5b5061019b6102bb36600461223a565b610759565b3480156102cc57600080fd5b506101f46102db36600461225c565b610bd4565b3480156102ec57600080fd5b506102396102fb366004612298565b6001600160a01b03166000908152600b602052604090205490565b34801561032257600080fd5b50604051601281526020016101cb565b34801561033e57600080fd5b5061035261034d366004612210565b610c7e565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101cb565b34801561039357600080fd5b506101f46103a2366004612210565b610cd8565b3480156103b357600080fd5b50610239610d14565b3480156103c857600080fd5b5061019b6103d736600461223a565b610d23565b3480156103e857600080fd5b50610239611122565b3480156103fd57600080fd5b5061023961112d565b34801561041257600080fd5b50610239610421366004612298565b6001600160a01b031660009081526020819052604090205490565b34801561044857600080fd5b5061045c6104573660046122b3565b611137565b6040516101cb91906122df565b34801561047557600080fd5b506101be611155565b34801561048a57600080fd5b506101f4610499366004612210565b611164565b3480156104aa57600080fd5b506101f46104b9366004612210565b6111fd565b3480156104ca57600080fd5b506102396104d9366004612310565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561051057600080fd5b50600554610239565b34801561052557600080fd5b5061023961053436600461223a565b61120a565b60606003805461054890612343565b80601f016020809104026020016040519081016040528092919081815260200182805461057490612343565b80156105c15780601f10610596576101008083540402835291602001916105c1565b820191906000526020600020905b8154815290600101906020018083116105a457829003601f168201915b5050505050905090565b60006105d8338484611227565b50600192915050565b6105eb828261134c565b60006105f7838361149a565b905060006106058483612393565b905081600554116106685760405162461bcd60e51b815260206004820152602760248201527f5468657265206973206e6f7420656e6f75676820746f20636f76657220796f7560448201526672207374616b6560c81b6064820152608401610192565b61067384848361157f565b8160055461068191906123ab565b60058190555083600860008282546106999190612393565b9250508190555080600760008282546106b29190612393565b909155505050505050565b6000806005546007546106cf60025490565b6106d99190612393565b6106e39190612393565b92915050565b60008060008060008060008060006007549850600854975060055460075461071060025490565b61071a9190612393565b6107249190612393565b965061072e611702565b9550600954945061073d61171a565b93506006549250600a5491506005549050909192939495969798565b336000908152600b6020526040812080549091036107af5760405162461bcd60e51b81526020600482015260136024820152725374616b65204c69737420697320456d70747960681b6044820152606401610192565b805483106107f85760405162461bcd60e51b81526020600482015260166024820152750dcdee840c240ecc2d8d2c840e6e8c2d6ca92dcc8caf60531b6044820152606401610192565b60006040518060e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250905061086082858154811061084b5761084b6123c2565b90600052602060002090600702018483611738565b60008080600090506000806108828660400151876080015188606001516117c9565b60208101518151919250111561090a5785602001518660c001516108a691906123ab565b6005546108b39190612393565b6005556020860151600094508492506108cd9033906118d2565b8560c00151600760008282546108e391906123ab565b90915550506020860151600880546000906108ff9084906123ab565b90915550610a509050565b6020810151815161091b91906123ab565b9450610926866119b1565b9195509350915081156109cd5785602001518660c0015161094791906123ab565b600560008282546109589190612393565b9250508190555081600960008282546109719190612393565b909155505060c08601516007541061099f578560c001516007600082825461099991906123ab565b90915550505b8560200151600854106109c8578560200151600860008282546109c291906123ab565b90915550505b610a40565b82600754106109ee5782600760008282546109e891906123ab565b90915550505b856020015160075410610a1757856020015160076000828254610a1191906123ab565b90915550505b856020015160085410610a4057856020015160086000828254610a3a91906123ab565b90915550505b8315610a5057610a5033856118d2565b85516060808301516020808a015160c0808c015160a0808e0151604080519788529587019490945293850152938301526080820186905281018790526003929133917f599a340c142edf87d421bb7c191f9481e5762e2be20f5367d6e77e4c5bcdac15910160405180910390a48654600090610ace906001906123ab565b9050808a14610b6157878181548110610ae957610ae96123c2565b9060005260206000209060070201888b81548110610b0957610b096123c2565b9060005260206000209060070201600082015481600001556001820154816001015560028201548160020155600382015481600301556004820154816004015560058201548160050155600682015481600601559050505b87805480610b7157610b716123d8565b6000828152602081206007600019909301928302018181556001818101839055600282018390556003820183905560048201839055600582018390556006909101919091559155600a54610bc591906123ab565b600a5550505050505050505050565b6000610be1848484611a82565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610c665760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610192565b610c738533858403611227565b506001949350505050565b600b6020528160005260406000208181548110610c9a57600080fd5b600091825260209091206007909102018054600182015460028301546003840154600485015460058601546006909601549497509295509093909287565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105d8918590610d0f908690612393565b611227565b6000610d1e611702565b905090565b336000908152600b602052604081208054909103610d765760405162461bcd60e51b815260206004820152601060248201526f115b5c1d1e481cdd185ad9481b1a5cdd60821b6044820152606401610192565b80548310610dbb5760405162461bcd60e51b81526020600482015260126024820152711cdd185ad9525b99195e081a5b9d985b1a5960721b6044820152606401610192565b60006040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509050610e0e82858154811061084b5761084b6123c2565b336000908152600b60205260408120805486908110610e2f57610e2f6123c2565b9060005260206000209060070201905060008260a00151905060008360c0015190506000610e6a8560400151866080015187606001516117c9565b80516040870151919250600091829182918111610ee15760405162461bcd60e51b815260206004820152602f60248201527f5363726170696e67206973206e6f7420616c6c6f7765642c207374616b65206d60448201526e1d5cdd081cdd185c9d08199a5c9cdd608a1b6064820152608401610192565b6060850151811115610f455760405162461bcd60e51b815260206004820152602760248201527f5363726170696e67206973206e6f7420616c6c6f7765642c206d75737420656e60448201526664207374616b6560c81b6064820152608401610192565b60408501518111610fc85760405162461bcd60e51b815260206004820152604160248201527f5363726170696e67206973206e6f7420616c6c6f77656420756e74696c20312060448201527f6f72206d6f7265207374616b656420646179732068617320636f6d706c6574656064820152601960fa1b608482015260a401610192565b60a089015160208a0151909750610fe7908660045b602002015161149a565b60208a0151865160608801519296506110099261100491906123ab565b61149a565b9150600089602001518361101d9190612393565b9050600085881161102f576000611039565b61103986896123ab565b9050818111156110505761104d82826123ab565b94505b85156111125761106033876118d2565b841561107857846005546110749190612393565b6005555b611082868a612393565b60a08c0181905260c08c0183905260608c018490528b51808c5560208d015160018d015560408d015160028d015560038c018590556080808e015160048e015560058d0183905560068d018590558901516110e1928c908c9089611c52565b87600760008282546110f391906123ab565b92505081905550816007600082825461110c9190612393565b90915550505b5050505050505050505050505050565b6000610d1e60025490565b6000610d1e61171a565b61113f612106565b600061114c8585856117c9565b95945050505050565b60606004805461054890612343565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156111e65760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610192565b6111f33385858403611227565b5060019392505050565b60006105d8338484611a82565b6000611216838361134c565b611220838361149a565b9392505050565b6001600160a01b0383166112895760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610192565b6001600160a01b0382166112ea5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610192565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600181101561139d5760405162461bcd60e51b815260206004820152601960248201527f5374616b65206c656e67746820697320746f6f20736d616c6c000000000000006044820152606401610192565b611f648111156113ef5760405162461bcd60e51b815260206004820152601960248201527f5374616b65206c656e67746820697320746f6f206c61726765000000000000006044820152606401610192565b6127108210156114415760405162461bcd60e51b815260206004820152601c60248201527f5072696e6369706c65206973206e6f74206869676820656e6f756768000000006044820152606401610192565b6c01431e0fae6d7217caa00000008211156114965760405162461bcd60e51b81526020600482015260156024820152740a0e4d2dcc6d2e0d8ca40d2e640e8dede40d0d2ced605b1b6044820152606401610192565b5050565b6000806114a86064846123ee565b905060006114b4611cb0565b90506000806000805b601684101561157357618ead8611156114e55750618ead6114de81876123ab565b95506114ea565b506000945b8484601781106114fc576114fc6123c2565b60200201519250600060648a61151286856123ee565b61151c91906123ee565b611526919061240d565b905061153a670de0b6b3a7640000806123ee565b611544908261240d565b92506115508389612393565b975061155d856001612393565b94508660000361156d5750611573565b506114bd565b50505050505092915050565b600061158961171a565b90506000611598826001612393565b9050806115a53387611e89565b60006006600081546115b69061242f565b9190508190559050600b6000336001600160a01b03166001600160a01b031681526020019081526020016000206040518060e0016040528083815260200189815260200185815260200184815260200188815260200160008152602001878152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050600181336001600160a01b03167f8fdc0cbd36b6db294b289125f705adcfb3320fb50626f3de2f09632811b2c458868a8c8b6040516116e0949392919093845260208401929092526040830152606082015260800190565b60405180910390a4600a546116f6906001612393565b600a5550505050505050565b600060075461171060025490565b610d1e9190612393565b60006201518061172e6363a39e00426123ab565b610d1e919061240d565b825482146117815760405162461bcd60e51b81526020600482015260166024820152756d795374616b654964206e6f7420696e207374616b6560501b6044820152606401610192565b8254815260018301546020820152600283015460408201526003830154606082015260048301546080820152600583015460a082015260069092015460c09092019190915250565b6117d1612106565b600183101561182c5760405162461bcd60e51b815260206004820152602160248201527f7374616b652064617973206d7573742062652067726561746572207468616e206044820152603160f81b6064820152608401610192565b600061183661171a565b905060006118448587612393565b90506000868510156118565786611858565b845b9050600061186682846123ab565b905060008483111561187a5750600061189e565b838510156118915761188c83866123ab565b61189b565b61189b83856123ab565b90505b6040805160c08101825295865260208601999099529784019590955250606082015260808101949094525060a08301525090565b6001600160a01b0382166119285760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610192565b806002600082825461193a9190612393565b90915550506001600160a01b03821660009081526020819052604081208054839290611967908490612393565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60a081015160408201516080830151606084015160009384938493849384926119db9290916117c9565b606081015181519192501115611a39576119f487611fcf565b93508660200151841115611a1a5760028760200151611a13919061240d565b9250611a2d565b838760200151611a2a91906123ab565b92505b82955060009450611a78565b6020870151611a4a90826004610fdd565b9450611a568583612393565b60a0880152600060c08801526020870151611a719086612393565b9550600093505b5050509193909250565b6001600160a01b038316611ae65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610192565b6001600160a01b038216611b485760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610192565b6001600160a01b03831660009081526020819052604090205481811015611bc05760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610192565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611bf7908490612393565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c4391815260200190565b60405180910390a35b50505050565b60408051868152602081018690529081018490526060810183905260808101829052600290879033907f464fbd494c736696c02460d8c6c817142a314d106db57638db0977eedacbf1899060a00160405180910390a4505050505050565b611cb8612124565b604051806102e001604052806d06bfd3a68f166e7321aa1baf65cd81526020016d0819646178815156f532879f46f781526020016d0acc85d74b57171e9c435f7f094981526020016d0ed938080797bfca16dca34eacc481526020016d143f7af3ad434b5964fe530e316981526020016d1aff4e9a3c59b9cc86a86ebd973781526020016d2318b2fbb4db0b237bdaf65cde2e81526020016d2c8ba81816c73f5e4495e9ec064e81526020016d37582def621e567ce0d9496b0f9881526020016d437e448196e0507f50a514d9fa0a81526020016d50fdebceb50d2d6593f94c38c5a681526020016d5fd723d6bca4ed2faad5ef87726b81526020016d7009ec99ada78fdd953afec6005981526020016d819646178815156f532879f46f7181526020016d947c30504bed7de4e49e6112bfb181526020016da8bbab43f930c93e499cb420f11b81526020016dbe54b6f28fdef77b8223731f03ad81526020016dd547535c0ff8089c8e329e0cf76a81526020016ded938080797bfca16dca34eacc4f81526020016e0107393e5fcc6ad38a20ea37b8825d81526020016e0122388cfa08c48d56a792a676199581526020016e013e916c4f2e892a0701c3812391f581526020016000815250905090565b6001600160a01b038216611ee95760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610192565b6001600160a01b03821660009081526020819052604090205481811015611f5d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610192565b6001600160a01b0383166000908152602081905260408120838303905560028054849290611f8c9084906123ab565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161133f565b600080611fe98360400151846080015185606001516117c9565b905060008060006064905060008082886080015161200791906123ee565b90506000811161201f5761201c8360016123ee565b90505b6020860151865110612068576020860151865103612049576120428360016123ee565b9150612068565b60208601518651849161205b916123ab565b61206591906123ee565b91505b8061207384846123ee565b61207d919061240d565b94506032851161209057603293506120bc565b6032851180156120a05750606485105b156120b7576120b08560646123ab565b93506120bc565b600093505b60648489602001516120ce91906123ee565b6120d8919061240d565b9650600087116120e757600096505b87602001518711156120fb57876020015196505b505050505050919050565b6040518060c001604052806006906020820280368337509192915050565b604051806102e001604052806017906020820280368337509192915050565b60005b8381101561215e578181015183820152602001612146565b83811115611c4c5750506000910152565b60008251612181818460208701612143565b7f3a20596f752063616e206e6f742073656e642045544820746f20746869732063920191825250676f6e74726163742160c01b6020820152602801919050565b60208152600082518060208401526121e0816040850160208701612143565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461220b57600080fd5b919050565b6000806040838503121561222357600080fd5b61222c836121f4565b946020939093013593505050565b6000806040838503121561224d57600080fd5b50508035926020909101359150565b60008060006060848603121561227157600080fd5b61227a846121f4565b9250612288602085016121f4565b9150604084013590509250925092565b6000602082840312156122aa57600080fd5b611220826121f4565b6000806000606084860312156122c857600080fd5b505081359360208301359350604090920135919050565b60c08101818360005b60068110156123075781518352602092830192909101906001016122e8565b50505092915050565b6000806040838503121561232357600080fd5b61232c836121f4565b915061233a602084016121f4565b90509250929050565b600181811c9082168061235757607f821691505b60208210810361237757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600082198211156123a6576123a661237d565b500190565b6000828210156123bd576123bd61237d565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008160001904831182151516156124085761240861237d565b500290565b60008261242a57634e487b7160e01b600052601260045260246000fd5b500490565b6000600182016124415761244161237d565b506001019056fea2646970667358221220bd4db68575faa397f8921486bf919774ac268e61c6330d36e646e3b79f1dc5d764736f6c634300080d0033

Deployed Bytecode Sourcemap

268:860:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;977:1;960:14;1034:6;:4;:6::i;:::-;1017:68;;;;;;;;:::i;:::-;;;;;;;;;;;;;989:98;;;;;-1:-1:-1;;;989:98:5;;;;;;;;:::i;:::-;;;;;;;;;;268:860;;;;;;;;;1750:105:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3927:169;;;;;;;;;;-1:-1:-1;3927:169:1;;;;;:::i;:::-;;:::i;:::-;;;1788:14:6;;1781:22;1763:41;;1751:2;1736:18;3927:169:1;1623:187:6;5847:1226:4;;;;;;;;;;-1:-1:-1;5847:1226:4;;;;;:::i;:::-;;:::i;39302:403::-;;;;;;;;;;;;;:::i;:::-;;;2214:25:6;;;2202:2;2187:18;39302:403:4;2068:177:6;20354:1016:4;;;;;;;;;;;;;:::i;:::-;;;;2621:25:6;;;2677:2;2662:18;;2655:34;;;;2705:18;;;2698:34;;;;2763:2;2748:18;;2741:34;;;;2806:3;2791:19;;2784:35;;;;2850:3;2835:19;;2828:35;2894:3;2879:19;;2872:35;2938:3;2923:19;;2916:35;2982:3;2967:19;;2960:35;2608:3;2593:19;20354:1016:4;2250:751:6;13406:5983:4;;;;;;;;;;-1:-1:-1;13406:5983:4;;;;;:::i;:::-;;:::i;4578:492:1:-;;;;;;;;;;-1:-1:-1;4578:492:1;;;;;:::i;:::-;;:::i;21511:162:4:-;;;;;;;;;;-1:-1:-1;21511:162:4;;;;;:::i;:::-;-1:-1:-1;;;;;21639:19:4;21601:7;21639:19;;;:6;:19;;;;;:26;;21511:162;2722:93:1;;;;;;;;;;-1:-1:-1;2722:93:1;;2805:2;3672:36:6;;3660:2;3645:18;2722:93:1;3530:184:6;4470:45:4;;;;;;;;;;-1:-1:-1;4470:45:4;;;;;:::i;:::-;;:::i;:::-;;;;4034:25:6;;;4090:2;4075:18;;4068:34;;;;4118:18;;;4111:34;;;;4176:2;4161:18;;4154:34;;;;4219:3;4204:19;;4197:35;4263:3;4248:19;;4241:35;4307:3;4292:19;;4285:35;4021:3;4006:19;4470:45:4;3719:607:6;5479:215:1;;;;;;;;;;-1:-1:-1;5479:215:1;;;;;:::i;:::-;;:::i;19448:139:4:-;;;;;;;;;;;;;:::i;7486:5586::-;;;;;;;;;;-1:-1:-1;7486:5586:4;;;;;:::i;:::-;;:::i;40200:323::-;;;;;;;;;;;;;:::i;19706:126::-;;;;;;;;;;;;;:::i;3051:127:1:-;;;;;;;;;;-1:-1:-1;3051:127:1;;;;;:::i;:::-;-1:-1:-1;;;;;3152:18:1;3125:7;3152:18;;;;;;;;;;;;3051:127;22260:309:4;;;;;;;;;;-1:-1:-1;22260:309:4;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1974:109:1:-;;;;;;;;;;;;;:::i;6197:413::-;;;;;;;;;;-1:-1:-1;6197:413:1;;;;;:::i;:::-;;:::i;3391:175::-;;;;;;;;;;-1:-1:-1;3391:175:1;;;;;:::i;:::-;;:::i;3629:151::-;;;;;;;;;;-1:-1:-1;3629:151:1;;;;;:::i;:::-;-1:-1:-1;;;;;3745:18:1;;;3718:7;3745:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3629:151;39788:319:4;;;;;;;;;;-1:-1:-1;40083:16:4;;39788:319;;22778:332;;;;;;;;;;-1:-1:-1;22778:332:4;;;;;:::i;:::-;;:::i;1750:105:1:-;1804:13;1837:10;1830:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1750:105;:::o;3927:169::-;4010:4;4027:39;766:10:0;4050:7:1;4059:6;4027:8;:39::i;:::-;-1:-1:-1;4084:4:1;3927:169;;;;:::o;5847:1226:4:-;6021:66;6059:15;6076:10;6021:37;:66::i;:::-;6145:24;6172:47;6191:15;6208:10;6172:18;:47::i;:::-;6145:74;-1:-1:-1;6280:21:4;6304:34;6323:15;6145:74;6304:34;:::i;:::-;6280:58;;6427:16;6407;;:36;6399:88;;;;-1:-1:-1;;;6399:88:4;;6269:2:6;6399:88:4;;;6251:21:6;6308:2;6288:18;;;6281:30;6347:34;6327:18;;;6320:62;-1:-1:-1;;;6398:18:6;;;6391:37;6445:19;;6399:88:4;6067:403:6;6399:88:4;6528:55;6540:15;6557:10;6569:13;6528:11;:55::i;:::-;6760:16;6741;;:35;;;;:::i;:::-;6722:16;:54;;;;6899:15;6873:22;;:41;;;;;;;:::i;:::-;;;;;;;;7010:13;6993;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;5847:1226:4:o;39302:403::-;39355:7;39595:14;39650:16;;39634:13;;39612:19;2968:12:1;;;2880:108;39612:19:4;:35;;;;:::i;:::-;:54;;;;:::i;:::-;39595:71;39302:403;-1:-1:-1;;39302:403:4:o;20354:1016::-;20427:20;20459:30;20500:20;20531:24;20566:23;20600:19;20630:23;20664:20;20695:24;20758:13;;20743:28;;20807:22;;20782:47;;20905:16;;20889:13;;20867:19;2968:12:1;;;2880:108;20867:19:4;:35;;;;:::i;:::-;:54;;;;:::i;:::-;20852:69;;20963:18;:16;:18::i;:::-;20944:37;;21010:16;;20992:34;;21051:13;:11;:13::i;:::-;21037:27;;21093:15;;21075:33;;21134:13;;21119:28;;21177:16;;21158:35;;20354:1016;;;;;;;;;:::o;13406:5983::-;13533:10;13493:30;13526:18;;;:6;:18;;;;;13563:17;;13526:18;;13563:22;13555:54;;;;-1:-1:-1;;;13555:54:4;;6807:2:6;13555:54:4;;;6789:21:6;6846:2;6826:18;;;6819:30;-1:-1:-1;;;6865:18:6;;;6858:49;6924:18;;13555:54:4;6605:343:6;13555:54:4;13641:17;;13628:30;;13620:65;;;;-1:-1:-1;;;13620:65:4;;7155:2:6;13620:65:4;;;7137:21:6;7194:2;7174:18;;;7167:30;-1:-1:-1;;;7213:18:6;;;7206:52;7275:18;;13620:65:4;6953:346:6;13620:65:4;13750:22;13775:24;;;;;;;;13785:1;13775:24;;;;13787:1;13775:24;;;;13789:1;13775:24;;;;13791:1;13775:24;;;;13793:1;13775:24;;;;13795:1;13775:24;;;;13797:1;13775:24;;;13750:49;;13812:52;13823:10;13834;13823:22;;;;;;;;:::i;:::-;;;;;;;;;;;13847:9;13858:5;13812:10;:52::i;:::-;13896:18;13929;13958:23;13984:1;13958:27;;13996:15;14516:23;14542:73;14562:5;:15;;;14579:5;:17;;;14598:5;:16;;;14542:19;:73::i;:::-;14890:11;;;;14876;;14516:99;;-1:-1:-1;;14872:3629:4;;;15082:5;:22;;;15059:5;:20;;;:45;;;;:::i;:::-;15039:16;;:66;;;;:::i;:::-;15020:16;:85;15311:22;;;;15208:1;;-1:-1:-1;15208:1:4;;-1:-1:-1;15293:41:4;;15299:10;;15293:5;:41::i;:::-;15412:5;:20;;;15395:13;;:37;;;;;;;:::i;:::-;;;;-1:-1:-1;;15545:22:4;;;;15519;:48;;:22;;:48;;15545:22;;15519:48;:::i;:::-;;;;-1:-1:-1;14872:3629:4;;-1:-1:-1;14872:3629:4;;15687:11;;;;15673;;:25;;15687:11;15673:25;:::i;:::-;15660:38;;15798:27;15819:5;15798:20;:27::i;:::-;15757:68;;-1:-1:-1;15757:68:4;-1:-1:-1;15757:68:4;-1:-1:-1;15882:11:4;;15878:2012;;16085:5;:22;;;16062:5;:20;;;:45;;;;:::i;:::-;16041:16;;:67;;;;;;;:::i;:::-;;;;;;;;16243:7;16223:16;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;16373:20:4;;;;16355:13;;:39;16352:125;;16436:5;:20;;;16418:13;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;16352:125:4;16650:5;:22;;;16624;;:48;16621:143;;16722:5;:22;;;16696;;:48;;;;;;;:::i;:::-;;;;-1:-1:-1;;16621:143:4;15878:2012;;;17092:15;17075:13;;:32;17071:116;;17148:15;17131:13;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;17071:116:4;17375:5;:22;;;17358:13;;:39;17354:130;;17438:5;:22;;;17421:13;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;17354:130:4;17757:5;:22;;;17731;;:48;17728:147;;17829:5;:22;;;17803;;:48;;;;;;;:::i;:::-;;;;-1:-1:-1;;17728:147:4;18063:15;;18059:431;;18317:29;18323:10;18335;18317:5;:29::i;:::-;18656:14;;18736:11;;;;;;18771:22;;;;18817:20;;;;;18861:22;;;;;18608:352;;;7723:25:6;;;7764:18;;;7757:34;;;;7807:18;;;7800:34;7850:18;;;7843:34;7908:3;7893:19;;7886:35;;;7937:19;;7930:35;;;18693:1:4;;18656:14;18631:10;;18608:352;;7695:19:6;18608:352:4;;;;;;;19041:17;;19021;;19041:21;;19061:1;;19041:21;:::i;:::-;19021:41;;19139:9;19125:10;:23;19121:102;;19190:10;19201:9;19190:21;;;;;;;;:::i;:::-;;;;;;;;;;;19165:10;19176;19165:22;;;;;;;;:::i;:::-;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19121:102;19233:10;:16;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;19233:16:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19364:13;;:17;;19233:16;19364:17;:::i;:::-;19348:13;:33;-1:-1:-1;;;;;;;;;;13406:5983:4:o;4578:492:1:-;4718:4;4735:36;4745:6;4753:9;4764:6;4735:9;:36::i;:::-;-1:-1:-1;;;;;4811:19:1;;4784:24;4811:19;;;:11;:19;;;;;;;;766:10:0;4811:33:1;;;;;;;;4863:26;;;;4855:79;;;;-1:-1:-1;;;4855:79:1;;8310:2:6;4855:79:1;;;8292:21:6;8349:2;8329:18;;;8322:30;8388:34;8368:18;;;8361:62;-1:-1:-1;;;8439:18:6;;;8432:38;8487:19;;4855:79:1;8108:404:6;4855:79:1;4970:57;4979:6;766:10:0;5020:6:1;5001:16;:25;4970:8;:57::i;:::-;-1:-1:-1;5058:4:1;;4578:492;-1:-1:-1;;;;4578:492:1:o;4470:45:4:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4470:45:4;;-1:-1:-1;4470:45:4;;;;;:::o;5479:215:1:-;766:10:0;5567:4:1;5616:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;5616:34:1;;;;;;;;;;5567:4;;5584:80;;5607:7;;5616:47;;5653:10;;5616:47;:::i;:::-;5584:8;:80::i;19448:139:4:-;19523:7;19561:18;:16;:18::i;:::-;19554:25;;19448:139;:::o;7486:5586::-;7616:10;7576:30;7609:18;;;:6;:18;;;;;7646:17;;7609:18;;7646:22;7638:51;;;;-1:-1:-1;;;7638:51:4;;8719:2:6;7638:51:4;;;8701:21:6;8758:2;8738:18;;;8731:30;-1:-1:-1;;;8777:18:6;;;8770:46;8833:18;;7638:51:4;8517:340:6;7638:51:4;7721:17;;7708:30;;7700:61;;;;-1:-1:-1;;;7700:61:4;;9064:2:6;7700:61:4;;;9046:21:6;9103:2;9083:18;;;9076:30;-1:-1:-1;;;9122:18:6;;;9115:48;9180:18;;7700:61:4;8862:342:6;7700:61:4;7826:22;7851:24;;;;;;;;7861:1;7851:24;;;;7863:1;7851:24;;;;7865:1;7851:24;;;;7867:1;7851:24;;;;7869:1;7851:24;;;;7871:1;7851:24;;;;7873:1;7851:24;;;7826:49;;7888:52;7899:10;7910;7899:22;;;;;;;;:::i;7888:52::-;8036:10;7996:30;8029:18;;;:6;:18;;;;;:30;;8048:10;;8029:30;;;;;;:::i;:::-;;;;;;;;;;;7996:63;;8091:24;8118:5;:22;;;8091:49;;8151:29;8183:5;:20;;;8151:52;;8241:23;8267:73;8287:5;:15;;;8304:5;:17;;;8323:5;:16;;;8267:19;:73::i;:::-;9024:11;;9120:15;;;;8241:99;;-1:-1:-1;8892:23:4;;;;;;9111:24;;9103:84;;;;-1:-1:-1;;;9103:84:4;;9411:2:6;9103:84:4;;;9393:21:6;9450:2;9430:18;;;9423:30;9489:34;9469:18;;;9462:62;-1:-1:-1;;;9540:18:6;;;9533:45;9595:19;;9103:84:4;9209:411:6;9103:84:4;9290:11;;;;9280:21;;;9272:73;;;;-1:-1:-1;;;9272:73:4;;9827:2:6;9272:73:4;;;9809:21:6;9866:2;9846:18;;;9839:30;9905:34;9885:18;;;9878:62;-1:-1:-1;;;9956:18:6;;;9949:37;10003:19;;9272:73:4;9625:403:6;9272:73:4;9524:11;;;;9515:20;;9507:98;;;;-1:-1:-1;;;9507:98:4;;10235:2:6;9507:98:4;;;10217:21:6;10274:2;10254:18;;;10247:30;10313:34;10293:18;;;10286:62;10384:34;10364:18;;;10357:62;-1:-1:-1;;;10435:19:6;;;10428:32;10477:19;;9507:98:4;10033:469:6;9507:98:4;9895:22;;;;10163;;;;9895;;-1:-1:-1;10144:55:4;;10187:8;10196:1;10187:11;;;;;10144:18;:55::i;:::-;10332:22;;;;10369:11;;10357;;;;10126:73;;-1:-1:-1;10313:69:4;;10357:23;;10369:11;10357:23;:::i;:::-;10313:18;:69::i;:::-;10291:91;;10393:37;10455:5;:22;;;10433:19;:44;;;;:::i;:::-;10393:84;;10912:36;10975:15;10951:21;:39;:87;;11037:1;10951:87;;;10994:39;11018:15;10994:21;:39;:::i;:::-;10912:126;;11087:32;11053:31;:66;11049:237;;;11208:66;11242:32;11208:31;:66;:::i;:::-;11193:81;;11049:237;11617:20;;11613:1452;;11705:34;11711:10;11723:15;11705:5;:34::i;:::-;11836:16;;11832:108;;11912:12;11893:16;;:31;;;;:::i;:::-;11874:16;:50;11832:108;12040:34;12059:15;12040:16;:34;:::i;:::-;12015:22;;;:59;;;12194:20;;;:56;;;12309:16;;;:25;;;25220:14;;25201:33;;;25280:22;;;;25245:24;;;:58;-1:-1:-1;25342:15:4;;;25314:17;;;:44;25369:18;;;:46;;;25456:17;;;;;25426:19;;;:48;25485:24;;;:58;;;25554:22;;;:54;;;12574:11;;;12499:265;;12613:16;;12649:21;;12730:19;12499:15;:265::i;:::-;12909:21;12892:13;;:38;;;;;;;:::i;:::-;;;;;;;;13021:32;13004:13;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;;11613:1452:4;7565:5507;;;;;;;;;;;;7486:5586;;:::o;40200:323::-;40247:7;40495:19;2968:12:1;;;2880:108;19706:126:4;19776:4;19811:13;:11;:13::i;22260:309::-;22405:14;;:::i;:::-;22443:23;22469:64;22489:12;22503:14;22519:13;22469:19;:64::i;:::-;22443:90;22260:309;-1:-1:-1;;;;;22260:309:4:o;1974:109:1:-;2030:13;2063:12;2056:19;;;;;:::i;6197:413::-;766:10:0;6290:4:1;6334:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6334:34:1;;;;;;;;;;6387:35;;;;6379:85;;;;-1:-1:-1;;;6379:85:1;;10709:2:6;6379:85:1;;;10691:21:6;10748:2;10728:18;;;10721:30;10787:34;10767:18;;;10760:62;-1:-1:-1;;;10838:18:6;;;10831:35;10883:19;;6379:85:1;10507:401:6;6379:85:1;6500:67;766:10:0;6523:7:1;6551:15;6532:16;:34;6500:8;:67::i;:::-;-1:-1:-1;6598:4:1;;6197:413;-1:-1:-1;;;6197:413:1:o;3391:175::-;3477:4;3494:42;766:10:0;3518:9:1;3529:6;3494:9;:42::i;22778:332:4:-;22897:16;22937:66;22975:15;22992:10;22937:37;:66::i;:::-;23025:47;23044:15;23061:10;23025:18;:47::i;:::-;23014:58;22778:332;-1:-1:-1;;;22778:332:4:o;9881:380:1:-;-1:-1:-1;;;;;10017:19:1;;10009:68;;;;-1:-1:-1;;;10009:68:1;;11115:2:6;10009:68:1;;;11097:21:6;11154:2;11134:18;;;11127:30;11193:34;11173:18;;;11166:62;-1:-1:-1;;;11244:18:6;;;11237:34;11288:19;;10009:68:1;10913:400:6;10009:68:1;-1:-1:-1;;;;;10096:21:1;;10088:68;;;;-1:-1:-1;;;10088:68:1;;11520:2:6;10088:68:1;;;11502:21:6;11559:2;11539:18;;;11532:30;11598:34;11578:18;;;11571:62;-1:-1:-1;;;11649:18:6;;;11642:32;11691:19;;10088:68:1;11318:398:6;10088:68:1;-1:-1:-1;;;;;10169:18:1;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10221:32;;2214:25:6;;;10221:32:1;;2187:18:6;10221:32:1;;;;;;;;9881:380;;;:::o;27283:483:4:-;707:1;27468:10;:28;;27460:66;;;;-1:-1:-1;;;27460:66:4;;11923:2:6;27460:66:4;;;11905:21:6;11962:2;11942:18;;;11935:30;12001:27;11981:18;;;11974:55;12046:18;;27460:66:4;11721:349:6;27460:66:4;758:4;27545:10;:28;;27537:66;;;;-1:-1:-1;;;27537:66:4;;12277:2:6;27537:66:4;;;12259:21:6;12316:2;12296:18;;;12289:30;12355:27;12335:18;;;12328:55;12400:18;;27537:66:4;12075:349:6;27537:66:4;906:5;27622:9;:29;;27614:70;;;;-1:-1:-1;;;27614:70:4;;12631:2:6;27614:70:4;;;12613:21:6;12670:2;12650:18;;;12643:30;12709;12689:18;;;12682:58;12757:18;;27614:70:4;12429:352:6;27614:70:4;963:4;27703:9;:29;;27695:63;;;;-1:-1:-1;;;27695:63:4;;12988:2:6;27695:63:4;;;12970:21:6;13027:2;13007:18;;;13000:30;-1:-1:-1;;;13046:18:6;;;13039:51;13107:18;;27695:63:4;12786:345:6;27695:63:4;27283:483;;:::o;28186:2209::-;28300:21;;28451:26;2026:3;28451:10;:26;:::i;:::-;28429:48;;28597:34;28634:24;:22;:24::i;:::-;28597:61;;28727:18;28760:27;28802:26;28843:15;28875:1478;847:2;28882:10;:28;28875:1478;;;1927:5;28931:11;:25;28927:351;;;-1:-1:-1;1927:5:4;29017:26;1927:5;29017:26;;:::i;:::-;;;28927:351;;;-1:-1:-1;29261:1:4;;28927:351;29390:18;29409:10;29390:30;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29737:32:4;2026:3;29853:9;29820:29;29390:30;29820:7;:29;:::i;:::-;29819:43;;;;:::i;:::-;29818:61;;;;:::i;:::-;29788:91;-1:-1:-1;29946:21:4;1868:4;;29946:21;:::i;:::-;29915:53;;:27;:53;:::i;:::-;29894:74;-1:-1:-1;30070:35:4;29894:74;30070:35;;:::i;:::-;;-1:-1:-1;30211:14:4;:10;30224:1;30211:14;:::i;:::-;30198:27;;30284:11;30299:1;30284:16;30280:62;;30321:5;;;30280:62;28912:1441;28875:1478;;;30365:22;;;;;;28186:2209;;;;:::o;25856:1283::-;26040:12;26055:13;:11;:13::i;:::-;26040:28;-1:-1:-1;26111:16:4;26130:8;26040:28;26137:1;26130:8;:::i;:::-;26111:27;-1:-1:-1;26111:27:4;26285:34;26291:10;26303:15;26285:5;:34::i;:::-;26387:18;26410:15;;26408:17;;;;;:::i;:::-;;;;;;;26387:38;;26496:6;:18;26503:10;-1:-1:-1;;;;;26496:18:4;-1:-1:-1;;;;;26496:18:4;;;;;;;;;;;;26534:232;;;;;;;;26562:10;26534:232;;;;26591:15;26534:232;;;;26625:8;26534:232;;;;26652:9;26534:232;;;;26680:10;26534:232;;;;26717:1;26534:232;;;;26738:13;26534:232;;;26496:281;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26924:1;26890:10;26857;-1:-1:-1;;;;;26832:211:4;;26941:8;26964:10;26989:15;27019:13;26832:211;;;;;;;;13902:25:6;;;13958:2;13943:18;;13936:34;;;;14001:2;13986:18;;13979:34;14044:2;14029:18;;14022:34;13889:3;13874:19;;13671:391;26832:211:4;;;;;;;;27114:13;;:17;;27130:1;27114:17;:::i;:::-;27098:13;:33;-1:-1:-1;;;;;;;25856:1283:4:o;23315:160::-;23390:7;23452:13;;23430:19;2968:12:1;;;2880:108;23430:19:4;:35;;;;:::i;23591:173::-;23662:23;23750:6;23717:29;544:10;23717:15;:29;:::i;:::-;23716:40;;;;:::i;24203:615::-;24403:16;;24390:29;;24382:64;;;;-1:-1:-1;;;24382:64:4;;14269:2:6;24382:64:4;;;14251:21:6;14308:2;14288:18;;;14281:30;-1:-1:-1;;;14327:18:6;;;14320:52;14389:18;;24382:64:4;14067:346:6;24382:64:4;24474:16;;24457:33;;24526:24;;;;24501:22;;;:49;24579:17;;;;24561:15;;;:35;24626:18;;;;24607:16;;;:37;24675:19;;;;24655:17;;;:39;24730:24;;;;24705:22;;;:49;24788:22;;;;;24765:20;;;;:45;;;;-1:-1:-1;24203:615:4:o;35933:1639::-;36057:14;;:::i;:::-;707:1;36168:10;:28;;36160:74;;;;-1:-1:-1;;;36160:74:4;;14620:2:6;36160:74:4;;;14602:21:6;14659:2;14639:18;;;14632:30;14698:34;14678:18;;;14671:62;-1:-1:-1;;;14749:18:6;;;14742:31;14790:19;;36160:74:4;14418:397:6;36160:74:4;36245:14;36262:13;:11;:13::i;:::-;36245:30;-1:-1:-1;36300:21:4;36324;36335:10;36324:8;:21;:::i;:::-;36300:45;;36453:22;36491:8;36478:9;:21;;:44;;36514:8;36478:44;;;36502:9;36478:44;36453:69;-1:-1:-1;36580:20:4;36603:30;36453:69;36603:13;:30;:::i;:::-;36580:53;;36644:20;36975:6;36958:14;:23;36954:424;;;-1:-1:-1;37231:1:4;36954:424;;;37290:13;37280:6;:23;;:86;;37342:23;37351:14;37342:6;:23;:::i;:::-;37280:86;;;37307:30;37323:14;37307:13;:30;:::i;:::-;37265:101;;36954:424;37390:174;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37390:174:4;;;;;;;;;;;-1:-1:-1;37390:174:4;;;;-1:-1:-1;37390:174:4;35933:1639::o;8120:399:1:-;-1:-1:-1;;;;;8204:21:1;;8196:65;;;;-1:-1:-1;;;8196:65:1;;15022:2:6;8196:65:1;;;15004:21:6;15061:2;15041:18;;;15034:30;15100:33;15080:18;;;15073:61;15151:18;;8196:65:1;14820:355:6;8196:65:1;8352:6;8336:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8369:18:1;;:9;:18;;;;;;;;;;:28;;8391:6;;8369:9;:28;;8391:6;;8369:28;:::i;:::-;;;;-1:-1:-1;;8413:37:1;;2214:25:6;;;-1:-1:-1;;;;;8413:37:1;;;8430:1;;8413:37;;2202:2:6;2187:18;8413:37:1;;;;;;;27283:483:4;;:::o;32809:2433::-;33186:22;;;;33265:15;;;;33282:17;;;;33301:16;;;;32911:18;;;;;;;;;;33245:73;;33265:15;;33245:19;:73::i;:::-;33978:11;;;;33964;;33219:99;;-1:-1:-1;;33960:1275:4;;;34061:24;34079:5;34061:17;:24::i;:::-;34051:34;;34114:5;:22;;;34104:7;:32;34100:394;;;34295:1;34270:5;:22;;;:26;;;;:::i;:::-;34251:45;;34100:394;;;34470:7;34445:5;:22;;;:32;;;;:::i;:::-;34425:53;;34100:394;34626:16;34613:29;;34675:1;34657:19;;33960:1275;;;34804:22;;;;34785:55;;34828:8;34837:1;34828:11;;34785:55;34767:73;-1:-1:-1;34937:34:4;34767:73;34937:16;:34;:::i;:::-;34912:22;;;:59;35067:1;35044:20;;;:24;35175:22;;;;35157:40;;:15;:40;:::i;:::-;35144:53;;35222:1;35212:11;;33960:1275;33002:2240;;;32809:2433;;;;;:::o;7100:733:1:-;-1:-1:-1;;;;;7240:20:1;;7232:70;;;;-1:-1:-1;;;7232:70:1;;15382:2:6;7232:70:1;;;15364:21:6;15421:2;15401:18;;;15394:30;15460:34;15440:18;;;15433:62;-1:-1:-1;;;15511:18:6;;;15504:35;15556:19;;7232:70:1;15180:401:6;7232:70:1;-1:-1:-1;;;;;7321:23:1;;7313:71;;;;-1:-1:-1;;;7313:71:1;;15788:2:6;7313:71:1;;;15770:21:6;15827:2;15807:18;;;15800:30;15866:34;15846:18;;;15839:62;-1:-1:-1;;;15917:18:6;;;15910:33;15960:19;;7313:71:1;15586:399:6;7313:71:1;-1:-1:-1;;;;;7481:17:1;;7457:21;7481:17;;;;;;;;;;;7517:23;;;;7509:74;;;;-1:-1:-1;;;7509:74:1;;16192:2:6;7509:74:1;;;16174:21:6;16231:2;16211:18;;;16204:30;16270:34;16250:18;;;16243:62;-1:-1:-1;;;16321:18:6;;;16314:36;16367:19;;7509:74:1;15990:402:6;7509:74:1;-1:-1:-1;;;;;7619:17:1;;;:9;:17;;;;;;;;;;;7639:22;;;7619:42;;7683:20;;;;;;;;:30;;7655:6;;7619:9;7683:30;;7655:6;;7683:30;:::i;:::-;;;;;;;;7748:9;-1:-1:-1;;;;;7731:35:1;7740:6;-1:-1:-1;;;;;7731:35:1;;7759:6;7731:35;;;;2214:25:6;;2202:2;2187:18;;2068:177;7731:35:1;;;;;;;;7779:46;7221:612;7100:733;;;:::o;5075:594:4:-;5328:333;;;16656:25:6;;;16712:2;16697:18;;16690:34;;;16740:18;;;16733:34;;;16798:2;16783:18;;16776:34;;;16841:3;16826:19;;16819:35;;;5462:1:4;;5412:7;;5354:10;;5328:333;;16643:3:6;16628:19;5328:333:4;;;;;;;5075:594;;;;;;:::o;37782:1453::-;37854:31;;:::i;:::-;38025:1165;;;;;;;;38059:33;38025:1165;;;;38110:33;38025:1165;;;;38160:33;38025:1165;;;;38210:33;38025:1165;;;;38260:33;38025:1165;;;;38310:33;38025:1165;;;;38360:33;38025:1165;;;;38410:33;38025:1165;;;;38460:34;38025:1165;;;;38511:34;38025:1165;;;;38562:34;38025:1165;;;;38613:34;38025:1165;;;;38664:34;38025:1165;;;;38715:34;38025:1165;;;;38766:34;38025:1165;;;;38817:34;38025:1165;;;;38868:34;38025:1165;;;;38919:34;38025:1165;;;;38970:34;38025:1165;;;;39021:34;38025:1165;;;;39072:34;38025:1165;;;;39123:34;38025:1165;;;;39174:1;38025:1165;;;;;37782:1453;:::o;8852:591:1:-;-1:-1:-1;;;;;8936:21:1;;8928:67;;;;-1:-1:-1;;;8928:67:1;;17067:2:6;8928:67:1;;;17049:21:6;17106:2;17086:18;;;17079:30;17145:34;17125:18;;;17118:62;-1:-1:-1;;;17196:18:6;;;17189:31;17237:19;;8928:67:1;16865:397:6;8928:67:1;-1:-1:-1;;;;;9095:18:1;;9070:22;9095:18;;;;;;;;;;;9132:24;;;;9124:71;;;;-1:-1:-1;;;9124:71:1;;17469:2:6;9124:71:1;;;17451:21:6;17508:2;17488:18;;;17481:30;17547:34;17527:18;;;17520:62;-1:-1:-1;;;17598:18:6;;;17591:32;17640:19;;9124:71:1;17267:398:6;9124:71:1;-1:-1:-1;;;;;9231:18:1;;:9;:18;;;;;;;;;;9252:23;;;9231:44;;9297:12;:22;;9269:6;;9231:9;9297:22;;9269:6;;9297:22;:::i;:::-;;;;-1:-1:-1;;9337:37:1;;2214:25:6;;;9363:1:1;;-1:-1:-1;;;;;9337:37:1;;;;;2202:2:6;2187:18;9337:37:1;2068:177:6;30881:1889:4;30979:21;31084:23;31110:73;31130:5;:15;;;31147:5;:17;;;31166:5;:16;;;31110:19;:73::i;:::-;31084:99;;31194:11;31220:15;31250:20;31273:3;31250:26;;31287:22;31324;31369:12;31349:5;:17;;;:32;;;;:::i;:::-;31324:57;;31473:1;31455:14;:19;31451:128;;31508:16;31512:12;31508:1;:16;:::i;:::-;31491:33;;31451:128;31607:11;;;;31593;;:25;31589:349;;31724:11;;;;31709;;:26;31705:233;;31770:16;31774:12;31770:1;:16;:::i;:::-;31752:35;;31705:233;;;31899:11;;;;31885;;31914:12;;31885:25;;;:::i;:::-;31884:42;;;;:::i;:::-;31867:59;;31705:233;32020:14;31987:29;32004:12;31987:14;:29;:::i;:::-;31986:48;;;;:::i;:::-;31980:54;;32121:2;32114:3;:9;32110:177;;32150:2;32140:12;;32110:177;;;32180:2;32174:3;:8;:21;;;;;32192:3;32186;:9;32174:21;32170:117;;;32222:9;32228:3;32222;:9;:::i;:::-;32212:19;;32170:117;;;32274:1;32264:11;;32170:117;32395:3;32384:7;32359:5;:22;;;:32;;;;:::i;:::-;32358:40;;;;:::i;:::-;32342:56;;32472:1;32455:13;:18;32451:68;;32506:1;32490:17;;32451:68;32639:5;:22;;;32623:13;:38;32619:109;;;32694:5;:22;;;32678:38;;32619:109;32740:22;;;;;;30881:1889;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:258:6:-;86:1;96:113;110:6;107:1;104:13;96:113;;;186:11;;;180:18;167:11;;;160:39;132:2;125:10;96:113;;;227:6;224:1;221:13;218:48;;;-1:-1:-1;;262:1:6;244:16;;237:27;14:258::o;277:516::-;509:3;547:6;541:13;563:53;609:6;604:3;597:4;589:6;585:17;563:53;:::i;:::-;677:34;638:16;;663:49;;;-1:-1:-1;;;;739:4:6;728:16;;721:36;784:2;773:14;;277:516;-1:-1:-1;277:516:6:o;798:383::-;947:2;936:9;929:21;910:4;979:6;973:13;1022:6;1017:2;1006:9;1002:18;995:34;1038:66;1097:6;1092:2;1081:9;1077:18;1072:2;1064:6;1060:15;1038:66;:::i;:::-;1165:2;1144:15;-1:-1:-1;;1140:29:6;1125:45;;;;1172:2;1121:54;;798:383;-1:-1:-1;;798:383:6:o;1186:173::-;1254:20;;-1:-1:-1;;;;;1303:31:6;;1293:42;;1283:70;;1349:1;1346;1339:12;1283:70;1186:173;;;:::o;1364:254::-;1432:6;1440;1493:2;1481:9;1472:7;1468:23;1464:32;1461:52;;;1509:1;1506;1499:12;1461:52;1532:29;1551:9;1532:29;:::i;:::-;1522:39;1608:2;1593:18;;;;1580:32;;-1:-1:-1;;;1364:254:6:o;1815:248::-;1883:6;1891;1944:2;1932:9;1923:7;1919:23;1915:32;1912:52;;;1960:1;1957;1950:12;1912:52;-1:-1:-1;;1983:23:6;;;2053:2;2038:18;;;2025:32;;-1:-1:-1;1815:248:6:o;3006:328::-;3083:6;3091;3099;3152:2;3140:9;3131:7;3127:23;3123:32;3120:52;;;3168:1;3165;3158:12;3120:52;3191:29;3210:9;3191:29;:::i;:::-;3181:39;;3239:38;3273:2;3262:9;3258:18;3239:38;:::i;:::-;3229:48;;3324:2;3313:9;3309:18;3296:32;3286:42;;3006:328;;;;;:::o;3339:186::-;3398:6;3451:2;3439:9;3430:7;3426:23;3422:32;3419:52;;;3467:1;3464;3457:12;3419:52;3490:29;3509:9;3490:29;:::i;4331:316::-;4408:6;4416;4424;4477:2;4465:9;4456:7;4452:23;4448:32;4445:52;;;4493:1;4490;4483:12;4445:52;-1:-1:-1;;4516:23:6;;;4586:2;4571:18;;4558:32;;-1:-1:-1;4637:2:6;4622:18;;;4609:32;;4331:316;-1:-1:-1;4331:316:6:o;4652:495::-;4832:3;4817:19;;4821:9;4913:6;4790:4;4947:194;4961:4;4958:1;4955:11;4947:194;;;5020:13;;5008:26;;5057:4;5081:12;;;;5116:15;;;;4981:1;4974:9;4947:194;;;4951:3;;;4652:495;;;;:::o;5152:260::-;5220:6;5228;5281:2;5269:9;5260:7;5256:23;5252:32;5249:52;;;5297:1;5294;5287:12;5249:52;5320:29;5339:9;5320:29;:::i;:::-;5310:39;;5368:38;5402:2;5391:9;5387:18;5368:38;:::i;:::-;5358:48;;5152:260;;;;;:::o;5417:380::-;5496:1;5492:12;;;;5539;;;5560:61;;5614:4;5606:6;5602:17;5592:27;;5560:61;5667:2;5659:6;5656:14;5636:18;5633:38;5630:161;;5713:10;5708:3;5704:20;5701:1;5694:31;5748:4;5745:1;5738:15;5776:4;5773:1;5766:15;5630:161;;5417:380;;;:::o;5802:127::-;5863:10;5858:3;5854:20;5851:1;5844:31;5894:4;5891:1;5884:15;5918:4;5915:1;5908:15;5934:128;5974:3;6005:1;6001:6;5998:1;5995:13;5992:39;;;6011:18;;:::i;:::-;-1:-1:-1;6047:9:6;;5934:128::o;6475:125::-;6515:4;6543:1;6540;6537:8;6534:34;;;6548:18;;:::i;:::-;-1:-1:-1;6585:9:6;;6475:125::o;7304:127::-;7365:10;7360:3;7356:20;7353:1;7346:31;7396:4;7393:1;7386:15;7420:4;7417:1;7410:15;7976:127;8037:10;8032:3;8028:20;8025:1;8018:31;8068:4;8065:1;8058:15;8092:4;8089:1;8082:15;13136:168;13176:7;13242:1;13238;13234:6;13230:14;13227:1;13224:21;13219:1;13212:9;13205:17;13201:45;13198:71;;;13249:18;;:::i;:::-;-1:-1:-1;13289:9:6;;13136:168::o;13309:217::-;13349:1;13375;13365:132;;13419:10;13414:3;13410:20;13407:1;13400:31;13454:4;13451:1;13444:15;13482:4;13479:1;13472:15;13365:132;-1:-1:-1;13511:9:6;;13309:217::o;13531:135::-;13570:3;13591:17;;;13588:43;;13611:18;;:::i;:::-;-1:-1:-1;13658:1:6;13647:13;;13531:135::o

Swarm Source

ipfs://bd4db68575faa397f8921486bf919774ac268e61c6330d36e646e3b79f1dc5d7
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.