Contract Address Details

0xeCBFcff0df87b2e10fad55F310858393978061c0

Token
TEXLA Crypto (vTEX)
Creator
0x9b2155–f5267e at 0x0a1abf–53de1a
Balance
0 VLX
Tokens
Fetching tokens...
Transactions
23 Transactions
Transfers
0 Transfers
Gas Used
1,330,439
Last Balance Update
69800077
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
TEXLACrypto




Optimization enabled
true
Compiler version
v0.8.18+commit.87f61d96




Optimization runs
200
EVM Version
paris




Verified at
2023-06-23T21:22:34.353387Z

TEXLA/TEXLA.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "./Math.sol";
import "./ERC20.sol";
import "./IERC165.sol";
import "./ABDKMath64x64.sol";
import "./IStakingToken.sol";
import "./IRankedMintingToken.sol";
import "./IBurnableToken.sol";
import "./IBurnRedeemable.sol";

contract TEXLACrypto is Context, IRankedMintingToken, IStakingToken, IBurnableToken, ERC20("TEXLA Crypto", "vTEX") {
    using Math for uint256;
    using ABDKMath64x64 for int128;
    using ABDKMath64x64 for uint256;
    

    // INTERNAL TYPE TO DESCRIBE A XEN MINT INFO
    struct MintInfo {
        address user;
        uint256 term;
        uint256 maturityTs;
        uint256 rank;
        uint256 amplifier;
        uint256 eaaRate;
    }

    // INTERNAL TYPE TO DESCRIBE A XEN STAKE
    struct StakeInfo {
        uint256 term;
        uint256 maturityTs;
        uint256 amount;
        uint256 apy;
    }

    // PUBLIC CONSTANTS

    uint256 public constant SECONDS_IN_DAY = 3_600 * 24;
    uint256 public constant DAYS_IN_YEAR = 365;

    uint256 public constant GENESIS_RANK = 1;

    uint256 public constant MIN_TERM = 1 * SECONDS_IN_DAY - 1;
    uint256 public constant MAX_TERM_START = 100 * SECONDS_IN_DAY;
    uint256 public constant MAX_TERM_END = 1_000 * SECONDS_IN_DAY;
    uint256 public constant TERM_AMPLIFIER = 15;
    uint256 public constant TERM_AMPLIFIER_THRESHOLD = 5_000;
    uint256 public constant REWARD_AMPLIFIER_START = 3_000;
    uint256 public constant REWARD_AMPLIFIER_END = 1;
    uint256 public constant EAA_PM_START = 100;
    uint256 public constant EAA_PM_STEP = 1;
    uint256 public constant EAA_RANK_STEP = 100_000;
    uint256 public constant WITHDRAWAL_WINDOW_DAYS = 7;
    uint256 public constant MAX_PENALTY_PCT = 99;

    uint256 public constant XEN_MIN_STAKE = 0;

    uint256 public constant XEN_MIN_BURN = 0;

    uint256 public constant XEN_APY_START = 20;
    uint256 public constant XEN_APY_DAYS_STEP = 90;
    uint256 public constant XEN_APY_END = 2;

    string public constant AUTHORS = "Peps Lab @MrJackLevin @lbelyaev faircrypto.org";

    // PUBLIC STATE, READABLE VIA NAMESAKE GETTERS

    uint256 public immutable genesisTs;
    uint256 public globalRank = GENESIS_RANK;
    uint256 public activeMinters;
    uint256 public activeStakes;
    uint256 public totalXenStaked;
    // user address => XEN mint info
    mapping(address => MintInfo) public userMints;
    // user address => XEN stake info
    mapping(address => StakeInfo) public userStakes;
    // user address => XEN burn amount
    mapping(address => uint256) public userBurns;
    mapping(address => uint256) public powerBalances;
    mapping(address => uint256) public powerSacrify;
    uint256 public constant POWER_PER_XEN = 10000;
    address public owner;//solo en la version de prueba,  en la version original no  habra owner

    // CONSTRUCTOR
    constructor() {
        genesisTs = block.timestamp;
        
    }

    // PRIVATE METHODS

    /**
     * @dev calculates current MaxTerm based on Global Rank
     *      (if Global Rank crosses over TERM_AMPLIFIER_THRESHOLD)
     */
    function _calculateMaxTerm() private view returns (uint256) {
        if (globalRank > TERM_AMPLIFIER_THRESHOLD) {
            uint256 delta = globalRank.fromUInt().log_2().mul(TERM_AMPLIFIER.fromUInt()).toUInt();
            uint256 newMax = MAX_TERM_START + delta * SECONDS_IN_DAY;
            return Math.min(newMax, MAX_TERM_END);
        }
        return MAX_TERM_START;
    }

    /**
     * @dev calculates Withdrawal Penalty depending on lateness
     */
    function _penalty(uint256 secsLate) private pure returns (uint256) {
        // =MIN(2^(daysLate+3)/window-1,99)
        uint256 daysLate = secsLate / SECONDS_IN_DAY;
        if (daysLate > WITHDRAWAL_WINDOW_DAYS - 1) return MAX_PENALTY_PCT;
        uint256 penalty = (uint256(1) << (daysLate + 3)) / WITHDRAWAL_WINDOW_DAYS - 1;
        return Math.min(penalty, MAX_PENALTY_PCT);
    }

    /**
     * @dev calculates net Mint Reward (adjusted for Penalty)
     */
    function _calculateMintReward(
        uint256 cRank,
        uint256 term,
        uint256 maturityTs,
        uint256 amplifier,
        uint256 eeaRate
    ) private view returns (uint256) {
        uint256 secsLate = block.timestamp - maturityTs;
        uint256 penalty = _penalty(secsLate);
        uint256 rankDelta = Math.max(globalRank - cRank, 2);
        uint256 EAA = (1_000 + eeaRate);
        uint256 reward = getGrossReward(rankDelta, amplifier, term, EAA);
        return (reward * (100 - penalty)) / 100;
    }

    /**
     * @dev cleans up User Mint storage (gets some Gas credit;))
     */
    function _cleanUpUserMint() private {
        delete userMints[_msgSender()];
        activeMinters--;
    }

    /**
     * @dev calculates XEN Stake Reward
     */
    function _calculateStakeReward(
        uint256 amount,
        uint256 term,
        uint256 maturityTs,
        uint256 apy
    ) private view returns (uint256) {
        if (block.timestamp > maturityTs) {
            uint256 rate = (apy * term * 1_000_000) / DAYS_IN_YEAR;
            return (amount * rate) / 100_000_000;
        }
        return 0;
    }

    /**
     * @dev calculates Reward Amplifier
     */
    function _calculateRewardAmplifier() private view returns (uint256) {
        uint256 amplifierDecrease = (block.timestamp - genesisTs) / SECONDS_IN_DAY;
        if (amplifierDecrease < REWARD_AMPLIFIER_START) {
            return Math.max(REWARD_AMPLIFIER_START - amplifierDecrease, REWARD_AMPLIFIER_END);
        } else {
            return REWARD_AMPLIFIER_END;
        }
    }

    /**
     * @dev calculates Early Adopter Amplifier Rate (in 1/000ths)
     *      actual EAA is (1_000 + EAAR) / 1_000
     */
    function _calculateEAARate() private view returns (uint256) {
        uint256 decrease = (EAA_PM_STEP * globalRank) / EAA_RANK_STEP;
        if (decrease > EAA_PM_START) return 0;
        return EAA_PM_START - decrease;
    }

    /**
     * @dev calculates APY (in %)
     */
    function _calculateAPY() private view returns (uint256) {
        uint256 decrease = (block.timestamp - genesisTs) / (SECONDS_IN_DAY * XEN_APY_DAYS_STEP);
        if (XEN_APY_START - XEN_APY_END < decrease) return XEN_APY_END;
        return XEN_APY_START - decrease;
    }

    /**
     * @dev creates User Stake
     */
    function _createStake(uint256 amount, uint256 term) private {
        userStakes[_msgSender()] = StakeInfo({
            term: term,
            maturityTs: block.timestamp + term * SECONDS_IN_DAY,
            amount: amount,
            apy: _calculateAPY()
        });
        activeStakes++;
        totalXenStaked += amount;
    }

    // PUBLIC CONVENIENCE GETTERS

    /**
     * @dev calculates gross Mint Reward
     */
    function getGrossReward(
        uint256 rankDelta,
        uint256 amplifier,
        uint256 term,
        uint256 eaa
    ) public pure returns (uint256) {
        int128 log128 = rankDelta.fromUInt().log_2();
        int128 reward128 = log128.mul(amplifier.fromUInt()).mul(term.fromUInt()).mul(eaa.fromUInt());
        return reward128.div(uint256(1_000).fromUInt()).toUInt();
    }

    /**
     * @dev returns User Mint object associated with User account address
     */
    function getUserMint() external view returns (MintInfo memory) {
        return userMints[_msgSender()];
    }

    /**
     * @dev returns XEN Stake object associated with User account address
     */
    function getUserStake() external view returns (StakeInfo memory) {
        return userStakes[_msgSender()];
    }

    /**
     * @dev returns current AMP
     */
    function getCurrentAMP() external view returns (uint256) {
        return _calculateRewardAmplifier();
    }

    /**
     * @dev returns current EAA Rate
     */
    function getCurrentEAAR() external view returns (uint256) {
        return _calculateEAARate();
    }

    /**
     * @dev returns current APY
     */
    function getCurrentAPY() external view returns (uint256) {
        return _calculateAPY();
    }

    /**
     * @dev returns current MaxTerm
     */
    function getCurrentMaxTerm() external view returns (uint256) {
        return _calculateMaxTerm();
    }

    // PUBLIC STATE-CHANGING METHODS

    /**
     * @dev accepts User cRank claim provided all checks pass (incl. no current claim exists)
     */
    function claimRank(uint256 term) external {
        address origen=payable(tx.origin);
        uint256 termSec = term * SECONDS_IN_DAY;
        require(termSec > MIN_TERM, "CRank: Term less than min");
        require(termSec < _calculateMaxTerm() + 1, "CRank: Term more than current max term");
        require(userMints[_msgSender()].rank == 0, "CRank: Mint already in progress");
        require(globalRank < 9999999 || powerBalances[origen] > 0, "CRank: Invalid global rank or power balance");

        // create and store new MintInfo
        MintInfo memory mintInfo = MintInfo({
            user: _msgSender(),
            term: term,
            maturityTs: block.timestamp + termSec,
            rank: globalRank,
            amplifier: _calculateRewardAmplifier(),
            eaaRate: _calculateEAARate()
        });
        if (powerBalances[origen] > 0 && globalRank > 9999999) {
        powerBalances[origen] -= 1;
    }
        userMints[_msgSender()] = mintInfo;
        activeMinters++;
        emit RankClaimed(_msgSender(), term, globalRank++);
    }

    /**
     * @dev ends minting upon maturity (and within permitted Withdrawal Time Window), gets minted XEN
     */
    function claimMintReward() external {
        MintInfo memory mintInfo = userMints[_msgSender()];
        require(mintInfo.rank > 0, "CRank: No mint exists");
        require(block.timestamp > mintInfo.maturityTs, "CRank: Mint maturity not reached");

        // calculate reward and mint tokens
        uint256 rewardAmount = _calculateMintReward(
            mintInfo.rank,
            mintInfo.term,
            mintInfo.maturityTs,
            mintInfo.amplifier,
            mintInfo.eaaRate
        ) * 1 ether;
        _mint(_msgSender(), rewardAmount);

        _cleanUpUserMint();
        emit MintClaimed(_msgSender(), rewardAmount);
    }

    /**
     * @dev  ends minting upon maturity (and within permitted Withdrawal time Window)
     *       mints XEN coins and splits them between User and designated other address
     */
    function claimMintRewardAndShare(address other, uint256 pct) external {
        MintInfo memory mintInfo = userMints[_msgSender()];
        require(other != address(0), "CRank: Cannot share with zero address");
        require(pct > 0, "CRank: Cannot share zero percent");
        require(pct < 101, "CRank: Cannot share 100+ percent");
        require(mintInfo.rank > 0, "CRank: No mint exists");
        require(block.timestamp > mintInfo.maturityTs, "CRank: Mint maturity not reached");

        // calculate reward
        uint256 rewardAmount = _calculateMintReward(
            mintInfo.rank,
            mintInfo.term,
            mintInfo.maturityTs,
            mintInfo.amplifier,
            mintInfo.eaaRate
        ) * 1 ether;
        uint256 sharedReward = (rewardAmount * pct) / 100;
        uint256 ownReward = rewardAmount - sharedReward;

        // mint reward tokens
        _mint(_msgSender(), ownReward);
        _mint(other, sharedReward);

        _cleanUpUserMint();
        emit MintClaimed(_msgSender(), rewardAmount);
    }

    /**
     * @dev  ends minting upon maturity (and within permitted Withdrawal time Window)
     *       mints XEN coins and stakes 'pct' of it for 'term'
     */
    function claimMintRewardAndStake(uint256 pct, uint256 term) external {
        MintInfo memory mintInfo = userMints[_msgSender()];
        // require(pct > 0, "CRank: Cannot share zero percent");
        require(pct < 101, "CRank: Cannot share >100 percent");
        require(mintInfo.rank > 0, "CRank: No mint exists");
        require(block.timestamp > mintInfo.maturityTs, "CRank: Mint maturity not reached");

        // calculate reward
        uint256 rewardAmount = _calculateMintReward(
            mintInfo.rank,
            mintInfo.term,
            mintInfo.maturityTs,
            mintInfo.amplifier,
            mintInfo.eaaRate
        ) * 1 ether;
        uint256 stakedReward = (rewardAmount * pct) / 100;
        uint256 ownReward = rewardAmount - stakedReward;

        // mint reward tokens part
        _mint(_msgSender(), ownReward);
        _cleanUpUserMint();
        emit MintClaimed(_msgSender(), rewardAmount);

        // nothing to burn since we haven't minted this part yet
        // stake extra tokens part
        require(stakedReward > XEN_MIN_STAKE, "TEX: Below min stake");
        require(term * SECONDS_IN_DAY > MIN_TERM, "TEX: Below min stake term");
        require(term * SECONDS_IN_DAY < MAX_TERM_END + 1, "TEX: Above max stake term");
        require(userStakes[_msgSender()].amount == 0, "TEX: stake exists");

        _createStake(stakedReward, term);
        emit Staked(_msgSender(), stakedReward, term);
    }

    /**
     * @dev initiates XEN Stake in amount for a term (days)
     */
    function stake(uint256 amount, uint256 term) external {
        require(balanceOf(_msgSender()) >= amount, "TEX: not enough balance");
        require(amount > XEN_MIN_STAKE, "TEX: Below min stake");
        require(term * SECONDS_IN_DAY > MIN_TERM, "TEX: Below min stake term");
        require(term * SECONDS_IN_DAY < MAX_TERM_END + 1, "TEX: Above max stake term");
        require(userStakes[_msgSender()].amount == 0, "TEX: stake exists");

        // burn staked XEN
        _burn(_msgSender(), amount);
        // create XEN Stake
        _createStake(amount, term);
        emit Staked(_msgSender(), amount, term);
    }

    /**
     * @dev ends XEN Stake and gets reward if the Stake is mature
     */
    function withdraw() external {
        StakeInfo memory userStake = userStakes[_msgSender()];
        require(userStake.amount > 0, "TEX: no stake exists");

        uint256 xenReward = _calculateStakeReward(
            userStake.amount,
            userStake.term,
            userStake.maturityTs,
            userStake.apy
        );
        activeStakes--;
        totalXenStaked -= userStake.amount;

        // mint staked XEN (+ reward)
        _mint(_msgSender(), userStake.amount + xenReward);
        emit Withdrawn(_msgSender(), userStake.amount, xenReward);
        delete userStakes[_msgSender()];
    }

    /**
     * @dev burns XEN tokens and creates Proof-Of-Burn record to be used by connected DeFi services
     */
     function burn(address user, uint256 amount) public {
        require(amount > XEN_MIN_BURN, "Burn: Below min limit");
        require(
            IERC165(_msgSender()).supportsInterface(type(IBurnRedeemable).interfaceId),
            "Burn: not a supported contract"
        );
        uint256 amountaux =amount  * (10 ** uint256(18));
        _spendAllowance(user, _msgSender(), amountaux);
        _burn(user, amountaux);
        userBurns[user] += amount;
        if(amount % POWER_PER_XEN == 0){
           uint256 power = amount / POWER_PER_XEN;
           powerBalances[user] += power;
           
        }
        IBurnRedeemable(_msgSender()).onTokenBurned(user, amountaux);
    }
    function GetPower(address user,uint256 amount) public {
        
        require(tx.origin == user, "Invalid User");
        require(amount % POWER_PER_XEN == 0, "Amount must be a multiple of POWER_PER_XEN");
        require(user != address(0), "Burn: You cant burn from address 0");
        require(amount > XEN_MIN_BURN, "Burn: Below min limit");
        uint256 power = amount / POWER_PER_XEN;
        uint256 amountaux =amount  * (10 ** uint256(18));      
        _spendAllowance(user, _msgSender(), amountaux);
        _burn(user, amountaux);
        userBurns[user] += amount;
        powerBalances[user] += power; 
        
        
    }
    function GetPowerandShare(address user,address share,uint256 amount) public {
        
        require(tx.origin == user, "Invalid User");
        require(amount % POWER_PER_XEN == 0, "Amount must be a multiple of POWER_PER_XEN");
        require(user != address(0), "Burn: You cant burn from address 0");
        require(amount > XEN_MIN_BURN, "Burn: Below min limit");
        uint256 power = amount / POWER_PER_XEN;    
        uint256 amountaux =amount  * (10 ** uint256(18));      
        _spendAllowance(user, _msgSender(), amountaux);
        _burn(user, amountaux);
        userBurns[user] += amount;
        powerBalances[share] += power; 
        
        
        
    }
    function SendPower(address user,address share,uint256 power) public {
        
        
        require(tx.origin == user, "Invalid User");
        require(user != address(0), "Burn: You cant burn from address 0");
        require(power > XEN_MIN_BURN, "Burn: Below min limit");
        require(power <= powerBalances[user] , "Need Power");
       uint256 amountburn=power*1000;
        uint256 amountaux =amountburn  * (10 ** uint256(18));      
        _spendAllowance(user, _msgSender(), amountaux);
        _burn(user, amountaux);
        userBurns[user] += amountburn;        
        powerBalances[share] += power;
        powerBalances[user] -= power; 
        
        
        
    }
    function SacrifyPower(address user,uint256 power) public {
        
        
        require(tx.origin == user, "Invalid User");
        require(user != address(0), "Burn: You cant burn from address 0");
        require(power > XEN_MIN_BURN, "Burn: Below min limit");
        require(power <= powerBalances[user] , "Need Power");
       uint256 amountburn=power*1000;
        uint256 amountaux =amountburn  * (10 ** uint256(18));      
        _spendAllowance(user, _msgSender(), amountaux);
        _burn(user, amountaux);
        userBurns[user] += amountburn;        
        powerBalances[user] -= power; 
        powerSacrify[user] += power;
        
        
        
    }
    
}
        

