Token Phenix

Overview CRC20

Price
$0.00 @ 0.000000 CRO
Fully Diluted Market Cap
Total Supply:
21,831,619,187.427389 PHNX

Holders:
6,187 addresses
Balance
321.214053765605186516 PHNX

Value
$0.00
0x768f2a7ccdfde9ebdfd5cea8b635dd590cb3a3f1
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xae65d32ddED15c83B4744BEb4Ea26F9786351982

Contract Name:
Phenix

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 8 of 11: Phenix.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

import "./ERC20Detailed.sol";
import "./IVVSFactory.sol";
import "./IVVSRouter.sol";
import "./ERC20Detailed.sol";
import "./ERC20Detailed.sol";
import "./Ownable.sol";
import "./SafeMath.sol";
import "./SafeMathInt.sol";
import "./InterfaceLP.sol";
import "./TokenVesting.sol";

contract Phenix is ERC20Detailed, Ownable {
    using SafeMath for uint256;
    using SafeMathInt for int256;

    event Rebase(uint256 indexed totalSupply);

    InterfaceLP public pairContract;
    address public liquidityReceiver;
    address public phenixFundReserveReciever;
    bool public initialDistributionFinished;
    bool public autoRebaseState;

    PhenixTokenVesting private phenixVestingContract;

    mapping(address => bool) _allowTransfer;
    mapping(address => bool) _isFeeExempt;

    uint256 private constant DECIMALS = 18;
    uint256 private constant MAX_UINT256 = ~uint256(0);
    address private constant DEAD = 0x000000000000000000000000000000000000dEaD;
    address private constant ZERO = 0x0000000000000000000000000000000000000000;
    uint256 private constant REBASE_SCALING_VALUE = 100000;
    uint256 private constant REBASE_INTERVAL = 86400;
    uint256 private constant INITIAL_FRAGMENTS_SUPPLY =
        1 * 10**9 * 10**DECIMALS;

    uint256 public liquidityFee = 5;
    uint256 public phenixVaultFee = 8;
    uint256 public sellFee = 2;
    uint256 public totalFee = liquidityFee.add(phenixVaultFee);
    uint256 public feeDenominator = 100;

    uint256 public lastRebaseTimestamp = block.timestamp;
    uint256 public lastRebaseDelta = 0;
    uint256 public rebasePercentDelta = 18; // 1.8 percent
    uint256 public rebaseDenominator = 1000;
    uint256 public minimumRebaseTimestampDelta = 60;

    uint256 targetLiquidity = 50;
    uint256 targetLiquidityDenominator = 100;

    IVVSRouter public router;
    address public pair;

    bool public swapEnabled = true;
    uint256 private gonSwapThreshold = (TOTAL_GONS * 10) / 10000;
    bool inSwap;

    uint256 private constant TOTAL_GONS =
        MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);
    uint256 private constant MAX_SUPPLY = ~uint128(0);
    uint256 private _totalSupply;
    uint256 private _gonsPerFragment;
    mapping(address => uint256) private _gonBalances;
    mapping(address => mapping(address => uint256)) private _allowedFragments;

    constructor() ERC20Detailed("Phenix", "PHNX", uint8(DECIMALS)) {
        router = IVVSRouter(0x145677FC4d9b8F19B5D56d1820c48e0443049a30);

        pair = IVVSFactory(router.factory()).createPair(
            router.WETH(),
            address(this)
        );

        phenixVestingContract = new PhenixTokenVesting(
            address(this),
            address(pair),
            address(msg.sender)
        );

        liquidityReceiver = address(phenixVestingContract);
        phenixFundReserveReciever = address(phenixVestingContract);

        _allowedFragments[address(this)][address(router)] = uint256(-1);
        pairContract = InterfaceLP(pair);

        _totalSupply = INITIAL_FRAGMENTS_SUPPLY;
        _gonBalances[address(phenixVestingContract)] = TOTAL_GONS;
        _gonsPerFragment = TOTAL_GONS.div(_totalSupply);

        initialDistributionFinished = false;
        autoRebaseState = false;

        _isFeeExempt[address(phenixFundReserveReciever)] = true;
        _isFeeExempt[address(phenixVestingContract)] = true;
        _isFeeExempt[address(this)] = true;
        _isFeeExempt[address(msg.sender)] = true;

        _allowTransfer[address(phenixVestingContract)] = true;

        emit Transfer(
            address(0x0),
            address(phenixVestingContract),
            _totalSupply
        );
    }

    /**
     * @dev Swapping switch used to mitigate any calculation
     * issues during swapBack.
     */
    modifier noReentrancy() {
        inSwap = true;
        _;
        inSwap = false;
    }

    modifier initialDistributionLock() {
        require(
            initialDistributionFinished ||
                isOwner() ||
                _allowTransfer[msg.sender]
        );
        _;
    }

    modifier validRecipient(address to) {
        require(to != address(0x0));
        _;
    }

    /**
     * @dev Updates the autoRebaseState state. Only callable by
     * owner address. This will also reset the last rebase time.
     * @param _state boolean state for autoRebaseState.
     */
    function _updateAutoRebaseState(bool _state) internal {
        autoRebaseState = _state;
        lastRebaseTimestamp = block.timestamp;
    }

    /**
     * @dev Updates the autoRebaseState state. Only callable by
     * owner address.
     * @return next rebase delta as uint256 value.
     */
    function getNextRebase() public view returns (uint256) {
        uint256 currentTimestamp = block.timestamp;

        uint256 rebaseTimestampDelta = currentTimestamp - lastRebaseTimestamp;

        uint256 nextScaledRebaseIntervalPercentage = rebaseTimestampDelta
            .mul(REBASE_SCALING_VALUE)
            .div(REBASE_INTERVAL);

        uint256 nextRebaseDelta = _totalSupply
            .mul(rebasePercentDelta)
            .div(rebaseDenominator)
            .mul(nextScaledRebaseIntervalPercentage)
            .div(REBASE_SCALING_VALUE);

        return nextRebaseDelta;
    }

    /**
     * @dev Rebases total token supply based on the getNextRebase()
     * return result. Rebase is capped when MAX_SUPPLY is reached.
     */
    function _rebase() internal {
        uint256 supplyDelta = getNextRebase();
        _totalSupply = _totalSupply.add(uint256(supplyDelta));

        if (_totalSupply > MAX_SUPPLY) {
            _totalSupply = MAX_SUPPLY;
        }

        _gonsPerFragment = TOTAL_GONS.div(_totalSupply);

        lastRebaseDelta = supplyDelta;
        lastRebaseTimestamp = block.timestamp;

        emit Rebase(_totalSupply);
    }

    /**
     * @dev Returns total token supply. Overrides ERC-20
     * totalSupply() function to return elastic supply.
     */
    function totalSupply() external view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev Transfers amount tokens to an address.
     * @param to Receiver of the transfered tokens.
     * @param value Amount of tokens that are received.
     * @return true
     */
    function transfer(address to, uint256 value)
        external
        override
        validRecipient(to)
        initialDistributionLock
        returns (bool)
    {
        _transferFrom(msg.sender, to, value);
        return true;
    }

    /**
     * @dev Updates LP contract address and removes
     * fees from the given address.
     * @param _address Update LP contract address.
     */
    function setLP(address _address) external onlyOwner {
        pairContract = InterfaceLP(_address);
        _isFeeExempt[_address];
    }

    /**
     * @dev Returns spender alloance of an owner address.
     * Overides ERC-20 allowance(address, address) function
     * to return allowed fragments.
     * @param owner Owner address of tokens.
     * @param spender Spender address of tokens.
     * @return uint256 Amount of allowed tokens for the spender to use.
     */
    function allowance(address owner, address spender)
        external
        view
        override
        returns (uint256)
    {
        return _allowedFragments[owner][spender];
    }

    /**
     * @dev Returns balance of given address. Overrides
     * ERC-20 balanceOf(address) to provide balance based
     * on holder gons and gonsPerFragment.
     * @param who Balance of address.
     * @return uint256 value of address balance.
     */
    function balanceOf(address who) external view override returns (uint256) {
        return _gonBalances[who].div(_gonsPerFragment);
    }

    /**
     * @dev Performs basic token transfer. Used as
     * internal function in _transferFrom(address,
     * address, uint256) function.
     * @param from sender address of transfer.
     * @param to receiver adddress of transfer.
     * @param amount amount of tokens for receiver.
     * @return true.
     */
    function _basicTransfer(
        address from,
        address to,
        uint256 amount
    ) internal returns (bool) {
        uint256 gonAmount = amount.mul(_gonsPerFragment);
        _gonBalances[from] = _gonBalances[from].sub(gonAmount);
        _gonBalances[to] = _gonBalances[to].add(gonAmount);
        return true;
    }

    /**
     * @dev Transfers token from sender address
     * to receiver address. Performs token supply
     * rebase provided it is acceptable. Executes
     * _baseTransfer(address, address, uint256) if
     * swap is in progress.
     * @param sender sender address of transfer.
     * @param to receiver adddress of transfer.
     * @param amount amount of tokens for receiver.
     * @return true.
     */
    function _transferFrom(
        address sender,
        address to,
        uint256 amount
    ) internal returns (bool) {
        if (autoRebaseState == true &&
                _shouldRebase() &&
                (pair == sender || pair == to)
        ) {
            _rebase();
            if(to == pair) {
                pairContract.sync();
            }
        }

        if (inSwap) {
            return _basicTransfer(sender, to, amount);
        }

        uint256 gonAmount = amount.mul(_gonsPerFragment);

        if (_shouldSwapBack()) {
            _swapBack();
        }

        _gonBalances[sender] = _gonBalances[sender].sub(gonAmount);

        uint256 gonAmountReceived = _shouldTakeFee(sender, to)
            ? _takeFee(sender, to, gonAmount)
            : gonAmount;
        _gonBalances[to] = _gonBalances[to].add(gonAmountReceived);

        emit Transfer(sender, to, gonAmountReceived.div(_gonsPerFragment));

        return true;
    }

    /**
     * @dev Transfers token from sender address
     * to receiver address. Overrides ERC-20
     * transferFrom(address, address, uint256) to
     * check value of allowed fragments that sender
     * can access from the owner (from address).
     * @param from sender address of transfer.
     * @param to receiver adddress of transfer.
     * @param value amount of tokens for receiver.
     * @return true.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external override validRecipient(to) returns (bool) {
        if (_allowedFragments[from][msg.sender] != uint256(-1)) {
            _allowedFragments[from][msg.sender] = _allowedFragments[from][
                msg.sender
            ].sub(value, "Insufficient Allowance");
        }

        _transferFrom(from, to, value);
        return true;
    }

    /**
     * @dev Executes fee allocations and distributes tokens
     * to contract address, phenix vault receiver address, and
     * liquidity receiver address. Does not liquify tokens if
     * over-liquified (determined by isOverLiquified() function).
     */
    function _swapBack() internal noReentrancy {
        uint256 dynamicLiquidityFee = isOverLiquified() ? 0 : liquidityFee;
        uint256 contractTokenBalance = _gonBalances[address(this)].div(
            _gonsPerFragment
        );
        uint256 amountToLiquify = contractTokenBalance
            .mul(dynamicLiquidityFee)
            .div(totalFee)
            .div(2);
        uint256 amountToSwap = contractTokenBalance.sub(amountToLiquify);

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = router.WETH();

        uint256 balanceBefore = address(this).balance;

        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amountToSwap,
            0,
            path,
            address(this),
            block.timestamp
        );

        uint256 amountETH = address(this).balance.sub(balanceBefore);

        uint256 totalETHFee = totalFee.sub(dynamicLiquidityFee.div(2));

        uint256 amountETHLiquidity = amountETH
            .mul(dynamicLiquidityFee)
            .div(totalETHFee)
            .div(2);

        uint256 amountETHPhenixVault = amountETH.mul(phenixVaultFee).div(
            totalETHFee
        );

        (bool success, ) = payable(phenixFundReserveReciever).call{
            value: amountETHPhenixVault,
            gas: 30000
        }("");

        success = false;

        if (amountToLiquify > 0) {
            router.addLiquidityETH{value: amountETHLiquidity}(
                address(this),
                amountToLiquify,
                0,
                0,
                liquidityReceiver,
                block.timestamp
            );
        }
    }

    /**
     * @dev Calculates swap fee and returns new allocation
     * of swap based on swap conditions. Calculate is based
     * on liquidity fee and phenix vault fee. Sell fee will also
     * be taken into consideration if receiver is pair address.
     * @return uint256 gonAmount that is transfered in the swap.
     */
    function _takeFee(
        address sender,
        address to,
        uint256 gonAmount
    ) internal returns (uint256) {
        uint256 _totalFee = totalFee;
        if (to == pair) _totalFee = _totalFee.add(sellFee);

        uint256 feeAmount = gonAmount.mul(_totalFee).div(feeDenominator);

        _gonBalances[address(this)] = _gonBalances[address(this)].add(
            feeAmount
        );
        emit Transfer(sender, address(this), feeAmount.div(_gonsPerFragment));

        return gonAmount.sub(feeAmount);
    }

    /**
     * @dev Decreases spender allowance of sender address.
     * @param spender Spender address.
     * @param subtractedValue Amount to reduce spender allowance by.
     * @return bool
     */
    function decreaseAllowance(address spender, uint256 subtractedValue)
        external
        initialDistributionLock
        returns (bool)
    {
        uint256 oldValue = _allowedFragments[msg.sender][spender];
        if (subtractedValue >= oldValue) {
            _allowedFragments[msg.sender][spender] = 0;
        } else {
            _allowedFragments[msg.sender][spender] = oldValue.sub(
                subtractedValue
            );
        }
        emit Approval(
            msg.sender,
            spender,
            _allowedFragments[msg.sender][spender]
        );
        return true;
    }

    /**
     * @dev Updates router address
     * @param _address address to set for the dex router
     */
    function updateRouter(address _address) external onlyOwner {
        require(address(router) != _address, "Router address already set");
        router = IVVSRouter(_address);
    }

    /**
     * @dev Increases spender allowance of sender address.
     * @param spender Spender address.
     * @param addedValue Amount to increase spender allowance by.
     * @return bool
     */
    function increaseAllowance(address spender, uint256 addedValue)
        external
        initialDistributionLock
        returns (bool)
    {
        _allowedFragments[msg.sender][spender] = _allowedFragments[msg.sender][
            spender
        ].add(addedValue);
        emit Approval(
            msg.sender,
            spender,
            _allowedFragments[msg.sender][spender]
        );
        return true;
    }

    /**
     * @dev Approves spender address to use sender tokens.
     * @param spender Spender address.
     * @param value Amount of tokens spender can access.
     * @return bool
     */
    function approve(address spender, uint256 value)
        external
        override
        initialDistributionLock
        returns (bool)
    {
        _allowedFragments[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev Checks if given address is exempt from swap fees.
     * @param _addr Address to check current exemption status.
     * @return bool
     */
    function checkFeeExempt(address _addr) external view returns (bool) {
        return _isFeeExempt[_addr];
    }

    /**
     * @dev Unlocks tokens and sets initialDistributedFinished
     * to true. Only callable from owner address.
     */
    function setInitialDistributionFinished() external onlyOwner {
        initialDistributionFinished = true;
    }

    /**
     * @dev Enables transfers for a specific address.
     * Only callable from owner address.
     * @param _addr Address to enable transfers.
     */
    function enableTransfer(address _addr) external onlyOwner {
        _allowTransfer[_addr] = true;
    }

    /**
     * @dev Sets given address to have exceptions from
     * swap fees. Only callable from owner address.
     * @param _addr Address to set fee exemptions.
     */
    function setFeeExempt(address _addr) external onlyOwner {
        _isFeeExempt[_addr] = true;
    }

    /**
     * @dev Checks if a token supply rebase is ready to
     * execute. Function utilized in _transferFrom(address,
     * address, uint256) internal function.
     * @return bool True if rebase can execute.
     */
    function _shouldRebase() internal view returns (bool) {
        return (uint256(block.timestamp).sub(lastRebaseTimestamp) >
            minimumRebaseTimestampDelta);
    }

    /**
     * @dev Checks if a sender (from) and receiver
     * (to) need swap fees applied in transfer. Used
     * in _transferFrom(address, address, uint256) internal
     * function. Should only apply when user is interacting with
     * the pair (to or from)
     * @param from Sender address of swap
     * @param to Receiver address of swap.
     * @return bool True if fees apply on transfer.
     */
    function _shouldTakeFee(address from, address to)
        internal
        view
        returns (bool)
    {
        return (pair == from || pair == to) && (!_isFeeExempt[from]);
    }

    /**
     * @dev Updates swap back settings.
     * @param _enabled bool value to determine of swap back is enabled.
     * @param _num uint256 value for the swap back threshhold
     * @param _denom uint256 value used for the threshold deminator
     */
    function setSwapBackSettings(
        bool _enabled,
        uint256 _num,
        uint256 _denom
    ) external onlyOwner {
        swapEnabled = _enabled;
        gonSwapThreshold = TOTAL_GONS.div(_denom).mul(_num);
    }

    /**
     * @dev Configures Rebase settings. Set AutoRebaseState,
     * RebasePercentDelta, and Accuracy.
     * @param _autoRebaseState True if rebase on each transfer
     * @param _percentage value of rebase percent delta based on a daily interval (18)
     * @param _accuracy defines the value of the rebase delta percentage demoninator (1000)
     */
    function setRebaseSettings(
        bool _autoRebaseState,
        uint256 _percentage,
        uint256 _accuracy
    ) external onlyOwner {
        _updateAutoRebaseState(_autoRebaseState);
        rebasePercentDelta = _percentage;
        rebaseDenominator = _accuracy;
    }

    /**
     * @dev Check whether the a swap back can be performed.
     * @return bool, true if swapBack is allowed to execute.
     */
    function _shouldSwapBack() internal view returns (bool) {
        return
            msg.sender != pair &&
            !inSwap &&
            swapEnabled &&
            _gonBalances[address(this)] >= gonSwapThreshold;
    }

    /**
     * @dev Returns current circulating token supply
     * @return uint256, value of total circulating supply.
     */
    function getCirculatingSupply() public view returns (uint256) {
        return
            (TOTAL_GONS.sub(_gonBalances[DEAD]).sub(_gonBalances[ZERO])).div(
                _gonsPerFragment
            );
    }

    function setTargetLiquidity(uint256 target, uint256 accuracy)
        external
        onlyOwner
    {
        targetLiquidity = target;
        targetLiquidityDenominator = accuracy;
    }

    function isNotInSwap() external view returns (bool) {
        return !inSwap;
    }

    function checkSwapThreshold() external view returns (uint256) {
        return gonSwapThreshold.div(_gonsPerFragment);
    }

    function setFeeReceivers(
        address _liquidityReceiver,
        address _phenixFundReserveReciever
    ) external onlyOwner {
        liquidityReceiver = _liquidityReceiver;
        phenixFundReserveReciever = _phenixFundReserveReciever;
    }

    function setFees(
        uint256 _liquidityFee,
        uint256 _phenixVaultFee,
        uint256 _sellFee,
        uint256 _feeDenominator
    ) external onlyOwner {
        liquidityFee = _liquidityFee;
        phenixVaultFee = _phenixVaultFee;
        sellFee = _sellFee;
        totalFee = liquidityFee.add(phenixVaultFee);
        feeDenominator = _feeDenominator;
        require(totalFee < feeDenominator / 4);
    }

    function getLiquidityBacking() public view returns (uint256) {
        uint256 liquidityBalance = _gonBalances[pair].div(_gonsPerFragment);
        return
            targetLiquidityDenominator.mul(liquidityBalance.mul(2)).div(
                getCirculatingSupply()
            );
    }

    function isOverLiquified() public view returns (bool) {
        return getLiquidityBacking() > targetLiquidity;
    }

    receive() external payable {}
}

File 1 of 11: ERC20Detailed.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

import "./IERC20.sol";

abstract contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor(
        string memory name,
        string memory symbol,
        uint8 decimals
    ) {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns (uint8) {
        return _decimals;
    }
}

File 2 of 11: IERC20.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

interface IERC20 {
    function totalSupply() external view returns (uint256);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

File 3 of 11: InterfaceLP.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

interface InterfaceLP {
    function sync() external;
}

File 4 of 11: IVVSFactory.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

interface IVVSFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB)
        external
        view
        returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;
}

