false
true
0

Contract Address Details

0xC737bE95a34D2a2D0b788f472f6c8165126dfd27

Token
Pulseium (PSM)
Creator
0x7811eb–1fe369 at 0x10daf3–ca7a58
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
1,741 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25928209
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Pulseium




Optimization enabled
true
Compiler version
v0.8.20+commit.a1b79de6




Optimization runs
200
EVM Version
shanghai




Verified at
2025-07-23T23:27:18.372073Z

Contract source code

// SPDX-License-Identifier: MIT
// File: Pulseium/Context.sol



pragma solidity ^0.8.0;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
	
    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
// File: Pulseium/Ownable.sol



pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
// File: Pulseium/IERC20.sol



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;


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

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

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



pragma solidity ^0.8.0;




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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;

/**
 * @title IDistributor
 * @notice Interface for the Dividend Distributor contract.
 */
interface IDistributor {
    /**
     * @notice Sets distribution criteria such as minimum period and minimum distribution.
     * @param minPeriod Minimum time between claims for a shareholder (in seconds).
     * @param minDistribution Minimum amount of reward (in wei) to trigger a distribution.
     */
    function setDistributionCriteria(uint256 minPeriod, uint256 minDistribution) external;

    /**
     * @notice Sets the share of a specific shareholder.
     * @param shareholder Address of the shareholder.
     * @param amount Number of tokens held by the shareholder.
     */
    function setShare(address shareholder, uint256 amount) external;

    /**
     * @notice Deposit native tokens (e.g., PLS or ETH) into the distributor to be shared.
     */
    function deposit() external payable;

    /**
     * @notice Distributes rewards to shareholders using the specified gas limit.
     * @param gas Maximum gas to use for distribution loop.
     */
    function process(uint256 gas) external;
}

/**
 * @title ReentrancyGuard
 * @notice Protects against reentrant calls to functions using a simple status lock.
 */
abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;
    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     */
    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        _status = _ENTERED;
        _;
        _status = _NOT_ENTERED;
    }
}

/**
 * @title Distributor
 * @notice Manages dividend distribution to token holders proportionally to their share.
 * @dev Only callable by the token contract (owner). Uses ReentrancyGuard to prevent claim loops.
 */
contract Distributor is IDistributor, ReentrancyGuard {
    /// @notice Address of the token contract that owns this distributor.
    address owner;
	
    /**
     * @notice Stores shareholder-specific information for dividend tracking.
     * @param amount Number of shares (tokens) the shareholder holds.
     * @param totalExcluded Cumulative dividends excluded from this shareholder (to avoid double-counting).
     * @param totalRealised Total amount of dividends the shareholder has received.
     */
    struct Share {
        uint256 amount;
        uint256 totalExcluded;
        uint256 totalRealised;
    }
	
    /// @notice List of all current shareholders.
    address[] shareholders;

    /// @notice Mapping from shareholder address to their index in the `shareholders` array.
    mapping (address => uint256) public shareholderIndexes;

    /// @notice Timestamp of the last claim for each shareholder.
    mapping (address => uint256) public shareholderClaims;

    /// @notice Mapping from address to their share details.
    mapping (address => Share) public shares;

    /// @notice Emitted when the distribution criteria are updated.
    /// @param minPeriod Minimum time between distributions (in seconds).
    /// @param minDistribution Minimum amount of dividends to trigger a distribution (in wei).
    event DistributionCriteriaUpdate(uint256 minPeriod, uint256 minDistribution);

    /// @notice Emitted when new funds are deposited into the distributor.
    /// @param amount Amount of native tokens (e.g., PLS or ETH) deposited.
    event NewFundDeposit(address indexed depositor, uint256 amount);
	
	/// @notice Emitted when dividends are distributed to a shareholder.
	/// @param shareholder The address receiving the dividend.
	/// @param amount The amount of native tokens (PLS) distributed.
	event DividendDistributed(address indexed shareholder, uint256 amount);

    /// @notice Total number of shares held by all shareholders.
    uint256 public totalShares;

    /// @notice Total amount of dividends that have been deposited.
    uint256 public totalDividends;

    /// @notice Total amount of dividends that have been distributed.
    uint256 public totalDistributed;

    /// @notice Dividends per share scaled by the `dividendsPerShareAccuracyFactor`.
    uint256 public dividendsPerShare;

    /// @notice Factor used to maintain precision when calculating dividends per share.
    uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;

    /// @notice Minimum time between dividend distributions for each shareholder (in seconds).
    uint256 public minPeriod = 10;

    /// @notice Minimum dividend amount (in wei) required to trigger a distribution.
    uint256 public minDistribution = 1 * (10**10);

    /// @notice Current index used to iterate through shareholders during processing.
    uint256 currentIndex;
	
	/**
     * @dev Modifier to restrict access to the contract owner.
     */
    modifier onlyOwner() {
        require(msg.sender == owner, "!Token"); _;
    }
	
    constructor () {
        owner = msg.sender;
    }
	
	/**
     * @notice Accepts incoming native token transfers (PLS, ETH).
     */
	receive() external payable {}
	
	/**
     * @inheritdoc IDistributor
     */
    function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external override onlyOwner {
        minPeriod = _minPeriod;
        minDistribution = _minDistribution;
		emit DistributionCriteriaUpdate(minPeriod, minDistribution);
    }
	
	/**
     * @inheritdoc IDistributor
     */
    function setShare(address shareholder, uint256 amount) external override onlyOwner {
        if(shares[shareholder].amount > 0)
		{
			distributeDividend(shareholder);
        }
		if(amount > 0 && shares[shareholder].amount == 0)
		{
            addShareholder(shareholder);
        }
		else if(amount == 0 && shares[shareholder].amount > 0)
		{
           removeShareholder(shareholder);
        }
        totalShares = totalShares - shares[shareholder].amount + amount;
        shares[shareholder].amount = amount;
        shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
    }

	/**
     * @inheritdoc IDistributor
     */
    function deposit() external override onlyOwner payable {
		totalDividends += msg.value;
		dividendsPerShare += ((dividendsPerShareAccuracyFactor * msg.value) / totalShares);
		emit NewFundDeposit(msg.sender, msg.value);
    }
	
	/**
     * @inheritdoc IDistributor
     */
    function process(uint256 gas) external override onlyOwner {
        uint256 shareholderCount = shareholders.length;

        if(shareholderCount == 0) { return; }

        uint256 gasUsed = 0;
        uint256 gasLeft = gasleft();

        uint256 iterations = 0;

        while(gasUsed < gas && iterations < shareholderCount) {
            if(currentIndex >= shareholderCount)
			{
                currentIndex = 0;
            }
            if(shouldDistribute(shareholders[currentIndex]))
			{
                distributeDividend(shareholders[currentIndex]);
            }
            gasUsed = gasUsed + gasLeft - gasleft();
            gasLeft = gasleft();
            currentIndex++;
            iterations++;
        }
    }

	/**
     * @notice Determines if a shareholder is eligible for a distribution.
     * @param shareholder Address of the shareholder.
     * @return Whether the shareholder should receive a distribution.
	 */
    function shouldDistribute(address shareholder) private view returns (bool) {
        return (shareholderClaims[shareholder] + minPeriod) < block.timestamp && getUnpaidEarnings(shareholder) > minDistribution;
    }
	
	/**
     * @notice Distributes available earnings to a shareholder.
     * @param shareholder Address to distribute to.
     */
    function distributeDividend(address shareholder) private {
        if(shares[shareholder].amount == 0){ return; }
		
        uint256 amount = getUnpaidEarnings(shareholder);
        if(amount > 0) 
		{
		    (bool success, ) = shareholder.call{value: amount}("");
			if(success)
			{
			   totalDistributed += amount;
			   shareholderClaims[shareholder] = block.timestamp;
			   shares[shareholder].totalRealised = shares[shareholder].totalRealised + amount;
			   shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
			   emit DividendDistributed(shareholder, amount);
			}
        }
    }
	
	/**
     * @notice Claims available dividends for the sender.
     * @dev Protected by nonReentrant to avoid recursive distribution.
     */
    function claimReward() external nonReentrant {
	   if(shouldDistribute(msg.sender)) 
	   {
		  distributeDividend(msg.sender);
	   }
    }
	
	/**
     * @notice Calculates unpaid earnings for a shareholder.
     * @param shareholder Address of the shareholder.
     * @return The amount of unpaid earnings.
     */
    function getUnpaidEarnings(address shareholder) public view returns (uint256) {
        if(shares[shareholder].amount == 0){ return 0; }

        uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
        uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;

        if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }
        return shareholderTotalDividends - shareholderTotalExcluded;
    }

	/**
     * @notice Calculates the total dividends for a given amount of shares.
     * @param share The number of shares.
     * @return The total cumulative dividends for those shares.
     */
    function getCumulativeDividends(uint256 share) private view returns (uint256) {
        return share * dividendsPerShare / dividendsPerShareAccuracyFactor;
    }

	/**
     * @notice Adds a shareholder to the list.
     * @param shareholder Address to add.
    */
    function addShareholder(address shareholder) private {
        shareholderIndexes[shareholder] = shareholders.length;
        shareholders.push(shareholder);
    }
	
	/**
     * @notice Removes a shareholder from the list.
     * @param shareholder Address to remove.
     */
    function removeShareholder(address shareholder) private {
        shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
        shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
        shareholders.pop();
    }
}
// File: Pulseium/IPulseX.sol



