false
true
0

Contract Address Details

0x67D67511DBe79082Fc7e5F39c791b4DE4c940742

Token
Pulse Index (PINDEX)
Creator
0xbd6507–f0dfb9 at 0xbba43d–fde80d
Balance
28,662,327.031565506061133239 PLS ( )
Tokens
Fetching tokens...
Transactions
2,469 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26126617
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
PulseIndex




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




Optimization runs
200
EVM Version
shanghai




Verified at
2025-11-08T11:59:36.449098Z

Constructor Arguments

0x000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000600000000000000000000000095b303987a60c71504d99aa1b13b4da07b0790ab0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d0000000000000000000000002b591e99afe9f32eaa6214f7b7629768c40eeb3900000000000000000000000057fde0a71132198bbec939b98976993d8d89d225000000000000000000000000b17d901469b9208b17d916112988a3fed19b5ca100000000000000000000000002dcdd04e3f455d838cd1249292c58f3b79e3c3c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000003e8
              

PulseIndex.sol

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

// ---------------------------------------------------------
// Minimal Context / ERC20 / Ownable / ReentrancyGuard
// ---------------------------------------------------------
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
}

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ERC20 is Context, IERC20 {
    mapping(address => uint256) internal _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    uint256 internal _totalSupply;
    string private _name;
    string private _symbol;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    function name() public view virtual returns (string memory) { return _name; }
    function symbol() public view virtual returns (string memory) { return _symbol; }
    function decimals() public pure virtual returns (uint8) { return 18; }

    function totalSupply() public view virtual override returns (uint256) { return _totalSupply; }

    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _allowances[sender][_msgSender()] = currentAllowance - amount;
        }
        return true;
    }

    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from zero");
        require(recipient != address(0), "ERC20: transfer to zero");
        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;
        emit Transfer(sender, recipient, amount);
    }

    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to zero");
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from zero");
        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            _totalSupply -= amount;
        }
        emit Transfer(account, address(0), amount);
    }

    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from zero");
        require(spender != address(0), "ERC20: approve to zero");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
}

abstract contract Ownable is Context {
    address private _owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        _transferOwnership(_msgSender());
    }

    function owner() public view virtual returns (address) { return _owner; }

    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not owner");
        _;
    }

    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner zero");
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED     = 2;
    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant");
        _status = _ENTERED;
        _;
        _status = _NOT_ENTERED;
    }
}

// ---------------------------------------------------------
// PulseX / UniswapV2 router interface
// ---------------------------------------------------------
interface IUniswapV2Router02 {
    function WETH() external pure returns (address); // WPLS on PulseChain

    function swapExactETHForTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable returns (uint[] memory amounts);