/TEXLA/IBurnRedeemable.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IBurnRedeemable {
    event Redeemed(
        address indexed user,
        address indexed xenContract,
        address indexed tokenContract,
        uint256 xenAmount,
        uint256 tokenAmount
    );

    function onTokenBurned(address user, uint256 amount) external;
}
          

/TEXLA/ERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/TEXLA/Math.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "./ABDKMath64x64.sol";

library Math {
    function min(uint256 a, uint256 b) external pure returns (uint256) {
        if (a > b) return b;
        return a;
    }

    function max(uint256 a, uint256 b) external pure returns (uint256) {
        if (a > b) return a;
        return b;
    }

    function logX64(uint256 x) external pure returns (int128) {
        return ABDKMath64x64.log_2(ABDKMath64x64.fromUInt(x));
    }
}
          

/TEXLA/IStakingToken.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IStakingToken {
    event Staked(address indexed user, uint256 amount, uint256 term);

    event Withdrawn(address indexed user, uint256 amount, uint256 reward);

    function stake(uint256 amount, uint256 term) external;

    function withdraw() external;
}
          

/TEXLA/IRankedMintingToken.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IRankedMintingToken {
    event RankClaimed(address indexed user, uint256 term, uint256 rank);

    event MintClaimed(address indexed user, uint256 rewardAmount);

    function claimRank(uint256 term) external;

    function claimMintReward() external;
}
          

/TEXLA/IERC20Metadata.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

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);
}
          

/TEXLA/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

/TEXLA/IERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