pragma solidity 0.8.20;

/// @title PulseX Factory Interface
/// @notice Interface for creating liquidity pairs on PulseX
interface IPulseXFactory {
    /// @notice Creates a new trading pair between two tokens
    /// @param tokenA Address of the first token
    /// @param tokenB Address of the second token
    /// @return pair Address of the newly created pair contract
    function createPair(address tokenA, address tokenB) external returns (address pair);
}

/// @title PulseX Router Interface
/// @notice Interface for interacting with PulseX Router for swaps and liquidity
interface IPulseXRouter {
    /// @notice Returns the address of the factory contract
    /// @return Address of the PulseX factory
    function factory() external pure returns (address);

    /// @notice Returns the address of the wrapped PLS token (WPLS)
    /// @return Address of the WPLS token
    function WPLS() external pure returns (address);

    /**
     * @notice Swaps an exact amount of input tokens for ETH
     * @dev Supports fee-on-transfer tokens
     * @param amountIn Amount of input tokens to send
     * @param amountOutMin Minimum amount of ETH to receive
     * @param path Array of token addresses for the swap path
     * @param to Address to receive the ETH
     * @param deadline Unix timestamp after which the transaction will revert
     */
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

    /**
     * @notice Adds liquidity to an ETH/token pair
     * @param token Address of the ERC20 token
     * @param amountTokenDesired Amount of tokens to add as liquidity
     * @param amountTokenMin Minimum amount of tokens to add (slippage control)
     * @param amountETHMin Minimum amount of ETH to add (slippage control)
     * @param to Address to receive liquidity tokens
     * @param deadline Unix timestamp after which the transaction will revert
     * @return amountToken Amount of tokens added
     * @return amountETH Amount of ETH added
     * @return liquidity Amount of liquidity tokens received
     */
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
}

/// @title PulseX Pair Interface
/// @notice Interface for querying pair token addresses in a PulseX liquidity pool
interface IPulseXPair {
    /// @notice Returns the address of token0 in the pair
    /// @return Address of token0
    function token0() external view returns (address);

    /// @notice Returns the address of token1 in the pair
    /// @return Address of token1
    function token1() external view returns (address);
}

// File: Pulseium/Pulseium.sol

pragma solidity 0.8.20;