    function swapExactTokensForETH(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
}

// ---------------------------------------------------------
// PulseIndex
// ---------------------------------------------------------
contract PulseIndex is ERC20, Ownable, ReentrancyGuard {
    // Router and WPLS
    address public immutable routerAddress;
    address public immutable wplsAddress;

    // Basket tokens + weights (BPS, sum = 10_000)
    address[] public basketTokens;
    uint16[] public basketWeights; // e.g. [2000,2000,2000,2000,1000,1000]

    // Fees in basis points (1% = 100)
    uint16 public depositFeeBps = 100; // 1%
    uint16 public redeemFeeBps  = 100; // 1%
    uint16 public constant MAX_FEE_BPS = 300; // 3% hard cap

    // PLS rewards pool + accounting
    uint256 public rewardsPool;          // PLS set aside for rewards
    uint256 public rewardPerTokenStored; // scaled by 1e18

    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards; // accrued but not claimed

    uint256 private constant REWARD_SCALE = 1e18;

    event BasketUpdated(address[] tokens, uint16[] weights);
    event FeesUpdated(uint16 depositFeeBps, uint16 redeemFeeBps);
    event RewardAdded(uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);

    constructor(
        address _router,
        address _wpls,
        address[] memory _tokens,
        uint16[] memory _weights
    ) ERC20("Pulse Index", "PINDEX") {
        require(_router != address(0), "Router zero");
        require(_wpls != address(0), "WPLS zero");
        routerAddress = _router;
        wplsAddress   = _wpls;

        _setBasket(_tokens, _weights);
    }

    receive() external payable {}

    // -----------------------------------------------------
    // Basket management
    // -----------------------------------------------------
    function getBasket() external view returns (address[] memory tokens, uint16[] memory weights) {
        return (basketTokens, basketWeights);
    }

    function setBasket(address[] calldata _tokens, uint16[] calldata _weights) external onlyOwner {
        _setBasket(_tokens, _weights);
    }

    function _setBasket(address[] memory _tokens, uint16[] memory _weights) internal {
        require(_tokens.length > 0, "Empty basket");
        require(_tokens.length == _weights.length, "Length mismatch");

        uint256 sum;
        for (uint256 i = 0; i < _tokens.length; i++) {
            require(_tokens[i] != address(0), "Token zero");
            sum += _weights[i];
        }
        require(sum == 10_000, "Weights must sum to 10000");

        delete basketTokens;
        delete basketWeights;

        for (uint256 i = 0; i < _tokens.length; i++) {
            basketTokens.push(_tokens[i]);
            basketWeights.push(_weights[i]);
        }

        emit BasketUpdated(_tokens, _weights);
    }

    // -----------------------------------------------------
    // Fees
    // -----------------------------------------------------
    function setFees(uint16 _depositFeeBps, uint16 _redeemFeeBps) external onlyOwner {
        require(_depositFeeBps <= MAX_FEE_BPS, "Deposit fee too high");
        require(_redeemFeeBps  <= MAX_FEE_BPS, "Redeem fee too high");
        depositFeeBps = _depositFeeBps;
        redeemFeeBps  = _redeemFeeBps;
        emit FeesUpdated(_depositFeeBps, _redeemFeeBps);
    }

    // -----------------------------------------------------
    // Reward accounting helpers
    // -----------------------------------------------------
    function _updateReward(address account) internal {
        // rewardPerTokenStored is only updated when fees are added,
        // so nothing to do globally here.
        if (account != address(0)) {
            rewards[account] = earned(account);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }
    }

    function _notifyReward(uint256 amount) internal {
        if (amount == 0) return;
        require(_totalSupply > 0, "No supply for rewards");
        rewardsPool += amount;
        rewardPerTokenStored += amount * REWARD_SCALE / _totalSupply;
        emit RewardAdded(amount);
    }

    function earned(address account) public view returns (uint256) {
        uint256 paid = userRewardPerTokenPaid[account];
        uint256 delta = rewardPerTokenStored - paid;
        return _balances[account] * delta / REWARD_SCALE + rewards[account];
    }

    function withdrawableRewardOf(address account) external view returns (uint256) {
        return earned(account);
    }

    // -----------------------------------------------------
    // Deposit: mint 1:1, 1% fee to rewards, 99% buys basket
    // -----------------------------------------------------
    function deposit() external payable nonReentrant {
        uint256 amount = msg.value;
        require(amount > 0, "No PLS deposited");
        require(basketTokens.length > 0, "Basket not set");

        // 1) Mint 1:1 PINDEX
        _updateReward(msg.sender);
        _mint(msg.sender, amount);

        // 2) Split fee vs invested amount
        uint256 fee = amount * depositFeeBps / 10_000;
        uint256 investAmount = amount - fee;

        // 3) Fee → rewards
        if (fee > 0) {
            _notifyReward(fee);
        }

        // 4) Use 100% of investAmount to buy basket according to weights
        IUniswapV2Router02 router = IUniswapV2Router02(routerAddress);
        uint256 total = investAmount;
        uint256 remaining = investAmount;
        uint256 n = basketTokens.length;

        for (uint256 i = 0; i < n; i++) {
            uint256 share;
            if (i == n - 1) {
                share = remaining; // last token gets remainder
            } else {
                share = total * basketWeights[i] / 10_000;
                if (share > remaining) share = remaining;
                remaining -= share;
            }
            if (share == 0) continue;

            address[] memory path = new address[](2);
            path[0] = wplsAddress;
            path[1] = basketTokens[i];

            router.swapExactETHForTokens{value: share}(
                0,
                path,
                address(this),
                block.timestamp + 300
            );
        }
    }

    // -----------------------------------------------------
    // Redeem: burn PINDEX, sell share of basket to PLS, fee to rewards
    // -----------------------------------------------------
    function redeem(uint256 amount) external nonReentrant {
        require(amount > 0, "Zero amount");
        uint256 total = _totalSupply;
        require(total > 0, "No supply");

        _updateReward(msg.sender);

        // Snapshot PLS backing (exclude rewardsPool)
        uint256 backingPlsBefore = address(this).balance - rewardsPool;

        // User share of existing PLS
        uint256 plsShareFromBalance = backingPlsBefore * amount / total;

        IUniswapV2Router02 router = IUniswapV2Router02(routerAddress);

        // Sell proportional share of each basket token into PLS
        uint256 plsFromSalesBefore = address(this).balance;
        for (uint256 i = 0; i < basketTokens.length; i++) {
            address token = basketTokens[i];
            uint256 tokenBal = IERC20(token).balanceOf(address(this));
            if (tokenBal == 0) continue;

            uint256 tokenShare = tokenBal * amount / total;
            if (tokenShare == 0) continue;

            IERC20(token).approve(routerAddress, tokenShare);

            address[] memory path = new address[](2);
            path[0] = token;
            path[1] = wplsAddress;

            router.swapExactTokensForETH(
                tokenShare,
                0,
                path,
                address(this),
                block.timestamp + 300
            );
        }
        uint256 plsFromSales = address(this).balance - plsFromSalesBefore;

        uint256 grossPayout = plsShareFromBalance + plsFromSales;
        require(grossPayout > 0, "Nothing to redeem");

        // Burn PINDEX
        _burn(msg.sender, amount);

        // Apply redeem fee
        uint256 fee = grossPayout * redeemFeeBps / 10_000;
        uint256 netPayout = grossPayout - fee;

        // Add fee to rewards
        if (fee > 0) {
            _notifyReward(fee);
        }

        // Pay user
        (bool ok, ) = payable(msg.sender).call{value: netPayout}("");
        require(ok, "PLS transfer failed");
    }

    // -----------------------------------------------------
    // Claim PLS rewards
    // -----------------------------------------------------
    function claimRewards() external nonReentrant {
        _updateReward(msg.sender);
        uint256 reward = rewards[msg.sender];
        require(reward > 0, "No rewards");
        rewards[msg.sender] = 0;

        require(rewardsPool >= reward, "Rewards pool low");
        rewardsPool -= reward;

        (bool ok, ) = payable(msg.sender).call{value: reward}("");
        require(ok, "PLS transfer failed");

        emit RewardPaid(msg.sender, reward);
    }

    // -----------------------------------------------------
    // ERC20 overrides – keep rewards in sync on transfers
    // -----------------------------------------------------
    function _transfer(address from, address to, uint256 value) internal virtual override {
        _updateReward(from);
        _updateReward(to);
        super._transfer(from, to, value);
    }

    function _mint(address account, uint256 amount) internal virtual override {
        _updateReward(account);
        super._mint(account, amount);
    }

    function _burn(address account, uint256 amount) internal virtual override {
        _updateReward(account);
        super._burn(account, amount);
    }
}
        

Compiler Settings

{"outputSelection":{"*":{"*":["abi","metadata","devdoc","userdoc","storageLayout","evm.legacyAssembly","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","evm.gasEstimates","evm.assembly"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"shanghai"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_router","internalType":"address"},{"type":"address","name":"_wpls","internalType":"address"},{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint16[]","name":"_weights","internalType":"uint16[]"}]},{"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":"BasketUpdated","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]","indexed":false},{"type":"uint16[]","name":"weights","internalType":"uint16[]","indexed":false}],"anonymous":false},{"type":"event","name":"FeesUpdated","inputs":[{"type":"uint16","name":"depositFeeBps","internalType":"uint16","indexed":false},{"type":"uint16","name":"redeemFeeBps","internalType":"uint16","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":"RewardAdded","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"MAX_FEE_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"basketTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"basketWeights","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimRewards","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"depositFeeBps","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earned","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"tokens","internalType":"address[]"},{"type":"uint16[]","name":"weights","internalType":"uint16[]"}],"name":"getBasket","inputs":[]},{"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":"nonpayable","outputs":[],"name":"redeem","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"redeemFeeBps","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerTokenStored","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardsPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"routerAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBasket","inputs":[{"type":"address[]","name":"_tokens","internalType":"address[]"},{"type":"uint16[]","name":"_weights","internalType":"uint16[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFees","inputs":[{"type":"uint16","name":"_depositFeeBps","internalType":"uint16"},{"type":"uint16","name":"_redeemFeeBps","internalType":"uint16"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","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":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userRewardPerTokenPaid","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawableRewardOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"wplsAddress","inputs":[]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

0x60c06040526009805463ffffffff19166264006417905534801562000022575f80fd5b5060405162002d9638038062002d968339810160408190526200004591620005fb565b6040518060400160405280600b81526020016a0a0ead8e6ca4092dcc8caf60ab1b815250604051806040016040528060068152602001650a0929c888ab60d31b815250816003908162000099919062000776565b506004620000a8828262000776565b505050620000c5620000bf6200018160201b60201c565b62000185565b60016006556001600160a01b038416620001145760405162461bcd60e51b815260206004820152600b60248201526a526f75746572207a65726f60a81b60448201526064015b60405180910390fd5b6001600160a01b038316620001585760405162461bcd60e51b815260206004820152600960248201526857504c53207a65726f60b81b60448201526064016200010b565b6001600160a01b03808516608052831660a052620001778282620001d6565b5050505062000927565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f825111620002175760405162461bcd60e51b815260206004820152600c60248201526b115b5c1d1e4818985cdad95d60a21b60448201526064016200010b565b80518251146200025c5760405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b60448201526064016200010b565b5f805b83518110156200031a575f6001600160a01b03168482815181106200028857620002886200083e565b60200260200101516001600160a01b031603620002d55760405162461bcd60e51b815260206004820152600a602482015269546f6b656e207a65726f60b01b60448201526064016200010b565b828181518110620002ea57620002ea6200083e565b602002602001015161ffff168262000303919062000866565b915080620003118162000882565b9150506200025f565b5080612710146200036e5760405162461bcd60e51b815260206004820152601960248201527f57656967687473206d7573742073756d20746f2031303030300000000000000060448201526064016200010b565b6200037b60075f62000499565b6200038860085f620004b9565b5f5b835181101562000458576007848281518110620003ab57620003ab6200083e565b60209081029190910181015182546001810184555f938452919092200180546001600160a01b0319166001600160a01b039092169190911790558251600890849083908110620003ff57620003ff6200083e565b60209081029190910181015182546001810184555f9384529190922060108204018054600f9092166002026101000a61ffff818102199093169290931692909202179055806200044f8162000882565b9150506200038a565b507f73192282755a6185dc90088ac8a3411af6b631198a2b4f31d174e9deec0aef5083836040516200048c9291906200089d565b60405180910390a1505050565b5080545f8255905f5260205f2090810190620004b69190620004d8565b50565b5080545f8255600f0160109004905f5260205f2090810190620004b691905b5b80821115620004ee575f8155600101620004d9565b5090565b80516001600160a01b038116811462000509575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156200054d576200054d6200050e565b604052919050565b5f6001600160401b038211156200057057620005706200050e565b5060051b60200190565b5f82601f8301126200058a575f80fd5b81516020620005a36200059d8362000555565b62000522565b82815260059290921b84018101918181019086841115620005c2575f80fd5b8286015b84811015620005f057805161ffff81168114620005e2575f8081fd5b8352918301918301620005c6565b509695505050505050565b5f805f80608085870312156200060f575f80fd5b6200061a85620004f2565b935060206200062b818701620004f2565b60408701519094506001600160401b038082111562000648575f80fd5b818801915088601f8301126200065c575f80fd5b81516200066d6200059d8262000555565b81815260059190911b8301840190848101908b8311156200068c575f80fd5b938501935b82851015620006b557620006a585620004f2565b8252938501939085019062000691565b60608b01519097509450505080831115620006ce575f80fd5b5050620006de878288016200057a565b91505092959194509250565b600181811c90821680620006ff57607f821691505b6020821081036200071e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000771575f81815260208120601f850160051c810160208610156200074c5750805b601f850160051c820191505b818110156200076d5782815560010162000758565b5050505b505050565b81516001600160401b038111156200079257620007926200050e565b620007aa81620007a38454620006ea565b8462000724565b602080601f831160018114620007e0575f8415620007c85750858301515b5f19600386901b1c1916600185901b1785556200076d565b5f85815260208120601f198616915b828110156200081057888601518255948401946001909101908401620007ef565b50858210156200082e57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156200087c576200087c62000852565b92915050565b5f6001820162000896576200089662000852565b5060010190565b604080825283519082018190525f906020906060840190828701845b82811015620008e05781516001600160a01b031684529284019290840190600101620008b9565b505050838103828501528451808252858301918301905f5b818110156200091a57835161ffff1683529284019291840191600101620008f8565b5090979650505050505050565b60805160a05161242a6200096c5f395f81816103ef01528181610eca01526112b301525f818161035001528181610df1015281816110e201526111e4015261242a5ff3fe6080604052600436106101d2575f3560e01c806370a08231116100fd578063ab87982711610092578063db006a7511610062578063db006a751461056b578063dd62ed3e1461058a578063df136d65146105ce578063f2fde38b146105e3575f80fd5b8063ab87982714610512578063cd6ef2b01461052c578063d0e30db01461054e578063d55be8c614610556575f80fd5b806395d89b41116100cd57806395d89b41146104a15780639ef833d4146104b5578063a461ee15146104d4578063a9059cbb146104f3575f80fd5b806370a0823114610411578063715018a6146104455780638b876347146104595780638da5cb5b14610484575f80fd5b806318160ddd11610173578063372500ab11610143578063372500ab1461038a5780633e5958e1146103a057806344a7e5c8146103bf5780634e69e92e146103de575f80fd5b806318160ddd146102f157806323b872dd14610305578063313ce567146103245780633268cc561461033f575f80fd5b80630700037d116101ae5780630700037d14610245578063095ea7b31461027057806309f6442c1461029f5780630c70754e146102d2575f80fd5b80628cc262146101dd5780630359fea91461020f57806306fdde0314610224575f80fd5b366101d957005b5f80fd5b3480156101e8575f80fd5b506101fc6101f7366004611ea9565b610602565b6040519081526020015b60405180910390f35b34801561021a575f80fd5b506101fc600a5481565b34801561022f575f80fd5b50610238610682565b6040516102069190611ec9565b348015610250575f80fd5b506101fc61025f366004611ea9565b600d6020525f908152604090205481565b34801561027b575f80fd5b5061028f61028a366004611f14565b610712565b6040519015158152602001610206565b3480156102aa575f80fd5b506009546102bf9062010000900461ffff1681565b60405161ffff9091168152602001610206565b3480156102dd575f80fd5b506101fc6102ec366004611ea9565b610728565b3480156102fc575f80fd5b506002546101fc565b348015610310575f80fd5b5061028f61031f366004611f3c565b610732565b34801561032f575f80fd5b5060405160128152602001610206565b34801561034a575f80fd5b506103727f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610206565b348015610395575f80fd5b5061039e6107fa565b005b3480156103ab575f80fd5b506102bf6103ba366004611f75565b6109a6565b3480156103ca575f80fd5b506103726103d9366004611f75565b6109db565b3480156103e9575f80fd5b506103727f000000000000000000000000000000000000000000000000000000000000000081565b34801561041c575f80fd5b506101fc61042b366004611ea9565b6001600160a01b03165f9081526020819052604090205490565b348015610450575f80fd5b5061039e610a03565b348015610464575f80fd5b506101fc610473366004611ea9565b600c6020525f908152604090205481565b34801561048f575f80fd5b506005546001600160a01b0316610372565b3480156104ac575f80fd5b50610238610a38565b3480156104c0575f80fd5b5061039e6104cf366004611f9d565b610a47565b3480156104df575f80fd5b5061039e6104ee366004612016565b610b6b565b3480156104fe575f80fd5b5061028f61050d366004611f14565b610c06565b34801561051d575f80fd5b506009546102bf9061ffff1681565b348015610537575f80fd5b50610540610c12565b6040516102069291906120bf565b61039e610cf2565b348015610561575f80fd5b506102bf61012c81565b348015610576575f80fd5b5061039e610585366004611f75565b611010565b348015610595575f80fd5b506101fc6105a4366004612118565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b3480156105d9575f80fd5b506101fc600b5481565b3480156105ee575f80fd5b5061039e6105fd366004611ea9565b6114d6565b6001600160a01b0381165f908152600c6020526040812054600b54829061062a908390612154565b6001600160a01b0385165f908152600d6020908152604080832054918390529091205491925090670de0b6b3a764000090610666908490612167565b610670919061217e565b61067a919061219d565b949350505050565b606060038054610691906121b0565b80601f01602080910402602001604051908101604052809291908181526020018280546106bd906121b0565b80156107085780601f106106df57610100808354040283529160200191610708565b820191905f5260205f20905b8154815290600101906020018083116106eb57829003601f168201915b5050505050905090565b5f61071e338484611562565b5060015b92915050565b5f61072282610602565b5f61073e848484611668565b6001600160a01b0384165f908152600160209081526040808320338452909152902054828110156107c75760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6001600160a01b03949094165f908152600160208181526040808420338552909152909120929094039091555090919050565b60026006540361081c5760405162461bcd60e51b81526004016107be906121e8565b600260065561082a3361168a565b335f908152600d6020526040902054806108735760405162461bcd60e51b815260206004820152600a6024820152694e6f207265776172647360b01b60448201526064016107be565b335f908152600d6020526040812055600a548111156108c75760405162461bcd60e51b815260206004820152601060248201526f5265776172647320706f6f6c206c6f7760801b60448201526064016107be565b80600a5f8282546108d89190612154565b90915550506040515f90339083908381818185875af1925050503d805f811461091c576040519150601f19603f3d011682016040523d82523d5f602084013e610921565b606091505b50509050806109685760405162461bcd60e51b8152602060048201526013602482015272141314c81d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107be565b60405182815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04869060200160405180910390a250506001600655565b600881815481106109b5575f80fd5b905f5260205f209060109182820401919006600202915054906101000a900461ffff1681565b600781815481106109ea575f80fd5b5f918252602090912001546001600160a01b0316905081565b6005546001600160a01b03163314610a2d5760405162461bcd60e51b81526004016107be9061221f565b610a365f6116cf565b565b606060048054610691906121b0565b6005546001600160a01b03163314610a715760405162461bcd60e51b81526004016107be9061221f565b61012c61ffff83161115610abe5760405162461bcd60e51b8152602060048201526014602482015273088cae0dee6d2e840cccaca40e8dede40d0d2ced60631b60448201526064016107be565b61012c61ffff82161115610b0a5760405162461bcd60e51b81526020600482015260136024820152720a4cac8cacada40cccaca40e8dede40d0d2ced606b1b60448201526064016107be565b6009805461ffff84811663ffffffff19909216821762010000918516918202179092556040805191825260208201929092527f2ac80c14c28700f7b5e36f947d572149fe2e3947bac32c3a8c098f3e03722c11910160405180910390a15050565b6005546001600160a01b03163314610b955760405162461bcd60e51b81526004016107be9061221f565b610c008484808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284375f9201919091525061172092505050565b50505050565b5f61071e338484611668565b6060806007600881805480602002602001604051908101604052809291908181526020018280548015610c6c57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311610c4e575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610ce357602002820191905f5260205f20905f905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610caa5790505b50505050509050915091509091565b600260065403610d145760405162461bcd60e51b81526004016107be906121e8565b60026006553480610d5a5760405162461bcd60e51b815260206004820152601060248201526f139bc8141314c819195c1bdcda5d195960821b60448201526064016107be565b600754610d9a5760405162461bcd60e51b815260206004820152600e60248201526d10985cdad95d081b9bdd081cd95d60921b60448201526064016107be565b610da33361168a565b610dad33826119bf565b6009545f9061271090610dc49061ffff1684612167565b610dce919061217e565b90505f610ddb8284612154565b90508115610dec57610dec826119d6565b6007547f000000000000000000000000000000000000000000000000000000000000000090829081905f5b81811015611001575f610e2b600184612154565b8203610e38575082610e9b565b61271060088381548110610e4e57610e4e612256565b5f9182526020909120601082040154610e7791600f166002026101000a900461ffff1687612167565b610e81919061217e565b905083811115610e8e5750825b610e988185612154565b93505b805f03610ea85750610fef565b6040805160028082526060820183525f926020830190803683370190505090507f0000000000000000000000000000000000000000000000000000000000000000815f81518110610efb57610efb612256565b60200260200101906001600160a01b031690816001600160a01b03168152505060078381548110610f2e57610f2e612256565b905f5260205f20015f9054906101000a90046001600160a01b031681600181518110610f5c57610f5c612256565b6001600160a01b0392831660209182029290920101528716637ff36ab5835f8430610f894261012c61219d565b6040518663ffffffff1660e01b8152600401610fa8949392919061227e565b5f6040518083038185885af1158015610fc3573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f19168201604052610feb91908101906122b2565b5050505b80610ff98161236b565b915050610e17565b50506001600655505050505050565b6002600654036110325760405162461bcd60e51b81526004016107be906121e8565b6002600655806110725760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b60448201526064016107be565b600254806110ae5760405162461bcd60e51b81526020600482015260096024820152684e6f20737570706c7960b81b60448201526064016107be565b6110b73361168a565b5f600a54476110c69190612154565b90505f826110d48584612167565b6110de919061217e565b90507f0000000000000000000000000000000000000000000000000000000000000000475f5b60075481101561138c575f6007828154811061112257611122612256565b5f9182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611172573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111969190612383565b9050805f036111a657505061137a565b5f886111b28b84612167565b6111bc919061217e565b9050805f036111cd5750505061137a565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905284169063095ea7b3906044016020604051808303815f875af1158015611239573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125d919061239a565b506040805160028082526060820183525f9260208301908036833701905050905083815f8151811061129157611291612256565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106112e5576112e5612256565b6001600160a01b03928316602091820292909201015287166318cbafe5835f84306113124261012c61219d565b6040518663ffffffff1660e01b81526004016113329594939291906123b9565b5f604051808303815f875af115801561134d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137491908101906122b2565b50505050505b806113848161236b565b915050611104565b505f6113988247612154565b90505f6113a5828661219d565b90505f81116113ea5760405162461bcd60e51b81526020600482015260116024820152704e6f7468696e6720746f2072656465656d60781b60448201526064016107be565b6113f43389611aa9565b6009545f90612710906114119062010000900461ffff1684612167565b61141b919061217e565b90505f6114288284612154565b9050811561143957611439826119d6565b6040515f90339083908381818185875af1925050503d805f8114611478576040519150601f19603f3d011682016040523d82523d5f602084013e61147d565b606091505b50509050806114c45760405162461bcd60e51b8152602060048201526013602482015272141314c81d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107be565b50506001600655505050505050505050565b6005546001600160a01b031633146115005760405162461bcd60e51b81526004016107be9061221f565b6001600160a01b0381166115565760405162461bcd60e51b815260206004820152601760248201527f4f776e61626c653a206e6577206f776e6572207a65726f00000000000000000060448201526064016107be565b61155f816116cf565b50565b6001600160a01b0383166115b85760405162461bcd60e51b815260206004820152601860248201527f45524332303a20617070726f76652066726f6d207a65726f000000000000000060448201526064016107be565b6001600160a01b0382166116075760405162461bcd60e51b815260206004820152601660248201527545524332303a20617070726f766520746f207a65726f60501b60448201526064016107be565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6116718361168a565b61167a8261168a565b611685838383611abc565b505050565b6001600160a01b0381161561155f576116a281610602565b6001600160a01b0382165f908152600d6020908152604080832093909355600b54600c9091529190205550565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f82511161175f5760405162461bcd60e51b815260206004820152600c60248201526b115b5c1d1e4818985cdad95d60a21b60448201526064016107be565b80518251146117a25760405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b60448201526064016107be565b5f805b8351811015611852575f6001600160a01b03168482815181106117ca576117ca612256565b60200260200101516001600160a01b0316036118155760405162461bcd60e51b815260206004820152600a602482015269546f6b656e207a65726f60b01b60448201526064016107be565b82818151811061182757611827612256565b602002602001015161ffff168261183e919061219d565b91508061184a8161236b565b9150506117a5565b5080612710146118a45760405162461bcd60e51b815260206004820152601960248201527f57656967687473206d7573742073756d20746f2031303030300000000000000060448201526064016107be565b6118af60075f611e3d565b6118ba60085f611e58565b5f5b83518110156119805760078482815181106118d9576118d9612256565b60209081029190910181015182546001810184555f938452919092200180546001600160a01b0319166001600160a01b03909216919091179055825160089084908390811061192a5761192a612256565b60209081029190910181015182546001810184555f9384529190922060108204018054600f9092166002026101000a61ffff818102199093169290931692909202179055806119788161236b565b9150506118bc565b507f73192282755a6185dc90088ac8a3411af6b631198a2b4f31d174e9deec0aef5083836040516119b29291906120bf565b60405180910390a1505050565b6119c88261168a565b6119d28282611c60565b5050565b805f036119e05750565b5f60025411611a295760405162461bcd60e51b81526020600482015260156024820152744e6f20737570706c7920666f72207265776172647360581b60448201526064016107be565b80600a5f828254611a3a919061219d565b9091555050600254611a54670de0b6b3a764000083612167565b611a5e919061217e565b600b5f828254611a6e919061219d565b90915550506040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b611ab28261168a565b6119d28282611d32565b6001600160a01b038316611b125760405162461bcd60e51b815260206004820152601960248201527f45524332303a207472616e736665722066726f6d207a65726f0000000000000060448201526064016107be565b6001600160a01b038216611b685760405162461bcd60e51b815260206004820152601760248201527f45524332303a207472616e7366657220746f207a65726f00000000000000000060448201526064016107be565b6001600160a01b0383165f9081526020819052604090205481811015611bd05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a207472616e7366657220657863656564732062616c616e63650060448201526064016107be565b6001600160a01b038085165f90815260208190526040808220858503905591851681529081208054849290611c0690849061219d565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c5291815260200190565b60405180910390a350505050565b6001600160a01b038216611cac5760405162461bcd60e51b815260206004820152601360248201527245524332303a206d696e7420746f207a65726f60681b60448201526064016107be565b8060025f828254611cbd919061219d565b90915550506001600160a01b0382165f9081526020819052604081208054839290611ce990849061219d565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216611d805760405162461bcd60e51b815260206004820152601560248201527445524332303a206275726e2066726f6d207a65726f60581b60448201526064016107be565b6001600160a01b0382165f9081526020819052604090205481811015611de85760405162461bcd60e51b815260206004820152601b60248201527f45524332303a206275726e20657863656564732062616c616e6365000000000060448201526064016107be565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161165b565b5080545f8255905f5260205f209081019061155f9190611e76565b5080545f8255600f0160109004905f5260205f209081019061155f91905b5b80821115611e8a575f8155600101611e77565b5090565b80356001600160a01b0381168114611ea4575f80fd5b919050565b5f60208284031215611eb9575f80fd5b611ec282611e8e565b9392505050565b5f6020808352835180828501525f5b81811015611ef457858101830151858201604001528201611ed8565b505f604082860101526040601f19601f8301168501019250505092915050565b5f8060408385031215611f25575f80fd5b611f2e83611e8e565b946020939093013593505050565b5f805f60608486031215611f4e575f80fd5b611f5784611e8e565b9250611f6560208501611e8e565b9150604084013590509250925092565b5f60208284031215611f85575f80fd5b5035919050565b803561ffff81168114611ea4575f80fd5b5f8060408385031215611fae575f80fd5b611fb783611f8c565b9150611fc560208401611f8c565b90509250929050565b5f8083601f840112611fde575f80fd5b50813567ffffffffffffffff811115611ff5575f80fd5b6020830191508360208260051b850101111561200f575f80fd5b9250929050565b5f805f8060408587031215612029575f80fd5b843567ffffffffffffffff80821115612040575f80fd5b61204c88838901611fce565b90965094506020870135915080821115612064575f80fd5b5061207187828801611fce565b95989497509550505050565b5f8151808452602080850194508084015f5b838110156120b45781516001600160a01b03168752958201959082019060010161208f565b509495945050505050565b604081525f6120d1604083018561207d565b8281036020848101919091528451808352858201928201905f5b8181101561210b57845161ffff16835293830193918301916001016120eb565b5090979650505050505050565b5f8060408385031215612129575f80fd5b61213283611e8e565b9150611fc560208401611e8e565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561072257610722612140565b808202811582820484141761072257610722612140565b5f8261219857634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561072257610722612140565b600181811c908216806121c457607f821691505b6020821081036121e257634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252601a908201527f5265656e7472616e637947756172643a207265656e7472616e74000000000000604082015260600190565b6020808252601c908201527f4f776e61626c653a2063616c6c6572206973206e6f74206f776e657200000000604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b848152608060208201525f612296608083018661207d565b6001600160a01b03949094166040830152506060015292915050565b5f60208083850312156122c3575f80fd5b825167ffffffffffffffff808211156122da575f80fd5b818501915085601f8301126122ed575f80fd5b8151818111156122ff576122ff61226a565b8060051b604051601f19603f830116810181811085821117156123245761232461226a565b604052918252848201925083810185019188831115612341575f80fd5b938501935b8285101561235f57845184529385019392850192612346565b98975050505050505050565b5f6001820161237c5761237c612140565b5060010190565b5f60208284031215612393575f80fd5b5051919050565b5f602082840312156123aa575f80fd5b81518015158114611ec2575f80fd5b85815284602082015260a060408201525f6123d760a083018661207d565b6001600160a01b039490941660608301525060800152939250505056fea2646970667358221220d6cda9c21d4d223105fbb51500e6dc54fac6be881dd2546f48cc0c2663f1016464736f6c63430008140033000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000600000000000000000000000095b303987a60c71504d99aa1b13b4da07b0790ab0000000000000000000000002fa878ab3f87cc1c9737fc071108f904c0b0c95d0000000000000000000000002b591e99afe9f32eaa6214f7b7629768c40eeb3900000000000000000000000057fde0a71132198bbec939b98976993d8d89d225000000000000000000000000b17d901469b9208b17d916112988a3fed19b5ca100000000000000000000000002dcdd04e3f455d838cd1249292c58f3b79e3c3c000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000003e8

Deployed ByteCode

0x6080604052600436106101d2575f3560e01c806370a08231116100fd578063ab87982711610092578063db006a7511610062578063db006a751461056b578063dd62ed3e1461058a578063df136d65146105ce578063f2fde38b146105e3575f80fd5b8063ab87982714610512578063cd6ef2b01461052c578063d0e30db01461054e578063d55be8c614610556575f80fd5b806395d89b41116100cd57806395d89b41146104a15780639ef833d4146104b5578063a461ee15146104d4578063a9059cbb146104f3575f80fd5b806370a0823114610411578063715018a6146104455780638b876347146104595780638da5cb5b14610484575f80fd5b806318160ddd11610173578063372500ab11610143578063372500ab1461038a5780633e5958e1146103a057806344a7e5c8146103bf5780634e69e92e146103de575f80fd5b806318160ddd146102f157806323b872dd14610305578063313ce567146103245780633268cc561461033f575f80fd5b80630700037d116101ae5780630700037d14610245578063095ea7b31461027057806309f6442c1461029f5780630c70754e146102d2575f80fd5b80628cc262146101dd5780630359fea91461020f57806306fdde0314610224575f80fd5b366101d957005b5f80fd5b3480156101e8575f80fd5b506101fc6101f7366004611ea9565b610602565b6040519081526020015b60405180910390f35b34801561021a575f80fd5b506101fc600a5481565b34801561022f575f80fd5b50610238610682565b6040516102069190611ec9565b348015610250575f80fd5b506101fc61025f366004611ea9565b600d6020525f908152604090205481565b34801561027b575f80fd5b5061028f61028a366004611f14565b610712565b6040519015158152602001610206565b3480156102aa575f80fd5b506009546102bf9062010000900461ffff1681565b60405161ffff9091168152602001610206565b3480156102dd575f80fd5b506101fc6102ec366004611ea9565b610728565b3480156102fc575f80fd5b506002546101fc565b348015610310575f80fd5b5061028f61031f366004611f3c565b610732565b34801561032f575f80fd5b5060405160128152602001610206565b34801561034a575f80fd5b506103727f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d981565b6040516001600160a01b039091168152602001610206565b348015610395575f80fd5b5061039e6107fa565b005b3480156103ab575f80fd5b506102bf6103ba366004611f75565b6109a6565b3480156103ca575f80fd5b506103726103d9366004611f75565b6109db565b3480156103e9575f80fd5b506103727f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b34801561041c575f80fd5b506101fc61042b366004611ea9565b6001600160a01b03165f9081526020819052604090205490565b348015610450575f80fd5b5061039e610a03565b348015610464575f80fd5b506101fc610473366004611ea9565b600c6020525f908152604090205481565b34801561048f575f80fd5b506005546001600160a01b0316610372565b3480156104ac575f80fd5b50610238610a38565b3480156104c0575f80fd5b5061039e6104cf366004611f9d565b610a47565b3480156104df575f80fd5b5061039e6104ee366004612016565b610b6b565b3480156104fe575f80fd5b5061028f61050d366004611f14565b610c06565b34801561051d575f80fd5b506009546102bf9061ffff1681565b348015610537575f80fd5b50610540610c12565b6040516102069291906120bf565b61039e610cf2565b348015610561575f80fd5b506102bf61012c81565b348015610576575f80fd5b5061039e610585366004611f75565b611010565b348015610595575f80fd5b506101fc6105a4366004612118565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b3480156105d9575f80fd5b506101fc600b5481565b3480156105ee575f80fd5b5061039e6105fd366004611ea9565b6114d6565b6001600160a01b0381165f908152600c6020526040812054600b54829061062a908390612154565b6001600160a01b0385165f908152600d6020908152604080832054918390529091205491925090670de0b6b3a764000090610666908490612167565b610670919061217e565b61067a919061219d565b949350505050565b606060038054610691906121b0565b80601f01602080910402602001604051908101604052809291908181526020018280546106bd906121b0565b80156107085780601f106106df57610100808354040283529160200191610708565b820191905f5260205f20905b8154815290600101906020018083116106eb57829003601f168201915b5050505050905090565b5f61071e338484611562565b5060015b92915050565b5f61072282610602565b5f61073e848484611668565b6001600160a01b0384165f908152600160209081526040808320338452909152902054828110156107c75760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6001600160a01b03949094165f908152600160208181526040808420338552909152909120929094039091555090919050565b60026006540361081c5760405162461bcd60e51b81526004016107be906121e8565b600260065561082a3361168a565b335f908152600d6020526040902054806108735760405162461bcd60e51b815260206004820152600a6024820152694e6f207265776172647360b01b60448201526064016107be565b335f908152600d6020526040812055600a548111156108c75760405162461bcd60e51b815260206004820152601060248201526f5265776172647320706f6f6c206c6f7760801b60448201526064016107be565b80600a5f8282546108d89190612154565b90915550506040515f90339083908381818185875af1925050503d805f811461091c576040519150601f19603f3d011682016040523d82523d5f602084013e610921565b606091505b50509050806109685760405162461bcd60e51b8152602060048201526013602482015272141314c81d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107be565b60405182815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04869060200160405180910390a250506001600655565b600881815481106109b5575f80fd5b905f5260205f209060109182820401919006600202915054906101000a900461ffff1681565b600781815481106109ea575f80fd5b5f918252602090912001546001600160a01b0316905081565b6005546001600160a01b03163314610a2d5760405162461bcd60e51b81526004016107be9061221f565b610a365f6116cf565b565b606060048054610691906121b0565b6005546001600160a01b03163314610a715760405162461bcd60e51b81526004016107be9061221f565b61012c61ffff83161115610abe5760405162461bcd60e51b8152602060048201526014602482015273088cae0dee6d2e840cccaca40e8dede40d0d2ced60631b60448201526064016107be565b61012c61ffff82161115610b0a5760405162461bcd60e51b81526020600482015260136024820152720a4cac8cacada40cccaca40e8dede40d0d2ced606b1b60448201526064016107be565b6009805461ffff84811663ffffffff19909216821762010000918516918202179092556040805191825260208201929092527f2ac80c14c28700f7b5e36f947d572149fe2e3947bac32c3a8c098f3e03722c11910160405180910390a15050565b6005546001600160a01b03163314610b955760405162461bcd60e51b81526004016107be9061221f565b610c008484808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284375f9201919091525061172092505050565b50505050565b5f61071e338484611668565b6060806007600881805480602002602001604051908101604052809291908181526020018280548015610c6c57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311610c4e575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610ce357602002820191905f5260205f20905f905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610caa5790505b50505050509050915091509091565b600260065403610d145760405162461bcd60e51b81526004016107be906121e8565b60026006553480610d5a5760405162461bcd60e51b815260206004820152601060248201526f139bc8141314c819195c1bdcda5d195960821b60448201526064016107be565b600754610d9a5760405162461bcd60e51b815260206004820152600e60248201526d10985cdad95d081b9bdd081cd95d60921b60448201526064016107be565b610da33361168a565b610dad33826119bf565b6009545f9061271090610dc49061ffff1684612167565b610dce919061217e565b90505f610ddb8284612154565b90508115610dec57610dec826119d6565b6007547f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d990829081905f5b81811015611001575f610e2b600184612154565b8203610e38575082610e9b565b61271060088381548110610e4e57610e4e612256565b5f9182526020909120601082040154610e7791600f166002026101000a900461ffff1687612167565b610e81919061217e565b905083811115610e8e5750825b610e988185612154565b93505b805f03610ea85750610fef565b6040805160028082526060820183525f926020830190803683370190505090507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27815f81518110610efb57610efb612256565b60200260200101906001600160a01b031690816001600160a01b03168152505060078381548110610f2e57610f2e612256565b905f5260205f20015f9054906101000a90046001600160a01b031681600181518110610f5c57610f5c612256565b6001600160a01b0392831660209182029290920101528716637ff36ab5835f8430610f894261012c61219d565b6040518663ffffffff1660e01b8152600401610fa8949392919061227e565b5f6040518083038185885af1158015610fc3573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f19168201604052610feb91908101906122b2565b5050505b80610ff98161236b565b915050610e17565b50506001600655505050505050565b6002600654036110325760405162461bcd60e51b81526004016107be906121e8565b6002600655806110725760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b60448201526064016107be565b600254806110ae5760405162461bcd60e51b81526020600482015260096024820152684e6f20737570706c7960b81b60448201526064016107be565b6110b73361168a565b5f600a54476110c69190612154565b90505f826110d48584612167565b6110de919061217e565b90507f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9475f5b60075481101561138c575f6007828154811061112257611122612256565b5f9182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611172573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111969190612383565b9050805f036111a657505061137a565b5f886111b28b84612167565b6111bc919061217e565b9050805f036111cd5750505061137a565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9811660048301526024820183905284169063095ea7b3906044016020604051808303815f875af1158015611239573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061125d919061239a565b506040805160028082526060820183525f9260208301908036833701905050905083815f8151811061129157611291612256565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27816001815181106112e5576112e5612256565b6001600160a01b03928316602091820292909201015287166318cbafe5835f84306113124261012c61219d565b6040518663ffffffff1660e01b81526004016113329594939291906123b9565b5f604051808303815f875af115801561134d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137491908101906122b2565b50505050505b806113848161236b565b915050611104565b505f6113988247612154565b90505f6113a5828661219d565b90505f81116113ea5760405162461bcd60e51b81526020600482015260116024820152704e6f7468696e6720746f2072656465656d60781b60448201526064016107be565b6113f43389611aa9565b6009545f90612710906114119062010000900461ffff1684612167565b61141b919061217e565b90505f6114288284612154565b9050811561143957611439826119d6565b6040515f90339083908381818185875af1925050503d805f8114611478576040519150601f19603f3d011682016040523d82523d5f602084013e61147d565b606091505b50509050806114c45760405162461bcd60e51b8152602060048201526013602482015272141314c81d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107be565b50506001600655505050505050505050565b6005546001600160a01b031633146115005760405162461bcd60e51b81526004016107be9061221f565b6001600160a01b0381166115565760405162461bcd60e51b815260206004820152601760248201527f4f776e61626c653a206e6577206f776e6572207a65726f00000000000000000060448201526064016107be565b61155f816116cf565b50565b6001600160a01b0383166115b85760405162461bcd60e51b815260206004820152601860248201527f45524332303a20617070726f76652066726f6d207a65726f000000000000000060448201526064016107be565b6001600160a01b0382166116075760405162461bcd60e51b815260206004820152601660248201527545524332303a20617070726f766520746f207a65726f60501b60448201526064016107be565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6116718361168a565b61167a8261168a565b611685838383611abc565b505050565b6001600160a01b0381161561155f576116a281610602565b6001600160a01b0382165f908152600d6020908152604080832093909355600b54600c9091529190205550565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f82511161175f5760405162461bcd60e51b815260206004820152600c60248201526b115b5c1d1e4818985cdad95d60a21b60448201526064016107be565b80518251146117a25760405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b60448201526064016107be565b5f805b8351811015611852575f6001600160a01b03168482815181106117ca576117ca612256565b60200260200101516001600160a01b0316036118155760405162461bcd60e51b815260206004820152600a602482015269546f6b656e207a65726f60b01b60448201526064016107be565b82818151811061182757611827612256565b602002602001015161ffff168261183e919061219d565b91508061184a8161236b565b9150506117a5565b5080612710146118a45760405162461bcd60e51b815260206004820152601960248201527f57656967687473206d7573742073756d20746f2031303030300000000000000060448201526064016107be565b6118af60075f611e3d565b6118ba60085f611e58565b5f5b83518110156119805760078482815181106118d9576118d9612256565b60209081029190910181015182546001810184555f938452919092200180546001600160a01b0319166001600160a01b03909216919091179055825160089084908390811061192a5761192a612256565b60209081029190910181015182546001810184555f9384529190922060108204018054600f9092166002026101000a61ffff818102199093169290931692909202179055806119788161236b565b9150506118bc565b507f73192282755a6185dc90088ac8a3411af6b631198a2b4f31d174e9deec0aef5083836040516119b29291906120bf565b60405180910390a1505050565b6119c88261168a565b6119d28282611c60565b5050565b805f036119e05750565b5f60025411611a295760405162461bcd60e51b81526020600482015260156024820152744e6f20737570706c7920666f72207265776172647360581b60448201526064016107be565b80600a5f828254611a3a919061219d565b9091555050600254611a54670de0b6b3a764000083612167565b611a5e919061217e565b600b5f828254611a6e919061219d565b90915550506040518181527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a150565b611ab28261168a565b6119d28282611d32565b6001600160a01b038316611b125760405162461bcd60e51b815260206004820152601960248201527f45524332303a207472616e736665722066726f6d207a65726f0000000000000060448201526064016107be565b6001600160a01b038216611b685760405162461bcd60e51b815260206004820152601760248201527f45524332303a207472616e7366657220746f207a65726f00000000000000000060448201526064016107be565b6001600160a01b0383165f9081526020819052604090205481811015611bd05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a207472616e7366657220657863656564732062616c616e63650060448201526064016107be565b6001600160a01b038085165f90815260208190526040808220858503905591851681529081208054849290611c0690849061219d565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c5291815260200190565b60405180910390a350505050565b6001600160a01b038216611cac5760405162461bcd60e51b815260206004820152601360248201527245524332303a206d696e7420746f207a65726f60681b60448201526064016107be565b8060025f828254611cbd919061219d565b90915550506001600160a01b0382165f9081526020819052604081208054839290611ce990849061219d565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038216611d805760405162461bcd60e51b815260206004820152601560248201527445524332303a206275726e2066726f6d207a65726f60581b60448201526064016107be565b6001600160a01b0382165f9081526020819052604090205481811015611de85760405162461bcd60e51b815260206004820152601b60248201527f45524332303a206275726e20657863656564732062616c616e6365000000000060448201526064016107be565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161165b565b5080545f8255905f5260205f209081019061155f9190611e76565b5080545f8255600f0160109004905f5260205f209081019061155f91905b5b80821115611e8a575f8155600101611e77565b5090565b80356001600160a01b0381168114611ea4575f80fd5b919050565b5f60208284031215611eb9575f80fd5b611ec282611e8e565b9392505050565b5f6020808352835180828501525f5b81811015611ef457858101830151858201604001528201611ed8565b505f604082860101526040601f19601f8301168501019250505092915050565b5f8060408385031215611f25575f80fd5b611f2e83611e8e565b946020939093013593505050565b5f805f60608486031215611f4e575f80fd5b611f5784611e8e565b9250611f6560208501611e8e565b9150604084013590509250925092565b5f60208284031215611f85575f80fd5b5035919050565b803561ffff81168114611ea4575f80fd5b5f8060408385031215611fae575f80fd5b611fb783611f8c565b9150611fc560208401611f8c565b90509250929050565b5f8083601f840112611fde575f80fd5b50813567ffffffffffffffff811115611ff5575f80fd5b6020830191508360208260051b850101111561200f575f80fd5b9250929050565b5f805f8060408587031215612029575f80fd5b843567ffffffffffffffff80821115612040575f80fd5b61204c88838901611fce565b90965094506020870135915080821115612064575f80fd5b5061207187828801611fce565b95989497509550505050565b5f8151808452602080850194508084015f5b838110156120b45781516001600160a01b03168752958201959082019060010161208f565b509495945050505050565b604081525f6120d1604083018561207d565b8281036020848101919091528451808352858201928201905f5b8181101561210b57845161ffff16835293830193918301916001016120eb565b5090979650505050505050565b5f8060408385031215612129575f80fd5b61213283611e8e565b9150611fc560208401611e8e565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561072257610722612140565b808202811582820484141761072257610722612140565b5f8261219857634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561072257610722612140565b600181811c908216806121c457607f821691505b6020821081036121e257634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252601a908201527f5265656e7472616e637947756172643a207265656e7472616e74000000000000604082015260600190565b6020808252601c908201527f4f776e61626c653a2063616c6c6572206973206e6f74206f776e657200000000604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b848152608060208201525f612296608083018661207d565b6001600160a01b03949094166040830152506060015292915050565b5f60208083850312156122c3575f80fd5b825167ffffffffffffffff808211156122da575f80fd5b818501915085601f8301126122ed575f80fd5b8151818111156122ff576122ff61226a565b8060051b604051601f19603f830116810181811085821117156123245761232461226a565b604052918252848201925083810185019188831115612341575f80fd5b938501935b8285101561235f57845184529385019392850192612346565b98975050505050505050565b5f6001820161237c5761237c612140565b5060010190565b5f60208284031215612393575f80fd5b5051919050565b5f602082840312156123aa575f80fd5b81518015158114611ec2575f80fd5b85815284602082015260a060408201525f6123d760a083018661207d565b6001600160a01b039490941660608301525060800152939250505056fea2646970667358221220d6cda9c21d4d223105fbb51500e6dc54fac6be881dd2546f48cc0c2663f1016464736f6c63430008140033