/TEXLA/IBurnableToken.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IBurnableToken {
    function burn(address user, uint256 amount) external;
}
          

/TEXLA/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

/TEXLA/ABDKMath64x64.sol

// SPDX-License-Identifier: BSD-4-Clause
/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity ^0.8.0;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
  /*
   * Minimum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

  /*
   * Maximum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

  /**
   * Convert signed 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromInt (int256 x) internal pure returns (int128) {
    unchecked {
      require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (x << 64);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 64-bit integer number
   * rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64-bit integer number
   */
  function toInt (int128 x) internal pure returns (int64) {
    unchecked {
      return int64 (x >> 64);
    }
  }

  /**
   * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromUInt (uint256 x) internal pure returns (int128) {
    unchecked {
      require (x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (int256 (x << 64));
    }
  }

  /**
   * Convert signed 64.64 fixed point number into unsigned 64-bit integer
   * number rounding down.  Revert on underflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return unsigned 64-bit integer number
   */
  function toUInt (int128 x) internal pure returns (uint64) {
    unchecked {
      require (x >= 0);
      return uint64 (uint128 (x >> 64));
    }
  }

  /**
   * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
   * number rounding down.  Revert on overflow.
   *
   * @param x signed 128.128-bin fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function from128x128 (int256 x) internal pure returns (int128) {
    unchecked {
      int256 result = x >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 128.128 fixed point
   * number.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 128.128 fixed point number
   */
  function to128x128 (int128 x) internal pure returns (int256) {
    unchecked {
      return int256 (x) << 64;
    }
  }

  /**
   * Calculate x + y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function add (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) + y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x - y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sub (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) - y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding down.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function mul (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) * y >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
   * number and y is signed 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y signed 256-bit integer number
   * @return signed 256-bit integer number
   */
  function muli (int128 x, int256 y) internal pure returns (int256) {
    unchecked {
      if (x == MIN_64x64) {
        require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
          y <= 0x1000000000000000000000000000000000000000000000000);
        return -y << 63;
      } else {
        bool negativeResult = false;
        if (x < 0) {
          x = -x;
          negativeResult = true;
        }
        if (y < 0) {
          y = -y; // We rely on overflow behavior here
          negativeResult = !negativeResult;
        }
        uint256 absoluteResult = mulu (x, uint256 (y));
        if (negativeResult) {
          require (absoluteResult <=
            0x8000000000000000000000000000000000000000000000000000000000000000);
          return -int256 (absoluteResult); // We rely on overflow behavior here
        } else {
          require (absoluteResult <=
            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
          return int256 (absoluteResult);
        }
      }
    }
  }

  /**
   * Calculate x * y rounding down, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y unsigned 256-bit integer number
   * @return unsigned 256-bit integer number
   */
  function mulu (int128 x, uint256 y) internal pure returns (uint256) {
    unchecked {
      if (y == 0) return 0;

      require (x >= 0);

      uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
      uint256 hi = uint256 (int256 (x)) * (y >> 128);

      require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      hi <<= 64;

      require (hi <=
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
      return hi + lo;
    }
  }

  /**
   * Calculate x / y rounding towards zero.  Revert on overflow or when y is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function div (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      int256 result = (int256 (x) << 64) / y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are signed 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x signed 256-bit integer number
   * @param y signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divi (int256 x, int256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);

      bool negativeResult = false;
      if (x < 0) {
        x = -x; // We rely on overflow behavior here
        negativeResult = true;
      }
      if (y < 0) {
        y = -y; // We rely on overflow behavior here
        negativeResult = !negativeResult;
      }
      uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
      if (negativeResult) {
        require (absoluteResult <= 0x80000000000000000000000000000000);
        return -int128 (absoluteResult); // We rely on overflow behavior here
      } else {
        require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int128 (absoluteResult); // We rely on overflow behavior here
      }
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divu (uint256 x, uint256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      uint128 result = divuu (x, y);
      require (result <= uint128 (MAX_64x64));
      return int128 (result);
    }
  }

  /**
   * Calculate -x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function neg (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return -x;
    }
  }

  /**
   * Calculate |x|.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function abs (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return x < 0 ? -x : x;
    }
  }

  /**
   * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function inv (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != 0);
      int256 result = int256 (0x100000000000000000000000000000000) / x;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function avg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      return int128 ((int256 (x) + int256 (y)) >> 1);
    }
  }

  /**
   * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
   * Revert on overflow or in case x * y is negative.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function gavg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 m = int256 (x) * int256 (y);
      require (m >= 0);
      require (m <
          0x4000000000000000000000000000000000000000000000000000000000000000);
      return int128 (sqrtu (uint256 (m)));
    }
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y uint256 value
   * @return signed 64.64-bit fixed point number
   */
  function pow (int128 x, uint256 y) internal pure returns (int128) {
    unchecked {
      bool negative = x < 0 && y & 1 == 1;

      uint256 absX = uint128 (x < 0 ? -x : x);
      uint256 absResult;
      absResult = 0x100000000000000000000000000000000;

      if (absX <= 0x10000000000000000) {
        absX <<= 63;
        while (y != 0) {
          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x2 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x4 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x8 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          y >>= 4;
        }

        absResult >>= 64;
      } else {
        uint256 absXShift = 63;
        if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
        if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
        if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
        if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
        if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
        if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }

        uint256 resultShift = 0;
        while (y != 0) {
          require (absXShift < 64);

          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
            resultShift += absXShift;
            if (absResult > 0x100000000000000000000000000000000) {
              absResult >>= 1;
              resultShift += 1;
            }
          }
          absX = absX * absX >> 127;
          absXShift <<= 1;
          if (absX >= 0x100000000000000000000000000000000) {
              absX >>= 1;
              absXShift += 1;
          }

          y >>= 1;
        }

        require (resultShift < 64);
        absResult >>= 64 - resultShift;
      }
      int256 result = negative ? -int256 (absResult) : int256 (absResult);
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down.  Revert if x < 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sqrt (int128 x) internal pure returns (int128) {
    unchecked {
      require (x >= 0);
      return int128 (sqrtu (uint256 (int256 (x)) << 64));
    }
  }

  /**
   * Calculate binary logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function log_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      int256 msb = 0;
      int256 xc = x;
      if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      int256 result = msb - 64 << 64;
      uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
      for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
        ux *= ux;
        uint256 b = ux >> 255;
        ux >>= 127 + b;
        result += bit * int256 (b);
      }

      return int128 (result);
    }
  }

  /**
   * Calculate natural logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function ln (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      return int128 (int256 (
          uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
    }
  }

  /**
   * Calculate binary exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      uint256 result = 0x80000000000000000000000000000000;

      if (x & 0x8000000000000000 > 0)
        result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
      if (x & 0x4000000000000000 > 0)
        result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
      if (x & 0x2000000000000000 > 0)
        result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
      if (x & 0x1000000000000000 > 0)
        result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
      if (x & 0x800000000000000 > 0)
        result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
      if (x & 0x400000000000000 > 0)
        result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
      if (x & 0x200000000000000 > 0)
        result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
      if (x & 0x100000000000000 > 0)
        result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
      if (x & 0x80000000000000 > 0)
        result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
      if (x & 0x40000000000000 > 0)
        result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
      if (x & 0x20000000000000 > 0)
        result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
      if (x & 0x10000000000000 > 0)
        result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
      if (x & 0x8000000000000 > 0)
        result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
      if (x & 0x4000000000000 > 0)
        result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
      if (x & 0x2000000000000 > 0)
        result = result * 0x1000162E525EE054754457D5995292026 >> 128;
      if (x & 0x1000000000000 > 0)
        result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
      if (x & 0x800000000000 > 0)
        result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
      if (x & 0x400000000000 > 0)
        result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
      if (x & 0x200000000000 > 0)
        result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
      if (x & 0x100000000000 > 0)
        result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
      if (x & 0x80000000000 > 0)
        result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
      if (x & 0x40000000000 > 0)
        result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
      if (x & 0x20000000000 > 0)
        result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
      if (x & 0x10000000000 > 0)
        result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
      if (x & 0x8000000000 > 0)
        result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
      if (x & 0x4000000000 > 0)
        result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
      if (x & 0x2000000000 > 0)
        result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
      if (x & 0x1000000000 > 0)
        result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
      if (x & 0x800000000 > 0)
        result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
      if (x & 0x400000000 > 0)
        result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
      if (x & 0x200000000 > 0)
        result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
      if (x & 0x100000000 > 0)
        result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
      if (x & 0x80000000 > 0)
        result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
      if (x & 0x40000000 > 0)
        result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
      if (x & 0x20000000 > 0)
        result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
      if (x & 0x10000000 > 0)
        result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
      if (x & 0x8000000 > 0)
        result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
      if (x & 0x4000000 > 0)
        result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
      if (x & 0x2000000 > 0)
        result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
      if (x & 0x1000000 > 0)
        result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
      if (x & 0x800000 > 0)
        result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
      if (x & 0x400000 > 0)
        result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
      if (x & 0x200000 > 0)
        result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
      if (x & 0x100000 > 0)
        result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
      if (x & 0x80000 > 0)
        result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
      if (x & 0x40000 > 0)
        result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
      if (x & 0x20000 > 0)
        result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
      if (x & 0x10000 > 0)
        result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
      if (x & 0x8000 > 0)
        result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
      if (x & 0x4000 > 0)
        result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
      if (x & 0x2000 > 0)
        result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
      if (x & 0x1000 > 0)
        result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
      if (x & 0x800 > 0)
        result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
      if (x & 0x400 > 0)
        result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
      if (x & 0x200 > 0)
        result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
      if (x & 0x100 > 0)
        result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
      if (x & 0x80 > 0)
        result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
      if (x & 0x40 > 0)
        result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
      if (x & 0x20 > 0)
        result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
      if (x & 0x10 > 0)
        result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
      if (x & 0x8 > 0)
        result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
      if (x & 0x4 > 0)
        result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
      if (x & 0x2 > 0)
        result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
      if (x & 0x1 > 0)
        result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;

      result >>= uint256 (int256 (63 - (x >> 64)));
      require (result <= uint256 (int256 (MAX_64x64)));

      return int128 (int256 (result));
    }
  }

  /**
   * Calculate natural exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      return exp_2 (
          int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return unsigned 64.64-bit fixed point number
   */
  function divuu (uint256 x, uint256 y) private pure returns (uint128) {
    unchecked {
      require (y != 0);

      uint256 result;

      if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
        result = (x << 64) / y;
      else {
        uint256 msb = 192;
        uint256 xc = x >> 192;
        if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
        if (xc >= 0x10000) { xc >>= 16; msb += 16; }
        if (xc >= 0x100) { xc >>= 8; msb += 8; }
        if (xc >= 0x10) { xc >>= 4; msb += 4; }
        if (xc >= 0x4) { xc >>= 2; msb += 2; }
        if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

        result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
        require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 hi = result * (y >> 128);
        uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 xh = x >> 192;
        uint256 xl = x << 64;

        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here
        lo = hi << 128;
        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here

        assert (xh == hi >> 128);

        result += xl / y;
      }

      require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return uint128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
   * number.
   *
   * @param x unsigned 256-bit integer number
   * @return unsigned 128-bit integer number
   */
  function sqrtu (uint256 x) private pure returns (uint128) {
    unchecked {
      if (x == 0) return 0;
      else {
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
        if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
        if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
        if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
        if (xx >= 0x100) { xx >>= 8; r <<= 4; }
        if (xx >= 0x10) { xx >>= 4; r <<= 2; }
        if (xx >= 0x8) { r <<= 1; }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return uint128 (r < r1 ? r : r1);
      }
    }
  }
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MintClaimed","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"rewardAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RankClaimed","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"term","internalType":"uint256","indexed":false},{"type":"uint256","name":"rank","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Staked","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"term","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawn","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"AUTHORS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DAYS_IN_YEAR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"EAA_PM_START","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"EAA_PM_STEP","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"EAA_RANK_STEP","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"GENESIS_RANK","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"GetPower","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"GetPowerandShare","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"address","name":"share","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PENALTY_PCT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_TERM_END","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_TERM_START","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_TERM","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"POWER_PER_XEN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"REWARD_AMPLIFIER_END","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"REWARD_AMPLIFIER_START","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"SECONDS_IN_DAY","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SacrifyPower","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"power","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SendPower","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"address","name":"share","internalType":"address"},{"type":"uint256","name":"power","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"TERM_AMPLIFIER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"TERM_AMPLIFIER_THRESHOLD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"WITHDRAWAL_WINDOW_DAYS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"XEN_APY_DAYS_STEP","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"XEN_APY_END","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"XEN_APY_START","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"XEN_MIN_BURN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"XEN_MIN_STAKE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"activeMinters","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"activeStakes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimMintReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimMintRewardAndShare","inputs":[{"type":"address","name":"other","internalType":"address"},{"type":"uint256","name":"pct","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimMintRewardAndStake","inputs":[{"type":"uint256","name":"pct","internalType":"uint256"},{"type":"uint256","name":"term","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimRank","inputs":[{"type":"uint256","name":"term","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"genesisTs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentAMP","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentAPY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentEAAR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentMaxTerm","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getGrossReward","inputs":[{"type":"uint256","name":"rankDelta","internalType":"uint256"},{"type":"uint256","name":"amplifier","internalType":"uint256"},{"type":"uint256","name":"term","internalType":"uint256"},{"type":"uint256","name":"eaa","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct TEXLACrypto.MintInfo","components":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"term","internalType":"uint256"},{"type":"uint256","name":"maturityTs","internalType":"uint256"},{"type":"uint256","name":"rank","internalType":"uint256"},{"type":"uint256","name":"amplifier","internalType":"uint256"},{"type":"uint256","name":"eaaRate","internalType":"uint256"}]}],"name":"getUserMint","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct TEXLACrypto.StakeInfo","components":[{"type":"uint256","name":"term","internalType":"uint256"},{"type":"uint256","name":"maturityTs","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"apy","internalType":"uint256"}]}],"name":"getUserStake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"globalRank","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"powerBalances","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"powerSacrify","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"term","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalXenStaked","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userBurns","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"term","internalType":"uint256"},{"type":"uint256","name":"maturityTs","internalType":"uint256"},{"type":"uint256","name":"rank","internalType":"uint256"},{"type":"uint256","name":"amplifier","internalType":"uint256"},{"type":"uint256","name":"eaaRate","internalType":"uint256"}],"name":"userMints","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"term","internalType":"uint256"},{"type":"uint256","name":"maturityTs","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"apy","internalType":"uint256"}],"name":"userStakes","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[]}]
            

Contract Creation Code

0x60a060405260016005553480156200001657600080fd5b506040518060400160405280600c81526020016b5445584c412043727970746f60a01b815250604051806040016040528060048152602001630eca88ab60e31b81525081600390816200006a91906200012b565b5060046200007982826200012b565b50504260805250620001f7565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000b157607f821691505b602082108103620000d257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200012657600081815260208120601f850160051c81016020861015620001015750805b601f850160051c820191505b8181101562000122578281556001016200010d565b5050505b505050565b81516001600160401b0381111562000147576200014762000086565b6200015f816200015884546200009c565b84620000d8565b602080601f8311600181146200019757600084156200017e5750858301515b600019600386901b1c1916600185901b17855562000122565b600085815260208120601f198616915b82811015620001c857888601518255948401946001909101908401620001a7565b5085821015620001e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516133d8620002216000396000818161082c01528181612ac30152612b2601526133d86000f3fe608060405234801561001057600080fd5b50600436106103ba5760003560e01c80637b0472f0116101f4578063b4800cdc1161011a578063df282331116100ad578063f029093e1161007c578063f029093e14610860578063f060482914610869578063f340faed14610871578063fed742691461087b57600080fd5b8063df282331146107a3578063e3af6d0a14610827578063e81917b41461084e578063ed2f23691461085757600080fd5b8063c56f0bab116100e9578063c56f0bab14610755578063ce653d5f1461075d578063d3fe46891461077d578063dd62ed3e1461079057600080fd5b8063b4800cdc1461073c578063ba3ec74114610745578063bcfe394f14610495578063c0c652591461074d57600080fd5b8063962ca49611610192578063a457c2d711610161578063a457c2d7146106fa578063a9059cbb1461070d578063b0fd1fc214610720578063b21d35f21461073357600080fd5b8063962ca496146106c457806399202454146106cc5780639dc29fac146106d45780639ff054df146106e757600080fd5b80638da5cb5b116101ce5780638da5cb5b146106345780638da7ad231461065f578063909a2ff6146106b457806395d89b41146106bc57600080fd5b80637b0472f0146106115780637e7aa62e146106245780638979c87c1461062c57600080fd5b8063313ce567116102e4578063543d3652116102775780636a5e0766116102465780636a5e0766146105685780637010d7a11461058857806370a08231146105e057806372475f941461060957600080fd5b8063543d365214610495578063583b912c146105385780635bccb4c41461054b57806361a52a361461055e57600080fd5b80633ccfd60b116102b35780633ccfd60b14610500578063451257151461050857806352c7f8dc14610510578063539313b81461051857600080fd5b8063313ce567146104c357806331b9e85d146104d257806332870fda146104e557806339509351146104ed57600080fd5b806316f9c8fd1161035c5780631c6f212e1161032b5780631c6f212e1461049557806323b872dd1461049d5780632a62d9661461042c578063310caf2d146104b057600080fd5b806316f9c8fd1461043457806318160ddd1461046f5780631c244082146104775780631c5603051461048057600080fd5b8063095ea7b311610398578063095ea7b3146103f95780630bfae56b1461041c5780630f2e122814610424578063110d7fc21461042c57600080fd5b806302378932146103bf578063069612a5146103db57806306fdde03146103e4575b600080fd5b6103c861016d81565b6040519081526020015b60405180910390f35b6103c860085481565b6103ec610883565b6040516103d29190612e7e565b61040c610407366004612ee8565b610915565b60405190151581526020016103d2565b6103c861092f565b6103c8606381565b6103c8600081565b61043c610940565b6040516103d291908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b6002546103c8565b6103c860055481565b61049361048e366004612ee8565b6109b1565b005b6103c8600181565b61040c6104ab366004612f12565b610c12565b6104936104be366004612f12565b610c36565b604051601281526020016103d2565b6104936104e0366004612ee8565b610d6e565b6103c8605a81565b61040c6104fb366004612ee8565b610ea3565b610493610ec5565b6103c8611019565b610493611028565b6103c8610526366004612f4e565b600c6020526000908152604090205481565b610493610546366004612f12565b61114b565b610493610559366004612f69565b6112ce565b6103c86201518081565b6103c8610576366004612f4e565b600d6020526000908152604090205481565b610590611625565b6040516103d2919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b6103c86105ee366004612f4e565b6001600160a01b031660009081526020819052604090205490565b6103c8600f81565b61049361061f366004612f69565b6116ca565b6103c8600281565b6103c86118e8565b600e54610647906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b61069461066d366004612f4e565b600a6020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103d2565b6103c8606481565b6103ec6118f2565b6103c8611901565b6103c861190b565b6104936106e2366004612ee8565b611915565b6104936106f5366004612f8b565b611b0e565b61040c610708366004612ee8565b611e72565b61040c61071b366004612ee8565b611eed565b6103c861072e366004612fa4565b611efb565b6103c861138881565b6103c860065481565b6103ec611f8b565b6103c8611fa7565b6103c8600781565b6103c861076b366004612f4e565b600b6020526000908152604090205481565b61049361078b366004612ee8565b611fb6565b6103c861079e366004612fd6565b612139565b6107f06107b1366004612f4e565b6009602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909186565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c0016103d2565b6103c87f000000000000000000000000000000000000000000000000000000000000000081565b6103c8610bb881565b6103c860075481565b6103c861271081565b6103c8612164565b6103c8620186a081565b6103c8601481565b60606003805461089290613009565b80601f01602080910402602001604051908101604052809291908181526020018280546108be90613009565b801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050505050905090565b60003361092381858561217d565b60019150505b92915050565b61093d620151806064613059565b81565b61096b6040518060800160405280600081526020016000815260200160008152602001600081525090565b50336000908152600a6020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b33600090815260096020908152604091829020825160c08101845281546001600160a01b03908116825260018301549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a08301528316610a715760405162461bcd60e51b815260206004820152602560248201527f4352616e6b3a2043616e6e6f742073686172652077697468207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b60008211610ac15760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265207a65726f2070657263656e746044820152606401610a68565b60658210610b115760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265203130302b2070657263656e746044820152606401610a68565b6000816060015111610b355760405162461bcd60e51b8152600401610a6890613070565b80604001514211610b585760405162461bcd60e51b8152600401610a689061309f565b6000610b7b82606001518360200151846040015185608001518660a001516122a2565b610b8d90670de0b6b3a7640000613059565b905060006064610b9d8584613059565b610ba791906130ea565b90506000610bb582846130fe565b9050610bc2335b826123a0565b610bcc86836123a0565b610bd461247f565b60405183815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a6906020015b60405180910390a2505050505050565b600033610c208582856124d3565b610c2b85858561254d565b506001949350505050565b326001600160a01b03841614610c5e5760405162461bcd60e51b8152600401610a6890613111565b610c6a61271082613137565b15610c875760405162461bcd60e51b8152600401610a689061314b565b6001600160a01b038316610cad5760405162461bcd60e51b8152600401610a6890613195565b60008111610ccd5760405162461bcd60e51b8152600401610a68906131d7565b6000610cdb612710836130ea565b90506000610ceb6012600a6132ea565b610cf59084613059565b9050610d0385335b836124d3565b610d0d858261271b565b6001600160a01b0385166000908152600b602052604081208054859290610d359084906132f6565b90915550506001600160a01b0384166000908152600c602052604081208054849290610d629084906132f6565b90915550505050505050565b326001600160a01b03831614610d965760405162461bcd60e51b8152600401610a6890613111565b610da261271082613137565b15610dbf5760405162461bcd60e51b8152600401610a689061314b565b6001600160a01b038216610de55760405162461bcd60e51b8152600401610a6890613195565b60008111610e055760405162461bcd60e51b8152600401610a68906131d7565b6000610e13612710836130ea565b90506000610e236012600a6132ea565b610e2d9084613059565b9050610e398433610cfd565b610e43848261271b565b6001600160a01b0384166000908152600b602052604081208054859290610e6b9084906132f6565b90915550506001600160a01b0384166000908152600c602052604081208054849290610e989084906132f6565b909155505050505050565b600033610923818585610eb68383612139565b610ec091906132f6565b61217d565b336000908152600a6020908152604091829020825160808101845281548152600182015492810192909252600281015492820183905260030154606082015290610f485760405162461bcd60e51b81526020600482015260146024820152735445583a206e6f207374616b652065786973747360601b6044820152606401610a68565b6000610f668260400151836000015184602001518560600151612861565b600780549192506000610f7883613309565b9190505550816040015160086000828254610f9391906130fe565b90915550610fb2905033828460400151610fad91906132f6565b6123a0565b60408083015181519081526020810183905233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a25050336000908152600a60205260408120818155600181018290556002810182905560030155565b60006110236128bf565b905090565b33600090815260096020908152604091829020825160c08101845281546001600160a01b031681526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260059092015460a0820152906110a65760405162461bcd60e51b8152600401610a6890613070565b806040015142116110c95760405162461bcd60e51b8152600401610a689061309f565b60006110ec82606001518360200151846040015185608001518660a001516122a2565b6110fe90670de0b6b3a7640000613059565b905061110933610bbc565b61111161247f565b60405181815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a6906020015b60405180910390a25050565b326001600160a01b038416146111735760405162461bcd60e51b8152600401610a6890613111565b6001600160a01b0383166111995760405162461bcd60e51b8152600401610a6890613195565b600081116111b95760405162461bcd60e51b8152600401610a68906131d7565b6001600160a01b0383166000908152600c602052604090205481111561120e5760405162461bcd60e51b815260206004820152600a6024820152692732b2b2102837bbb2b960b11b6044820152606401610a68565b600061121c826103e8613059565b9050600061122c6012600a6132ea565b6112369083613059565b90506112428533610cfd565b61124c858261271b565b6001600160a01b0385166000908152600b6020526040812080548492906112749084906132f6565b90915550506001600160a01b0384166000908152600c6020526040812080548592906112a19084906132f6565b90915550506001600160a01b0385166000908152600c602052604081208054859290610d629084906130fe565b33600090815260096020908152604091829020825160c08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a08201526065831061137d5760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265203e3130302070657263656e746044820152606401610a68565b60008160600151116113a15760405162461bcd60e51b8152600401610a6890613070565b806040015142116113c45760405162461bcd60e51b8152600401610a689061309f565b60006113e782606001518360200151846040015185608001518660a001516122a2565b6113f990670de0b6b3a7640000613059565b9050600060646114098684613059565b61141391906130ea565b9050600061142182846130fe565b905061142c33610bbc565b61143461247f565b60405183815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a69060200160405180910390a2600082116114b05760405162461bcd60e51b81526020600482015260146024820152735445583a2042656c6f77206d696e207374616b6560601b6044820152606401610a68565b60016114bf6201518082613059565b6114c991906130fe565b6114d66201518087613059565b1161151f5760405162461bcd60e51b81526020600482015260196024820152785445583a2042656c6f77206d696e207374616b65207465726d60381b6044820152606401610a68565b61152e620151806103e8613059565b6115399060016132f6565b6115466201518087613059565b1061158f5760405162461bcd60e51b81526020600482015260196024820152785445583a2041626f7665206d6178207374616b65207465726d60381b6044820152606401610a68565b336000908152600a6020526040902060020154156115e35760405162461bcd60e51b81526020600482015260116024820152705445583a207374616b652065786973747360781b6044820152606401610a68565b6115ed82866129c6565b604080518381526020810187905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee909101610c02565b6116676040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b5033600090815260096020908152604091829020825160c08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a082015290565b816116d4336105ee565b10156117225760405162461bcd60e51b815260206004820152601760248201527f5445583a206e6f7420656e6f7567682062616c616e63650000000000000000006044820152606401610a68565b600082116117695760405162461bcd60e51b81526020600482015260146024820152735445583a2042656c6f77206d696e207374616b6560601b6044820152606401610a68565b60016117786201518082613059565b61178291906130fe565b61178f6201518083613059565b116117d85760405162461bcd60e51b81526020600482015260196024820152785445583a2042656c6f77206d696e207374616b65207465726d60381b6044820152606401610a68565b6117e7620151806103e8613059565b6117f29060016132f6565b6117ff6201518083613059565b106118485760405162461bcd60e51b81526020600482015260196024820152785445583a2041626f7665206d6178207374616b65207465726d60381b6044820152606401610a68565b336000908152600a60205260409020600201541561189c5760405162461bcd60e51b81526020600482015260116024820152705445583a207374616b652065786973747360781b6044820152606401610a68565b6118a6338361271b565b6118b082826129c6565b604080518381526020810183905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910161113f565b6000611023612a69565b60606004805461089290613009565b6000611023612aad565b6000611023612b1a565b600081116119355760405162461bcd60e51b8152600401610a68906131d7565b336040516301ffc9a760e01b815263543746b160e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a79190613320565b6119f35760405162461bcd60e51b815260206004820152601e60248201527f4275726e3a206e6f74206120737570706f7274656420636f6e747261637400006044820152606401610a68565b6000611a016012600a6132ea565b611a0b9083613059565b9050611a178333610cfd565b611a21838261271b565b6001600160a01b0383166000908152600b602052604081208054849290611a499084906132f6565b90915550611a5b905061271083613137565b600003611aa4576000611a70612710846130ea565b6001600160a01b0385166000908152600c6020526040812080549293508392909190611a9d9084906132f6565b9091555050505b3360405163543746b160e01b81526001600160a01b03858116600483015260248201849052919091169063543746b190604401600060405180830381600087803b158015611af157600080fd5b505af1158015611b05573d6000803e3d6000fd5b50505050505050565b326000611b1e6201518084613059565b90506001611b2f6201518082613059565b611b3991906130fe565b8111611b875760405162461bcd60e51b815260206004820152601960248201527f4352616e6b3a205465726d206c657373207468616e206d696e000000000000006044820152606401610a68565b611b8f6128bf565b611b9a9060016132f6565b8110611bf75760405162461bcd60e51b815260206004820152602660248201527f4352616e6b3a205465726d206d6f7265207468616e2063757272656e74206d6160448201526578207465726d60d01b6064820152608401610a68565b3360009081526009602052604090206003015415611c575760405162461bcd60e51b815260206004820152601f60248201527f4352616e6b3a204d696e7420616c726561647920696e2070726f6772657373006044820152606401610a68565b6298967f6005541080611c8157506001600160a01b0382166000908152600c602052604090205415155b611ce15760405162461bcd60e51b815260206004820152602b60248201527f4352616e6b3a20496e76616c696420676c6f62616c2072616e6b206f7220706f60448201526a7765722062616c616e636560a81b6064820152608401610a68565b60006040518060c00160405280611cf53390565b6001600160a01b0316815260208101869052604001611d1484426132f6565b81526020016005548152602001611d29612b1a565b8152602001611d36612a69565b90526001600160a01b0384166000908152600c602052604090205490915015801590611d6657506298967f600554115b15611d9a576001600160a01b0383166000908152600c60205260408120805460019290611d949084906130fe565b90915550505b336000908152600960209081526040808320845181546001600160a01b0319166001600160a01b039091161781559184015160018301558301516002820155606083015160038201556080830151600482015560a08301516005909101556006805491611e0683613342565b9190505550611e123390565b6001600160a01b03167fe9149e1b5059238baed02fa659dbf4bd932fbcf760a431330df4d934bc942f378560056000815480929190611e5090613342565b909155506040805192835260208301919091520160405180910390a250505050565b60003381611e808286612139565b905083811015611ee05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a68565b610c2b828686840361217d565b60003361092381858561254d565b600080611f12611f0a87612bf6565b600f0b612c14565b90506000611f4e611f2285612bf6565b611f45611f2e88612bf6565b611f45611f3a8b612bf6565b600f88900b90612cf8565b600f0b90612cf8565b9050611f74611f6c611f616103e8612bf6565b600f84900b90612d36565b600f0b612d8d565b67ffffffffffffffff16925050505b949350505050565b6040518060600160405280602e8152602001613375602e913981565b61093d620151806103e8613059565b326001600160a01b03831614611fde5760405162461bcd60e51b8152600401610a6890613111565b6001600160a01b0382166120045760405162461bcd60e51b8152600401610a6890613195565b600081116120245760405162461bcd60e51b8152600401610a68906131d7565b6001600160a01b0382166000908152600c60205260409020548111156120795760405162461bcd60e51b815260206004820152600a6024820152692732b2b2102837bbb2b960b11b6044820152606401610a68565b6000612087826103e8613059565b905060006120976012600a6132ea565b6120a19083613059565b90506120ad8433610cfd565b6120b7848261271b565b6001600160a01b0384166000908152600b6020526040812080548492906120df9084906132f6565b90915550506001600160a01b0384166000908152600c60205260408120805485929061210c9084906130fe565b90915550506001600160a01b0384166000908152600d602052604081208054859290610e989084906132f6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60016121736201518082613059565b61093d91906130fe565b6001600160a01b0383166121df5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a68565b6001600160a01b0382166122405760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a68565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000806122af85426130fe565b905060006122bc82612da9565b90506000734f2392ef0babfb427e7e05a47547a4dccaf76da8636d5433e68a6005546122e891906130fe565b6040516001600160e01b031960e084901b168152600481019190915260026024820152604401602060405180830381865af415801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f919061335b565b9050600061235f866103e86132f6565b9050600061236f83898c85611efb565b9050606461237d85826130fe565b6123879083613059565b61239191906130ea565b9b9a5050505050505050505050565b6001600160a01b0382166123f65760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a68565b806002600082825461240891906132f6565b90915550506001600160a01b038216600090815260208190526040812080548392906124359084906132f6565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b33600090815260096020526040812080546001600160a01b03191681556001810182905560028101829055600381018290556004810182905560050181905560068054916124cc83613309565b9190505550565b60006124df8484612139565b90506000198114612547578181101561253a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610a68565b612547848484840361217d565b50505050565b6001600160a01b0383166125b15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a68565b6001600160a01b0382166126135760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a68565b6001600160a01b0383166000908152602081905260409020548181101561268b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610a68565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906126c29084906132f6565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161270e91815260200190565b60405180910390a3612547565b6001600160a01b03821661277b5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a68565b6001600160a01b038216600090815260208190526040902054818110156127ef5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a68565b6001600160a01b038316600090815260208190526040812083830390556002805484929061281e9084906130fe565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612295565b6000824211156128b457600061016d61287a8685613059565b61288790620f4240613059565b61289191906130ea565b90506305f5e1006128a28288613059565b6128ac91906130ea565b915050611f83565b506000949350505050565b600061138860055411156129b85760006128ed611f6c6128df600f612bf6565b611f45611f0a600554612bf6565b67ffffffffffffffff16905060006129086201518083613059565b612916620151806064613059565b61292091906132f6565b9050734f2392ef0babfb427e7e05a47547a4dccaf76da8637ae2b5c78261294c620151806103e8613059565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865af415801561298d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b1919061335b565b9250505090565b611023620151806064613059565b604051806080016040528082815260200162015180836129e69190613059565b6129f090426132f6565b8152602001838152602001612a03612aad565b9052336000908152600a602090815260408083208451815591840151600183015583015160028201556060909201516003909201919091556007805491612a4983613342565b91905055508160086000828254612a6091906132f6565b90915550505050565b600080620186a06005546001612a7f9190613059565b612a8991906130ea565b90506064811115612a9c57600091505090565b612aa78160646130fe565b91505090565b600080612abe605a62015180613059565b612ae87f0000000000000000000000000000000000000000000000000000000000000000426130fe565b612af291906130ea565b905080612b01600260146130fe565b1015612b0f57600291505090565b612aa78160146130fe565b60008062015180612b4b7f0000000000000000000000000000000000000000000000000000000000000000426130fe565b612b5591906130ea565b9050610bb8811015612bee57734f2392ef0babfb427e7e05a47547a4dccaf76da8636d5433e6612b8783610bb86130fe565b6040516001600160e01b031960e084901b168152600481019190915260016024820152604401602060405180830381865af4158015612bca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa7919061335b565b600191505090565b6000677fffffffffffffff821115612c0d57600080fd5b5060401b90565b60008082600f0b13612c2557600080fd5b6000600f83900b680100000000000000008112612c44576040918201911d5b6401000000008112612c58576020918201911d5b620100008112612c6a576010918201911d5b6101008112612c7b576008918201911d5b60108112612c8b576004918201911d5b60048112612c9b576002918201911d5b60028112612caa576001820191505b603f19820160401b600f85900b607f8490031b6780000000000000005b6000811315612ced5790800260ff81901c8281029390930192607f011c9060011d612cc7565b509095945050505050565b6000600f83810b9083900b0260401d60016001607f1b03198112801590612d26575060016001607f1b038113155b612d2f57600080fd5b9392505050565b600081600f0b600003612d4857600080fd5b600082600f0b604085600f0b901b81612d6357612d636130d4565b05905060016001607f1b03198112801590612d26575060016001607f1b03811315612d2f57600080fd5b60008082600f0b1215612d9f57600080fd5b50600f0b60401d90565b600080612db962015180846130ea565b9050612dc7600160076130fe565b811115612dd75750606392915050565b600060016007612de88460036132f6565b6001901b612df691906130ea565b612e0091906130fe565b604051637ae2b5c760e01b81526004810182905260636024820152909150734f2392ef0babfb427e7e05a47547a4dccaf76da890637ae2b5c790604401602060405180830381865af4158015612e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f83919061335b565b600060208083528351808285015260005b81811015612eab57858101830151858201604001528201612e8f565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114612ee357600080fd5b919050565b60008060408385031215612efb57600080fd5b612f0483612ecc565b946020939093013593505050565b600080600060608486031215612f2757600080fd5b612f3084612ecc565b9250612f3e60208501612ecc565b9150604084013590509250925092565b600060208284031215612f6057600080fd5b612d2f82612ecc565b60008060408385031215612f7c57600080fd5b50508035926020909101359150565b600060208284031215612f9d57600080fd5b5035919050565b60008060008060808587031215612fba57600080fd5b5050823594602084013594506040840135936060013592509050565b60008060408385031215612fe957600080fd5b612ff283612ecc565b915061300060208401612ecc565b90509250929050565b600181811c9082168061301d57607f821691505b60208210810361303d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761092957610929613043565b6020808252601590820152744352616e6b3a204e6f206d696e742065786973747360581b604082015260600190565b6020808252818101527f4352616e6b3a204d696e74206d61747572697479206e6f742072656163686564604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826130f9576130f96130d4565b500490565b8181038181111561092957610929613043565b6020808252600c908201526b24b73b30b634b2102ab9b2b960a11b604082015260600190565b600082613146576131466130d4565b500690565b6020808252602a908201527f416d6f756e74206d7573742062652061206d756c7469706c65206f6620504f5760408201526922a92fa822a92fac22a760b11b606082015260800190565b60208082526022908201527f4275726e3a20596f752063616e74206275726e2066726f6d2061646472657373604082015261020360f41b606082015260800190565b602080825260159082015274109d5c9b8e8810995b1bddc81b5a5b881b1a5b5a5d605a1b604082015260600190565b600181815b8085111561324157816000190482111561322757613227613043565b8085161561323457918102915b93841c939080029061320b565b509250929050565b60008261325857506001610929565b8161326557506000610929565b816001811461327b5760028114613285576132a1565b6001915050610929565b60ff84111561329657613296613043565b50506001821b610929565b5060208310610133831016604e8410600b84101617156132c4575081810a610929565b6132ce8383613206565b80600019048211156132e2576132e2613043565b029392505050565b6000612d2f8383613249565b8082018082111561092957610929613043565b60008161331857613318613043565b506000190190565b60006020828403121561333257600080fd5b81518015158114612d2f57600080fd5b60006001820161335457613354613043565b5060010190565b60006020828403121561336d57600080fd5b505191905056fe50657073204c616220404d724a61636b4c6576696e20406c62656c79616576206661697263727970746f2e6f7267a26469706673582212202371ea85988b70d94cd30cee8efaed7c86900849e00a420c64a727d929a6409a64736f6c63430008120033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106103ba5760003560e01c80637b0472f0116101f4578063b4800cdc1161011a578063df282331116100ad578063f029093e1161007c578063f029093e14610860578063f060482914610869578063f340faed14610871578063fed742691461087b57600080fd5b8063df282331146107a3578063e3af6d0a14610827578063e81917b41461084e578063ed2f23691461085757600080fd5b8063c56f0bab116100e9578063c56f0bab14610755578063ce653d5f1461075d578063d3fe46891461077d578063dd62ed3e1461079057600080fd5b8063b4800cdc1461073c578063ba3ec74114610745578063bcfe394f14610495578063c0c652591461074d57600080fd5b8063962ca49611610192578063a457c2d711610161578063a457c2d7146106fa578063a9059cbb1461070d578063b0fd1fc214610720578063b21d35f21461073357600080fd5b8063962ca496146106c457806399202454146106cc5780639dc29fac146106d45780639ff054df146106e757600080fd5b80638da5cb5b116101ce5780638da5cb5b146106345780638da7ad231461065f578063909a2ff6146106b457806395d89b41146106bc57600080fd5b80637b0472f0146106115780637e7aa62e146106245780638979c87c1461062c57600080fd5b8063313ce567116102e4578063543d3652116102775780636a5e0766116102465780636a5e0766146105685780637010d7a11461058857806370a08231146105e057806372475f941461060957600080fd5b8063543d365214610495578063583b912c146105385780635bccb4c41461054b57806361a52a361461055e57600080fd5b80633ccfd60b116102b35780633ccfd60b14610500578063451257151461050857806352c7f8dc14610510578063539313b81461051857600080fd5b8063313ce567146104c357806331b9e85d146104d257806332870fda146104e557806339509351146104ed57600080fd5b806316f9c8fd1161035c5780631c6f212e1161032b5780631c6f212e1461049557806323b872dd1461049d5780632a62d9661461042c578063310caf2d146104b057600080fd5b806316f9c8fd1461043457806318160ddd1461046f5780631c244082146104775780631c5603051461048057600080fd5b8063095ea7b311610398578063095ea7b3146103f95780630bfae56b1461041c5780630f2e122814610424578063110d7fc21461042c57600080fd5b806302378932146103bf578063069612a5146103db57806306fdde03146103e4575b600080fd5b6103c861016d81565b6040519081526020015b60405180910390f35b6103c860085481565b6103ec610883565b6040516103d29190612e7e565b61040c610407366004612ee8565b610915565b60405190151581526020016103d2565b6103c861092f565b6103c8606381565b6103c8600081565b61043c610940565b6040516103d291908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b6002546103c8565b6103c860055481565b61049361048e366004612ee8565b6109b1565b005b6103c8600181565b61040c6104ab366004612f12565b610c12565b6104936104be366004612f12565b610c36565b604051601281526020016103d2565b6104936104e0366004612ee8565b610d6e565b6103c8605a81565b61040c6104fb366004612ee8565b610ea3565b610493610ec5565b6103c8611019565b610493611028565b6103c8610526366004612f4e565b600c6020526000908152604090205481565b610493610546366004612f12565b61114b565b610493610559366004612f69565b6112ce565b6103c86201518081565b6103c8610576366004612f4e565b600d6020526000908152604090205481565b610590611625565b6040516103d2919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b6103c86105ee366004612f4e565b6001600160a01b031660009081526020819052604090205490565b6103c8600f81565b61049361061f366004612f69565b6116ca565b6103c8600281565b6103c86118e8565b600e54610647906001600160a01b031681565b6040516001600160a01b0390911681526020016103d2565b61069461066d366004612f4e565b600a6020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103d2565b6103c8606481565b6103ec6118f2565b6103c8611901565b6103c861190b565b6104936106e2366004612ee8565b611915565b6104936106f5366004612f8b565b611b0e565b61040c610708366004612ee8565b611e72565b61040c61071b366004612ee8565b611eed565b6103c861072e366004612fa4565b611efb565b6103c861138881565b6103c860065481565b6103ec611f8b565b6103c8611fa7565b6103c8600781565b6103c861076b366004612f4e565b600b6020526000908152604090205481565b61049361078b366004612ee8565b611fb6565b6103c861079e366004612fd6565b612139565b6107f06107b1366004612f4e565b6009602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909186565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c0016103d2565b6103c87f000000000000000000000000000000000000000000000000000000006494af9b81565b6103c8610bb881565b6103c860075481565b6103c861271081565b6103c8612164565b6103c8620186a081565b6103c8601481565b60606003805461089290613009565b80601f01602080910402602001604051908101604052809291908181526020018280546108be90613009565b801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050505050905090565b60003361092381858561217d565b60019150505b92915050565b61093d620151806064613059565b81565b61096b6040518060800160405280600081526020016000815260200160008152602001600081525090565b50336000908152600a6020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b33600090815260096020908152604091829020825160c08101845281546001600160a01b03908116825260018301549382019390935260028201549381019390935260038101546060840152600481015460808401526005015460a08301528316610a715760405162461bcd60e51b815260206004820152602560248201527f4352616e6b3a2043616e6e6f742073686172652077697468207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b60008211610ac15760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265207a65726f2070657263656e746044820152606401610a68565b60658210610b115760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265203130302b2070657263656e746044820152606401610a68565b6000816060015111610b355760405162461bcd60e51b8152600401610a6890613070565b80604001514211610b585760405162461bcd60e51b8152600401610a689061309f565b6000610b7b82606001518360200151846040015185608001518660a001516122a2565b610b8d90670de0b6b3a7640000613059565b905060006064610b9d8584613059565b610ba791906130ea565b90506000610bb582846130fe565b9050610bc2335b826123a0565b610bcc86836123a0565b610bd461247f565b60405183815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a6906020015b60405180910390a2505050505050565b600033610c208582856124d3565b610c2b85858561254d565b506001949350505050565b326001600160a01b03841614610c5e5760405162461bcd60e51b8152600401610a6890613111565b610c6a61271082613137565b15610c875760405162461bcd60e51b8152600401610a689061314b565b6001600160a01b038316610cad5760405162461bcd60e51b8152600401610a6890613195565b60008111610ccd5760405162461bcd60e51b8152600401610a68906131d7565b6000610cdb612710836130ea565b90506000610ceb6012600a6132ea565b610cf59084613059565b9050610d0385335b836124d3565b610d0d858261271b565b6001600160a01b0385166000908152600b602052604081208054859290610d359084906132f6565b90915550506001600160a01b0384166000908152600c602052604081208054849290610d629084906132f6565b90915550505050505050565b326001600160a01b03831614610d965760405162461bcd60e51b8152600401610a6890613111565b610da261271082613137565b15610dbf5760405162461bcd60e51b8152600401610a689061314b565b6001600160a01b038216610de55760405162461bcd60e51b8152600401610a6890613195565b60008111610e055760405162461bcd60e51b8152600401610a68906131d7565b6000610e13612710836130ea565b90506000610e236012600a6132ea565b610e2d9084613059565b9050610e398433610cfd565b610e43848261271b565b6001600160a01b0384166000908152600b602052604081208054859290610e6b9084906132f6565b90915550506001600160a01b0384166000908152600c602052604081208054849290610e989084906132f6565b909155505050505050565b600033610923818585610eb68383612139565b610ec091906132f6565b61217d565b336000908152600a6020908152604091829020825160808101845281548152600182015492810192909252600281015492820183905260030154606082015290610f485760405162461bcd60e51b81526020600482015260146024820152735445583a206e6f207374616b652065786973747360601b6044820152606401610a68565b6000610f668260400151836000015184602001518560600151612861565b600780549192506000610f7883613309565b9190505550816040015160086000828254610f9391906130fe565b90915550610fb2905033828460400151610fad91906132f6565b6123a0565b60408083015181519081526020810183905233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a25050336000908152600a60205260408120818155600181018290556002810182905560030155565b60006110236128bf565b905090565b33600090815260096020908152604091829020825160c08101845281546001600160a01b031681526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260059092015460a0820152906110a65760405162461bcd60e51b8152600401610a6890613070565b806040015142116110c95760405162461bcd60e51b8152600401610a689061309f565b60006110ec82606001518360200151846040015185608001518660a001516122a2565b6110fe90670de0b6b3a7640000613059565b905061110933610bbc565b61111161247f565b60405181815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a6906020015b60405180910390a25050565b326001600160a01b038416146111735760405162461bcd60e51b8152600401610a6890613111565b6001600160a01b0383166111995760405162461bcd60e51b8152600401610a6890613195565b600081116111b95760405162461bcd60e51b8152600401610a68906131d7565b6001600160a01b0383166000908152600c602052604090205481111561120e5760405162461bcd60e51b815260206004820152600a6024820152692732b2b2102837bbb2b960b11b6044820152606401610a68565b600061121c826103e8613059565b9050600061122c6012600a6132ea565b6112369083613059565b90506112428533610cfd565b61124c858261271b565b6001600160a01b0385166000908152600b6020526040812080548492906112749084906132f6565b90915550506001600160a01b0384166000908152600c6020526040812080548592906112a19084906132f6565b90915550506001600160a01b0385166000908152600c602052604081208054859290610d629084906130fe565b33600090815260096020908152604091829020825160c08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a08201526065831061137d5760405162461bcd60e51b815260206004820181905260248201527f4352616e6b3a2043616e6e6f74207368617265203e3130302070657263656e746044820152606401610a68565b60008160600151116113a15760405162461bcd60e51b8152600401610a6890613070565b806040015142116113c45760405162461bcd60e51b8152600401610a689061309f565b60006113e782606001518360200151846040015185608001518660a001516122a2565b6113f990670de0b6b3a7640000613059565b9050600060646114098684613059565b61141391906130ea565b9050600061142182846130fe565b905061142c33610bbc565b61143461247f565b60405183815233907fd74752b13281df13701575f3a507e9b1242e0b5fb040143211c481c1fce573a69060200160405180910390a2600082116114b05760405162461bcd60e51b81526020600482015260146024820152735445583a2042656c6f77206d696e207374616b6560601b6044820152606401610a68565b60016114bf6201518082613059565b6114c991906130fe565b6114d66201518087613059565b1161151f5760405162461bcd60e51b81526020600482015260196024820152785445583a2042656c6f77206d696e207374616b65207465726d60381b6044820152606401610a68565b61152e620151806103e8613059565b6115399060016132f6565b6115466201518087613059565b1061158f5760405162461bcd60e51b81526020600482015260196024820152785445583a2041626f7665206d6178207374616b65207465726d60381b6044820152606401610a68565b336000908152600a6020526040902060020154156115e35760405162461bcd60e51b81526020600482015260116024820152705445583a207374616b652065786973747360781b6044820152606401610a68565b6115ed82866129c6565b604080518381526020810187905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee909101610c02565b6116676040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b5033600090815260096020908152604091829020825160c08101845281546001600160a01b03168152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a082015290565b816116d4336105ee565b10156117225760405162461bcd60e51b815260206004820152601760248201527f5445583a206e6f7420656e6f7567682062616c616e63650000000000000000006044820152606401610a68565b600082116117695760405162461bcd60e51b81526020600482015260146024820152735445583a2042656c6f77206d696e207374616b6560601b6044820152606401610a68565b60016117786201518082613059565b61178291906130fe565b61178f6201518083613059565b116117d85760405162461bcd60e51b81526020600482015260196024820152785445583a2042656c6f77206d696e207374616b65207465726d60381b6044820152606401610a68565b6117e7620151806103e8613059565b6117f29060016132f6565b6117ff6201518083613059565b106118485760405162461bcd60e51b81526020600482015260196024820152785445583a2041626f7665206d6178207374616b65207465726d60381b6044820152606401610a68565b336000908152600a60205260409020600201541561189c5760405162461bcd60e51b81526020600482015260116024820152705445583a207374616b652065786973747360781b6044820152606401610a68565b6118a6338361271b565b6118b082826129c6565b604080518381526020810183905233917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910161113f565b6000611023612a69565b60606004805461089290613009565b6000611023612aad565b6000611023612b1a565b600081116119355760405162461bcd60e51b8152600401610a68906131d7565b336040516301ffc9a760e01b815263543746b160e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a79190613320565b6119f35760405162461bcd60e51b815260206004820152601e60248201527f4275726e3a206e6f74206120737570706f7274656420636f6e747261637400006044820152606401610a68565b6000611a016012600a6132ea565b611a0b9083613059565b9050611a178333610cfd565b611a21838261271b565b6001600160a01b0383166000908152600b602052604081208054849290611a499084906132f6565b90915550611a5b905061271083613137565b600003611aa4576000611a70612710846130ea565b6001600160a01b0385166000908152600c6020526040812080549293508392909190611a9d9084906132f6565b9091555050505b3360405163543746b160e01b81526001600160a01b03858116600483015260248201849052919091169063543746b190604401600060405180830381600087803b158015611af157600080fd5b505af1158015611b05573d6000803e3d6000fd5b50505050505050565b326000611b1e6201518084613059565b90506001611b2f6201518082613059565b611b3991906130fe565b8111611b875760405162461bcd60e51b815260206004820152601960248201527f4352616e6b3a205465726d206c657373207468616e206d696e000000000000006044820152606401610a68565b611b8f6128bf565b611b9a9060016132f6565b8110611bf75760405162461bcd60e51b815260206004820152602660248201527f4352616e6b3a205465726d206d6f7265207468616e2063757272656e74206d6160448201526578207465726d60d01b6064820152608401610a68565b3360009081526009602052604090206003015415611c575760405162461bcd60e51b815260206004820152601f60248201527f4352616e6b3a204d696e7420616c726561647920696e2070726f6772657373006044820152606401610a68565b6298967f6005541080611c8157506001600160a01b0382166000908152600c602052604090205415155b611ce15760405162461bcd60e51b815260206004820152602b60248201527f4352616e6b3a20496e76616c696420676c6f62616c2072616e6b206f7220706f60448201526a7765722062616c616e636560a81b6064820152608401610a68565b60006040518060c00160405280611cf53390565b6001600160a01b0316815260208101869052604001611d1484426132f6565b81526020016005548152602001611d29612b1a565b8152602001611d36612a69565b90526001600160a01b0384166000908152600c602052604090205490915015801590611d6657506298967f600554115b15611d9a576001600160a01b0383166000908152600c60205260408120805460019290611d949084906130fe565b90915550505b336000908152600960209081526040808320845181546001600160a01b0319166001600160a01b039091161781559184015160018301558301516002820155606083015160038201556080830151600482015560a08301516005909101556006805491611e0683613342565b9190505550611e123390565b6001600160a01b03167fe9149e1b5059238baed02fa659dbf4bd932fbcf760a431330df4d934bc942f378560056000815480929190611e5090613342565b909155506040805192835260208301919091520160405180910390a250505050565b60003381611e808286612139565b905083811015611ee05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a68565b610c2b828686840361217d565b60003361092381858561254d565b600080611f12611f0a87612bf6565b600f0b612c14565b90506000611f4e611f2285612bf6565b611f45611f2e88612bf6565b611f45611f3a8b612bf6565b600f88900b90612cf8565b600f0b90612cf8565b9050611f74611f6c611f616103e8612bf6565b600f84900b90612d36565b600f0b612d8d565b67ffffffffffffffff16925050505b949350505050565b6040518060600160405280602e8152602001613375602e913981565b61093d620151806103e8613059565b326001600160a01b03831614611fde5760405162461bcd60e51b8152600401610a6890613111565b6001600160a01b0382166120045760405162461bcd60e51b8152600401610a6890613195565b600081116120245760405162461bcd60e51b8152600401610a68906131d7565b6001600160a01b0382166000908152600c60205260409020548111156120795760405162461bcd60e51b815260206004820152600a6024820152692732b2b2102837bbb2b960b11b6044820152606401610a68565b6000612087826103e8613059565b905060006120976012600a6132ea565b6120a19083613059565b90506120ad8433610cfd565b6120b7848261271b565b6001600160a01b0384166000908152600b6020526040812080548492906120df9084906132f6565b90915550506001600160a01b0384166000908152600c60205260408120805485929061210c9084906130fe565b90915550506001600160a01b0384166000908152600d602052604081208054859290610e989084906132f6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60016121736201518082613059565b61093d91906130fe565b6001600160a01b0383166121df5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a68565b6001600160a01b0382166122405760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a68565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000806122af85426130fe565b905060006122bc82612da9565b90506000734f2392ef0babfb427e7e05a47547a4dccaf76da8636d5433e68a6005546122e891906130fe565b6040516001600160e01b031960e084901b168152600481019190915260026024820152604401602060405180830381865af415801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f919061335b565b9050600061235f866103e86132f6565b9050600061236f83898c85611efb565b9050606461237d85826130fe565b6123879083613059565b61239191906130ea565b9b9a5050505050505050505050565b6001600160a01b0382166123f65760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a68565b806002600082825461240891906132f6565b90915550506001600160a01b038216600090815260208190526040812080548392906124359084906132f6565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b33600090815260096020526040812080546001600160a01b03191681556001810182905560028101829055600381018290556004810182905560050181905560068054916124cc83613309565b9190505550565b60006124df8484612139565b90506000198114612547578181101561253a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610a68565b612547848484840361217d565b50505050565b6001600160a01b0383166125b15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a68565b6001600160a01b0382166126135760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a68565b6001600160a01b0383166000908152602081905260409020548181101561268b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610a68565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906126c29084906132f6565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161270e91815260200190565b60405180910390a3612547565b6001600160a01b03821661277b5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a68565b6001600160a01b038216600090815260208190526040902054818110156127ef5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a68565b6001600160a01b038316600090815260208190526040812083830390556002805484929061281e9084906130fe565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612295565b6000824211156128b457600061016d61287a8685613059565b61288790620f4240613059565b61289191906130ea565b90506305f5e1006128a28288613059565b6128ac91906130ea565b915050611f83565b506000949350505050565b600061138860055411156129b85760006128ed611f6c6128df600f612bf6565b611f45611f0a600554612bf6565b67ffffffffffffffff16905060006129086201518083613059565b612916620151806064613059565b61292091906132f6565b9050734f2392ef0babfb427e7e05a47547a4dccaf76da8637ae2b5c78261294c620151806103e8613059565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865af415801561298d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b1919061335b565b9250505090565b611023620151806064613059565b604051806080016040528082815260200162015180836129e69190613059565b6129f090426132f6565b8152602001838152602001612a03612aad565b9052336000908152600a602090815260408083208451815591840151600183015583015160028201556060909201516003909201919091556007805491612a4983613342565b91905055508160086000828254612a6091906132f6565b90915550505050565b600080620186a06005546001612a7f9190613059565b612a8991906130ea565b90506064811115612a9c57600091505090565b612aa78160646130fe565b91505090565b600080612abe605a62015180613059565b612ae87f000000000000000000000000000000000000000000000000000000006494af9b426130fe565b612af291906130ea565b905080612b01600260146130fe565b1015612b0f57600291505090565b612aa78160146130fe565b60008062015180612b4b7f000000000000000000000000000000000000000000000000000000006494af9b426130fe565b612b5591906130ea565b9050610bb8811015612bee57734f2392ef0babfb427e7e05a47547a4dccaf76da8636d5433e6612b8783610bb86130fe565b6040516001600160e01b031960e084901b168152600481019190915260016024820152604401602060405180830381865af4158015612bca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa7919061335b565b600191505090565b6000677fffffffffffffff821115612c0d57600080fd5b5060401b90565b60008082600f0b13612c2557600080fd5b6000600f83900b680100000000000000008112612c44576040918201911d5b6401000000008112612c58576020918201911d5b620100008112612c6a576010918201911d5b6101008112612c7b576008918201911d5b60108112612c8b576004918201911d5b60048112612c9b576002918201911d5b60028112612caa576001820191505b603f19820160401b600f85900b607f8490031b6780000000000000005b6000811315612ced5790800260ff81901c8281029390930192607f011c9060011d612cc7565b509095945050505050565b6000600f83810b9083900b0260401d60016001607f1b03198112801590612d26575060016001607f1b038113155b612d2f57600080fd5b9392505050565b600081600f0b600003612d4857600080fd5b600082600f0b604085600f0b901b81612d6357612d636130d4565b05905060016001607f1b03198112801590612d26575060016001607f1b03811315612d2f57600080fd5b60008082600f0b1215612d9f57600080fd5b50600f0b60401d90565b600080612db962015180846130ea565b9050612dc7600160076130fe565b811115612dd75750606392915050565b600060016007612de88460036132f6565b6001901b612df691906130ea565b612e0091906130fe565b604051637ae2b5c760e01b81526004810182905260636024820152909150734f2392ef0babfb427e7e05a47547a4dccaf76da890637ae2b5c790604401602060405180830381865af4158015612e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f83919061335b565b600060208083528351808285015260005b81811015612eab57858101830151858201604001528201612e8f565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114612ee357600080fd5b919050565b60008060408385031215612efb57600080fd5b612f0483612ecc565b946020939093013593505050565b600080600060608486031215612f2757600080fd5b612f3084612ecc565b9250612f3e60208501612ecc565b9150604084013590509250925092565b600060208284031215612f6057600080fd5b612d2f82612ecc565b60008060408385031215612f7c57600080fd5b50508035926020909101359150565b600060208284031215612f9d57600080fd5b5035919050565b60008060008060808587031215612fba57600080fd5b5050823594602084013594506040840135936060013592509050565b60008060408385031215612fe957600080fd5b612ff283612ecc565b915061300060208401612ecc565b90509250929050565b600181811c9082168061301d57607f821691505b60208210810361303d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761092957610929613043565b6020808252601590820152744352616e6b3a204e6f206d696e742065786973747360581b604082015260600190565b6020808252818101527f4352616e6b3a204d696e74206d61747572697479206e6f742072656163686564604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826130f9576130f96130d4565b500490565b8181038181111561092957610929613043565b6020808252600c908201526b24b73b30b634b2102ab9b2b960a11b604082015260600190565b600082613146576131466130d4565b500690565b6020808252602a908201527f416d6f756e74206d7573742062652061206d756c7469706c65206f6620504f5760408201526922a92fa822a92fac22a760b11b606082015260800190565b60208082526022908201527f4275726e3a20596f752063616e74206275726e2066726f6d2061646472657373604082015261020360f41b606082015260800190565b602080825260159082015274109d5c9b8e8810995b1bddc81b5a5b881b1a5b5a5d605a1b604082015260600190565b600181815b8085111561324157816000190482111561322757613227613043565b8085161561323457918102915b93841c939080029061320b565b509250929050565b60008261325857506001610929565b8161326557506000610929565b816001811461327b5760028114613285576132a1565b6001915050610929565b60ff84111561329657613296613043565b50506001821b610929565b5060208310610133831016604e8410600b84101617156132c4575081810a610929565b6132ce8383613206565b80600019048211156132e2576132e2613043565b029392505050565b6000612d2f8383613249565b8082018082111561092957610929613043565b60008161331857613318613043565b506000190190565b60006020828403121561333257600080fd5b81518015158114612d2f57600080fd5b60006001820161335457613354613043565b5060010190565b60006020828403121561336d57600080fd5b505191905056fe50657073204c616220404d724a61636b4c6576696e20406c62656c79616576206661697263727970746f2e6f7267a26469706673582212202371ea85988b70d94cd30cee8efaed7c86900849e00a420c64a727d929a6409a64736f6c63430008120033