/// @title Pulseium Token Contract
/// @author 
/// @notice Custom ERC20 token with auto liquidity, reward distribution, and fee mechanisms on PulseChain
/// @dev Uses PulseXRouter for swaps and liquidity. Rewards distributed via custom Distributor contract.
contract Pulseium is Ownable, ERC20 {

	/// @notice Fee taken for reward distribution
	uint256 public immutable rewardFee;
	
	/// @notice Fee taken for burning
	uint256 public immutable burnFee;
	
	/// @notice Fee taken for adding liquidity
	uint256 public immutable liquidityFee;
	
	/// @notice Total fee that gets swapped (liquidity + reward)
	uint256 private immutable swappableFee;
	
	/// @notice Denominator for fee calculation (e.g. 10000 for basis points)
	uint256 private immutable divider;
	
	/// @notice Denominator for share calculation (e.g. 100 for basis points)
	uint256 private immutable shareDivider;

	/// @notice Gas limit for reward distributor processing
	uint256 public distributorGas;
	
	/// @notice Minimum token threshold before swap and liquify
	uint256 public swapThreshold;
	
	/// @notice Flag indicating if the contract is currently performing a swap
	bool private swapping;
	
	/// @notice Whether trading is enabled
	bool public tradingEnabled;
	
	/// @notice Whether reward distribution is enabled
	bool public distributionEnabled;
	
	/// @notice List of recognized liquidity pair addressess
	address[] public liquidityPairs;
	
	/// @notice Address to which burned tokens are sent
	address public immutable burnWallet;
	
	/// @notice Main PulseX pair address
	address public immutable pulsexPair;
	
	/// @notice PulseX Router interface
	IPulseXRouter public immutable pulsexRouter;
	
	/// @notice Custom reward distributor instance
	Distributor public rewardDistributor;
	
	/// @notice Wallets excluded from fees
    mapping(address => bool) public isExcludedFromFee;
	
	/// @notice Wallets excluded from rewards
    mapping(address => bool) public isExcludedFromReward;
	
	/// @notice Mapping for identifying liquidity pair addresses
	mapping(address => bool) public isLiquidityPair;
	
	/// @notice Shares for each LP pair in the reward calculation
	mapping(address => uint256) public liquidityPairShare;
	
	/// @notice Emitted when the swap threshold is updated
	event SwapThresholdUpdated(uint256 amount);

    /// @notice Emitted when a liquidity pair is added or removed
	event LPPairUpdated(address indexed pair, bool status);

    /// @notice Emitted when a wallet is excluded or included in fees
	event WalletExcludeFromFee(address indexed wallet, bool status);

    /// @notice Emitted when a wallet is excluded or included in rewards
	event WalletExcludedFromReward(address indexed wallet, bool value);

    /// @notice Emitted when reward distribution criteria are updated
	event DistributionCriteriaUpdated(uint256 minPeriod, uint256 minDistribution);

    /// @notice Emitted when the gas limit for distributor is updated
	event DistributorGasUpdated(uint256 distributorGas);

    /// @notice Emitted when trading is enabled
	event TradingEnabled();

    /// @notice Emitted when adding liquidity fails
	event LiquidityAddFailed(uint256 tokenAmount, uint256 plsAmount);

    /// @notice Emitted when swapping tokens for PLS fails
	event SwapFailed(uint256 tokenAmount);
	
	/// @notice Emitted when reward distribution is enabled or disabled
	event DistributionStatusUpdated(bool status);
	
	/// @notice Emitted when lp share update
	event LPPairShareUpdated(address indexed pair, uint256 newShare);
	
	/// @notice Constructor to initialize token and setup fees, LP, and exclusions
	constructor() ERC20("Pulseium", "PSM") {
	
		pulsexRouter = IPulseXRouter(0x165C3410fC91EF562C50559f7d2289fEbed552d9);
		pulsexPair = IPulseXFactory(pulsexRouter.factory()).createPair(address(this), pulsexRouter.WPLS());
		rewardDistributor = new Distributor();
		burnWallet = address(0x0000000000000000000000000000000000000369);
	
		distributionEnabled = true;
		
		rewardFee = 350;
		burnFee = 50;
		liquidityFee = 100;
		swappableFee = (rewardFee + liquidityFee);
		divider = 10000;
		shareDivider = 100;
		
		distributorGas = 250000;
		swapThreshold = 250_000_000 * (10**18);
		
		isLiquidityPair[address(pulsexPair)] = true;
	   
		isExcludedFromFee[address(msg.sender)] = true;
		isExcludedFromFee[address(this)] = true;
		isExcludedFromFee[address(burnWallet)] = true;
	   
		isExcludedFromReward[address(this)] = true;
		isExcludedFromReward[address(pulsexPair)] = true;
		isExcludedFromReward[address(burnWallet)] = true;
		
		liquidityPairs.push(pulsexPair);
		_mint(address(msg.sender), 1_555_369_000_000 * (10**18));
    }
	
	/// @notice Allows the contract to receive native PLS
	receive() external payable {}
	
	/// @notice Updates the minimum token amount before swap is triggered
    /// @param _amount New threshold in token units
	function updateSwapThreshold(uint256 _amount) external onlyOwner {
  	    require(_amount <= totalSupply(), "Amount cannot be over the total supply.");
		require(_amount >= 1000 * (10**18), "Minimum `1000` token per swap required");
		
		swapThreshold = _amount;
		emit SwapThresholdUpdated(_amount);
  	}
	
	/// @notice Excludes or includes a wallet from paying fees
    /// @param _wallet Address of the wallet
    /// @param _status True to exclude, false to include
	function excludeWalletFromFee(address _wallet, bool _status) external onlyOwner {
        require(_wallet != address(0), "Wallet address is not correct");
		require(isExcludedFromFee[_wallet] != _status, "Wallet is already the value of 'status'");
		
		isExcludedFromFee[_wallet] = _status;
		emit WalletExcludeFromFee(_wallet, _status);
    }
	
	/// @notice Enables token trading
	function enableTrading() external onlyOwner {
		require(!tradingEnabled, "Trading already enabled");
		
		tradingEnabled = true;
		emit TradingEnabled();
	}
	
	/// @notice Excludes or includes a wallet from receiving rewards
    /// @param _wallet Address of the wallet
    /// @param _status True to exclude, false to include
	function excludeWalletFromReward(address _wallet, bool _status) external onlyOwner {
	    require(_wallet != address(0), "Zero address");
	    require(isExcludedFromReward[_wallet] != _status, "Wallet is already the value of 'status'");
		
	    isExcludedFromReward[_wallet] = _status;
		if(_status) {
			try rewardDistributor.setShare(_wallet, 0) {} catch {}
        } else {
			_updateShares(_wallet);
        }
	    emit WalletExcludedFromReward(_wallet, _status);
	}
	
	/// @notice Sets the reward distribution timing and minimum thresholds
    /// @param _minPeriod Minimum time between distributions
    /// @param _minDistribution Minimum token amount required for a distribution
	function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external onlyOwner {
	    require(_minDistribution > 0, "Min. distribution can't be zero");
		
        try rewardDistributor.setDistributionCriteria(_minPeriod, _minDistribution) {} catch {}
		emit DistributionCriteriaUpdated(_minPeriod, _minDistribution);
    }
	
	/// @notice Sets the gas limit for the distributor
    /// @param _gas New gas limit
	function setDistributorGas(uint256 _gas) external onlyOwner {
       require(_gas < 750000, "Gas is greater than limit");
	   
       distributorGas = _gas;
	   emit DistributorGasUpdated(_gas);
    }
	
	/// @notice Enables or disables reward distribution
	/// @param status True to enable, false to disable
	function setDistributionStatus(bool status) external onlyOwner {
		distributionEnabled = status;
		emit DistributionStatusUpdated(status);
	}
	
	/// @notice Adds or removes a liquidity pair
    /// @param _pair The LP token address
    /// @param _status True to add, false to remove
    /// @param _share The share of the LP in reward calculations (basis points)
	function setLiquidityPair(address _pair, bool _status, uint256 _share) external onlyOwner {
        require(isLiquidityPair[_pair] != _status, "Pair is already set to that status");
		require(_pair != address(pulsexPair), "Can't update the status of main pair");
		
		if(_status)
		{
			require(isValidLiquidityPair(_pair), "Invalid liquidity pair");
			require(_share > 0, "Share must be greater than zero");
			
			liquidityPairs.push(_pair);
			isLiquidityPair[_pair] = _status;
			isExcludedFromReward[_pair] = _status;
			liquidityPairShare[_pair] = _share;
		}
		else if(isLiquidityPair[_pair])
		{
			for (uint256 i = 0; i < liquidityPairs.length; i++) {
				if (liquidityPairs[i] == _pair) {
					liquidityPairs[i] = liquidityPairs[liquidityPairs.length - 1];
					liquidityPairs.pop();
					break;
				}
			}
			liquidityPairShare[_pair] = 0;
			isLiquidityPair[_pair] = _status;
			isExcludedFromReward[_pair] = _status;
		}
		emit LPPairUpdated(_pair, _status);
    }
	
	/// @notice Updates the share of an existing liquidity pair
	/// @param _pair The LP token address
	/// @param _newShare The new share value in basis points (must be > 0)
	function updateLiquidityPairShare(address _pair, uint256 _newShare) external onlyOwner {
		require(isLiquidityPair[_pair], "Not a registered liquidity pair");
		require(_newShare > 0, "Share must be greater than zero");

		liquidityPairShare[_pair] = _newShare;
		emit LPPairShareUpdated(_pair, _newShare);
	}
	
	/// @notice Checks if the address is a valid LP pair (includes this token)
    /// @param _pair The LP token address
    /// @return Whether the pair is valid
	function isValidLiquidityPair(address _pair) private view returns (bool) {
		try IPulseXPair(_pair).token0() returns (address token0) {
			address token1 = IPulseXPair(_pair).token1();
			return (token0 == address(this) || token1 == address(this));
		} catch {
			return false;
		}
	}
	
	/// @dev Overridden ERC20 transfer to handle fee collection, swapping, and reward tracking
	function _transfer(address _sender, address _recipient, uint256 _amount) internal override(ERC20) {      
		if (!tradingEnabled) {
			require(_sender == owner() || _recipient == owner(), "Trading not enabled");
		}
		
		if(!swapping && isLiquidityPair[_recipient])  {
			uint256 contractTokenBalance = balanceOf(address(this));
			if(contractTokenBalance >= swapThreshold) {
				swapping = true;
				
				uint256 liqudityToken = (((swapThreshold * liquidityFee) / (swappableFee)) / (2));
				uint256 rewardToken = ((swapThreshold * rewardFee) / (swappableFee));
				uint256 swapToken = (liqudityToken + rewardToken);
				
				swapTokensForPLS(swapToken);
				
				uint256 PLSBalance = address(this).balance;
				uint256 liqudityShare = (PLSBalance * liqudityToken) / (swapToken);
				uint256 rewardShare = (PLSBalance - liqudityShare);
				
				if(liqudityShare > 0) {
					addLiquidity(liqudityToken, liqudityShare);
				} 
				if(rewardShare > 0) {
					try rewardDistributor.deposit{value: rewardShare}() {} catch {}
				}
				swapping = false;
			}
        }
		
		if(isExcludedFromFee[_sender] || isExcludedFromFee[_recipient] || (!isLiquidityPair[_sender] && !isLiquidityPair[_recipient])) {
			super._transfer(_sender, _recipient, _amount);
		} else {
		    (uint256 _burnFee, uint256 _swappableFee) = collectFee(_amount);
		    if(_swappableFee > 0) {
				super._transfer(_sender, address(this), _swappableFee);
		    }
			if(_burnFee > 0) {
				super._transfer(_sender, address(burnWallet), _burnFee);
		    }
			super._transfer(_sender, _recipient, (_amount - (_swappableFee + _burnFee)));
		}
		if(!isExcludedFromReward[_sender]){ _updateShares(_sender); }
        if(!isExcludedFromReward[_recipient]){ _updateShares(_recipient); }
		if(distributionEnabled){
			try rewardDistributor.process(distributorGas) {} catch {}
		}
    }
	
	/// @notice Updates reward shares for a holder
    /// @param _holder Address of the token or LP holder
	function _updateShares(address _holder) private {
		if (isExcludedFromReward[_holder]) return;
		
		uint256 totalBalance = balanceOf(_holder);
		
		for (uint256 i = 0; i < liquidityPairs.length; i++)  {
			address pair = liquidityPairs[i];
			totalBalance += (((IERC20(pair).balanceOf(_holder) * liquidityPairShare[pair])) / (shareDivider));
		}
		try rewardDistributor.setShare(_holder, totalBalance) {} catch {}
	}
	
	/// @notice Calculates burn and other fee from the amount
    /// @param _amount Token amount
    /// @return burn fee and other fees in tokens
	function collectFee(uint256 _amount) private view returns  (uint256, uint256) {
		uint256 _rewardFee = (_amount * rewardFee) / (divider);
		uint256 _liquidityFee = (_amount * liquidityFee) / (divider);
		uint256 _burnFee = (_amount * burnFee) / (divider);
		
        return (_burnFee, (_rewardFee + _liquidityFee));
    }
	
	/// @notice Swaps tokens to PLS via PulseX
    /// @param _tokenAmount Amount of tokens to swap
	function swapTokensForPLS(uint256 _tokenAmount) private {
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = pulsexRouter.WPLS();
		
        _approve(address(this), address(pulsexRouter), _tokenAmount);
        try pulsexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            _tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        ){} catch {
			emit SwapFailed(_tokenAmount);
		}
    }
	
	/// @notice Adds liquidity to PulseX
    /// @param _tokenAmount Amount of tokens to add
    /// @param _PLSAmount Amount of PLS to pair with tokens
	function addLiquidity(uint256 _tokenAmount, uint256 _PLSAmount) private {
        _approve(address(this), address(pulsexRouter), _tokenAmount);
        try pulsexRouter.addLiquidityETH{value: _PLSAmount}(
            address(this),
            _tokenAmount,
            0, 
            0,
            address(this),
            block.timestamp
        ){} catch {
		   emit LiquidityAddFailed(_tokenAmount, _PLSAmount);
		}
    }
}
        

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":"DistributionCriteriaUpdated","inputs":[{"type":"uint256","name":"minPeriod","internalType":"uint256","indexed":false},{"type":"uint256","name":"minDistribution","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DistributionStatusUpdated","inputs":[{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"DistributorGasUpdated","inputs":[{"type":"uint256","name":"distributorGas","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LPPairShareUpdated","inputs":[{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"uint256","name":"newShare","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LPPairUpdated","inputs":[{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"LiquidityAddFailed","inputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"plsAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SwapFailed","inputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SwapThresholdUpdated","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TradingEnabled","inputs":[],"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":"WalletExcludeFromFee","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"WalletExcludedFromReward","inputs":[{"type":"address","name":"wallet","internalType":"address","indexed":true},{"type":"bool","name":"value","internalType":"bool","indexed":false}],"anonymous":false},{"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":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burnFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"burnWallet","inputs":[]},{"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":"bool","name":"","internalType":"bool"}],"name":"distributionEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributorGas","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableTrading","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"excludeWalletFromFee","inputs":[{"type":"address","name":"_wallet","internalType":"address"},{"type":"bool","name":"_status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"excludeWalletFromReward","inputs":[{"type":"address","name":"_wallet","internalType":"address"},{"type":"bool","name":"_status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromFee","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromReward","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isLiquidityPair","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidityFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidityPairShare","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"liquidityPairs","inputs":[{"type":"uint256","name":"","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":"address","name":"","internalType":"address"}],"name":"pulsexPair","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPulseXRouter"}],"name":"pulsexRouter","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract Distributor"}],"name":"rewardDistributor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributionCriteria","inputs":[{"type":"uint256","name":"_minPeriod","internalType":"uint256"},{"type":"uint256","name":"_minDistribution","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributionStatus","inputs":[{"type":"bool","name":"status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributorGas","inputs":[{"type":"uint256","name":"_gas","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLiquidityPair","inputs":[{"type":"address","name":"_pair","internalType":"address"},{"type":"bool","name":"_status","internalType":"bool"},{"type":"uint256","name":"_share","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"swapThreshold","inputs":[]},{"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":"bool","name":"","internalType":"bool"}],"name":"tradingEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateLiquidityPairShare","inputs":[{"type":"address","name":"_pair","internalType":"address"},{"type":"uint256","name":"_newShare","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSwapThreshold","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x6101a060405234801562000011575f80fd5b506040518060400160405280600881526020016750756c736569756d60c01b8152506040518060400160405280600381526020016250534d60e81b81525062000069620000636200039660201b60201c565b6200039a565b600462000077838262000580565b50600562000086828262000580565b505073165c3410fc91ef562c50559f7d2289febed552d96101808190526040805163c45a015560e01b8152905191925063c45a01559160048083019260209291908290030181865afa158015620000df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000105919062000648565b6001600160a01b031663c9c6539630610180516001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000154573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200017a919062000648565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af1158015620001c5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001eb919062000648565b6001600160a01b0316610160526040516200020690620004d3565b604051809103905ff08015801562000220573d5f803e3d5ffd5b50600a80546001600160a01b03929092166001600160a01b0319909216919091179055610369610140526008805462ff000019166201000017905561015e6080819052603260a052606460c08190526200027a9162000677565b60e052612710610100526064610120526203d0906006556acecb8f27f4200f3a000000600755610160516001600160a01b039081165f818152600d602090815260408083208054600160ff19918216811790925533808652600b85528386208054831684179055308087528487208054841685179055610140519098168087528487208054841685179055978652600c90945282852080548216831790558585528285208054821683179055958452908320805490951681179094556009805494850181559091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af90920180546001600160a01b031916909117905562000390906c13a1ab1508d490547a49000000620003e9565b6200069d565b3390565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620004445760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060035f82825462000457919062000677565b90915550506001600160a01b0382165f90815260016020526040812080548392906200048590849062000677565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b505050565b610c5b8062002f5083390190565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200050a57607f821691505b6020821081036200052957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115620004ce575f81815260208120601f850160051c81016020861015620005575750805b601f850160051c820191505b81811015620005785782815560010162000563565b505050505050565b81516001600160401b038111156200059c576200059c620004e1565b620005b481620005ad8454620004f5565b846200052f565b602080601f831160018114620005ea575f8415620005d25750858301515b5f19600386901b1c1916600185901b17855562000578565b5f85815260208120601f198616915b828110156200061a57888601518255948401946001909101908401620005f9565b50858210156200063857878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f6020828403121562000659575f80fd5b81516001600160a01b038116811462000670575f80fd5b9392505050565b808201808211156200069757634e487b7160e01b5f52601160045260245ffd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516127e46200076c5f395f81816106bc01528181611e3501528181611eec01528181611f2801528181611fce015261202901525f818161043e0152610ffa01525f818161026f01526119f801525f611bed01525f81816122aa01528181612302015261235a01525f81816117b0015261181401525f818161062c015281816117d6015261232601525f818161078a015261237e01525f81816105c90152818161183501526122ce01526127e45ff3fe60806040526004361061022b575f3560e01c806370a0823111610129578063a457c2d7116100a8578063dd62ed3e1161006d578063dd62ed3e146106fd578063f0f2c9ef1461071c578063f2fde38b1461073b578063f9a580f81461075a578063fce589d814610779575f80fd5b8063a457c2d71461064e578063a9059cbb1461066d578063acc2166a1461068c578063b9b6f9b6146106ab578063cc274b29146106de575f80fd5b80638a8c523c116100ee5780638a8c523c146105a45780638b424267146105b85780638da5cb5b146105eb57806395d89b411461060757806398118cb41461061b575f80fd5b806370a08231146104f0578063715018a6146105245780637803deaa14610538578063866083261461055757806388f8202014610576575f80fd5b8063244ce7db116101b55780634c62f0931161017a5780634c62f0931461042d5780635342acb4146104605780635c9a05b81461048e57806360e71962146104bc57806364dfd203146104d1575f80fd5b8063244ce7db146103975780632d48e896146103b6578063313ce567146103d557806339509351146103f05780634ada218b1461040f575f80fd5b80630a2d140c116101fb5780630a2d140c146102f957806318160ddd1461031a5780631b7a1fb21461032e5780631ba765401461034d57806323b872dd14610378575f80fd5b80630445b66714610236578063062287491461025e57806306fdde03146102a9578063095ea7b3146102ca575f80fd5b3661023257005b5f80fd5b348015610241575f80fd5b5061024b60075481565b6040519081526020015b60405180910390f35b348015610269575f80fd5b506102917f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610255565b3480156102b4575f80fd5b506102bd6107ac565b60405161025591906123c6565b3480156102d5575f80fd5b506102e96102e4366004612425565b61083c565b6040519015158152602001610255565b348015610304575f80fd5b5061031861031336600461245e565b610855565b005b348015610325575f80fd5b5060035461024b565b348015610339575f80fd5b5061029161034836600461247e565b6108b3565b348015610358575f80fd5b5061024b610367366004612495565b600e6020525f908152604090205481565b348015610383575f80fd5b506102e96103923660046124b0565b6108db565b3480156103a2575f80fd5b506103186103b136600461247e565b6108fe565b3480156103c1575f80fd5b506103186103d03660046124ee565b610992565b3480156103e0575f80fd5b5060405160128152602001610255565b3480156103fb575f80fd5b506102e961040a366004612425565b610a83565b34801561041a575f80fd5b506008546102e990610100900460ff1681565b348015610438575f80fd5b506102917f000000000000000000000000000000000000000000000000000000000000000081565b34801561046b575f80fd5b506102e961047a366004612495565b600b6020525f908152604090205460ff1681565b348015610499575f80fd5b506102e96104a8366004612495565b600d6020525f908152604090205460ff1681565b3480156104c7575f80fd5b5061024b60065481565b3480156104dc575f80fd5b506103186104eb36600461250e565b610aa4565b3480156104fb575f80fd5b5061024b61050a366004612495565b6001600160a01b03165f9081526001602052604090205490565b34801561052f575f80fd5b50610318610ba0565b348015610543575f80fd5b5061031861055236600461250e565b610bb3565b348015610562575f80fd5b506008546102e99062010000900460ff1681565b348015610581575f80fd5b506102e9610590366004612495565b600c6020525f908152604090205460ff1681565b3480156105af575f80fd5b50610318610d16565b3480156105c3575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105f6575f80fd5b505f546001600160a01b0316610291565b348015610612575f80fd5b506102bd610daf565b348015610626575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b348015610659575f80fd5b506102e9610668366004612425565b610dbe565b348015610678575f80fd5b506102e9610687366004612425565b610e38565b348015610697575f80fd5b50600a54610291906001600160a01b031681565b3480156106b6575f80fd5b506102917f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e9575f80fd5b506103186106f836600461247e565b610e45565b348015610708575f80fd5b5061024b610717366004612541565b610f4c565b348015610727575f80fd5b50610318610736366004612578565b610f76565b348015610746575f80fd5b50610318610755366004612495565b611363565b348015610765575f80fd5b50610318610774366004612425565b6113dc565b348015610784575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b6060600480546107bb906125b3565b80601f01602080910402602001604051908101604052809291908181526020018280546107e7906125b3565b80156108325780601f1061080957610100808354040283529160200191610832565b820191905f5260205f20905b81548152906001019060200180831161081557829003601f168201915b5050505050905090565b5f336108498185856114e6565b60019150505b92915050565b61085d611609565b60088054821515620100000262ff0000199091161790556040517fb38aef214af8a01121ddda7dd915117d0bbe821c96b4ab3915f4cee420bb54d9906108a890831515815260200190565b60405180910390a150565b600981815481106108c2575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f336108e8858285611662565b6108f38585856116da565b506001949350505050565b610906611609565b620b71b0811061095d5760405162461bcd60e51b815260206004820152601960248201527f4761732069732067726561746572207468616e206c696d69740000000000000060448201526064015b60405180910390fd5b60068190556040518181527f5f0cf7d11c1aaf2b53b91892382eaee789338051f9fcecf528ca006d062bfba8906020016108a8565b61099a611609565b5f81116109e95760405162461bcd60e51b815260206004820152601f60248201527f4d696e2e20646973747269627574696f6e2063616e2774206265207a65726f006044820152606401610954565b600a546040516316a4744b60e11b815260048101849052602481018390526001600160a01b0390911690632d48e896906044015f604051808303815f87803b158015610a33575f80fd5b505af1925050508015610a44575060015b5060408051838152602081018390527f4bee245ad45dacfa3feb4cc8a61ace735c47b485fb8a399ce9e3f6c87aade41891015b60405180910390a15050565b5f33610849818585610a958383610f4c565b610a9f91906125ff565b6114e6565b610aac611609565b6001600160a01b038216610b025760405162461bcd60e51b815260206004820152601d60248201527f57616c6c65742061646472657373206973206e6f7420636f72726563740000006044820152606401610954565b6001600160a01b0382165f908152600b602052604090205481151560ff909116151503610b415760405162461bcd60e51b815260040161095490612612565b6001600160a01b0382165f818152600b6020908152604091829020805460ff191685151590811790915591519182527f793188c766da601299dd85f7f21348a41b2cb4cadf893f2155f210d64fc049b891015b60405180910390a25050565b610ba8611609565b610bb15f611b02565b565b610bbb611609565b6001600160a01b038216610c005760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606401610954565b6001600160a01b0382165f908152600c602052604090205481151560ff909116151503610c3f5760405162461bcd60e51b815260040161095490612612565b6001600160a01b0382165f908152600c60205260409020805460ff19168215801591909117909155610cd057600a54604051630a5b654b60e11b81526001600160a01b0384811660048301525f6024830152909116906314b6ca96906044015f604051808303815f87803b158015610cb5575f80fd5b505af1925050508015610cc6575060015b15610cd957610cd9565b610cd982611b51565b816001600160a01b03167f21dfac5ff6a7cc530320d4cb002a96edf0c323b87dbe9eb9a4c39a5c3a62cbb982604051610b94911515815260200190565b610d1e611609565b600854610100900460ff1615610d765760405162461bcd60e51b815260206004820152601760248201527f54726164696e6720616c726561647920656e61626c65640000000000000000006044820152606401610954565b6008805461ff0019166101001790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7905f90a1565b6060600580546107bb906125b3565b5f3381610dcb8286610f4c565b905083811015610e2b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610954565b6108f382868684036114e6565b5f336108498185856116da565b610e4d611609565b600354811115610eaf5760405162461bcd60e51b815260206004820152602760248201527f416d6f756e742063616e6e6f74206265206f7665722074686520746f74616c2060448201526639bab838363c9760c91b6064820152608401610954565b683635c9adc5dea00000811015610f175760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d2060313030306020746f6b656e2070657220737761702072656044820152651c5d5a5c995960d21b6064820152608401610954565b60078190556040518181527f18ff2fc8464635e4f668567019152095047e34d7a2ab4b97661ba4dc7fd06476906020016108a8565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205490565b610f7e611609565b6001600160a01b0383165f908152600d602052604090205482151560ff909116151503610ff85760405162461bcd60e51b815260206004820152602260248201527f5061697220697320616c72656164792073657420746f20746861742073746174604482015261757360f01b6064820152608401610954565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110855760405162461bcd60e51b8152602060048201526024808201527f43616e2774207570646174652074686520737461747573206f66206d61696e206044820152633830b4b960e11b6064820152608401610954565b81156111b25761109483611ceb565b6110d95760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103634b8bab4b234ba3c903830b4b960511b6044820152606401610954565b5f81116111285760405162461bcd60e51b815260206004820152601f60248201527f5368617265206d7573742062652067726561746572207468616e207a65726f006044820152606401610954565b60098054600181019091557f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0385166001600160a01b031990911681179091555f908152600d60209081526040808320805486151560ff199182168117909255600c845282852080549091169091179055600e9091529020819055611319565b6001600160a01b0383165f908152600d602052604090205460ff1615611319575f5b6009548110156112d257836001600160a01b0316600982815481106111fb576111fb612659565b5f918252602090912001546001600160a01b0316036112c057600980546112249060019061266d565b8154811061123457611234612659565b5f91825260209091200154600980546001600160a01b03909216918390811061125f5761125f612659565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600980548061129b5761129b612680565b5f8281526020902081015f1990810180546001600160a01b03191690550190556112d2565b806112ca81612694565b9150506111d4565b506001600160a01b0383165f908152600e60209081526040808320839055600d8252808320805486151560ff199182168117909255600c9093529220805490911690911790555b826001600160a01b03167f4bf69fee59f1751bf6064f46595c52d722796b529aca2b5a7b6d1ac6a8f8b03183604051611356911515815260200190565b60405180910390a2505050565b61136b611609565b6001600160a01b0381166113d05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610954565b6113d981611b02565b50565b6113e4611609565b6001600160a01b0382165f908152600d602052604090205460ff1661144b5760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420612072656769737465726564206c69717569646974792070616972006044820152606401610954565b5f811161149a5760405162461bcd60e51b815260206004820152601f60248201527f5368617265206d7573742062652067726561746572207468616e207a65726f006044820152606401610954565b6001600160a01b0382165f818152600e602052604090819020839055517fd678ae6319b7a48589104de503993168ab3f547fddc47d3e725f3062325414f190610b949084815260200190565b6001600160a01b0383166115485760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610954565b6001600160a01b0382166115a95760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610954565b6001600160a01b038381165f8181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f546001600160a01b03163314610bb15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610954565b5f61166d8484610f4c565b90505f1981146116d457818110156116c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610954565b6116d484848484036114e6565b50505050565b600854610100900460ff16611752575f546001600160a01b038481169116148061171057505f546001600160a01b038381169116145b6117525760405162461bcd60e51b8152602060048201526013602482015272151c98591a5b99c81b9bdd08195b98589b1959606a1b6044820152606401610954565b60085460ff1615801561177c57506001600160a01b0382165f908152600d602052604090205460ff165b1561193357305f908152600160205260409020546007548110611931576008805460ff191660011790556007545f906002907f0000000000000000000000000000000000000000000000000000000000000000906117fb907f0000000000000000000000000000000000000000000000000000000000000000906126ac565b61180591906126c3565b61180f91906126c3565b90505f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060075461186191906126ac565b61186b91906126c3565b90505f61187882846125ff565b905061188381611de0565b475f8261189086846126ac565b61189a91906126c3565b90505f6118a7828461266d565b905081156118b9576118b98683611fc8565b801561192057600a5f9054906101000a90046001600160a01b03166001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b15801561190c575f80fd5b505af19350505050801561191e575060015b505b50506008805460ff19169055505050505b505b6001600160a01b0383165f908152600b602052604090205460ff168061197057506001600160a01b0382165f908152600b602052604090205460ff165b806119b657506001600160a01b0383165f908152600d602052604090205460ff161580156119b657506001600160a01b0382165f908152600d602052604090205460ff16155b156119cb576119c68383836120d9565b611a3e565b5f806119d6836122a5565b909250905080156119ec576119ec8530836120d9565b8115611a1d57611a1d857f0000000000000000000000000000000000000000000000000000000000000000846120d9565b611a3b8585611a2c85856125ff565b611a36908761266d565b6120d9565b50505b6001600160a01b0383165f908152600c602052604090205460ff16611a6657611a6683611b51565b6001600160a01b0382165f908152600c602052604090205460ff16611a8e57611a8e82611b51565b60085462010000900460ff1615611afd57600a546006546040516001624d3b8760e01b031981526001600160a01b039092169163ffb2c47991611ad79160040190815260200190565b5f604051808303815f87803b158015611aee575f80fd5b505af19250505080156116d457505b505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381165f908152600c602052604090205460ff1615611b745750565b6001600160a01b0381165f90815260016020526040812054905b600954811015611c8c575f60098281548110611bac57611bac612659565b5f918252602080832091909101546001600160a01b03908116808452600e9092526040928390205492516370a0823160e01b815290871660048201529092507f0000000000000000000000000000000000000000000000000000000000000000919083906370a0823190602401602060405180830381865afa158015611c34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c5891906126e2565b611c6291906126ac565b611c6c91906126c3565b611c7690846125ff565b9250508080611c8490612694565b915050611b8e565b50600a54604051630a5b654b60e11b81526001600160a01b03848116600483015260248201849052909116906314b6ca96906044015f604051808303815f87803b158015611cd8575f80fd5b505af1925050508015611afd57505b5050565b5f816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611d46575060408051601f3d908101601f19168201909252611d43918101906126f9565b60015b611d5157505f919050565b5f836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db291906126f9565b90506001600160a01b038216301480611dd357506001600160a01b03811630145b949350505050565b919050565b6040805160028082526060820183525f9260208301908036833701905050905030815f81518110611e1357611e13612659565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb391906126f9565b81600181518110611ec657611ec6612659565b60200260200101906001600160a01b031690816001600160a01b031681525050611f11307f0000000000000000000000000000000000000000000000000000000000000000846114e6565b60405163791ac94760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063791ac94790611f659085905f90869030904290600401612714565b5f604051808303815f87803b158015611f7c575f80fd5b505af1925050508015611f8d575060015b611ce7576040518281527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f9060200160405180910390a15050565b611ff3307f0000000000000000000000000000000000000000000000000000000000000000846114e6565b60405163f305d71960e01b81523060048201819052602482018490525f60448301819052606483015260848201524260a48201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f305d71990839060c40160606040518083038185885af193505050508015612098575060408051601f3d908101601f1916820190925261209591810190612783565b60015b6120d25760408051838152602081018390527f5da0a291cd4a66542c9b71428cd223b8efd210676ebf390e5dc0092e50d15f919101610a77565b5050505050565b6001600160a01b03831661213d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610954565b6001600160a01b03821661219f5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610954565b6001600160a01b0383165f90815260016020526040902054818110156122165760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610954565b6001600160a01b038085165f9081526001602052604080822085850390559185168152908120805484929061224c9084906125ff565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161229891815260200190565b60405180910390a36116d4565b5f80807f00000000000000000000000000000000000000000000000000000000000000006122f37f0000000000000000000000000000000000000000000000000000000000000000866126ac565b6122fd91906126c3565b90505f7f000000000000000000000000000000000000000000000000000000000000000061234b7f0000000000000000000000000000000000000000000000000000000000000000876126ac565b61235591906126c3565b90505f7f00000000000000000000000000000000000000000000000000000000000000006123a37f0000000000000000000000000000000000000000000000000000000000000000886126ac565b6123ad91906126c3565b9050806123ba83856125ff565b94509450505050915091565b5f6020808352835180828501525f5b818110156123f1578581018301518582016040015282016123d5565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146113d9575f80fd5b5f8060408385031215612436575f80fd5b823561244181612411565b946020939093013593505050565b80358015158114611ddb575f80fd5b5f6020828403121561246e575f80fd5b6124778261244f565b9392505050565b5f6020828403121561248e575f80fd5b5035919050565b5f602082840312156124a5575f80fd5b813561247781612411565b5f805f606084860312156124c2575f80fd5b83356124cd81612411565b925060208401356124dd81612411565b929592945050506040919091013590565b5f80604083850312156124ff575f80fd5b50508035926020909101359150565b5f806040838503121561251f575f80fd5b823561252a81612411565b91506125386020840161244f565b90509250929050565b5f8060408385031215612552575f80fd5b823561255d81612411565b9150602083013561256d81612411565b809150509250929050565b5f805f6060848603121561258a575f80fd5b833561259581612411565b92506125a36020850161244f565b9150604084013590509250925092565b600181811c908216806125c757607f821691505b6020821081036125e557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561084f5761084f6125eb565b60208082526027908201527f57616c6c657420697320616c7265616479207468652076616c7565206f6620276040820152667374617475732760c81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561084f5761084f6125eb565b634e487b7160e01b5f52603160045260245ffd5b5f600182016126a5576126a56125eb565b5060010190565b808202811582820484141761084f5761084f6125eb565b5f826126dd57634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156126f2575f80fd5b5051919050565b5f60208284031215612709575f80fd5b815161247781612411565b5f60a082018783526020878185015260a0604085015281875180845260c08601915082890193505f5b818110156127625784516001600160a01b03168352938301939183019160010161273d565b50506001600160a01b03969096166060850152505050608001529392505050565b5f805f60608486031215612795575f80fd5b835192506020840151915060408401519050925092509256fea2646970667358221220a1233dfb8affacd3db35f63b1dfe5a21456f8da90abc062358b380c680d9350a64736f6c6343000814003360806040526ec097ce7bc90715b34b9f1000000000600a55600a600b556402540be400600c55348015610030575f80fd5b5060015f81905580546001600160a01b03191633179055610c07806100545f395ff3fe6080604052600436106100f2575f3560e01c8063b88a802f11610087578063e2d2e21911610057578063e2d2e2191461028a578063efca2eed1461029f578063ffb2c479146102b4578063ffd49c84146102d3575f80fd5b8063b88a802f146101ee578063ce7c2ac214610202578063d0e30db014610257578063d4fda1f21461025f575f80fd5b80633a98ef39116100c25780633a98ef39146101845780634fab0ae81461019957806366817df5146101ae578063997664d7146101d9575f80fd5b806311ce023d146100fd57806314b6ca961461012557806328fd3198146101465780632d48e89614610165575f80fd5b366100f957005b5f80fd5b348015610108575f80fd5b50610112600a5481565b6040519081526020015b60405180910390f35b348015610130575f80fd5b5061014461013f366004610a82565b6102e8565b005b348015610151575f80fd5b50610112610160366004610aaa565b610474565b348015610170575f80fd5b5061014461017f366004610aca565b6104fa565b34801561018f575f80fd5b5061011260065481565b3480156101a4575f80fd5b50610112600c5481565b3480156101b9575f80fd5b506101126101c8366004610aaa565b60046020525f908152604090205481565b3480156101e4575f80fd5b5061011260075481565b3480156101f9575f80fd5b5061014461056b565b34801561020d575f80fd5b5061023c61021c366004610aaa565b60056020525f908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161011c565b6101446105dd565b34801561026a575f80fd5b50610112610279366004610aaa565b60036020525f908152604090205481565b348015610295575f80fd5b5061011260095481565b3480156102aa575f80fd5b5061011260085481565b3480156102bf575f80fd5b506101446102ce366004610aea565b610684565b3480156102de575f80fd5b50610112600b5481565b6001546001600160a01b0316331461031b5760405162461bcd60e51b815260040161031290610b01565b60405180910390fd5b6001600160a01b0382165f90815260056020526040902054156103415761034182610794565b5f8111801561036557506001600160a01b0382165f90815260056020526040902054155b156103ca57600280546001600160a01b0384165f818152600360205260408120839055600183018455929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b03191690911790556103fc565b801580156103ee57506001600160a01b0382165f9081526005602052604090205415155b156103fc576103fc826108f1565b6001600160a01b0382165f90815260056020526040902054600654829161042291610b35565b61042c9190610b48565b6006556001600160a01b0382165f90815260056020526040902081905561045281610a01565b6001600160a01b039092165f9081526005602052604090206001019190915550565b6001600160a01b0381165f90815260056020526040812054810361049957505f919050565b6001600160a01b0382165f908152600560205260408120546104ba90610a01565b6001600160a01b0384165f908152600560205260409020600101549091508082116104e857505f9392505050565b6104f28183610b35565b949350505050565b6001546001600160a01b031633146105245760405162461bcd60e51b815260040161031290610b01565b600b829055600c81905560408051838152602081018390527f7d38de579bb682aa05ace7e32d15f88df69a3a53f6f89fcd0236f93fcc7e6362910160405180910390a15050565b60025f54036105bc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610312565b60025f556105c933610a23565b156105d7576105d733610794565b60015f55565b6001546001600160a01b031633146106075760405162461bcd60e51b815260040161031290610b01565b3460075f8282546106189190610b48565b9091555050600654600a5461062e903490610b5b565b6106389190610b72565b60095f8282546106489190610b48565b909155505060405134815233907f61f49175fe1d0957ca728302166505f7a310d3088ac3b748e92533f9f3458e399060200160405180910390a2565b6001546001600160a01b031633146106ae5760405162461bcd60e51b815260040161031290610b01565b6002545f8190036106bd575050565b5f805a90505f5b84831080156106d257508381105b1561078d5783600d54106106e5575f600d555b6107166002600d54815481106106fd576106fd610b91565b5f918252602090912001546001600160a01b0316610a23565b1561074c5761074c6002600d548154811061073357610733610b91565b5f918252602090912001546001600160a01b0316610794565b5a6107578385610b48565b6107619190610b35565b92505a600d80549193505f61077583610ba5565b9190505550808061078590610ba5565b9150506106c4565b5050505050565b6001600160a01b0381165f9081526005602052604081205490036107b55750565b5f6107bf82610474565b905080156108ed575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610810576040519150601f19603f3d011682016040523d82523d5f602084013e610815565b606091505b5050905080156108eb578160085f8282546108309190610b48565b90915550506001600160a01b0383165f9081526004602090815260408083204290556005909152902060020154610868908390610b48565b6001600160a01b0384165f90815260056020526040902060028101919091555461089190610a01565b6001600160a01b0384165f81815260056020526040908190206001019290925590517f84fcdd4a7f507f2206dd50958e7473061bf941f91791c6ffaf74033a07c82f12906108e29085815260200190565b60405180910390a25b505b5050565b6002805461090190600190610b35565b8154811061091157610911610b91565b5f9182526020808320909101546001600160a01b038481168452600390925260409092205460028054929093169291811061094e5761094e610b91565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526003918290526040812054600280549193929161099990600190610b35565b815481106109a9576109a9610b91565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205560028054806109de576109de610bbd565b5f8281526020902081015f1990810180546001600160a01b031916905501905550565b5f600a5460095483610a139190610b5b565b610a1d9190610b72565b92915050565b600b546001600160a01b0382165f9081526004602052604081205490914291610a4c9190610b48565b108015610a1d5750600c54610a6083610474565b1192915050565b80356001600160a01b0381168114610a7d575f80fd5b919050565b5f8060408385031215610a93575f80fd5b610a9c83610a67565b946020939093013593505050565b5f60208284031215610aba575f80fd5b610ac382610a67565b9392505050565b5f8060408385031215610adb575f80fd5b50508035926020909101359150565b5f60208284031215610afa575f80fd5b5035919050565b60208082526006908201526510aa37b5b2b760d11b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610a1d57610a1d610b21565b80820180821115610a1d57610a1d610b21565b8082028115828204841417610a1d57610a1d610b21565b5f82610b8c57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b5f60018201610bb657610bb6610b21565b5060010190565b634e487b7160e01b5f52603160045260245ffdfea2646970667358221220398e9bc5cac124f7d8fddb11f860be4dcdf8f7289c980fb53876f982415d23b764736f6c63430008140033

Deployed ByteCode

0x60806040526004361061022b575f3560e01c806370a0823111610129578063a457c2d7116100a8578063dd62ed3e1161006d578063dd62ed3e146106fd578063f0f2c9ef1461071c578063f2fde38b1461073b578063f9a580f81461075a578063fce589d814610779575f80fd5b8063a457c2d71461064e578063a9059cbb1461066d578063acc2166a1461068c578063b9b6f9b6146106ab578063cc274b29146106de575f80fd5b80638a8c523c116100ee5780638a8c523c146105a45780638b424267146105b85780638da5cb5b146105eb57806395d89b411461060757806398118cb41461061b575f80fd5b806370a08231146104f0578063715018a6146105245780637803deaa14610538578063866083261461055757806388f8202014610576575f80fd5b8063244ce7db116101b55780634c62f0931161017a5780634c62f0931461042d5780635342acb4146104605780635c9a05b81461048e57806360e71962146104bc57806364dfd203146104d1575f80fd5b8063244ce7db146103975780632d48e896146103b6578063313ce567146103d557806339509351146103f05780634ada218b1461040f575f80fd5b80630a2d140c116101fb5780630a2d140c146102f957806318160ddd1461031a5780631b7a1fb21461032e5780631ba765401461034d57806323b872dd14610378575f80fd5b80630445b66714610236578063062287491461025e57806306fdde03146102a9578063095ea7b3146102ca575f80fd5b3661023257005b5f80fd5b348015610241575f80fd5b5061024b60075481565b6040519081526020015b60405180910390f35b348015610269575f80fd5b506102917f000000000000000000000000000000000000000000000000000000000000036981565b6040516001600160a01b039091168152602001610255565b3480156102b4575f80fd5b506102bd6107ac565b60405161025591906123c6565b3480156102d5575f80fd5b506102e96102e4366004612425565b61083c565b6040519015158152602001610255565b348015610304575f80fd5b5061031861031336600461245e565b610855565b005b348015610325575f80fd5b5060035461024b565b348015610339575f80fd5b5061029161034836600461247e565b6108b3565b348015610358575f80fd5b5061024b610367366004612495565b600e6020525f908152604090205481565b348015610383575f80fd5b506102e96103923660046124b0565b6108db565b3480156103a2575f80fd5b506103186103b136600461247e565b6108fe565b3480156103c1575f80fd5b506103186103d03660046124ee565b610992565b3480156103e0575f80fd5b5060405160128152602001610255565b3480156103fb575f80fd5b506102e961040a366004612425565b610a83565b34801561041a575f80fd5b506008546102e990610100900460ff1681565b348015610438575f80fd5b506102917f0000000000000000000000007114ead44cab77ca9a136d2663a6e500de8bd0ef81565b34801561046b575f80fd5b506102e961047a366004612495565b600b6020525f908152604090205460ff1681565b348015610499575f80fd5b506102e96104a8366004612495565b600d6020525f908152604090205460ff1681565b3480156104c7575f80fd5b5061024b60065481565b3480156104dc575f80fd5b506103186104eb36600461250e565b610aa4565b3480156104fb575f80fd5b5061024b61050a366004612495565b6001600160a01b03165f9081526001602052604090205490565b34801561052f575f80fd5b50610318610ba0565b348015610543575f80fd5b5061031861055236600461250e565b610bb3565b348015610562575f80fd5b506008546102e99062010000900460ff1681565b348015610581575f80fd5b506102e9610590366004612495565b600c6020525f908152604090205460ff1681565b3480156105af575f80fd5b50610318610d16565b3480156105c3575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000015e81565b3480156105f6575f80fd5b505f546001600160a01b0316610291565b348015610612575f80fd5b506102bd610daf565b348015610626575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000006481565b348015610659575f80fd5b506102e9610668366004612425565b610dbe565b348015610678575f80fd5b506102e9610687366004612425565b610e38565b348015610697575f80fd5b50600a54610291906001600160a01b031681565b3480156106b6575f80fd5b506102917f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d981565b3480156106e9575f80fd5b506103186106f836600461247e565b610e45565b348015610708575f80fd5b5061024b610717366004612541565b610f4c565b348015610727575f80fd5b50610318610736366004612578565b610f76565b348015610746575f80fd5b50610318610755366004612495565b611363565b348015610765575f80fd5b50610318610774366004612425565b6113dc565b348015610784575f80fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000003281565b6060600480546107bb906125b3565b80601f01602080910402602001604051908101604052809291908181526020018280546107e7906125b3565b80156108325780601f1061080957610100808354040283529160200191610832565b820191905f5260205f20905b81548152906001019060200180831161081557829003601f168201915b5050505050905090565b5f336108498185856114e6565b60019150505b92915050565b61085d611609565b60088054821515620100000262ff0000199091161790556040517fb38aef214af8a01121ddda7dd915117d0bbe821c96b4ab3915f4cee420bb54d9906108a890831515815260200190565b60405180910390a150565b600981815481106108c2575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f336108e8858285611662565b6108f38585856116da565b506001949350505050565b610906611609565b620b71b0811061095d5760405162461bcd60e51b815260206004820152601960248201527f4761732069732067726561746572207468616e206c696d69740000000000000060448201526064015b60405180910390fd5b60068190556040518181527f5f0cf7d11c1aaf2b53b91892382eaee789338051f9fcecf528ca006d062bfba8906020016108a8565b61099a611609565b5f81116109e95760405162461bcd60e51b815260206004820152601f60248201527f4d696e2e20646973747269627574696f6e2063616e2774206265207a65726f006044820152606401610954565b600a546040516316a4744b60e11b815260048101849052602481018390526001600160a01b0390911690632d48e896906044015f604051808303815f87803b158015610a33575f80fd5b505af1925050508015610a44575060015b5060408051838152602081018390527f4bee245ad45dacfa3feb4cc8a61ace735c47b485fb8a399ce9e3f6c87aade41891015b60405180910390a15050565b5f33610849818585610a958383610f4c565b610a9f91906125ff565b6114e6565b610aac611609565b6001600160a01b038216610b025760405162461bcd60e51b815260206004820152601d60248201527f57616c6c65742061646472657373206973206e6f7420636f72726563740000006044820152606401610954565b6001600160a01b0382165f908152600b602052604090205481151560ff909116151503610b415760405162461bcd60e51b815260040161095490612612565b6001600160a01b0382165f818152600b6020908152604091829020805460ff191685151590811790915591519182527f793188c766da601299dd85f7f21348a41b2cb4cadf893f2155f210d64fc049b891015b60405180910390a25050565b610ba8611609565b610bb15f611b02565b565b610bbb611609565b6001600160a01b038216610c005760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b6044820152606401610954565b6001600160a01b0382165f908152600c602052604090205481151560ff909116151503610c3f5760405162461bcd60e51b815260040161095490612612565b6001600160a01b0382165f908152600c60205260409020805460ff19168215801591909117909155610cd057600a54604051630a5b654b60e11b81526001600160a01b0384811660048301525f6024830152909116906314b6ca96906044015f604051808303815f87803b158015610cb5575f80fd5b505af1925050508015610cc6575060015b15610cd957610cd9565b610cd982611b51565b816001600160a01b03167f21dfac5ff6a7cc530320d4cb002a96edf0c323b87dbe9eb9a4c39a5c3a62cbb982604051610b94911515815260200190565b610d1e611609565b600854610100900460ff1615610d765760405162461bcd60e51b815260206004820152601760248201527f54726164696e6720616c726561647920656e61626c65640000000000000000006044820152606401610954565b6008805461ff0019166101001790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7905f90a1565b6060600580546107bb906125b3565b5f3381610dcb8286610f4c565b905083811015610e2b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610954565b6108f382868684036114e6565b5f336108498185856116da565b610e4d611609565b600354811115610eaf5760405162461bcd60e51b815260206004820152602760248201527f416d6f756e742063616e6e6f74206265206f7665722074686520746f74616c2060448201526639bab838363c9760c91b6064820152608401610954565b683635c9adc5dea00000811015610f175760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d2060313030306020746f6b656e2070657220737761702072656044820152651c5d5a5c995960d21b6064820152608401610954565b60078190556040518181527f18ff2fc8464635e4f668567019152095047e34d7a2ab4b97661ba4dc7fd06476906020016108a8565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205490565b610f7e611609565b6001600160a01b0383165f908152600d602052604090205482151560ff909116151503610ff85760405162461bcd60e51b815260206004820152602260248201527f5061697220697320616c72656164792073657420746f20746861742073746174604482015261757360f01b6064820152608401610954565b7f0000000000000000000000007114ead44cab77ca9a136d2663a6e500de8bd0ef6001600160a01b0316836001600160a01b0316036110855760405162461bcd60e51b8152602060048201526024808201527f43616e2774207570646174652074686520737461747573206f66206d61696e206044820152633830b4b960e11b6064820152608401610954565b81156111b25761109483611ceb565b6110d95760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103634b8bab4b234ba3c903830b4b960511b6044820152606401610954565b5f81116111285760405162461bcd60e51b815260206004820152601f60248201527f5368617265206d7573742062652067726561746572207468616e207a65726f006044820152606401610954565b60098054600181019091557f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0385166001600160a01b031990911681179091555f908152600d60209081526040808320805486151560ff199182168117909255600c845282852080549091169091179055600e9091529020819055611319565b6001600160a01b0383165f908152600d602052604090205460ff1615611319575f5b6009548110156112d257836001600160a01b0316600982815481106111fb576111fb612659565b5f918252602090912001546001600160a01b0316036112c057600980546112249060019061266d565b8154811061123457611234612659565b5f91825260209091200154600980546001600160a01b03909216918390811061125f5761125f612659565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600980548061129b5761129b612680565b5f8281526020902081015f1990810180546001600160a01b03191690550190556112d2565b806112ca81612694565b9150506111d4565b506001600160a01b0383165f908152600e60209081526040808320839055600d8252808320805486151560ff199182168117909255600c9093529220805490911690911790555b826001600160a01b03167f4bf69fee59f1751bf6064f46595c52d722796b529aca2b5a7b6d1ac6a8f8b03183604051611356911515815260200190565b60405180910390a2505050565b61136b611609565b6001600160a01b0381166113d05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610954565b6113d981611b02565b50565b6113e4611609565b6001600160a01b0382165f908152600d602052604090205460ff1661144b5760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420612072656769737465726564206c69717569646974792070616972006044820152606401610954565b5f811161149a5760405162461bcd60e51b815260206004820152601f60248201527f5368617265206d7573742062652067726561746572207468616e207a65726f006044820152606401610954565b6001600160a01b0382165f818152600e602052604090819020839055517fd678ae6319b7a48589104de503993168ab3f547fddc47d3e725f3062325414f190610b949084815260200190565b6001600160a01b0383166115485760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610954565b6001600160a01b0382166115a95760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610954565b6001600160a01b038381165f8181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f546001600160a01b03163314610bb15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610954565b5f61166d8484610f4c565b90505f1981146116d457818110156116c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610954565b6116d484848484036114e6565b50505050565b600854610100900460ff16611752575f546001600160a01b038481169116148061171057505f546001600160a01b038381169116145b6117525760405162461bcd60e51b8152602060048201526013602482015272151c98591a5b99c81b9bdd08195b98589b1959606a1b6044820152606401610954565b60085460ff1615801561177c57506001600160a01b0382165f908152600d602052604090205460ff165b1561193357305f908152600160205260409020546007548110611931576008805460ff191660011790556007545f906002907f00000000000000000000000000000000000000000000000000000000000001c2906117fb907f0000000000000000000000000000000000000000000000000000000000000064906126ac565b61180591906126c3565b61180f91906126c3565b90505f7f00000000000000000000000000000000000000000000000000000000000001c27f000000000000000000000000000000000000000000000000000000000000015e60075461186191906126ac565b61186b91906126c3565b90505f61187882846125ff565b905061188381611de0565b475f8261189086846126ac565b61189a91906126c3565b90505f6118a7828461266d565b905081156118b9576118b98683611fc8565b801561192057600a5f9054906101000a90046001600160a01b03166001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b15801561190c575f80fd5b505af19350505050801561191e575060015b505b50506008805460ff19169055505050505b505b6001600160a01b0383165f908152600b602052604090205460ff168061197057506001600160a01b0382165f908152600b602052604090205460ff165b806119b657506001600160a01b0383165f908152600d602052604090205460ff161580156119b657506001600160a01b0382165f908152600d602052604090205460ff16155b156119cb576119c68383836120d9565b611a3e565b5f806119d6836122a5565b909250905080156119ec576119ec8530836120d9565b8115611a1d57611a1d857f0000000000000000000000000000000000000000000000000000000000000369846120d9565b611a3b8585611a2c85856125ff565b611a36908761266d565b6120d9565b50505b6001600160a01b0383165f908152600c602052604090205460ff16611a6657611a6683611b51565b6001600160a01b0382165f908152600c602052604090205460ff16611a8e57611a8e82611b51565b60085462010000900460ff1615611afd57600a546006546040516001624d3b8760e01b031981526001600160a01b039092169163ffb2c47991611ad79160040190815260200190565b5f604051808303815f87803b158015611aee575f80fd5b505af19250505080156116d457505b505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381165f908152600c602052604090205460ff1615611b745750565b6001600160a01b0381165f90815260016020526040812054905b600954811015611c8c575f60098281548110611bac57611bac612659565b5f918252602080832091909101546001600160a01b03908116808452600e9092526040928390205492516370a0823160e01b815290871660048201529092507f0000000000000000000000000000000000000000000000000000000000000064919083906370a0823190602401602060405180830381865afa158015611c34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c5891906126e2565b611c6291906126ac565b611c6c91906126c3565b611c7690846125ff565b9250508080611c8490612694565b915050611b8e565b50600a54604051630a5b654b60e11b81526001600160a01b03848116600483015260248201849052909116906314b6ca96906044015f604051808303815f87803b158015611cd8575f80fd5b505af1925050508015611afd57505b5050565b5f816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611d46575060408051601f3d908101601f19168201909252611d43918101906126f9565b60015b611d5157505f919050565b5f836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db291906126f9565b90506001600160a01b038216301480611dd357506001600160a01b03811630145b949350505050565b919050565b6040805160028082526060820183525f9260208301908036833701905050905030815f81518110611e1357611e13612659565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d96001600160a01b031663ef8ef56f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb391906126f9565b81600181518110611ec657611ec6612659565b60200260200101906001600160a01b031690816001600160a01b031681525050611f11307f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9846114e6565b60405163791ac94760e01b81526001600160a01b037f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9169063791ac94790611f659085905f90869030904290600401612714565b5f604051808303815f87803b158015611f7c575f80fd5b505af1925050508015611f8d575060015b611ce7576040518281527ff9e10ddceffcb10b96e8833202366240699b814c91f371ddd9befa3aee9bc60f9060200160405180910390a15050565b611ff3307f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9846114e6565b60405163f305d71960e01b81523060048201819052602482018490525f60448301819052606483015260848201524260a48201527f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d96001600160a01b03169063f305d71990839060c40160606040518083038185885af193505050508015612098575060408051601f3d908101601f1916820190925261209591810190612783565b60015b6120d25760408051838152602081018390527f5da0a291cd4a66542c9b71428cd223b8efd210676ebf390e5dc0092e50d15f919101610a77565b5050505050565b6001600160a01b03831661213d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610954565b6001600160a01b03821661219f5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610954565b6001600160a01b0383165f90815260016020526040902054818110156122165760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610954565b6001600160a01b038085165f9081526001602052604080822085850390559185168152908120805484929061224c9084906125ff565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161229891815260200190565b60405180910390a36116d4565b5f80807f00000000000000000000000000000000000000000000000000000000000027106122f37f000000000000000000000000000000000000000000000000000000000000015e866126ac565b6122fd91906126c3565b90505f7f000000000000000000000000000000000000000000000000000000000000271061234b7f0000000000000000000000000000000000000000000000000000000000000064876126ac565b61235591906126c3565b90505f7f00000000000000000000000000000000000000000000000000000000000027106123a37f0000000000000000000000000000000000000000000000000000000000000032886126ac565b6123ad91906126c3565b9050806123ba83856125ff565b94509450505050915091565b5f6020808352835180828501525f5b818110156123f1578581018301518582016040015282016123d5565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146113d9575f80fd5b5f8060408385031215612436575f80fd5b823561244181612411565b946020939093013593505050565b80358015158114611ddb575f80fd5b5f6020828403121561246e575f80fd5b6124778261244f565b9392505050565b5f6020828403121561248e575f80fd5b5035919050565b5f602082840312156124a5575f80fd5b813561247781612411565b5f805f606084860312156124c2575f80fd5b83356124cd81612411565b925060208401356124dd81612411565b929592945050506040919091013590565b5f80604083850312156124ff575f80fd5b50508035926020909101359150565b5f806040838503121561251f575f80fd5b823561252a81612411565b91506125386020840161244f565b90509250929050565b5f8060408385031215612552575f80fd5b823561255d81612411565b9150602083013561256d81612411565b809150509250929050565b5f805f6060848603121561258a575f80fd5b833561259581612411565b92506125a36020850161244f565b9150604084013590509250925092565b600181811c908216806125c757607f821691505b6020821081036125e557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561084f5761084f6125eb565b60208082526027908201527f57616c6c657420697320616c7265616479207468652076616c7565206f6620276040820152667374617475732760c81b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561084f5761084f6125eb565b634e487b7160e01b5f52603160045260245ffd5b5f600182016126a5576126a56125eb565b5060010190565b808202811582820484141761084f5761084f6125eb565b5f826126dd57634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156126f2575f80fd5b5051919050565b5f60208284031215612709575f80fd5b815161247781612411565b5f60a082018783526020878185015260a0604085015281875180845260c08601915082890193505f5b818110156127625784516001600160a01b03168352938301939183019160010161273d565b50506001600160a01b03969096166060850152505050608001529392505050565b5f805f60608486031215612795575f80fd5b835192506020840151915060408401519050925092509256fea2646970667358221220a1233dfb8affacd3db35f63b1dfe5a21456f8da90abc062358b380c680d9350a64736f6c63430008140033