File 5 of 11: IVVSRouter.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

import "./IVVSRouter01.sol";

interface IVVSRouter is IVVSRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

File 6 of 11: IVVSRouter01.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

interface IVVSRouter01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

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

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

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

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

File 7 of 11: Ownable.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

contract Ownable {
    address private _owner;

    event OwnershipRenounced(address indexed previousOwner);

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

    constructor() {
        _owner = msg.sender;
    }

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

    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    function renounceOwnership() public onlyOwner {
        emit OwnershipRenounced(_owner);
        _owner = address(0);
    }

    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 9 of 11: SafeMath.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;

        return c;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

File 10 of 11: SafeMathInt.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != -1 || a != MIN_INT256);

        return a / b;
    }

    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }
}

File 11 of 11: TokenVesting.sol
pragma solidity ^0.7.4;

// SPDX-License-Identifier: MIT

import "./Ownable.sol";
import "./SafeMath.sol";
import "./IERC20.sol";
import "./IVVSRouter.sol";

contract PhenixTokenVesting is Ownable {
    using SafeMath for uint256;

    address private tokenAddress;
    address private pairAddress;
    uint256 private unlockTimestamp;
    uint256 private burnLimitPercentage;
    uint256 private burnLimitDenominator;
    uint256 public burnTimestampDifference;
    uint256 public lastBurnTimestamp;
    uint256 private buyBackPercentageAllocation;
    uint256 private buyBackPercentageDenominator;
    uint256 public buyBackAllocation;
    uint256 public totalTokensBurned;
    mapping(address => bool) private authorizedReceiver;
    IVVSRouter public router;

    address constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

    constructor(
        address _tokenAddress,
        address _pairAddress,
        address _owner
    ) {
        tokenAddress = _tokenAddress;
        pairAddress = _pairAddress;
        unlockTimestamp = block.timestamp;
        authorizedReceiver[_owner] = true;

        burnLimitPercentage = 1;
        burnLimitDenominator = 100;
        burnTimestampDifference = 432000;
        totalTokensBurned = 0;
        lastBurnTimestamp = block.timestamp;

        buyBackPercentageAllocation = 20;
        buyBackPercentageDenominator = 100;
        buyBackAllocation = 0;

        router = IVVSRouter(0x145863Eb42Cf62847A6Ca784e6416C1682b1b2Ae);

        _transferOwnership(_owner);
    }

    event WithdrawTokens(address indexed _address, uint256 indexed _amount);
    event WithdrawPairTokens(address indexed _address, uint256 indexed _amount);
    event BurnTokens(uint256 indexed _amount);
    event SetAuthorizedReceiver(address indexed _address, bool indexed _status);

    /**
     * @dev Updates the authorizedReciever state of a given address. An
     * authorizedReceiver is allowed to withdraw tokens. Owner only.
     */
    function setAuthorizedReceiver(address _address, bool _status)
        public
        onlyOwner
    {
        authorizedReceiver[_address] = _status;
    }

    /**
     * @dev Increases the token timelock value by a given amount.
     */
    function increaseTimeLock(uint256 _amount) external onlyOwner {
        unlockTimestamp = unlockTimestamp.add(_amount);
    }

    /**
     * @dev Withdraw tokens from the vesting contract. Requires that the
     * caller is an authorizedReceiver and that the timelock has expired.
     */
    function withdrawTokens(uint256 _amount) external {
        require(
            IERC20(tokenAddress).balanceOf(address(this)) >= _amount,
            "Not enough tokens."
        );
        require(
            authorizedReceiver[msg.sender] == true,
            "Not authorized receiver."
        );
        require(block.timestamp > unlockTimestamp, "Not unlocked.");

        IERC20(tokenAddress).transfer(msg.sender, _amount);

        emit WithdrawTokens(msg.sender, _amount);
    }

    /**
     * @dev Withdraw pair tokens from the vesting contract. Requires that the
     * caller is an authorizedReceiver and that the timelock has expired.
     */
    function withdrawPairTokens(uint256 _amount) external {
        require(
            IERC20(pairAddress).balanceOf(address(this)) >= _amount,
            "Not enough tokens."
        );
        require(
            authorizedReceiver[msg.sender] == true,
            "Not authorized receiver."
        );
        require(block.timestamp > unlockTimestamp, "Not unlocked.");

        IERC20(pairAddress).transfer(msg.sender, _amount);

        emit WithdrawPairTokens(msg.sender, _amount);
    }

    function swapAndBurnTokens(uint256 _amountEth) external {
        require(
            _amountEth <= buyBackAllocation,
            "Not enough buy back allocation"
        );

        require(
            authorizedReceiver[msg.sender] == true,
            "Not authorized receiver."
        );

        buyBackAllocation = buyBackAllocation.sub(_amountEth);

        address[] memory path = new address[](2);
        path[0] = router.WETH();
        path[1] = address(tokenAddress);
        uint256 deadline = block.timestamp + 60;

        uint256[] memory amountsOut = router.swapExactETHForTokens{
            value: _amountEth
        }(0, path, address(this), deadline);

        IERC20(tokenAddress).transfer(BURN_ADDRESS, amountsOut[1]);
        totalTokensBurned = totalTokensBurned.add(amountsOut[1]);
        emit BurnTokens(amountsOut[1]);
    }

    /**
     * @dev Sets the token address. Requires that the new address
     * doesn't equal the current address and that the caller is the
     * owner.
     */
    function setTokenAddress(address _address) external onlyOwner {
        require(_address != tokenAddress, "Token address already set.");
        tokenAddress = _address;
    }

    /**
     * @dev Sets the pair token address. Requires that the new address
     * doesn't equal the current address and that the caller is the
     * owner.
     */
    function setPairTokenAddress(address _address) external onlyOwner {
        require(_address != pairAddress, "Pair token address already set.");
        pairAddress = _address;
    }

    /**
     * @dev Updates router address
     * @param _address address to set for the dex router
     */
    function updateRouter(address _address) external onlyOwner {
        require(address(router) != _address, "Router address already set");
        router = IVVSRouter(_address);
    }

    /**
     * @dev Burns a given amount of tokens within the vesting contract.
     * Requires that the caller is an authorizedReceiver.
     */
    function burnTokens(uint256 _amount) external {
        require(
            authorizedReceiver[msg.sender] == true,
            "Not authorized receiver."
        );

        require(canBurnTokens(_amount), "Cannot burn tokens.");

        IERC20(tokenAddress).transfer(BURN_ADDRESS, _amount);
        lastBurnTimestamp = block.timestamp;
        totalTokensBurned = totalTokensBurned.add(_amount);
        emit BurnTokens(_amount);
    }

    /**
     * @dev Withdraw funds from the vesting contract. Requires that the
     * caller is an authorizedReceiver.
     */
    function withdrawFunds() external {
        require(
            authorizedReceiver[msg.sender] == true,
            "Not authorized receiver."
        );

        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");

        require(success, "No funds to withdrawal.");
    }

    function getTokenBurnLimit() public view returns (uint256) {
        return
            uint256(IERC20(tokenAddress).balanceOf(address(this)))
                .mul(burnLimitPercentage)
                .div(burnLimitDenominator);
    }

    function canBurnTokens(uint256 _tokenAmount) public view returns (bool) {
        return
            _tokenAmount <= getTokenBurnLimit() &&
            block.timestamp > lastBurnTimestamp.add(burnTimestampDifference);
    }

    function setBurnTokenSettings(
        uint256 _burnLimitPercentage,
        uint256 _burnLimitDenominator
    ) external onlyOwner {
        burnLimitPercentage = _burnLimitPercentage;
        burnLimitDenominator = _burnLimitDenominator;
    }

    /**
     * @dev Returns true if the token timelock is unlocked.
     */
    function isTokensUnlocked() external view returns (bool) {
        return block.timestamp > unlockTimestamp;
    }

    /**
     * @dev Returns unix timestamp of time unlock.
     */
    function getUnlockTimestamp() external view returns (uint256) {
        return unlockTimestamp;
    }

    /**
     * @dev Returns current address of token.
     */
    function getTokenAddress() external view returns (address) {
        return tokenAddress;
    }

    /**
     * @dev Returns current address of pair token.
     */
    function getPairAddress() external view returns (address) {
        return pairAddress;
    }

    function _updateBuyBackAllocation(uint256 _amountEth) internal {
        buyBackAllocation = buyBackAllocation.add(
            _amountEth.mul(buyBackPercentageAllocation).div(
                buyBackPercentageDenominator
            )
        );
    }

    receive() external payable {
        _updateBuyBackAllocation(msg.value);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoRebaseState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"checkFeeExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkSwapThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"enableTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLiquidityBacking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextRebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialDistributionFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isNotInSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOverLiquified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebaseDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebaseTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumRebaseTimestampDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairContract","outputs":[{"internalType":"contract InterfaceLP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phenixFundReserveReciever","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phenixVaultFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebasePercentDelta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IVVSRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"setFeeExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_liquidityReceiver","type":"address"},{"internalType":"address","name":"_phenixFundReserveReciever","type":"address"}],"name":"setFeeReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liquidityFee","type":"uint256"},{"internalType":"uint256","name":"_phenixVaultFee","type":"uint256"},{"internalType":"uint256","name":"_sellFee","type":"uint256"},{"internalType":"uint256","name":"_feeDenominator","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setInitialDistributionFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_autoRebaseState","type":"bool"},{"internalType":"uint256","name":"_percentage","type":"uint256"},{"internalType":"uint256","name":"_accuracy","type":"uint256"}],"name":"setRebaseSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"},{"internalType":"uint256","name":"_num","type":"uint256"},{"internalType":"uint256","name":"_denom","type":"uint256"}],"name":"setSwapBackSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"accuracy","type":"uint256"}],"name":"setTargetLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260056009556008600a556002600b5562000031600a546009546200049d60201b620014cf1790919060201c565b600c556064600d81905542600e556000600f55601260108190556103e8601155603c905560326013556014556016805460ff60a01b1916600160a01b1790556127106b1239a002a3db32d57fffffff19046017553480156200009257600080fd5b5060408051808201825260068152650a0d0cadcd2f60d31b6020808301918252835180850190945260048452630a0909cb60e31b908401528151919291601291620000e19160009190620005f0565b508151620000f7906001906020850190620005f0565b506002805460ff191660ff9290921691909117610100600160a81b031916610100330217905550506015805473145677fc4d9b8f19b5d56d1820c48e0443049a306001600160a01b031990911617908190556040805163c45a015560e01b815290516001600160a01b039092169163c45a015591600480820192602092909190829003018186803b1580156200018c57600080fd5b505afa158015620001a1573d6000803e3d6000fd5b505050506040513d6020811015620001b857600080fd5b5051601554604080516315ab88c960e31b815290516001600160a01b039384169363c9c6539693169163ad5c4648916004808301926020929190829003018186803b1580156200020757600080fd5b505afa1580156200021c573d6000803e3d6000fd5b505050506040513d60208110156200023357600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301523060248301525160448083019260209291908290030181600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d6020811015620002af57600080fd5b5051601680546001600160a01b0319166001600160a01b039283161790819055604051309291909116903390620002e69062000685565b6001600160a01b03938416815291831660208301529091166040808301919091525190819003606001906000f08015801562000326573d6000803e3d6000fd5b50600680546001600160a01b039283166001600160a01b03199182161780835560048054831691851691821790556005805483169091179055306000908152601c60209081526040808320601554871684528252808320600019905560165460038054909516908716179093556b033b2e3c9fd0803ce8000000601990815593549094168152601b8452206b01d290004395eb7bbfffffff19908190559054620003d992620004ff811b6200153017901c565b601a556005805461ffff60a01b1981169091556001600160a01b039081166000908152600860209081526040808320805460ff1990811660019081179092556006805487168652838620805483168417905530865283862080548316841790553386528386208054831684179055805487168652600785528386208054909216909217905554601954825190815291519416937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3620006aa565b600082820183811015620004f8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000620004f883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506200054960201b60201c565b60008183620005d95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200059d57818101518382015260200162000583565b50505050905090810190601f168015620005cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581620005e657fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262000628576000855562000673565b82601f106200064357805160ff191683800117855562000673565b8280016001018555821562000673579182015b828111156200067357825182559160200191906001019062000656565b506200068192915062000693565b5090565b61189a806200272483390190565b5b8082111562000681576000815560010162000694565b61206a80620006ba6000396000f3fe6080604052600436106102cd5760003560e01c806370a0823111610175578063a9059cbb116100dc578063d439979011610095578063e120938a1161006f578063e120938a146109b4578063ecd1b7a1146109c9578063f2fde38b146109de578063f887ea4014610a11576102d4565b8063d439979014610913578063d5938aac14610946578063dd62ed3e14610979576102d4565b8063a9059cbb14610830578063b065406914610869578063b86a2fd71461087e578063c851cc3214610893578063d0889358146108c6578063d1fce264146108fe576102d4565b806390c66c161161012e57806390c66c161461076857806395d89b411461077d57806398118cb414610792578063a457c2d7146107a7578063a4b45c00146107e0578063a8aa1b311461081b576102d4565b806370a08231146106ae578063715018a6146106e1578063749796a5146106f657806383b4ac68146107295780638da5cb5b1461073e5780638f32d59b14610753576102d4565b80632b28af1b116102345780634bfed05c116101ed5780636903e79b116101c75780636903e79b146106335780636d351d1a146106485780636ddd17131461065d5780636fcba37714610672576102d4565b80634bfed05c146105f45780634d709adf146106095780634e758d5b1461061e576102d4565b80632b28af1b1461051e5780632be6937d146105335780632f34d28214610548578063313ce5671461057b57806339509351146105a657806346e35f03146105df576102d4565b80631df4ccfc116102865780631df4ccfc1461043b578063201e79911461045057806323b872dd14610480578063264d26dd146104c35780632b112e49146104f45780632b14ca5614610509576102d4565b806306fdde03146102d95780630816929c14610363578063095ea7b31461039d5780631173cf57146103ea578063180b0d7e146103ff57806318160ddd14610426576102d4565b366102d457005b600080fd5b3480156102e557600080fd5b506102ee610a26565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610328578181015183820152602001610310565b50505050905090810190601f1680156103555780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036f57600080fd5b5061039b6004803603606081101561038657600080fd5b50803515159060208101359060400135610abc565b005b3480156103a957600080fd5b506103d6600480360360408110156103c057600080fd5b506001600160a01b038135169060200135610ae2565b604080519115158252519081900360200190f35b3480156103f657600080fd5b506103d6610b8b565b34801561040b57600080fd5b50610414610b9b565b60408051918252519081900360200190f35b34801561043257600080fd5b50610414610ba1565b34801561044757600080fd5b50610414610ba7565b34801561045c57600080fd5b5061039b6004803603604081101561047357600080fd5b5080359060200135610bad565b34801561048c57600080fd5b506103d6600480360360608110156104a357600080fd5b506001600160a01b03813581169160208101359091169060400135610bc9565b3480156104cf57600080fd5b506104d8610ca3565b604080516001600160a01b039092168252519081900360200190f35b34801561050057600080fd5b50610414610cb2565b34801561051557600080fd5b50610414610d3c565b34801561052a57600080fd5b50610414610d42565b34801561053f57600080fd5b5061039b610d48565b34801561055457600080fd5b5061039b6004803603602081101561056b57600080fd5b50356001600160a01b0316610d6e565b34801561058757600080fd5b50610590610da8565b6040805160ff9092168252519081900360200190f35b3480156105b257600080fd5b506103d6600480360360408110156105c957600080fd5b506001600160a01b038135169060200135610db1565b3480156105eb57600080fd5b506103d6610e85565b34801561060057600080fd5b50610414610e98565b34801561061557600080fd5b506104d8610e9e565b34801561062a57600080fd5b50610414610ead565b34801561063f57600080fd5b50610414610eb3565b34801561065457600080fd5b50610414610eb9565b34801561066957600080fd5b506103d6610ed2565b34801561067e57600080fd5b5061039b6004803603608081101561069557600080fd5b5080359060208101359060408101359060600135610ee2565b3480156106ba57600080fd5b50610414600480360360208110156106d157600080fd5b50356001600160a01b0316610f2b565b3480156106ed57600080fd5b5061039b610f53565b34801561070257600080fd5b5061039b6004803603602081101561071957600080fd5b50356001600160a01b0316610fb3565b34801561073557600080fd5b506103d6610fe8565b34801561074a57600080fd5b506104d8610ff2565b34801561075f57600080fd5b506103d6611006565b34801561077457600080fd5b506104d861101c565b34801561078957600080fd5b506102ee61102b565b34801561079e57600080fd5b5061041461108b565b3480156107b357600080fd5b506103d6600480360360408110156107ca57600080fd5b506001600160a01b038135169060200135611091565b3480156107ec57600080fd5b5061039b6004803603604081101561080357600080fd5b506001600160a01b03813581169160200135166111bb565b34801561082757600080fd5b506104d86111fa565b34801561083c57600080fd5b506103d66004803603604081101561085357600080fd5b506001600160a01b038135169060200135611209565b34801561087557600080fd5b50610414611273565b34801561088a57600080fd5b50610414611279565b34801561089f57600080fd5b5061039b600480360360208110156108b657600080fd5b50356001600160a01b031661127f565b3480156108d257600080fd5b5061039b600480360360608110156108e957600080fd5b50803515159060208101359060400135611315565b34801561090a57600080fd5b506103d661136c565b34801561091f57600080fd5b506103d66004803603602081101561093657600080fd5b50356001600160a01b031661137c565b34801561095257600080fd5b5061039b6004803603602081101561096957600080fd5b50356001600160a01b031661139a565b34801561098557600080fd5b506104146004803603604081101561099c57600080fd5b506001600160a01b03813581169160200135166113cf565b3480156109c057600080fd5b506104146113fa565b3480156109d557600080fd5b5061041461144e565b3480156109ea57600080fd5b5061039b60048036036020811015610a0157600080fd5b50356001600160a01b03166114a3565b348015610a1d57600080fd5b506104d86114c0565b60008054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ab25780601f10610a8757610100808354040283529160200191610ab2565b820191906000526020600020905b815481529060010190602001808311610a9557829003601f168201915b5050505050905090565b610ac4611006565b610acd57600080fd5b610ad683611572565b60109190915560115550565b600554600090600160a01b900460ff1680610b005750610b00611006565b80610b1a57503360009081526007602052604090205460ff165b610b2357600080fd5b336000818152601c602090815260408083206001600160a01b03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600554600160a81b900460ff1681565b600d5481565b60195490565b600c5481565b610bb5611006565b610bbe57600080fd5b601391909155601455565b6000826001600160a01b038116610bdf57600080fd5b6001600160a01b0385166000908152601c6020908152604080832033845290915290205460001914610c8c576040805180820182526016815275496e73756666696369656e7420416c6c6f77616e636560501b6020808301919091526001600160a01b0388166000908152601c82528381203382529091529190912054610c67918590611594565b6001600160a01b0386166000908152601c602090815260408083203384529091529020555b610c9785858561162b565b50600195945050505050565b6004546001600160a01b031681565b601a54601b6020527f584f46c60af19681376031579adb04a2416e54ee5505351c2a8435e3766026ea5461dead60009081527f6790d4910a095e0e04c8daa388834616a295bac3f59038957b6d0b93a2d21684549092610d37929091610d319190610d2b906b01d290004395eb7bbfffffff1990611848565b90611848565b90611530565b905090565b600b5481565b600f5481565b610d50611006565b610d5957600080fd5b6005805460ff60a01b1916600160a01b179055565b610d76611006565b610d7f57600080fd5b600380546001600160a01b039092166001600160a01b0319909216821790556000526008602052565b60025460ff1690565b600554600090600160a01b900460ff1680610dcf5750610dcf611006565b80610de957503360009081526007602052604090205460ff165b610df257600080fd5b336000908152601c602090815260408083206001600160a01b0387168452909152902054610e2090836114cf565b336000818152601c602090815260408083206001600160a01b0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b6000601354610e9261144e565b11905090565b60105481565b6003546001600160a01b031681565b60115481565b60125481565b6000610d37601a5460175461153090919063ffffffff16565b601654600160a01b900460ff1681565b610eea611006565b610ef357600080fd5b6009849055600a839055600b829055610f0c84846114cf565b600c55600d81905560048104600c5410610f2557600080fd5b50505050565b601a546001600160a01b0382166000908152601b60205260408120549091610b859190611530565b610f5b611006565b610f6457600080fd5b6002546040516101009091046001600160a01b0316907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a260028054610100600160a81b0319169055565b610fbb611006565b610fc457600080fd5b6001600160a01b03166000908152600860205260409020805460ff19166001179055565b60185460ff161590565b60025461010090046001600160a01b031690565b60025461010090046001600160a01b0316331490565b6005546001600160a01b031681565b60018054604080516020601f60026000196101008789161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ab25780601f10610a8757610100808354040283529160200191610ab2565b60095481565b600554600090600160a01b900460ff16806110af57506110af611006565b806110c957503360009081526007602052604090205460ff165b6110d257600080fd5b336000908152601c602090815260408083206001600160a01b038716845290915290205480831061112657336000908152601c602090815260408083206001600160a01b0388168452909152812055611155565b6111308184611848565b336000908152601c602090815260408083206001600160a01b03891684529091529020555b336000818152601c602090815260408083206001600160a01b0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b6111c3611006565b6111cc57600080fd5b600480546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6016546001600160a01b031681565b6000826001600160a01b03811661121f57600080fd5b600554600160a01b900460ff168061123a575061123a611006565b8061125457503360009081526007602052604090205460ff165b61125d57600080fd5b61126833858561162b565b506001949350505050565b600a5481565b600e5481565b611287611006565b61129057600080fd5b6015546001600160a01b03828116911614156112f3576040805162461bcd60e51b815260206004820152601a60248201527f526f75746572206164647265737320616c726561647920736574000000000000604482015290519081900360640190fd5b601580546001600160a01b0319166001600160a01b0392909216919091179055565b61131d611006565b61132657600080fd5b6016805460ff60a01b1916600160a01b851515021790556113648261135e836b033b2e3c9fd0803ce80000006000195b061990611530565b9061188a565b601755505050565b600554600160a01b900460ff1681565b6001600160a01b031660009081526008602052604090205460ff1690565b6113a2611006565b6113ab57600080fd5b6001600160a01b03166000908152600760205260409020805460ff19166001179055565b6001600160a01b039182166000908152601c6020908152604080832093909416825291909152205490565b600e54600090429081038261141962015180610d3184620186a061188a565b90506000611445620186a0610d318461135e601154610d3160105460195461188a90919063ffffffff16565b94505050505090565b601a546016546001600160a01b03166000908152601b60205260408120549091829161147991611530565b905061149d611486610cb2565b610d3161149484600261188a565b6014549061188a565b91505090565b6114ab611006565b6114b457600080fd5b6114bd816118e3565b50565b6015546001600160a01b031681565b600082820183811015611529576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061152983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061195d565b60058054911515600160a81b0260ff60a81b1990921691909117905542600e55565b600081848411156116235760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115e85781810151838201526020016115d0565b50505050905090810190601f1680156116155780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600554600090600160a81b900460ff161515600114801561164f575061164f6119c2565b801561167f57506016546001600160a01b038581169116148061167f57506016546001600160a01b038481169116145b1561170b5761168c6119dc565b6016546001600160a01b038481169116141561170b57600360009054906101000a90046001600160a01b03166001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156116f257600080fd5b505af1158015611706573d6000803e3d6000fd5b505050505b60185460ff161561172857611721848484611a6c565b9050611529565b600061173f601a548461188a90919063ffffffff16565b9050611749611afe565b1561175657611756611b54565b6001600160a01b0385166000908152601b60205260409020546117799082611848565b6001600160a01b0386166000908152601b602052604081209190915561179f8686611eed565b6117a957816117b4565b6117b4868684611f41565b6001600160a01b0386166000908152601b60205260409020549091506117da90826114cf565b6001600160a01b038087166000818152601b6020526040902092909255601a54908816907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061182b908590611530565b60408051918252519081900360200190a350600195945050505050565b600061152983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611594565b60008261189957506000610b85565b828202828482816118a657fe5b04146115295760405162461bcd60e51b81526004018080602001828103825260218152602001806120146021913960400191505060405180910390fd5b6001600160a01b0381166118f657600080fd5b6002546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600280546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600081836119ac5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156115e85781810151838201526020016115d0565b5060008385816119b857fe5b0495945050505050565b6000601254610e92600e544261184890919063ffffffff16565b60006119e66113fa565b6019549091506119f690826114cf565b60198190556001600160801b031015611a15576001600160801b036019555b601954611a31906b033b2e3c9fd0803ce8000000600019611356565b601a55600f81905542600e556019546040517fafae32ce2847c13a56ab802c034c27d3c19f1d61be48c424c5df134145cd44d090600090a250565b600080611a84601a548461188a90919063ffffffff16565b6001600160a01b0386166000908152601b6020526040902054909150611aaa9082611848565b6001600160a01b038087166000908152601b60205260408082209390935590861681522054611ad990826114cf565b6001600160a01b0385166000908152601b602052604090205550600190509392505050565b6016546000906001600160a01b03163314801590611b1f575060185460ff16155b8015611b345750601654600160a01b900460ff165b8015610d37575050601754306000908152601b6020526040902054101590565b6018805460ff191660011790556000611b6b610e85565b611b7757600954611b7a565b60005b601a54306000908152601b602052604081205492935091611b9a91611530565b90506000611bbc6002610d31600c54610d31878761188a90919063ffffffff16565b90506000611bca8383611848565b60408051600280825260608201835292935060009290916020830190803683370190505090503081600081518110611bfe57fe5b6001600160a01b03928316602091820292909201810191909152601554604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b158015611c5257600080fd5b505afa158015611c66573d6000803e3d6000fd5b505050506040513d6020811015611c7c57600080fd5b5051815182906001908110611c8d57fe5b6001600160a01b0392831660209182029290920181019190915260155460405163791ac94760e01b8152600481018681526000602483018190523060648401819052426084850181905260a060448601908152895160a487015289514799979097169763791ac947978c9795968c9690939260c49091019187820191028083838b5b83811015611d27578181015183820152602001611d0f565b505050509050019650505050505050600060405180830381600087803b158015611d5057600080fd5b505af1158015611d64573d6000803e3d6000fd5b505050506000611d7d824761184890919063ffffffff16565b90506000611d98611d8f896002611530565b600c5490611848565b90506000611dad6002610d318481878e61188a565b90506000611dca83610d31600a548761188a90919063ffffffff16565b6005546040519192506000916001600160a01b039091169061753090849084818181858888f193505050503d8060008114611e21576040519150601f19603f3d011682016040523d82523d6000602084013e611e26565b606091505b50600092505089159050611ed657601554600480546040805163f305d71960e01b81523093810193909352602483018d905260006044840181905260648401526001600160a01b0391821660848401524260a48401525192169163f305d71991869160c480830192606092919082900301818588803b158015611ea857600080fd5b505af1158015611ebc573d6000803e3d6000fd5b50505050506040513d6060811015611ed357600080fd5b50505b50506018805460ff19169055505050505050505050565b6016546000906001600160a01b0384811691161480611f1957506016546001600160a01b038381169116145b8015611529575050506001600160a01b031660009081526008602052604090205460ff161590565b600c54601654600091906001600160a01b0385811691161415611f6f57600b54611f6c9082906114cf565b90505b600d54600090611f8390610d31868561188a565b306000908152601b6020526040902054909150611fa090826114cf565b306000818152601b6020526040902091909155601a546001600160a01b038816907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611fee908590611530565b60408051918252519081900360200190a36120098482611848565b969550505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122044057066b342ea8b0d1b468902af58d86c4617a87b48f40282be8d5e1d36368964736f6c63430007060033608060405234801561001057600080fd5b5060405161189a38038061189a8339818101604052606081101561003357600080fd5b508051602080830151604093840151600080546001600160a01b031990811633178255600180546001600160a01b03808916918416919091178255600280548288169085161790554260038190559085168452600c909652968220805460ff1916881790556004969096556064600581905562069780600655600b8290556007949094556014600855600993909355600a92909255600d805490941673145863eb42cf62847a6ca784e6416c1682b1b2ae179093559091906100f4816100fc565b50505061016a565b6001600160a01b03811661010f57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b611721806101796000396000f3fe6080604052600436106101855760003560e01c806386348625116100d1578063ac54273a1161008a578063deb7153411610064578063deb7153414610490578063f2fde38b146104c3578063f887ea40146104f6578063f934c1a91461050b57610195565b8063ac54273a1461041e578063c851cc3214610448578063d157e3011461047b57610195565b806386348625146103655780638d5f81e21461037a5780638da5cb5b1461038f5780638f32d59b146103a45780639d64ce62146103b95780639e035f3a146103f457610195565b80633d3d937d1161013e57806358c62c741161011857806358c62c74146102e15780636d1b229d14610311578063715018a61461033b5780637ffb98c01461035057610195565b80633d3d937d14610279578063486f8a6e1461028e5780635373a66f146102a357610195565b806306fba8ad1461019a57806310192aea146101c157806310fe9ae8146101d657806324600fc31461020757806326a4e8d21461021c578063315a095d1461024f57610195565b366101955761019334610535565b005b600080fd5b3480156101a657600080fd5b506101af610568565b60408051918252519081900360200190f35b3480156101cd57600080fd5b506101af61056e565b3480156101e257600080fd5b506101eb610574565b604080516001600160a01b039092168252519081900360200190f35b34801561021357600080fd5b50610193610583565b34801561022857600080fd5b506101936004803603602081101561023f57600080fd5b50356001600160a01b031661067a565b34801561025b57600080fd5b506101936004803603602081101561027257600080fd5b5035610710565b34801561028557600080fd5b506101af61091b565b34801561029a57600080fd5b506101af610921565b3480156102af57600080fd5b506102cd600480360360208110156102c657600080fd5b5035610927565b604080519115158252519081900360200190f35b3480156102ed57600080fd5b506101936004803603604081101561030457600080fd5b5080359060200135610953565b34801561031d57600080fd5b506101936004803603602081101561033457600080fd5b503561096f565b34801561034757600080fd5b50610193610ada565b34801561035c57600080fd5b506101af610b33565b34801561037157600080fd5b506102cd610bda565b34801561038657600080fd5b506101eb610be2565b34801561039b57600080fd5b506101eb610bf1565b3480156103b057600080fd5b506102cd610c00565b3480156103c557600080fd5b50610193600480360360408110156103dc57600080fd5b506001600160a01b0381351690602001351515610c11565b34801561040057600080fd5b506101936004803603602081101561041757600080fd5b5035610c4d565b34801561042a57600080fd5b506101936004803603602081101561044157600080fd5b5035610c71565b34801561045457600080fd5b506101936004803603602081101561046b57600080fd5b50356001600160a01b031661109c565b34801561048757600080fd5b506101af611132565b34801561049c57600080fd5b50610193600480360360208110156104b357600080fd5b50356001600160a01b0316611138565b3480156104cf57600080fd5b50610193600480360360208110156104e657600080fd5b50356001600160a01b03166111ce565b34801561050257600080fd5b506101eb6111e8565b34801561051757600080fd5b506101936004803603602081101561052e57600080fd5b50356111f7565b6105626105596009546105536008548561140290919063ffffffff16565b90611462565b600a54906114a4565b600a5550565b600a5481565b60035490565b6001546001600160a01b031690565b336000908152600c602052604090205460ff1615156001146105da576040805162461bcd60e51b815260206004820152601860248201526000805160206116cc833981519152604482015290519081900360640190fd5b604051600090339047908381818185875af1925050503d806000811461061c576040519150601f19603f3d011682016040523d82523d6000602084013e610621565b606091505b5050905080610677576040805162461bcd60e51b815260206004820152601760248201527f4e6f2066756e647320746f207769746864726177616c2e000000000000000000604482015290519081900360640190fd5b50565b610682610c00565b61068b57600080fd5b6001546001600160a01b03828116911614156106ee576040805162461bcd60e51b815260206004820152601a60248201527f546f6b656e206164647265737320616c7265616479207365742e000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600154604080516370a0823160e01b8152306004820152905183926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561075a57600080fd5b505afa15801561076e573d6000803e3d6000fd5b505050506040513d602081101561078457600080fd5b505110156107ce576040805162461bcd60e51b81526020600482015260126024820152712737ba1032b737bab3b4103a37b5b2b7399760711b604482015290519081900360640190fd5b336000908152600c602052604090205460ff161515600114610825576040805162461bcd60e51b815260206004820152601860248201526000805160206116cc833981519152604482015290519081900360640190fd5b600354421161086b576040805162461bcd60e51b815260206004820152600d60248201526c2737ba103ab73637b1b5b2b21760991b604482015290519081900360640190fd5b6001546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156108bf57600080fd5b505af11580156108d3573d6000803e3d6000fd5b505050506040513d60208110156108e957600080fd5b5050604051819033907f680f2e4f4032ebf1774e8cdbaddcb1b617a5a606411c8ca96257ada338d3833c90600090a350565b60075481565b60065481565b6000610931610b33565b821115801561094d575060065460075461094a916114a4565b42115b92915050565b61095b610c00565b61096457600080fd5b600491909155600555565b336000908152600c602052604090205460ff1615156001146109c6576040805162461bcd60e51b815260206004820152601860248201526000805160206116cc833981519152604482015290519081900360640190fd5b6109cf81610927565b610a16576040805162461bcd60e51b815260206004820152601360248201527221b0b73737ba10313ab937103a37b5b2b7399760691b604482015290519081900360640190fd5b6001546040805163a9059cbb60e01b815261dead60048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b158015610a6c57600080fd5b505af1158015610a80573d6000803e3d6000fd5b505050506040513d6020811015610a9657600080fd5b505042600755600b54610aa990826114a4565b600b5560405181907f2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d2661438290600090a250565b610ae2610c00565b610aeb57600080fd5b600080546040516001600160a01b03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a2600080546001600160a01b0319169055565b6000610bd5600554610553600454600160009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610ba357600080fd5b505afa158015610bb7573d6000803e3d6000fd5b505050506040513d6020811015610bcd57600080fd5b505190611402565b905090565b600354421190565b6002546001600160a01b031690565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b610c19610c00565b610c2257600080fd5b6001600160a01b03919091166000908152600c60205260409020805460ff1916911515919091179055565b610c55610c00565b610c5e57600080fd5b600354610c6b90826114a4565b60035550565b600a54811115610cc8576040805162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820627579206261636b20616c6c6f636174696f6e0000604482015290519081900360640190fd5b336000908152600c602052604090205460ff161515600114610d1f576040805162461bcd60e51b815260206004820152601860248201526000805160206116cc833981519152604482015290519081900360640190fd5b600a54610d2c90826114fe565b600a556040805160028082526060820183526000926020830190803683375050600d54604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c464892506004808301926020929190829003018186803b158015610d9457600080fd5b505afa158015610da8573d6000803e3d6000fd5b505050506040513d6020811015610dbe57600080fd5b505181518290600090610dcd57fe5b6001600160a01b0392831660209182029290920101526001805483519216918391908110610df757fe5b6001600160a01b03928316602091820292909201810191909152600d54604051637ff36ab560e01b81526000600482018181523060448401819052603c420160648501819052608060248601908152895160848701528951919894979690941695637ff36ab5958b9589958c95948c94919360a4019187810191028083838b5b83811015610e8f578181015183820152602001610e77565b50505050905001955050505050506000604051808303818588803b158015610eb657600080fd5b505af1158015610eca573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526020811015610ef457600080fd5b8101908080516040519392919084640100000000821115610f1457600080fd5b908301906020820185811115610f2957600080fd5b8251866020820283011164010000000082111715610f4657600080fd5b82525081516020918201928201910280838360005b83811015610f73578181015183820152602001610f5b565b505050509190910160405250506001805484519495506001600160a01b03169363a9059cbb935061dead92508591908110610faa57fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610ff857600080fd5b505af115801561100c573d6000803e3d6000fd5b505050506040513d602081101561102257600080fd5b50508051611050908290600190811061103757fe5b6020026020010151600b546114a490919063ffffffff16565b600b5580518190600190811061106257fe5b60200260200101517f2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d2661438260405160405180910390a250505050565b6110a4610c00565b6110ad57600080fd5b600d546001600160a01b0382811691161415611110576040805162461bcd60e51b815260206004820152601a60248201527f526f75746572206164647265737320616c726561647920736574000000000000604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600b5481565b611140610c00565b61114957600080fd5b6002546001600160a01b03828116911614156111ac576040805162461bcd60e51b815260206004820152601f60248201527f5061697220746f6b656e206164647265737320616c7265616479207365742e00604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6111d6610c00565b6111df57600080fd5b61067781611540565b600d546001600160a01b031681565b600254604080516370a0823160e01b8152306004820152905183926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561124157600080fd5b505afa158015611255573d6000803e3d6000fd5b505050506040513d602081101561126b57600080fd5b505110156112b5576040805162461bcd60e51b81526020600482015260126024820152712737ba1032b737bab3b4103a37b5b2b7399760711b604482015290519081900360640190fd5b336000908152600c602052604090205460ff16151560011461130c576040805162461bcd60e51b815260206004820152601860248201526000805160206116cc833981519152604482015290519081900360640190fd5b6003544211611352576040805162461bcd60e51b815260206004820152600d60248201526c2737ba103ab73637b1b5b2b21760991b604482015290519081900360640190fd5b6002546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156113a657600080fd5b505af11580156113ba573d6000803e3d6000fd5b505050506040513d60208110156113d057600080fd5b5050604051819033907fc1a84c3ed6c24067051a448eca6ddf7195ee5c2826b5ce6c5d3cacfd8583585e90600090a350565b6000826114115750600061094d565b8282028284828161141e57fe5b041461145b5760405162461bcd60e51b81526004018080602001828103825260218152602001806116ab6021913960400191505060405180910390fd5b9392505050565b600061145b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506115ae565b60008282018381101561145b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061145b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611650565b6001600160a01b03811661155357600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000818361163a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115ff5781810151838201526020016115e7565b50505050905090810190601f16801561162c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161164657fe5b0495945050505050565b600081848411156116a25760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156115ff5781810151838201526020016115e7565b50505090039056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774e6f7420617574686f72697a65642072656365697665722e0000000000000000a2646970667358221220e3d87ffe6d6211790b00774e4211dbf30503657df7861a4316281df1d19d63fe64736f6c63430007060033

Deployed ByteCode Sourcemap

353:21550:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;426:83:0;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19281:285:7;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19281:285:7;;;;;;;;;;;;;;:::i;:::-;;15979:286;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15979:286:7;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;692:27;;;;;;;;;;;;;:::i;1527:35::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;6238:102;;;;;;;;;;;;;:::i;1462:58::-;;;;;;;;;;;;;:::i;20307:195::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20307:195:7;;;;;;;:::i;10613:457::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;10613:457:7;;;;;;;;;;;;;;;;;:::i;560:32::-;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;560:32:7;;;;;;;;;;;;;;20084:215;;;;;;;;;;;;;:::i;1429:26::-;;;;;;;;;;;;;:::i;1630:34::-;;;;;;;;;;;;;:::i;16693:114::-;;;;;;;;;;;;;:::i;6965:140::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6965:140:7;-1:-1:-1;;;;;6965:140:7;;:::i;612:83:0:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15335:439:7;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;15335:439:7;;;;;;;;:::i;21744:119::-;;;;;;;;;;;;;:::i;1671:38::-;;;;;;;;;;;;;:::i;522:31::-;;;;;;;;;;;;;:::i;1731:39::-;;;;;;;;;;;;;:::i;1777:47::-;;;;;;;;;;;;;:::i;20603:126::-;;;;;;;;;;;;;:::i;1976:30::-;;;;;;;;;;;;;:::i;21000:435::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21000:435:7;;;;;;;;;;;;;;;;;:::i;7924:138::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7924:138:7;-1:-1:-1;;;;;7924:138:7;;:::i;623:126:6:-;;;;;;;;;;;;;:::i;17272:101:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17272:101:7;-1:-1:-1;;;;;17272:101:7;;:::i;20510:85::-;;;;;;;;;;;;;:::i;358:79:6:-;;;;;;;;;;;;;:::i;523:92::-;;;;;;;;;;;;;:::i;599:40:7:-;;;;;;;;;;;;;:::i;517:87:0:-;;;;;;;;;;;;;:::i;1351:31:7:-;;;;;;;;;;;;;:::i;14188:629::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;14188:629:7;;;;;;;;:::i;20737:255::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;20737:255:7;;;;;;;;;;:::i;1948:19::-;;;;;;;;;;;;;:::i;6549:248::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6549:248:7;;;;;;;;:::i;1389:33::-;;;;;;;;;;;;;:::i;1571:52::-;;;;;;;;;;;;;:::i;14937:184::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14937:184:7;-1:-1:-1;;;;;14937:184:7;;:::i;18676:230::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18676:230:7;;;;;;;;;;;;;;:::i;646:39::-;;;;;;;;;;;;;:::i;16439:113::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16439:113:7;-1:-1:-1;;;;;16439:113:7;;:::i;16980:105::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16980:105:7;-1:-1:-1;;;;;16980:105:7;;:::i;7457:192::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7457:192:7;;;;;;;;;;:::i;4897:606::-;;;;;;;;;;;;;:::i;21443:293::-;;;;;;;;;;;;;:::i;757:109:6:-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;757:109:6;-1:-1:-1;;;;;757:109:6;;:::i;1917:24:7:-;;;;;;;;;;;;;:::i;426:83:0:-;496:5;489:12;;;;;;;;-1:-1:-1;;489:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;463:13;;489:12;;496:5;;489:12;;496:5;489:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;426:83;:::o;19281:285:7:-;485:9:6;:7;:9::i;:::-;477:18;;;;;;19435:40:7::1;19458:16;19435:22;:40::i;:::-;19486:18;:32:::0;;;;19529:17:::1;:29:::0;-1:-1:-1;19281:285:7:o;15979:286::-;4135:27;;16115:4;;-1:-1:-1;;;4135:27:7;;;;;:57;;;4183:9;:7;:9::i;:::-;4135:104;;;-1:-1:-1;4228:10:7;4213:26;;;;:14;:26;;;;;;;;4135:104;4113:137;;;;;;16155:10:::1;16137:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;16137:38:7;::::1;::::0;;;;;;;;;;:46;;;16199:36;;;;;;;16137:38;;16155:10;16199:36:::1;::::0;;;;;;;;;::::1;-1:-1:-1::0;16253:4:7::1;4261:1;15979:286:::0;;;;:::o;692:27::-;;;-1:-1:-1;;;692:27:7;;;;;:::o;1527:35::-;;;;:::o;6238:102::-;6320:12;;6238:102;:::o;1462:58::-;;;;:::o;20307:195::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;20422:15:7::1;:24:::0;;;;20457:26:::1;:37:::0;20307:195::o;10613:457::-;10756:4;10743:2;-1:-1:-1;;;;;4333:18:7;;4325:27;;;;;;-1:-1:-1;;;;;10777:23:7;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;10801:10:::1;10777:35:::0;;;;;;;;-1:-1:-1;;10777:50:7::1;10773:225;;10882:104;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;10882:104:7::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;10882:23:7;::::1;-1:-1:-1::0;10882:23:7;;;:17:::1;:23:::0;;;;;10924:10:::1;10882:67:::0;;;;;;;;;;:104:::1;::::0;10954:5;;10882:71:::1;:104::i;:::-;-1:-1:-1::0;;;;;10844:23:7;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;10868:10:::1;10844:35:::0;;;;;;;:142;10773:225:::1;11010:30;11024:4;11030:2;11034:5;11010:13;:30::i;:::-;-1:-1:-1::0;11058:4:7::1;::::0;10613:457;-1:-1:-1;;;;;10613:457:7:o;560:32::-;;;-1:-1:-1;;;;;560:32:7;;:::o;20084:215::-;20260:16;;20217:12;:18;;;;1011:42;20137:7;20193:18;;;;;20137:7;;20177:114;;20260:16;;20178:58;;20217:18;20178:34;;-1:-1:-1;;2147:54:7;20178:14;:34::i;:::-;:38;;:58::i;:::-;20177:64;;:114::i;:::-;20157:134;;20084:215;:::o;1429:26::-;;;;:::o;1630:34::-;;;;:::o;16693:114::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;16765:27:7::1;:34:::0;;-1:-1:-1;;;;16765:34:7::1;-1:-1:-1::0;;;16765:34:7::1;::::0;;16693:114::o;6965:140::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;7028:12:7::1;:36:::0;;-1:-1:-1;;;;;7028:36:7;;::::1;-1:-1:-1::0;;;;;;7028:36:7;;::::1;::::0;::::1;::::0;;:12:::1;7075:22:::0;:12:::1;:22;::::0;6965:140::o;612:83:0:-;678:9;;;;612:83;:::o;15335:439:7:-;4135:27;;15468:4;;-1:-1:-1;;;4135:27:7;;;;;:57;;;4183:9;:7;:9::i;:::-;4135:104;;;-1:-1:-1;4228:10:7;4213:26;;;;:14;:26;;;;;;;;4135:104;4113:137;;;;;;15549:10:::1;15531:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;15531:62:7;::::1;::::0;;;;;;;;:78:::1;::::0;15598:10;15531:66:::1;:78::i;:::-;15508:10;15490:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;15490:38:7;::::1;::::0;;;;;;;;;;:119;;;15625;;;;;;15490:38;;15625:119:::1;::::0;;;;;;;;;::::1;-1:-1:-1::0;15762:4:7::1;15335:439:::0;;;;:::o;21744:119::-;21792:4;21840:15;;21816:21;:19;:21::i;:::-;:39;21809:46;;21744:119;:::o;1671:38::-;;;;:::o;522:31::-;;;-1:-1:-1;;;;;522:31:7;;:::o;1731:39::-;;;;:::o;1777:47::-;;;;:::o;20603:126::-;20656:7;20683:38;20704:16;;20683;;:20;;:38;;;;:::i;1976:30::-;;;-1:-1:-1;;;1976:30:7;;;;;:::o;21000:435::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;21181:12:7::1;:28:::0;;;21220:14:::1;:32:::0;;;21263:7:::1;:18:::0;;;21303:32:::1;21196:13:::0;21237:15;21303:16:::1;:32::i;:::-;21292:8;:43:::0;21346:14:::1;:32:::0;;;21425:1:::1;21363:15:::0;21408:18:::1;21397:8;;:29;21389:38;;;::::0;::::1;;21000:435:::0;;;;:::o;7924:138::-;8037:16;;-1:-1:-1;;;;;8015:17:7;;7988:7;8015:17;;;:12;:17;;;;;;7988:7;;8015:39;;:17;:21;:39::i;623:126:6:-;485:9;:7;:9::i;:::-;477:18;;;;;;704:6:::1;::::0;685:26:::1;::::0;704:6:::1;::::0;;::::1;-1:-1:-1::0;;;;;704:6:6::1;::::0;685:26:::1;::::0;;;::::1;722:6;:19:::0;;-1:-1:-1;;;;;;722:19:6::1;::::0;;623:126::o;17272:101:7:-;485:9:6;:7;:9::i;:::-;477:18;;;;;;-1:-1:-1;;;;;17339:19:7::1;;::::0;;;:12:::1;:19;::::0;;;;:26;;-1:-1:-1;;17339:26:7::1;17361:4;17339:26;::::0;;17272:101::o;20510:85::-;20581:6;;;;20580:7;20510:85;:::o;358:79:6:-;423:6;;;;;-1:-1:-1;;;;;423:6:6;;358:79::o;523:92::-;601:6;;;;;-1:-1:-1;;;;;601:6:6;587:10;:20;;523:92::o;599:40:7:-;;;-1:-1:-1;;;;;599:40:7;;:::o;517:87:0:-;589:7;582:14;;;;;;;;-1:-1:-1;;582:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;556:13;;582:14;;589:7;;582:14;;589:7;582:14;;;;;;;;;;;;;;;;;;;;;;;;1351:31:7;;;;:::o;14188:629::-;4135:27;;14326:4;;-1:-1:-1;;;4135:27:7;;;;;:57;;;4183:9;:7;:9::i;:::-;4135:104;;;-1:-1:-1;4228:10:7;4213:26;;;;:14;:26;;;;;;;;4135:104;4113:137;;;;;;14385:10:::1;14348:16;14367:29:::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;14367:38:7;::::1;::::0;;;;;;;;14420:27;;::::1;14416:237;;14482:10;14505:1;14464:29:::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;14464:38:7;::::1;::::0;;;;;;;:42;14416:237:::1;;;14580:61;:8:::0;14611:15;14580:12:::1;:61::i;:::-;14557:10;14539:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;14539:38:7;::::1;::::0;;;;;;;:102;14416:237:::1;14691:10;14738:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;14668:119:7;::::1;14738:38:::0;;;;;;;;;;;14668:119;;;;;;;;;14691:10;14668:119:::1;::::0;;;;;;;;;::::1;-1:-1:-1::0;14805:4:7::1;::::0;14188:629;-1:-1:-1;;;14188:629:7:o;20737:255::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;20881:17:7::1;:38:::0;;-1:-1:-1;;;;;20881:38:7;;::::1;-1:-1:-1::0;;;;;;20881:38:7;;::::1;;::::0;;;20930:25:::1;:54:::0;;;;;::::1;::::0;::::1;;::::0;;20737:255::o;1948:19::-;;;-1:-1:-1;;;;;1948:19:7;;:::o;6549:248::-;6709:4;6654:2;-1:-1:-1;;;;;4333:18:7;;4325:27;;;;;;4135::::1;::::0;-1:-1:-1;;;4135:27:7;::::1;;;::::0;:57:::1;;;4183:9;:7;:9::i;:::-;4135:104;;;-1:-1:-1::0;4228:10:7::1;4213:26;::::0;;;:14:::1;:26;::::0;;;;;::::1;;4135:104;4113:137;;;::::0;::::1;;6731:36:::2;6745:10;6757:2;6761:5;6731:13;:36::i;:::-;-1:-1:-1::0;6785:4:7::2;::::0;6549:248;-1:-1:-1;;;;6549:248:7:o;1389:33::-;;;;:::o;1571:52::-;;;;:::o;14937:184::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;15023:6:7::1;::::0;-1:-1:-1;;;;;15015:27:7;;::::1;15023:6:::0;::::1;15015:27;;15007:66;;;::::0;;-1:-1:-1;;;15007:66:7;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;15084:6;:29:::0;;-1:-1:-1;;;;;;15084:29:7::1;-1:-1:-1::0;;;;;15084:29:7;;;::::1;::::0;;;::::1;::::0;;14937:184::o;18676:230::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;18814:11:7::1;:22:::0;;-1:-1:-1;;;;18814:22:7::1;-1:-1:-1::0;;;18814:22:7;::::1;;;;::::0;;18866:32:::1;18893:4:::0;18866:22:::1;18881:6:::0;1318:24;-1:-1:-1;;2162:38:7::1;;2147:54:::0;;18866:14:::1;:22::i;:::-;:26:::0;::::1;:32::i;:::-;18847:16;:51:::0;-1:-1:-1;;;18676:230:7:o;646:39::-;;;-1:-1:-1;;;646:39:7;;;;;:::o;16439:113::-;-1:-1:-1;;;;;16525:19:7;16501:4;16525:19;;;:12;:19;;;;;;;;;16439:113::o;16980:105::-;485:9:6;:7;:9::i;:::-;477:18;;;;;;-1:-1:-1;;;;;17049:21:7::1;;::::0;;;:14:::1;:21;::::0;;;;:28;;-1:-1:-1;;17049:28:7::1;17073:4;17049:28;::::0;;16980:105::o;7457:192::-;-1:-1:-1;;;;;7608:24:7;;;7576:7;7608:24;;;:17;:24;;;;;;;;:33;;;;;;;;;;;;;7457:192::o;4897:606::-;5068:19;;4943:7;;4990:15;;5049:38;;4943:7;5145:95;1245:5;5145:60;5049:38;1189:6;5145:38;:60::i;:95::-;5100:140;;5253:23;5279:181;1189:6;5279:141;5385:34;5279:87;5348:17;;5279:50;5310:18;;5279:12;;:30;;:50;;;;:::i;:181::-;5253:207;-1:-1:-1;;;;;4897:606:7;:::o;21443:293::-;21565:16;;21555:4;;-1:-1:-1;;;;;21555:4:7;21495:7;21542:18;;;:12;:18;;;;;;21495:7;;;;21542:40;;:22;:40::i;:::-;21515:67;;21613:115;21691:22;:20;:22::i;:::-;21613:55;21644:23;:16;21665:1;21644:20;:23::i;:::-;21613:26;;;:30;:55::i;:115::-;21593:135;;;21443:293;:::o;757:109:6:-;485:9;:7;:9::i;:::-;477:18;;;;;;830:28:::1;849:8;830:18;:28::i;:::-;757:109:::0;:::o;1917:24:7:-;;;-1:-1:-1;;;;;1917:24:7;;:::o;86:181:8:-;144:7;176:5;;;200:6;;;;192:46;;;;;-1:-1:-1;;;192:46:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;258:1;86:181;-1:-1:-1;;;86:181:8:o;911:132::-;969:7;996:39;1000:1;1003;996:39;;;;;;;;;;;;;;;;;:3;:39::i;4586:145:7:-;4651:15;:24;;;;;-1:-1:-1;;;4651:24:7;-1:-1:-1;;;;4651:24:7;;;;;;;;;4708:15;4686:19;:37;4586:145::o;419:226:8:-;539:7;575:12;567:6;;;;559:29;;;;-1:-1:-1;;;559:29:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;611:5:8;;;419:226::o;9171:996:7:-;9311:15;;9290:4;;-1:-1:-1;;;9311:15:7;;;;:23;;9330:4;9311:23;:59;;;;;9355:15;:13;:15::i;:::-;9311:110;;;;-1:-1:-1;9392:4:7;;-1:-1:-1;;;;;9392:14:7;;;:4;;:14;;:28;;-1:-1:-1;9410:4:7;;-1:-1:-1;;;;;9410:10:7;;;:4;;:10;9392:28;9307:245;;;9448:9;:7;:9::i;:::-;9481:4;;-1:-1:-1;;;;;9475:10:7;;;9481:4;;9475:10;9472:69;;;9506:12;;;;;;;;;-1:-1:-1;;;;;9506:12:7;-1:-1:-1;;;;;9506:17:7;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9472:69;9568:6;;;;9564:80;;;9598:34;9613:6;9621:2;9625:6;9598:14;:34::i;:::-;9591:41;;;;9564:80;9656:17;9676:28;9687:16;;9676:6;:10;;:28;;;;:::i;:::-;9656:48;;9721:17;:15;:17::i;:::-;9717:61;;;9755:11;:9;:11::i;:::-;-1:-1:-1;;;;;9813:20:7;;;;;;:12;:20;;;;;;:35;;9838:9;9813:24;:35::i;:::-;-1:-1:-1;;;;;9790:20:7;;;;;;:12;:20;;;;;:58;;;;9889:26;9803:6;9912:2;9889:14;:26::i;:::-;:98;;9978:9;9889:98;;;9931:31;9940:6;9948:2;9952:9;9931:8;:31::i;:::-;-1:-1:-1;;;;;10017:16:7;;;;;;:12;:16;;;;;;9861:126;;-1:-1:-1;10017:39:7;;9861:126;10017:20;:39::i;:::-;-1:-1:-1;;;;;9998:16:7;;;;;;;:12;:16;;;;;:58;;;;10117:16;;10074:61;;;;;;10095:39;;:17;;:21;:39::i;:::-;10074:61;;;;;;;;;;;;;;;-1:-1:-1;10155:4:7;;9171:996;-1:-1:-1;;;;;9171:996:7:o;275:136:8:-;333:7;360:43;364:1;367;360:43;;;;;;;;;;;;;;;;;:3;:43::i;653:250::-;711:7;735:6;731:47;;-1:-1:-1;765:1:8;758:8;;731:47;802:5;;;806:1;802;:5;:1;826:5;;;;;:10;818:56;;;;-1:-1:-1;;;818:56:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;874:187:6;-1:-1:-1;;;;;948:22:6;;940:31;;;;;;1008:6;;987:38;;-1:-1:-1;;;;;987:38:6;;;;1008:6;;;;;987:38;;;;;1036:6;:17;;-1:-1:-1;;;;;1036:17:6;;;;;-1:-1:-1;;;;;;1036:17:6;;;;;;;;;874:187::o;1051:225:8:-;1171:7;1206:12;1199:5;1191:28;;;;-1:-1:-1;;;1191:28:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1230:9;1246:1;1242;:5;;;;;;;1051:225;-1:-1:-1;;;;;1051:225:8:o;17611:174:7:-;17659:4;17749:27;;17684:49;17713:19;;17692:15;17684:28;;:49;;;;:::i;5666:431::-;5705:19;5727:15;:13;:15::i;:::-;5768:12;;5705:37;;-1:-1:-1;5768:38:7;;5705:37;5768:16;:38::i;:::-;5753:12;:53;;;-1:-1:-1;;;;;;5819:83:7;;;-1:-1:-1;;;;;5865:12:7;:25;5819:83;5948:12;;5933:28;;1318:24;-1:-1:-1;;2162:38:7;;5933:28;5914:16;:47;5974:15;:29;;;6036:15;6014:19;:37;6076:12;;6069:20;;;;-1:-1:-1;;6069:20:7;5666:431;:::o;8400:339::-;8518:4;8535:17;8555:28;8566:16;;8555:6;:10;;:28;;;;:::i;:::-;-1:-1:-1;;;;;8615:18:7;;;;;;:12;:18;;;;;;8535:48;;-1:-1:-1;8615:33:7;;8535:48;8615:22;:33::i;:::-;-1:-1:-1;;;;;8594:18:7;;;;;;;:12;:18;;;;;;:54;;;;8678:16;;;;;;;:31;;8699:9;8678:20;:31::i;:::-;-1:-1:-1;;;;;8659:16:7;;;;;;:12;:16;;;;;:50;-1:-1:-1;8727:4:7;;-1:-1:-1;8400:339:7;;;;;:::o;19715:229::-;19816:4;;19765;;-1:-1:-1;;;;;19816:4:7;19802:10;:18;;;;:42;;-1:-1:-1;19838:6:7;;;;19837:7;19802:42;:70;;;;-1:-1:-1;19861:11:7;;-1:-1:-1;;;19861:11:7;;;;19802:70;:134;;;;-1:-1:-1;;19920:16:7;;19910:4;19889:27;;;;:12;:27;;;;;;:47;;;19715:229::o;11351:1732::-;4001:6;:13;;-1:-1:-1;;4001:13:7;4010:4;4001:13;;;:6;11435:17:::1;:15;:17::i;:::-;:36;;11459:12;;11435:36;;;11455:1;11435:36;11559:16;::::0;11534:4:::1;11482:28;11513:27:::0;;;:12:::1;:27;::::0;;;;;11405:66;;-1:-1:-1;11482:28:7;11513:73:::1;::::0;:31:::1;:73::i;:::-;11482:104;;11597:23;11623:108;11729:1;11623:87;11701:8;;11623:59;11662:19;11623:20;:38;;:59;;;;:::i;:108::-;11597:134:::0;-1:-1:-1;11742:20:7::1;11765:41;:20:::0;11597:134;11765:24:::1;:41::i;:::-;11843:16;::::0;;11857:1:::1;11843:16:::0;;;;;::::1;::::0;;11742:64;;-1:-1:-1;11819:21:7::1;::::0;11843:16;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;11843:16:7::1;11819:40;;11888:4;11870;11875:1;11870:7;;;;;;;;-1:-1:-1::0;;;;;11870:23:7;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;11914:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;11914:13:7;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;11870:7;;11914:13;;;;;:6;:13;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;11914:13:7;11904:7;;:4;;11909:1:::1;::::0;11904:7;::::1;;;;;-1:-1:-1::0;;;;;11904:23:7;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;11998:6:::1;::::0;:188:::1;::::0;-1:-1:-1;;;11998:188:7;;::::1;::::0;::::1;::::0;;;11940:21:::1;11998:188:::0;;;;;;12140:4:::1;11998:188:::0;;;;;;12160:15:::1;11998:188:::0;;;;;;;;;;;;;;;;;;;;;11964:21:::1;::::0;11998:6;;;::::1;::::0;:57:::1;::::0;12070:12;;11940:21;;12113:4;;11998:188;;;;;;;;;;::::1;::::0;::::1;::::0;;;11940:21;11998:188:::1;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;12199:17;12219:40;12245:13;12219:21;:25;;:40;;;;:::i;:::-;12199:60:::0;-1:-1:-1;12272:19:7::1;12294:40;12307:26;:19:::0;12331:1:::1;12307:23;:26::i;:::-;12294:8;::::0;;:12:::1;:40::i;:::-;12272:62:::0;-1:-1:-1;12347:26:7::1;12376:100;12474:1;12376:79;12272:62:::0;12376:79;:9;12404:19;12376:27:::1;:48::i;:100::-;12347:129;;12489:28;12520:70;12568:11;12520:29;12534:14;;12520:9;:13;;:29;;;;:::i;:70::-;12630:25;::::0;12622:121:::1;::::0;12489:101;;-1:-1:-1;12604:12:7::1;::::0;-1:-1:-1;;;;;12630:25:7;;::::1;::::0;12723:5:::1;::::0;12489:101;;12604:12;12622:121;12604:12;12622:121;12489:101;12630:25;12723:5;12622:121:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;12766:5:7::1;::::0;-1:-1:-1;;12788:19:7;;;-1:-1:-1;12784:292:7::1;;12824:6;::::0;12998:17:::1;::::0;;12824:240:::1;::::0;;-1:-1:-1;;;12824:240:7;;12900:4:::1;12824:240:::0;;::::1;::::0;;;;;;;;;;:6:::1;:240:::0;;;;;;;;;;-1:-1:-1;;;;;12998:17:7;;::::1;12824:240:::0;;;;13034:15:::1;12824:240:::0;;;;;:6;::::1;::::0;:22:::1;::::0;12854:18;;12824:240;;;;;::::1;::::0;;;;;;;;12854:18;12824:6;:240;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;;12784:292:7::1;-1:-1:-1::0;;4037:6:7;:14;;-1:-1:-1;;4037:14:7;;;-1:-1:-1;;;;;;;;;11351:1732:7:o;18214:190::-;18344:4;;18314;;-1:-1:-1;;;;;18344:12:7;;;:4;;:12;;:26;;-1:-1:-1;18360:4:7;;-1:-1:-1;;;;;18360:10:7;;;:4;;:10;18344:26;18343:53;;;;-1:-1:-1;;;;;;;;18377:18:7;;;;;:12;:18;;;;;;;;18376:19;;18214:190::o;13427:544::-;13584:8;;13613:4;;13544:7;;13584:8;-1:-1:-1;;;;;13607:10:7;;;13613:4;;13607:10;13603:50;;;13645:7;;13631:22;;:9;;:13;:22::i;:::-;13619:34;;13603:50;13715:14;;13666:17;;13686:44;;:24;:9;13700;13686:13;:24::i;:44::-;13794:4;13773:27;;;;:12;:27;;;;;;13666:64;;-1:-1:-1;13773:66:7;;13666:64;13773:31;:66::i;:::-;13764:4;13743:27;;;;:12;:27;;;;;:96;;;;13901:16;;-1:-1:-1;;;;;13855:64:7;;;;;13887:31;;:9;;:13;:31::i;:::-;13855:64;;;;;;;;;;;;;;;13939:24;:9;13953;13939:13;:24::i;:::-;13932:31;13427:544;-1:-1:-1;;;;;;13427:544:7:o

Swarm Source

ipfs://e3d87ffe6d6211790b00774e4211dbf30503657df7861a4316281df1d19d63fe
Loading