ETH Price: $3,364.74 (-2.32%)
Gas: 1 Gwei

Token

Koto (KOTO)
 

Overview

Max Total Supply

2,286,403.167129653035674061 KOTO

Holders

370

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
zoomoid.eth
Balance
19,650.965448478863842715 KOTO

Value
$0.00
0x36cfb14435133753c0b51c6f8c072afb32c91063
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
KotoV3

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion, MIT license
File 1 of 7 : KotoV3.sol
// SPDX-License-Identifier: MIT

///@title Koto ERC20 Token
///@author Izanagi Dev
///@notice A stripped down ERC20 tax token that implements automated and continious monetary policy decisions.
///@dev Bonds are the ERC20 token in exchange for Ether. Unsold bonds with automatically be burned.
/// The bonding schedule is set to attempt to sell all of the tokens held within the contract in 1 day intervals. Taking a snapshot
/// of the amount currently held within the contract at the start of the next internal period, using this amount as the capcipty to be sold.

/// Socials
/// Telegram: https://t.me/KotoPortal

pragma solidity 0.8.23;

import {PricingLibrary} from "./PricingLibrary.sol";
import {SafeTransferLib} from "lib/solmate/src/utils/SafeTransferLib.sol";
import {FullMath} from "./libraries/FullMath.sol";
import {IERC20Minimal} from "./interfaces/IERC20Minimal.sol";
import {IKotoV3} from "./interfaces/IKotoV3.sol";

contract KotoV3 is IKotoV3 {
    // ========================== STORAGE ========================== \\

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _excluded;
    mapping(address => bool) private _amms;
    uint256 private _totalSupply;

    // ====================== ETH BOND STORAGE ===================== \\

    PricingLibrary.Adjustment private adjustment;
    PricingLibrary.Data private data;
    PricingLibrary.Market private market;
    PricingLibrary.Term private term;

    // ====================== LP BOND STORAGE ====================== \\

    PricingLibrary.Adjustment private lpAdjustment;
    PricingLibrary.Data private lpData;
    PricingLibrary.Market private lpMarket;
    PricingLibrary.Term private lpTerm;

    uint256 ethCapacityNext;
    uint256 lpCapacityNext;

    uint8 private locked;
    bool private launched;

    // =================== CONSTANTS / IMMUTABLES =================== \\

    string private constant NAME = "Koto";
    string private constant SYMBOL = "KOTO";
    uint8 private constant DECIMALS = 18;
    ///@dev flat 5% tax for buys and sells
    uint8 private constant FEE = 50;
    bool private immutable zeroForOne;
    address private constant UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address private constant UNISWAP_V2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address private constant OWNER = 0x946eF43867225695E29241813A8F41519634B36b;
    address private constant BOND_DEPOSITORY = 0xE58B33c813ac4077bd2519dE90FccB189a19FA71;
    address private immutable pair;
    address private immutable token0;
    address private immutable token1;
    uint256 private constant INTERVAL = 604800; // 7 days in seconds

    // ========================== MODIFIERS ========================== \\

    modifier lock() {
        if (locked == 2) revert Reentrancy();
        locked = 2;
        _;
        locked = 1;
    }

    // ========================= CONTRUCTOR ========================= \\

    constructor() {
        pair = _createUniswapV2Pair(address(this), WETH);
        _excluded[OWNER] = true;
        _excluded[BOND_DEPOSITORY] = true;
        _excluded[address(this)] = true;
        _amms[pair] = true;
        _mint(OWNER, IERC20Minimal(0xc75c635c1F5e21D23eC8592Cb37503B82A7EF942).totalSupply());
        (token0, token1) = _getTokens(pair);
        zeroForOne = address(this) == token0 ? true : false;
        _allowances[address(this)][UNISWAP_V2_ROUTER] = type(uint256).max;
    }

    // ==================== EXTERNAL FUNCTIONS ===================== \\

    function transfer(address _to, uint256 _value) public returns (bool success) {
        if (_to == address(0) || _value == 0) revert InvalidTransfer();
        _transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        if (_to == address(0) || _value == 0) revert InvalidTransfer();
        if (_from != msg.sender) {
            if (_allowances[_from][msg.sender] < _value) revert InsufficentAllowance();
            _allowances[_from][msg.sender] -= _value;
        }
        _transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) public returns (bool success) {
        address owner = msg.sender;
        _allowances[owner][_spender] = _value;
        return true;
    }

    ///@notice exchange ETH for Koto tokens at the current bonding price
    ///@dev bonds are set on 1 day intervals with 4 hour deposit intervals and 30 minute tune intervals.
    function bond() public payable lock returns (uint256 payout) {
        if (block.timestamp > term.conclusion) revert MarketClosed();
        if (market.capacity != 0) {
            // Cache variables for later use to minimize storage calls
            PricingLibrary.Market memory _market = market;
            PricingLibrary.Term memory _term = term;
            PricingLibrary.Data memory _data = data;
            PricingLibrary.Adjustment memory adjustments = adjustment;
            uint256 _supply = _totalSupply;
            uint48 time = uint48(block.timestamp);

            // Can pass in structs here as nothing has been updated yet
            (_market, _data, _term, adjustments) = PricingLibrary.decay(data, _market, _term, adjustments);

            uint256 price = PricingLibrary.marketPrice(_term.controlVariable, _market.totalDebt, _supply);

            payout = (msg.value * 1e18 / price);
            if (payout > market.maxPayout) revert MaxPayout();

            // Update market variables
            _market.capacity -= uint96(payout);
            _market.purchased += uint96(msg.value);
            _market.sold += uint96(payout);
            _market.totalDebt += uint96(payout);

            bool success = _bond(msg.sender, payout);
            if (!success) revert BondFailed();
            emit Bond(msg.sender, payout, price);

            //Touches market, data, terms, and adjustments
            (_market, _term, _data, adjustments) =
                PricingLibrary.tune(time, _market, _term, _data, adjustments, _supply);

            // Write changes to storage.
            market = _market;
            term = _term;
            data = _data;
            adjustment = adjustments;
        } else {
            //If bonds are not available refund the eth sent to the contract
            SafeTransferLib.safeTransferETH(msg.sender, msg.value);
        }
    }

    function bondLp(uint256 _lpAmount) public lock returns (uint256 payout) {
        if (block.timestamp > lpTerm.conclusion) revert MarketClosed();
        if (lpMarket.capacity != 0) {
            IERC20Minimal(pair).transferFrom(msg.sender, address(BOND_DEPOSITORY), _lpAmount);
            // Cache variables for later use to minimize storage calls
            PricingLibrary.Market memory _market = lpMarket;
            PricingLibrary.Term memory _term = lpTerm;
            PricingLibrary.Data memory _data = lpData;
            PricingLibrary.Adjustment memory adjustments = lpAdjustment;
            uint256 _supply = _totalSupply;
            uint48 time = uint48(block.timestamp);

            // Can pass in structs here as nothing has been updated yet
            (_market, _data, _term, adjustments) = PricingLibrary.decay(lpData, _market, _term, adjustments);

            uint256 price = PricingLibrary.marketPrice(_term.controlVariable, _market.totalDebt, _supply);

            payout = (_lpAmount * 1e18 / price);
            if (payout > lpMarket.maxPayout) revert MaxPayout();

            // Update market variables
            _market.capacity -= uint96(payout);
            _market.purchased += uint96(_lpAmount);
            _market.sold += uint96(payout);
            _market.totalDebt += uint96(payout);

            bool success = _bond(msg.sender, payout);
            if (!success) revert BondFailed();
            emit Bond(msg.sender, payout, price);

            //Touches market, data, terms, and adjustments
            (_market, _term, _data, adjustments) =
                PricingLibrary.tune(time, _market, _term, _data, adjustments, _supply);

            // Write changes to storage.
            lpMarket = _market;
            lpTerm = _term;
            lpData = _data;
            lpAdjustment = adjustments;
        }
    }

    ///@notice burn Koto tokens in exchange for a piece of the underlying reserves
    ///@param amount The amount of Koto tokens to redeem
    ///@return payout The amount of ETH received in exchange for the Koto tokens
    function redeem(uint256 amount) external returns (uint256 payout) {
        // Underlying reserves per token
        uint256 price = FullMath.mulDiv(address(this).balance, 1e18, _totalSupply);
        payout = FullMath.mulDiv(price, amount, 1e18);
        _burn(msg.sender, amount);
        SafeTransferLib.safeTransferETH(msg.sender, payout);
        emit Redeem(msg.sender, amount, payout, price);
    }

    ///@notice burn Koto tokens, without redemption
    ///@param amount the amount of Koto to burn
    function burn(uint256 amount) external returns (bool success) {
        _burn(msg.sender, amount);
        success = true;
        emit Transfer(msg.sender, address(0), amount);
    }

    // ==================== EXTERNAL VIEW FUNCTIONS ===================== \\

    ///@notice get the tokens name
    function name() public pure returns (string memory) {
        return NAME;
    }

    ///@notice get the tokens symbol
    function symbol() public pure returns (string memory) {
        return SYMBOL;
    }

    ///@notice get the tokens decimals
    function decimals() public pure returns (uint8) {
        return DECIMALS;
    }

    ///@notice get the tokens total supply
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    ///@notice get the current balance of a user
    ///@param _owner the user whos balance you want to check
    function balanceOf(address _owner) public view returns (uint256) {
        return _balances[_owner];
    }

    ///@notice get current approved amount for transfer from another party
    ///@param owner the current owner of the tokens
    ///@param spender the user who has approval (or not) to spend the owners tokens
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    ///@notice return the Uniswap V2 Pair address
    function pool() external view returns (address) {
        return pair;
    }

    ///@notice get the owner of the contract
    ///@dev ownership is nontransferable and limited to opening trade, exclusion / inclusion,s and increasing liquidity
    function ownership() external pure returns (address) {
        return OWNER;
    }

    ///@notice the current price a bond
    function bondPrice() external view returns (uint256) {
        return _currentMarketPrice(true);
    }

    function bondPriceLp() external view returns (uint256) {
        return _currentMarketPrice(false);
    }

    ///@notice return the current redemption price for 1 uint of Koto.
    function redemptionPrice() external view returns (uint256) {
        return ((address(this).balance * 1e18) / _totalSupply);
    }

    function marketInfo()
        external
        view
        returns (PricingLibrary.Market memory, PricingLibrary.Term memory, PricingLibrary.Data memory)
    {
        return (market, term, data);
    }

    function lpMarketInfo()
        external
        view
        returns (PricingLibrary.Market memory, PricingLibrary.Term memory, PricingLibrary.Data memory)
    {
        return (lpMarket, lpTerm, lpData);
    }

    function depository() external pure returns (address) {
        return BOND_DEPOSITORY;
    }

    // ========================= ADMIN FUNCTIONS ========================= \\

    ///@notice remove a given address from fees and limits
    ///@param user the user to exclude from fees
    ///@dev this is a one way street so once a user has been excluded they can not then be removed
    function exclude(address user) external {
        if (msg.sender != OWNER) revert OnlyOwner();
        _excluded[user] = true;
        emit UserExcluded(user);
    }

    ///@notice add a amm pool / pair
    ///@param _pool the address of the pool / pair to add
    function addAmm(address _pool) external {
        if (msg.sender != OWNER) revert OnlyOwner();
        _amms[_pool] = true;
        emit AmmAdded(_pool);
    }

    ///@notice seed the initial liquidity from this contract.
    function launch() external {
        if (msg.sender != OWNER) revert OnlyOwner();
        if (launched) revert AlreadyLaunched();
        _addInitialLiquidity();
        launched = true;
        emit Launched(block.timestamp);
    }

    ///@notice create a new bond market for ETH and LP bonds
    ///@param ethBondAmount the amount of koto tokens to be sold for ETH bonds during this period
    ///@param lpBondAmount the amount of koto tokens to be sold for LP bonds during this period.
    function create(uint256 ethBondAmount, uint256 lpBondAmount) external {
        if (msg.sender != OWNER && msg.sender != BOND_DEPOSITORY) revert InvalidSender();
        if (term.conclusion > block.timestamp) revert OngoingBonds();

        ///@dev clear the current unsold bonds in order to prevent build up of unsold tokens
        /// if this is not done over a longer time period it would effect the redemption rate for users.
        uint256 currentBalance = _balances[address(this)];
        if (currentBalance > 0) {
            unchecked {
                _balances[address(this)] -= currentBalance;
                _totalSupply -= currentBalance;
            }
            emit Transfer(address(this), address(0), currentBalance);
        }
        uint256 total = ethBondAmount + lpBondAmount;
        transferFrom(msg.sender, address(this), total);
        ethCapacityNext = ethBondAmount;
        lpCapacityNext = lpBondAmount;
        _create();
        _createLpMarket();
    }

    // ========================= INTERNAL FUNCTIONS ========================= \\

    ///@notice create the Uniswap V2 Pair
    ///@param _token0 token 0 of the pair
    ///@param _token1 token 1 of the pair
    ///@return _pair the pair address
    function _createUniswapV2Pair(address _token0, address _token1) private returns (address _pair) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0xc9c6539600000000000000000000000000000000000000000000000000000000)
            mstore(add(ptr, 4), and(_token0, 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(ptr, 36), and(_token1, 0xffffffffffffffffffffffffffffffffffffffff))
            let result := call(gas(), UNISWAP_V2_FACTORY, 0, ptr, 68, 0, 32)
            if iszero(result) { revert(0, 0) }
            _pair := mload(0x00)
        }
    }

    ///@notice add the initial liquidity of the pool.
    function _addInitialLiquidity() private {
        uint256 tokenAmount = _balances[address(this)];
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0xf305d71900000000000000000000000000000000000000000000000000000000)
            mstore(add(ptr, 4), and(address(), 0xffffffffffffffffffffffffffffffffffffffff))
            mstore(add(ptr, 36), tokenAmount)
            mstore(add(ptr, 68), 0)
            mstore(add(ptr, 100), 0)
            mstore(add(ptr, 132), BOND_DEPOSITORY)
            mstore(add(ptr, 164), timestamp())
            let result := call(gas(), UNISWAP_V2_ROUTER, balance(address()), ptr, 196, 0, 0)
            if iszero(result) { revert(0, 0) }
        }
    }

    ///@notice create the next bond market information
    ///@dev this is done automatically if the previous market conclusion has passed
    /// time check must be done elsewhere as the initial conclusion is set to uint48 max,
    /// tokens must also already be held within the contract or else the call will revert
    function _create() private {
        // Set the initial price to the current market price
        uint96 targetDebt = uint96(ethCapacityNext);
        if (ethCapacityNext > 0) {
            uint256 initialPrice = _getPrice();

            uint96 capacity = targetDebt;
            uint96 maxPayout = uint96(targetDebt * 86400 / INTERVAL);
            uint256 controlVariable = initialPrice * _totalSupply / targetDebt;
            bool policy = _policy(capacity, initialPrice);
            uint48 conclusion = uint48(block.timestamp + INTERVAL);

            if (policy) {
                market = PricingLibrary.Market(capacity, targetDebt, maxPayout, 0, 0);
                term = PricingLibrary.Term(conclusion, controlVariable);
                data =
                    PricingLibrary.Data(uint48(block.timestamp), uint48(block.timestamp), uint48(INTERVAL), 86400, 1800);
                emit CreateMarket(capacity, block.timestamp, conclusion);
            } else {
                _burn(address(this), capacity);
                // Set the markets so that they will be closed for the next interval. Important step to make sure
                // that if anyone accidently tries to buy a bond they get refunded their eth.
                term.conclusion = uint48(block.timestamp + INTERVAL);
                market.capacity = 0;
            }
        }
        ethCapacityNext = 0;
    }

    ///@notice create the next bond market for LP tokens -> koto
    function _createLpMarket() private {
        uint96 targetDebt = uint96(lpCapacityNext);
        if (targetDebt > 0) {
            uint256 initialPrice = _getLpPrice();
            uint96 capacity = targetDebt;
            uint96 maxPayout = uint96(targetDebt * 86400 / INTERVAL);
            uint256 controlVariable = initialPrice * _totalSupply / targetDebt;
            bool policy = _policy(capacity, initialPrice);
            uint48 conclusion = uint48(block.timestamp + INTERVAL);

            if (policy) {
                lpMarket = PricingLibrary.Market(capacity, targetDebt, maxPayout, 0, 0);
                lpTerm = PricingLibrary.Term(conclusion, controlVariable);
                lpData =
                    PricingLibrary.Data(uint48(block.timestamp), uint48(block.timestamp), uint48(INTERVAL), 86400, 1800);
                emit CreateMarket(capacity, block.timestamp, conclusion);
            } else {
                _burn(address(this), capacity);
                // Set the markets so that they will be closed for the next interval. Important step to make sure
                // that if anyone accidently tries to buy a bond they get refunded their eth.
                lpTerm.conclusion = uint48(block.timestamp + INTERVAL);
                lpMarket.capacity = 0;
            }
        }
        lpCapacityNext = 0;
    }

    ///@notice determines if to sell the tokens available as bonds or to burn them instead
    ///@param capacity the amount of tokens that will be available within the next bonding cycle
    ///@param price the starting price of the bonds to sell
    ///@return decision the decision reached determining which is more valuable to sell the bonds (true) or to burn them (false)
    ///@dev the decision is made optimistically using the initial price as the selling price for the deicison. If selling the tokens all at the starting
    /// price does not increase relative reserves more than burning the tokens then they are burned. If they are equivilant burning wins out.
    function _policy(uint256 capacity, uint256 price) private view returns (bool decision) {
        uint256 supply = _totalSupply;
        uint256 burnRelative = (address(this).balance * 1e18) / (supply - capacity);
        uint256 bondRelative = ((address(this).balance * 1e18) + ((capacity * price))) / supply;
        decision = burnRelative >= bondRelative ? false : true;
    }

    ///@notice internal transfer function to handle dealing with taxes
    function _transfer(address from, address to, uint256 _value) private {
        if (_value > _balances[from]) revert InsufficentBalance();
        bool fees;
        if (_amms[to] || _amms[from]) {
            if (_excluded[to] || _excluded[from]) {
                fees = false;
            } else {
                fees = true;
            }
        }
        if (fees) {
            uint256 fee = (_value * FEE) / 1000;

            unchecked {
                _balances[from] -= _value;
                _balances[BOND_DEPOSITORY] += fee;
            }
            _value -= fee;
            unchecked {
                _balances[to] += _value;
            }
        } else {
            unchecked {
                _balances[from] -= _value;
                _balances[to] += _value;
            }
        }
        emit Transfer(from, to, _value);
    }

    ///@notice mint new koto tokens
    ///@param to the user who will receive the tokens
    ///@param value the amount of tokens to mint
    ///@dev this function is used once, during the creation of the contract and is then
    /// not callable
    function _mint(address to, uint256 value) private {
        unchecked {
            _balances[to] += value;
            _totalSupply += value;
        }
        emit Transfer(address(0), to, value);
    }

    ///@notice burn koto tokens
    ///@param from the user to burn the tokens from
    ///@param value the amount of koto tokens to burn
    function _burn(address from, uint256 value) private {
        if (_balances[from] < value) revert InsufficentBalance();
        unchecked {
            _balances[from] -= value;
            _totalSupply -= value;
        }
        emit Transfer(from, address(0), value);
    }

    ///@notice send the user the correct amount of tokens after the have bought a bond
    ///@param to the user to send the tokens to
    ///@param value the amount of koto tokens to send
    ///@dev bonds are not subject to taxes
    function _bond(address to, uint256 value) private returns (bool success) {
        if (value > _balances[address(this)]) revert InsufficentBondsAvailable();
        unchecked {
            _balances[to] += value;
            _balances[address(this)] -= value;
        }
        success = true;
        emit Transfer(address(this), to, value);
    }

    ///@notice calculate the current market price based on the reserves of the Uniswap Pair
    ///@dev price is returned as the amount of ETH you would get back for 1 full (1e18) Koto tokens
    function _getPrice() private view returns (uint256 price) {
        address _pair = pair;
        uint112 reserve0;
        uint112 reserve1;
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x0902f1ac00000000000000000000000000000000000000000000000000000000)
            let success := staticcall(gas(), _pair, ptr, 4, 0, 0)
            if iszero(success) { revert(0, 0) }
            returndatacopy(0x00, 0, 32)
            returndatacopy(0x20, 0x20, 32)
            reserve0 := mload(0x00)
            reserve1 := mload(0x20)
        }

        if (zeroForOne) {
            price = FullMath.mulDiv(uint256(reserve1), 1e18, uint256(reserve0));
        } else {
            price = FullMath.mulDiv(uint256(reserve0), 1e18, uint256(reserve1));
        }
    }

    ///@notice return the current price in koto for 1 LP token
    function _getLpPrice() private view returns (uint256 _lpPrice) {
        address _pair = pair;
        uint112 reserve0;
        uint112 reserve1;
        uint256 lpTotalSupply;
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x0902f1ac00000000000000000000000000000000000000000000000000000000)
            let success := staticcall(gas(), _pair, ptr, 4, 0, 0)
            if iszero(success) { revert(0, 0) }
            returndatacopy(0x00, 0, 32)
            returndatacopy(0x20, 0x20, 32)
            reserve0 := mload(0x00)
            reserve1 := mload(0x20)
            mstore(add(ptr, 0x20), 0x18160ddd00000000000000000000000000000000000000000000000000000000)
            let result := staticcall(gas(), _pair, add(ptr, 0x20), 4, 0, 32)
            lpTotalSupply := mload(0x00)
        }
        ///@dev with uniswap v2 we simply treat the other token total as equal value to simplify the pricing mechanism
        if (zeroForOne) {
            _lpPrice = FullMath.mulDiv(reserve0 * 2, 1e18, lpTotalSupply);
        } else {
            _lpPrice = FullMath.mulDiv(reserve1 * 2, 1e18, lpTotalSupply);
        }
    }

    ///@notice return the tokens for a Uniswap V2 Pair
    ///@param _pair the address of the pair
    ///@return _token0 token 0 of the uniswap pair
    ///@return _token1 token 1 of the uniswap pair
    function _getTokens(address _pair) private view returns (address _token0, address _token1) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x0dfe168100000000000000000000000000000000000000000000000000000000)
            let resultToken0 := staticcall(gas(), _pair, ptr, 4, 0, 32)
            mstore(add(ptr, 4), 0xd21220a700000000000000000000000000000000000000000000000000000000)
            let resultToken1 := staticcall(gas(), _pair, add(ptr, 4), 4, 32, 32)
            if or(iszero(resultToken0), iszero(resultToken1)) { revert(0, 0) }
            _token0 := mload(0x00)
            _token1 := mload(0x20)
        }
    }

    ///@notice get the current market price of bonds based on decay and other factors
    ///@param eth true if you are getting the ETH bond price, false for LP bond price
    function _currentMarketPrice(bool eth) private view returns (uint256) {
        if (eth) {
            return (
                FullMath.mulDiv(
                    _currentControlVariable(term.controlVariable, adjustment),
                    PricingLibrary.debtRatio(market.totalDebt, _totalSupply),
                    1e18
                )
            );
        } else {
            return (
                FullMath.mulDiv(
                    _currentControlVariable(lpTerm.controlVariable, lpAdjustment),
                    PricingLibrary.debtRatio(lpMarket.totalDebt, _totalSupply),
                    1e18
                )
            );
        }
    }

    function _currentControlVariable(uint256 controlVariable, PricingLibrary.Adjustment memory info)
        private
        view
        returns (uint256)
    {
        (uint256 decay,,) = PricingLibrary.controlDecay(info);
        return controlVariable - decay;
    }

    receive() external payable {}
}

File 2 of 7 : PricingLibrary.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

library PricingLibrary {
    // 1 Slot
    struct Data {
        uint48 lastTune;
        uint48 lastDecay; // last timestamp when market was created and debt was decayed
        uint48 length; // time from creation to conclusion. used as speed to decay debt.
        uint48 depositInterval; // target frequency of deposits
        uint48 tuneInterval; // frequency of tuning
    }

    // 2 Storage slots
    struct Market {
        uint96 capacity; // capacity remaining
        uint96 totalDebt; // total debt from market
        uint96 maxPayout; // max tokens in/out
        uint96 sold; // Koto out
        uint96 purchased; // Eth in
    }

    // 1 Storage Slot
    struct Adjustment {
        uint128 change;
        uint48 lastAdjustment;
        uint48 timeToAdjusted;
        bool active;
    }

    // 2 Storage slots
    struct Term {
        uint48 conclusion; // timestamp when the current market will end
        uint256 controlVariable; // scaling variable for price
    }

    function decay(Data memory data, Market memory market, Term memory terms, Adjustment memory adjustments)
        internal
        view
        returns (Market memory, Data memory, Term memory, Adjustment memory)
    {
        uint48 time = uint48(block.timestamp);
        market.totalDebt -= debtDecay(data, market);
        data.lastDecay = time;

        if (adjustments.active) {
            (uint128 adjustby, uint48 dt, bool stillActive) = controlDecay(adjustments);
            terms.controlVariable -= adjustby;
            if (stillActive) {
                adjustments.change -= adjustby;
                adjustments.timeToAdjusted -= dt;
                adjustments.lastAdjustment = time;
            } else {
                adjustments.active = false;
            }
        }
        return (market, data, terms, adjustments);
    }

    function controlDecay(Adjustment memory info) internal view returns (uint128, uint48, bool) {
        if (!info.active) return (0, 0, false);

        uint48 secondsSince = uint48(block.timestamp) - info.lastAdjustment;
        bool active = secondsSince < info.timeToAdjusted;
        uint128 _decay = active ? (info.change * secondsSince) / info.timeToAdjusted : info.change;
        return (_decay, secondsSince, active);
    }

    function marketPrice(uint256 _controlVariable, uint256 _totalDebt, uint256 _totalSupply)
        internal
        pure
        returns (uint256)
    {
        return ((_controlVariable * debtRatio(_totalDebt, _totalSupply)) / 1e18);
    }

    function debtRatio(uint256 _totalDebt, uint256 _totalSupply) internal pure returns (uint256) {
        return ((_totalDebt * 1e18) / _totalSupply);
    }

    function debtDecay(Data memory data, Market memory market) internal view returns (uint64) {
        uint256 secondsSince = block.timestamp - data.lastDecay;
        return uint64((market.totalDebt * secondsSince) / data.length);
    }

    struct TuneCache {
        uint256 remaining;
        uint256 price;
        uint256 capacity;
        uint256 targetDebt;
        uint256 ncv;
    }

    function tune(
        uint48 time,
        Market memory market,
        Term memory term,
        Data memory data,
        Adjustment memory adjustment,
        uint256 _totalSupply
    ) internal pure returns (Market memory, Term memory, Data memory, Adjustment memory) {
        TuneCache memory cache;
        if (time >= data.lastTune + data.tuneInterval) {
            cache.remaining = term.conclusion - time;
            cache.price = marketPrice(term.controlVariable, market.totalDebt, _totalSupply);
            cache.capacity = market.capacity;
            market.maxPayout = uint96((cache.capacity * data.depositInterval / cache.remaining));
            cache.targetDebt = cache.capacity * data.length / cache.remaining;
            cache.ncv = (cache.price * _totalSupply) / cache.targetDebt;

            if (cache.ncv < term.controlVariable) {
                uint128 change = uint128(term.controlVariable - cache.ncv);
                adjustment = Adjustment(change, time, data.tuneInterval, true);
            } else {
                term.controlVariable = cache.ncv;
            }
            data.lastTune = time;
        }
        return (market, term, data, adjustment);
    }
}

File 3 of 7 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 4 of 7 : FullMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
library FullMath {
    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
    function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b
            // Compute the product mod 2**256 and mod 2**256 - 1
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(a, b, not(0))
                prod0 := mul(a, b)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division
            if (prod1 == 0) {
                require(denominator > 0);
                assembly {
                    result := div(prod0, denominator)
                }
                return result;
            }

            // Make sure the result is less than 2**256.
            // Also prevents denominator == 0
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0]
            // Compute remainder using mulmod
            uint256 remainder;
            assembly {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number
            assembly {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator
            // Compute largest power of two divisor of denominator.
            // Always >= 1.
            uint256 twos = (0 - denominator) & denominator;
            // Divide denominator by power of two
            assembly {
                denominator := div(denominator, twos)
            }

            // Divide [prod1 prod0] by the factors of two
            assembly {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos.
            // If twos is zero, then it becomes one
            assembly {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;

            // Invert denominator mod 2**256
            // Now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // correct for four bits. That is, denominator * inv = 1 mod 2**4
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // inverse mod 2**8
            inv *= 2 - denominator * inv; // inverse mod 2**16
            inv *= 2 - denominator * inv; // inverse mod 2**32
            inv *= 2 - denominator * inv; // inverse mod 2**64
            inv *= 2 - denominator * inv; // inverse mod 2**128
            inv *= 2 - denominator * inv; // inverse mod 2**256

            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the precoditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }

    /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
    /// @param a The multiplicand
    /// @param b The multiplier
    /// @param denominator The divisor
    /// @return result The 256-bit result
    function mulDivRoundingUp(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            result = mulDiv(a, b, denominator);
            if (mulmod(a, b, denominator) > 0) {
                require(result < type(uint256).max);
                result++;
            }
        }
    }
}

File 5 of 7 : IERC20Minimal.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

interface IERC20Minimal {
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function transfer(address, uint256) external returns (bool);
    function balanceOf(address) external view returns (uint256);
    function totalSupply() external view returns (uint256);
}

File 6 of 7 : IKotoV3.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

import {PricingLibrary} from "../PricingLibrary.sol";

interface IKotoV3 {
    // ==================== EXTERNAL FUNCTIONS ===================== \\

    function transfer(address _to, uint256 _value) external returns (bool success);

    function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);

    function approve(address _spender, uint256 _value) external returns (bool success);

    ///@notice exchange ETH for Koto tokens at the current bonding price
    ///@dev bonds are set on 1 day intervals with 4 hour deposit intervals and 30 minute tune intervals.
    function bond() external payable returns (uint256 payout);

    function bondLp(uint256 _lpAmount) external returns (uint256 payout);

    ///@notice burn Koto tokens in exchange for a piece of the underlying reserves
    ///@param amount The amount of Koto tokens to redeem
    ///@return payout The amount of ETH received in exchange for the Koto tokens
    function redeem(uint256 amount) external returns (uint256 payout);

    ///@notice burn Koto tokens, without redemption
    ///@param amount the amount of Koto to burn
    function burn(uint256 amount) external returns (bool success);

    // ==================== EXTERNAL VIEW FUNCTIONS ===================== \\

    ///@notice get the tokens name
    function name() external pure returns (string memory);

    ///@notice get the tokens symbol
    function symbol() external pure returns (string memory);

    ///@notice get the tokens decimals
    function decimals() external pure returns (uint8);

    ///@notice get the tokens total supply
    function totalSupply() external view returns (uint256);

    ///@notice get the current balance of a user
    ///@param _owner the user whos balance you want to check
    function balanceOf(address _owner) external view returns (uint256);

    ///@notice get current approved amount for transfer from another party
    ///@param owner the current owner of the tokens
    ///@param spender the user who has approval (or not) to spend the owners tokens
    function allowance(address owner, address spender) external view returns (uint256);

    ///@notice return the Uniswap V2 Pair address
    function pool() external view returns (address);

    ///@notice get the owner of the contract
    ///@dev ownership is nontransferable and limited to opening trade, exclusion / inclusion,s and increasing liquidity
    function ownership() external pure returns (address);

    ///@notice the current price a bond
    function bondPrice() external view returns (uint256);

    function bondPriceLp() external view returns (uint256);

    ///@notice return the current redemption price for 1 uint of Koto.
    function redemptionPrice() external view returns (uint256);

    function marketInfo()
        external
        view
        returns (PricingLibrary.Market memory, PricingLibrary.Term memory, PricingLibrary.Data memory);

    function lpMarketInfo()
        external
        view
        returns (PricingLibrary.Market memory, PricingLibrary.Term memory, PricingLibrary.Data memory);

    function depository() external pure returns (address);

    function create(uint256 ethBondAmount, uint256 lpBondAmount) external;

    // ========================= EVENTS ========================= \\

    event AmmAdded(address poolAdded);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    event Bond(address indexed buyer, uint256 amount, uint256 bondPrice);
    event CreateMarket(uint256 bonds, uint256 start, uint48 end);
    event IncreaseLiquidity(uint256 kotoAdded, uint256 ethAdded);
    event Launched(uint256 time);
    event LimitsRemoved(uint256 time);
    event OpenBondMarket(uint256 openingTime);
    event Redeem(address indexed sender, uint256 burned, uint256 payout, uint256 floorPrice);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event UserExcluded(address indexed userToExclude);

    // ========================= ERRORS ========================= \\

    error AlreadyLaunched();
    error BondFailed();
    error InsufficentAllowance();
    error InsufficentBalance();
    error InsufficentBondsAvailable();
    error InvalidSender();
    error InvalidTransfer();
    error LimitsReached();
    error MarketClosed();
    error MaxPayout();
    error OngoingBonds();
    error OnlyOwner();
    error RedeemFailed();
    error Reentrancy();
}

File 7 of 7 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

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

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyLaunched","type":"error"},{"inputs":[],"name":"BondFailed","type":"error"},{"inputs":[],"name":"InsufficentAllowance","type":"error"},{"inputs":[],"name":"InsufficentBalance","type":"error"},{"inputs":[],"name":"InsufficentBondsAvailable","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidTransfer","type":"error"},{"inputs":[],"name":"LimitsReached","type":"error"},{"inputs":[],"name":"MarketClosed","type":"error"},{"inputs":[],"name":"MaxPayout","type":"error"},{"inputs":[],"name":"OngoingBonds","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"RedeemFailed","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"poolAdded","type":"address"}],"name":"AmmAdded","type":"event"},{"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":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bondPrice","type":"uint256"}],"name":"Bond","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bonds","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint48","name":"end","type":"uint48"}],"name":"CreateMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"kotoAdded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAdded","type":"uint256"}],"name":"IncreaseLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Launched","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"LimitsRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"openingTime","type":"uint256"}],"name":"OpenBondMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"burned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"floorPrice","type":"uint256"}],"name":"Redeem","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userToExclude","type":"address"}],"name":"UserExcluded","type":"event"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"addAmm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bond","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpAmount","type":"uint256"}],"name":"bondLp","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bondPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondPriceLp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethBondAmount","type":"uint256"},{"internalType":"uint256","name":"lpBondAmount","type":"uint256"}],"name":"create","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"depository","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"exclude","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"launch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lpMarketInfo","outputs":[{"components":[{"internalType":"uint96","name":"capacity","type":"uint96"},{"internalType":"uint96","name":"totalDebt","type":"uint96"},{"internalType":"uint96","name":"maxPayout","type":"uint96"},{"internalType":"uint96","name":"sold","type":"uint96"},{"internalType":"uint96","name":"purchased","type":"uint96"}],"internalType":"struct PricingLibrary.Market","name":"","type":"tuple"},{"components":[{"internalType":"uint48","name":"conclusion","type":"uint48"},{"internalType":"uint256","name":"controlVariable","type":"uint256"}],"internalType":"struct PricingLibrary.Term","name":"","type":"tuple"},{"components":[{"internalType":"uint48","name":"lastTune","type":"uint48"},{"internalType":"uint48","name":"lastDecay","type":"uint48"},{"internalType":"uint48","name":"length","type":"uint48"},{"internalType":"uint48","name":"depositInterval","type":"uint48"},{"internalType":"uint48","name":"tuneInterval","type":"uint48"}],"internalType":"struct PricingLibrary.Data","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketInfo","outputs":[{"components":[{"internalType":"uint96","name":"capacity","type":"uint96"},{"internalType":"uint96","name":"totalDebt","type":"uint96"},{"internalType":"uint96","name":"maxPayout","type":"uint96"},{"internalType":"uint96","name":"sold","type":"uint96"},{"internalType":"uint96","name":"purchased","type":"uint96"}],"internalType":"struct PricingLibrary.Market","name":"","type":"tuple"},{"components":[{"internalType":"uint48","name":"conclusion","type":"uint48"},{"internalType":"uint256","name":"controlVariable","type":"uint256"}],"internalType":"struct PricingLibrary.Term","name":"","type":"tuple"},{"components":[{"internalType":"uint48","name":"lastTune","type":"uint48"},{"internalType":"uint48","name":"lastDecay","type":"uint48"},{"internalType":"uint48","name":"length","type":"uint48"},{"internalType":"uint48","name":"depositInterval","type":"uint48"},{"internalType":"uint48","name":"tuneInterval","type":"uint48"}],"internalType":"struct PricingLibrary.Data","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"ownership","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redemptionPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","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":"success","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":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

61010060405234801562000011575f80fd5b50620000323073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2620001c6565b6001600160a01b031660a0819052600260209081527fd1c69375fae4db1f9bc09d344dd4ca5ec7325a49ae090b3810917b7940a06d4b8054600160ff1991821681179092557fda4acfa3de973735c764cfbaff39d0713857968d5508c62047720cdf3757d5358054821683179055305f90815260408082208054841685179055948152600384528490208054909116909117905581516318160ddd60e01b81529151620001579273946ef43867225695e29241813a8f41519634b36b9273c75c635c1f5e21d23ec8592cb37503b82a7ef942926318160ddd9260048082019392918290030181865afa1580156200012b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001519190620002d0565b62000226565b60a05162000165906200027f565b6001600160a01b0390811660e0521660c0819052301462000187575f6200018a565b60015b1515608052305f908152600160209081526040808320737a250d5630b4cf539739df2c5dacb4c659f2488d845290915290205f199055620002e8565b5f6040516364e329cb60e11b81526001600160a01b03841660048201526001600160a01b038316602482015260205f6044835f735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f5af19050806200021c575f80fd5b50505f5192915050565b6001600160a01b0382165f818152602081815260408083208054860190556004805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f80604051630dfe168160e01b815260205f600483875afa63d21220a760e01b60048301526020806004808501885afa9150811581151715620002c0575f80fd5b50505f5191506020519050915091565b5f60208284031215620002e1575f80fd5b5051919050565b60805160a05160c05160e051612ffc620003325f395f50505f50505f81816102ab0152818161143e01528181612a2b0152612b8201525f8181612a830152612bfa0152612ffc5ff3fe608060405260043610610164575f3560e01c806364c9ec6f116100cd578063bedd12a511610087578063d926de1c11610062578063d926de1c146104bb578063db006a75146104da578063dd62ed3e146104f9578063df8980b31461053d575f80fd5b8063bedd12a51461046d578063c5b748c014610493578063d7ccfb0b146104a7575f80fd5b806364c9ec6f146103b357806370a08231146103bb5780637b16c21e146103ef57806395d89b41146104035780639f7b45791461042f578063a9059cbb1461044e575f80fd5b806323b872dd1161011e57806323b872dd1461030157806326749e8714610320578063313ce5671461033457806342966c681461034f5780634febf53d1461036e5780635d03147a1461038d575f80fd5b806301339c211461016f578063031bee001461018557806306fdde0314610239578063095ea7b31461026e57806316f0115b1461029d57806318160ddd146102e3575f80fd5b3661016b57005b5f80fd5b34801561017a575f80fd5b5061018361055c565b005b348015610190575f80fd5b5061019961060c565b6040805184516001600160601b0390811682526020808701518216818401528684015182168385015260608088015183168185015260809788015190921687840152855165ffffffffffff90811660a08501529581015160c08401528451861660e0840152840151851661010083015291830151841661012082015290820151831661014082015292015116610160820152610180015b60405180910390f35b348015610244575f80fd5b506040805180820190915260048152634b6f746f60e01b60208201525b6040516102309190612c90565b348015610279575f80fd5b5061028d610288366004612cf2565b6106f5565b6040519015158152602001610230565b3480156102a8575f80fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b039091168152602001610230565b3480156102ee575f80fd5b506004545b604051908152602001610230565b34801561030c575f80fd5b5061028d61031b366004612d1a565b610722565b34801561032b575f80fd5b506101996107f6565b34801561033f575f80fd5b5060405160128152602001610230565b34801561035a575f80fd5b5061028d610369366004612d53565b6108df565b348015610379575f80fd5b50610183610388366004612d6a565b610917565b348015610398575f80fd5b5073946ef43867225695e29241813a8f41519634b36b6102cb565b6102f3610996565b3480156103c6575f80fd5b506102f36103d5366004612d6a565b6001600160a01b03165f9081526020819052604090205490565b3480156103fa575f80fd5b506102f36110ee565b34801561040e575f80fd5b506040805180820190915260048152634b4f544f60e01b6020820152610261565b34801561043a575f80fd5b50610183610449366004612d83565b6110fd565b348015610459575f80fd5b5061028d610468366004612cf2565b61120d565b348015610478575f80fd5b5073e58b33c813ac4077bd2519de90fccb189a19fa716102cb565b34801561049e575f80fd5b506102f3611254565b3480156104b2575f80fd5b506102f3611275565b3480156104c6575f80fd5b506101836104d5366004612d6a565b611280565b3480156104e5575f80fd5b506102f36104f4366004612d53565b61130d565b348015610504575f80fd5b506102f3610513366004612da3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610548575f80fd5b506102f3610557366004612d53565b611398565b3373946ef43867225695e29241813a8f41519634b36b1461059057604051635fc483c560e01b815260040160405180910390fd5b601554610100900460ff16156105b9576040516319f4db0f60e31b815260040160405180910390fd5b6105c1611b8c565b6015805461ff0019166101001790556040517feca0dfbda743d141662328d4d48393e344b2c60df0430297221df823f2926dba906106029042815260200190565b60405180910390a1565b610614612c63565b604080518082019091525f808252602082015261062f612c63565b50506040805160a080820183526007546001600160601b038082168452600160601b91829004811660208086019190915260085480831686880152839004821660608087019190915260095490921660808087019190915286518088018852600a5465ffffffffffff9081168252600b5482850152885196870189526006548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b335f9081526001602081815260408084206001600160a01b03871685529091529091208290555b92915050565b5f6001600160a01b0383161580610737575081155b1561075557604051632f35253160e01b815260040160405180910390fd5b6001600160a01b03841633146107e0576001600160a01b0384165f9081526001602090815260408083203384529091529020548211156107a8576040516358d246fb60e11b815260040160405180910390fd5b6001600160a01b0384165f908152600160209081526040808320338452909152812080548492906107da908490612de8565b90915550505b6107eb848484611c2d565b5060015b9392505050565b6107fe612c63565b604080518082019091525f8082526020820152610819612c63565b50506040805160a08082018352600e546001600160601b038082168452600160601b918290048116602080860191909152600f548083168688015283900482166060808701919091526010549092166080808701919091528651808801885260115465ffffffffffff90811682526012548285015288519687018952600d548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b5f6108ea3383611e0e565b506040518181526001905f9033905f80516020612fa78339815191529060200160405180910390a3919050565b3373946ef43867225695e29241813a8f41519634b36b1461094b57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260026020526040808220805460ff19166001179055517fec2dffa455deca3e695cce255e2b110b5ca334fb5b166f3159bbaad319ce0f1b9190a250565b6015545f9060ff166002036109be5760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff164211156109f55760405162b5f6bf60e41b815260040160405180910390fd5b6007546001600160601b0316156110d4575f60076040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f600a6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f60056040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050610dcb60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786611e91565b809650819850829750839950505050505f610df8866020015188602001516001600160601b031685611fb7565b905080610e0d34670de0b6b3a7640000612dfb565b610e179190612e26565b6008549098506001600160601b0316881115610e46576040516305c250cf60e11b815260040160405180910390fd5b87875f01818151610e579190612e39565b6001600160601b0316905250608087018051349190610e77908390612e60565b6001600160601b0316905250606087018051899190610e97908390612e60565b6001600160601b0316905250602087018051899190610eb7908390612e60565b6001600160601b03169052505f610ece338a611fe7565b905080610eee5760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a2610f3783898989898961206b565b8351600780546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600880546060808d015193891691909616179187168602919091179055608098890151600980546001600160601b0319908116929097169190911790558751600a805465ffffffffffff191665ffffffffffff92831617905597820151600b55865160068054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b93871693909302929092179055815160058054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b91151591909102179055506110de9650505050505050565b6110de333461226e565b6015805460ff1916600117905590565b5f6110f85f6122c5565b905090565b3373946ef43867225695e29241813a8f41519634b36b1480159061113557503373e58b33c813ac4077bd2519de90fccb189a19fa7114155b1561115357604051636edaef2f60e11b815260040160405180910390fd5b600a544265ffffffffffff9091161115611180576040516301f2595960e01b815260040160405180910390fd5b305f9081526020819052604090205480156111d457305f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612fa7833981519152910160405180910390a35b5f6111df8385612e80565b90506111ec333083610722565b50601384905560148390556111ff6123df565b611207612620565b50505050565b5f6001600160a01b0383161580611222575081155b1561124057604051632f35253160e01b815260040160405180910390fd5b61124b338484611c2d565b50600192915050565b6004545f9061126b47670de0b6b3a7640000612dfb565b6110f89190612e26565b5f6110f860016122c5565b3373946ef43867225695e29241813a8f41519634b36b146112b457604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260036020908152604091829020805460ff1916600117905590519182527f10cdbb821aa416c854add806e1d7e8138afe2a538921cebe99b1351362ae38b2910160405180910390a150565b5f8061132447670de0b6b3a764000060045461286a565b90506113398184670de0b6b3a764000061286a565b91506113453384611e0e565b61134f338361226e565b604080518481526020810184905290810182905233907fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469060600160405180910390a250919050565b6015545f9060ff166002036113c05760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff1916600217905560115465ffffffffffff164211156113f75760405162b5f6bf60e41b815260040160405180910390fd5b600e546001600160601b031615611b7a576040516323b872dd60e01b815233600482015273e58b33c813ac4077bd2519de90fccb189a19fa716024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af115801561148c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114b09190612e93565b505f600e6040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f60116040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f600c6040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050611876600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786611e91565b809650819850829750839950505050505f6118a3866020015188602001516001600160601b031685611fb7565b9050806118b88a670de0b6b3a7640000612dfb565b6118c29190612e26565b600f549098506001600160601b03168811156118f1576040516305c250cf60e11b815260040160405180910390fd5b87875f018181516119029190612e39565b6001600160601b03169052506080870180518a9190611922908390612e60565b6001600160601b0316905250606087018051899190611942908390612e60565b6001600160601b0316905250602087018051899190611962908390612e60565b6001600160601b03169052505f611979338a611fe7565b9050806119995760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a26119e283898989898961206b565b8351600e80546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600f80546060808d015193891691909616179187168602919091179055608098890151601080546001600160601b03199081169290971691909117905587516011805465ffffffffffff191665ffffffffffff928316179055978201516012558651600d8054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b938716939093029290921790558151600c8054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b9115159190910217905550505050505050505b6015805460ff19166001179055919050565b5f805f306001600160a01b03166001600160a01b031681526020019081526020015f2054905060405163f305d71960e01b81526001600160a01b03301660048201528160248201525f60448201525f606482015273e58b33c813ac4077bd2519de90fccb189a19fa7160848201524260a48201525f8060c4833031737a250d5630b4cf539739df2c5dacb4c659f2488d5af1905080611c29575f80fd5b5050565b6001600160a01b0383165f90815260208190526040902054811115611c655760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f9081526003602052604081205460ff1680611ca257506001600160a01b0384165f9081526003602052604090205460ff165b15611cf4576001600160a01b0383165f9081526002602052604090205460ff1680611ce457506001600160a01b0384165f9081526002602052604090205460ff165b15611cf057505f611cf4565b5060015b8015611da1575f6103e8611d09603285612dfb565b611d139190612e26565b6001600160a01b0386165f9081526020819052604081208054869003905573e58b33c813ac4077bd2519de90fccb189a19fa7190527f1338836141591a3221ceb363e91a05d18b16e6fa044cb293d015e6c316402dc78054820190559050611d7b8184612de8565b6001600160a01b0385165f9081526020819052604090208054820190559250611dce9050565b6001600160a01b038085165f90815260208190526040808220805486900390559185168152208054830190555b826001600160a01b0316846001600160a01b03165f80516020612fa783398151915284604051611e0091815260200190565b60405180910390a350505050565b6001600160a01b0382165f90815260208190526040902054811115611e465760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612fa7833981519152910160405180910390a35050565b611e99612c63565b611ea1612c63565b6040805180820182525f8082526020808301829052835160808101855282815290810182905292830181905260608301529042611ede8989612914565b67ffffffffffffffff1688602001818151611ef99190612e39565b6001600160601b031690525065ffffffffffff811660208a0152606086015115611fa9575f805f611f2989612956565b925092509250826001600160801b03168a602001818151611f4a9190612de8565b9052508015611f9e5782895f01818151611f649190612eb2565b6001600160801b0316905250604089018051839190611f84908390612ed2565b65ffffffffffff908116909152851660208b015250611fa5565b5f60608a01525b5050505b509597949550929392505050565b5f670de0b6b3a7640000611fcb84846129e7565b611fd59086612dfb565b611fdf9190612e26565b949350505050565b305f9081526020819052604081205482111561201657604051635e36b3df60e01b815260040160405180910390fd5b506001600160a01b0382165f818152602081815260408083208054860190553080845292819020805486900390555184815260019392915f80516020612fa7833981519152910160405180910390a392915050565b612073612c63565b604080518082019091525f808252602082015261208e612c63565b604080516080810182525f8082526020820181905291810182905260608101919091526120de6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b608088015188516120ef9190612ef1565b65ffffffffffff168b65ffffffffffff161061225c578851612112908c90612ed2565b65ffffffffffff1681526020808a0151908b015161213a91906001600160601b031688611fb7565b602082015289516001600160601b031660408201819052815160608a0151909161216c9165ffffffffffff1690612dfb565b6121769190612e26565b6001600160601b03166040808c01919091528151898201519183015190916121a89165ffffffffffff90911690612dfb565b6121b29190612e26565b6060820181905260208201516121c9908890612dfb565b6121d39190612e26565b6080820181905260208a01511115612245575f81608001518a602001516121fa9190612de8565b90506040518060800160405280826001600160801b031681526020018d65ffffffffffff1681526020018a6080015165ffffffffffff16815260200160011515815250975050612250565b608081015160208a01525b65ffffffffffff8b1688525b50979996985094965092949350505050565b5f805f805f85875af19050806122c05760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b5f811561235a57600b54604080516080810182526005546001600160801b0381168252600160801b810465ffffffffffff9081166020840152600160b01b82041692820192909252600160e01b90910460ff161515606082015261071c9161232c91612a05565b60075460045461234c91600160601b90046001600160601b0316906129e7565b670de0b6b3a764000061286a565b60125460408051608081018252600c546001600160801b0381168252600160801b810465ffffffffffff9081166020840152600160b01b82041692820192909252600160e01b90910460ff161515606082015261071c916123ba91612a05565b600e5460045461234c91600160601b90046001600160601b0316906129e7565b919050565b6013548015612619575f6123f1612a27565b9050815f62093a806124068362015180612f10565b6001600160601b03166124199190612e26565b90505f846001600160601b0316600454856124349190612dfb565b61243e9190612e26565b90505f612454846001600160601b031686612b01565b90505f61246462093a8042612e80565b905081156125c3576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600780546001600160c01b03199081168617600160601b90950294909417905560088054909316909117909155600980546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c9052600a805465ffffffffffff191683179055600b8c9055885196870189524290811680885287870181905262093a80888b015262015180888601526107089790980196909652600680549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000002a300000000127560671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612612565b6125d630866001600160601b0316611e0e565b6125e362093a8042612e80565b600a805465ffffffffffff191665ffffffffffff92909216919091179055600780546001600160601b03191690555b5050505050505b505f601355565b6014546001600160601b03811615612863575f61263b612b7e565b9050815f62093a806126508362015180612f10565b6001600160601b03166126639190612e26565b90505f846001600160601b03166004548561267e9190612dfb565b6126889190612e26565b90505f61269e846001600160601b031686612b01565b90505f6126ae62093a8042612e80565b9050811561280d576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600e80546001600160c01b03199081168617600160601b909502949094179055600f8054909316909117909155601080546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c90526011805465ffffffffffff19168317905560128c9055885196870189524290811680885287870181905262093a80888b015262015180888601526107089790980196909652600d80549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000002a300000000127560671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a161285c565b61282030866001600160601b0316611e0e565b61282d62093a8042612e80565b6011805465ffffffffffff191665ffffffffffff92909216919091179055600e80546001600160601b03191690555b5050505050505b505f601455565b5f80805f19858709858702925082811083820303915050805f0361289e575f8411612893575f80fd5b5082900490506107ef565b8084116128a9575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f80836020015165ffffffffffff164261292e9190612de8565b9050836040015165ffffffffffff168184602001516001600160601b0316611fd59190612dfb565b5f805f836060015161296f57505f9150819050806129e0565b5f8460200151426129809190612ed2565b90505f856040015165ffffffffffff168265ffffffffffff161090505f816129a95786516129d7565b866040015165ffffffffffff168365ffffffffffff16885f01516129cd9190612f3b565b6129d79190612f5e565b95509193509150505b9193909250565b5f816129fb84670de0b6b3a7640000612dfb565b6107ef9190612e26565b5f80612a1083612956565b50506001600160801b03169050611fdf8185612de8565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f80604051630240bc6b60e21b81525f80600483875afa905080612a6e575f80fd5b5060205f803e60208060203e50505f516020517f000000000000000000000000000000000000000000000000000000000000000015612ad357612acc816001600160701b0316670de0b6b3a7640000846001600160701b031661286a565b9350612afb565b612af8826001600160701b0316670de0b6b3a7640000836001600160701b031661286a565b93505b50505090565b6004545f9081612b118583612de8565b612b2347670de0b6b3a7640000612dfb565b612b2d9190612e26565b90505f82612b3b8688612dfb565b612b4d47670de0b6b3a7640000612dfb565b612b579190612e80565b612b619190612e26565b905080821015612b72576001612b74565b5f5b9695505050505050565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f805f604051630240bc6b60e21b81525f80600483885afa80612bc4575f80fd5b5060205f803e60208060203e5f51935060205192506318160ddd60e01b602082015260205f600460208401885afa50505f5190507f000000000000000000000000000000000000000000000000000000000000000015612c4b57612c44612c2c846002612f83565b6001600160701b0316670de0b6b3a76400008361286a565b9450612c5c565b612c59612c2c836002612f83565b94505b5050505090565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290565b5f602080835283518060208501525f5b81811015612cbc57858101830151858201604001528201612ca0565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146123da575f80fd5b5f8060408385031215612d03575f80fd5b612d0c83612cdc565b946020939093013593505050565b5f805f60608486031215612d2c575f80fd5b612d3584612cdc565b9250612d4360208501612cdc565b9150604084013590509250925092565b5f60208284031215612d63575f80fd5b5035919050565b5f60208284031215612d7a575f80fd5b6107ef82612cdc565b5f8060408385031215612d94575f80fd5b50508035926020909101359150565b5f8060408385031215612db4575f80fd5b612dbd83612cdc565b9150612dcb60208401612cdc565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561071c5761071c612dd4565b808202811582820484141761071c5761071c612dd4565b634e487b7160e01b5f52601260045260245ffd5b5f82612e3457612e34612e12565b500490565b6001600160601b03828116828216039080821115612e5957612e59612dd4565b5092915050565b6001600160601b03818116838216019080821115612e5957612e59612dd4565b8082018082111561071c5761071c612dd4565b5f60208284031215612ea3575f80fd5b815180151581146107ef575f80fd5b6001600160801b03828116828216039080821115612e5957612e59612dd4565b65ffffffffffff828116828216039080821115612e5957612e59612dd4565b65ffffffffffff818116838216019080821115612e5957612e59612dd4565b6001600160601b03818116838216028082169190828114612f3357612f33612dd4565b505092915050565b6001600160801b03818116838216028082169190828114612f3357612f33612dd4565b5f6001600160801b0380841680612f7757612f77612e12565b92169190910492915050565b6001600160701b03818116838216028082169190828114612f3357612f33612dd456feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220caf4e3b4220f06c011dec8269de8b0005be17a0e02575fba2b57079b228073c064736f6c63430008170033

Deployed Bytecode

0x608060405260043610610164575f3560e01c806364c9ec6f116100cd578063bedd12a511610087578063d926de1c11610062578063d926de1c146104bb578063db006a75146104da578063dd62ed3e146104f9578063df8980b31461053d575f80fd5b8063bedd12a51461046d578063c5b748c014610493578063d7ccfb0b146104a7575f80fd5b806364c9ec6f146103b357806370a08231146103bb5780637b16c21e146103ef57806395d89b41146104035780639f7b45791461042f578063a9059cbb1461044e575f80fd5b806323b872dd1161011e57806323b872dd1461030157806326749e8714610320578063313ce5671461033457806342966c681461034f5780634febf53d1461036e5780635d03147a1461038d575f80fd5b806301339c211461016f578063031bee001461018557806306fdde0314610239578063095ea7b31461026e57806316f0115b1461029d57806318160ddd146102e3575f80fd5b3661016b57005b5f80fd5b34801561017a575f80fd5b5061018361055c565b005b348015610190575f80fd5b5061019961060c565b6040805184516001600160601b0390811682526020808701518216818401528684015182168385015260608088015183168185015260809788015190921687840152855165ffffffffffff90811660a08501529581015160c08401528451861660e0840152840151851661010083015291830151841661012082015290820151831661014082015292015116610160820152610180015b60405180910390f35b348015610244575f80fd5b506040805180820190915260048152634b6f746f60e01b60208201525b6040516102309190612c90565b348015610279575f80fd5b5061028d610288366004612cf2565b6106f5565b6040519015158152602001610230565b3480156102a8575f80fd5b507f00000000000000000000000047287d8d7c1a5854aa11868e7d2186b138069f845b6040516001600160a01b039091168152602001610230565b3480156102ee575f80fd5b506004545b604051908152602001610230565b34801561030c575f80fd5b5061028d61031b366004612d1a565b610722565b34801561032b575f80fd5b506101996107f6565b34801561033f575f80fd5b5060405160128152602001610230565b34801561035a575f80fd5b5061028d610369366004612d53565b6108df565b348015610379575f80fd5b50610183610388366004612d6a565b610917565b348015610398575f80fd5b5073946ef43867225695e29241813a8f41519634b36b6102cb565b6102f3610996565b3480156103c6575f80fd5b506102f36103d5366004612d6a565b6001600160a01b03165f9081526020819052604090205490565b3480156103fa575f80fd5b506102f36110ee565b34801561040e575f80fd5b506040805180820190915260048152634b4f544f60e01b6020820152610261565b34801561043a575f80fd5b50610183610449366004612d83565b6110fd565b348015610459575f80fd5b5061028d610468366004612cf2565b61120d565b348015610478575f80fd5b5073e58b33c813ac4077bd2519de90fccb189a19fa716102cb565b34801561049e575f80fd5b506102f3611254565b3480156104b2575f80fd5b506102f3611275565b3480156104c6575f80fd5b506101836104d5366004612d6a565b611280565b3480156104e5575f80fd5b506102f36104f4366004612d53565b61130d565b348015610504575f80fd5b506102f3610513366004612da3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610548575f80fd5b506102f3610557366004612d53565b611398565b3373946ef43867225695e29241813a8f41519634b36b1461059057604051635fc483c560e01b815260040160405180910390fd5b601554610100900460ff16156105b9576040516319f4db0f60e31b815260040160405180910390fd5b6105c1611b8c565b6015805461ff0019166101001790556040517feca0dfbda743d141662328d4d48393e344b2c60df0430297221df823f2926dba906106029042815260200190565b60405180910390a1565b610614612c63565b604080518082019091525f808252602082015261062f612c63565b50506040805160a080820183526007546001600160601b038082168452600160601b91829004811660208086019190915260085480831686880152839004821660608087019190915260095490921660808087019190915286518088018852600a5465ffffffffffff9081168252600b5482850152885196870189526006548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b335f9081526001602081815260408084206001600160a01b03871685529091529091208290555b92915050565b5f6001600160a01b0383161580610737575081155b1561075557604051632f35253160e01b815260040160405180910390fd5b6001600160a01b03841633146107e0576001600160a01b0384165f9081526001602090815260408083203384529091529020548211156107a8576040516358d246fb60e11b815260040160405180910390fd5b6001600160a01b0384165f908152600160209081526040808320338452909152812080548492906107da908490612de8565b90915550505b6107eb848484611c2d565b5060015b9392505050565b6107fe612c63565b604080518082019091525f8082526020820152610819612c63565b50506040805160a08082018352600e546001600160601b038082168452600160601b918290048116602080860191909152600f548083168688015283900482166060808701919091526010549092166080808701919091528651808801885260115465ffffffffffff90811682526012548285015288519687018952600d548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b5f6108ea3383611e0e565b506040518181526001905f9033905f80516020612fa78339815191529060200160405180910390a3919050565b3373946ef43867225695e29241813a8f41519634b36b1461094b57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260026020526040808220805460ff19166001179055517fec2dffa455deca3e695cce255e2b110b5ca334fb5b166f3159bbaad319ce0f1b9190a250565b6015545f9060ff166002036109be5760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff164211156109f55760405162b5f6bf60e41b815260040160405180910390fd5b6007546001600160601b0316156110d4575f60076040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f600a6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f60056040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050610dcb60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786611e91565b809650819850829750839950505050505f610df8866020015188602001516001600160601b031685611fb7565b905080610e0d34670de0b6b3a7640000612dfb565b610e179190612e26565b6008549098506001600160601b0316881115610e46576040516305c250cf60e11b815260040160405180910390fd5b87875f01818151610e579190612e39565b6001600160601b0316905250608087018051349190610e77908390612e60565b6001600160601b0316905250606087018051899190610e97908390612e60565b6001600160601b0316905250602087018051899190610eb7908390612e60565b6001600160601b03169052505f610ece338a611fe7565b905080610eee5760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a2610f3783898989898961206b565b8351600780546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600880546060808d015193891691909616179187168602919091179055608098890151600980546001600160601b0319908116929097169190911790558751600a805465ffffffffffff191665ffffffffffff92831617905597820151600b55865160068054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b93871693909302929092179055815160058054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b91151591909102179055506110de9650505050505050565b6110de333461226e565b6015805460ff1916600117905590565b5f6110f85f6122c5565b905090565b3373946ef43867225695e29241813a8f41519634b36b1480159061113557503373e58b33c813ac4077bd2519de90fccb189a19fa7114155b1561115357604051636edaef2f60e11b815260040160405180910390fd5b600a544265ffffffffffff9091161115611180576040516301f2595960e01b815260040160405180910390fd5b305f9081526020819052604090205480156111d457305f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612fa7833981519152910160405180910390a35b5f6111df8385612e80565b90506111ec333083610722565b50601384905560148390556111ff6123df565b611207612620565b50505050565b5f6001600160a01b0383161580611222575081155b1561124057604051632f35253160e01b815260040160405180910390fd5b61124b338484611c2d565b50600192915050565b6004545f9061126b47670de0b6b3a7640000612dfb565b6110f89190612e26565b5f6110f860016122c5565b3373946ef43867225695e29241813a8f41519634b36b146112b457604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260036020908152604091829020805460ff1916600117905590519182527f10cdbb821aa416c854add806e1d7e8138afe2a538921cebe99b1351362ae38b2910160405180910390a150565b5f8061132447670de0b6b3a764000060045461286a565b90506113398184670de0b6b3a764000061286a565b91506113453384611e0e565b61134f338361226e565b604080518481526020810184905290810182905233907fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469060600160405180910390a250919050565b6015545f9060ff166002036113c05760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff1916600217905560115465ffffffffffff164211156113f75760405162b5f6bf60e41b815260040160405180910390fd5b600e546001600160601b031615611b7a576040516323b872dd60e01b815233600482015273e58b33c813ac4077bd2519de90fccb189a19fa716024820152604481018390527f00000000000000000000000047287d8d7c1a5854aa11868e7d2186b138069f846001600160a01b0316906323b872dd906064016020604051808303815f875af115801561148c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114b09190612e93565b505f600e6040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f60116040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f600c6040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050611876600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786611e91565b809650819850829750839950505050505f6118a3866020015188602001516001600160601b031685611fb7565b9050806118b88a670de0b6b3a7640000612dfb565b6118c29190612e26565b600f549098506001600160601b03168811156118f1576040516305c250cf60e11b815260040160405180910390fd5b87875f018181516119029190612e39565b6001600160601b03169052506080870180518a9190611922908390612e60565b6001600160601b0316905250606087018051899190611942908390612e60565b6001600160601b0316905250602087018051899190611962908390612e60565b6001600160601b03169052505f611979338a611fe7565b9050806119995760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a26119e283898989898961206b565b8351600e80546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600f80546060808d015193891691909616179187168602919091179055608098890151601080546001600160601b03199081169290971691909117905587516011805465ffffffffffff191665ffffffffffff928316179055978201516012558651600d8054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b938716939093029290921790558151600c8054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b9115159190910217905550505050505050505b6015805460ff19166001179055919050565b5f805f306001600160a01b03166001600160a01b031681526020019081526020015f2054905060405163f305d71960e01b81526001600160a01b03301660048201528160248201525f60448201525f606482015273e58b33c813ac4077bd2519de90fccb189a19fa7160848201524260a48201525f8060c4833031737a250d5630b4cf539739df2c5dacb4c659f2488d5af1905080611c29575f80fd5b5050565b6001600160a01b0383165f90815260208190526040902054811115611c655760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f9081526003602052604081205460ff1680611ca257506001600160a01b0384165f9081526003602052604090205460ff165b15611cf4576001600160a01b0383165f9081526002602052604090205460ff1680611ce457506001600160a01b0384165f9081526002602052604090205460ff165b15611cf057505f611cf4565b5060015b8015611da1575f6103e8611d09603285612dfb565b611d139190612e26565b6001600160a01b0386165f9081526020819052604081208054869003905573e58b33c813ac4077bd2519de90fccb189a19fa7190527f1338836141591a3221ceb363e91a05d18b16e6fa044cb293d015e6c316402dc78054820190559050611d7b8184612de8565b6001600160a01b0385165f9081526020819052604090208054820190559250611dce9050565b6001600160a01b038085165f90815260208190526040808220805486900390559185168152208054830190555b826001600160a01b0316846001600160a01b03165f80516020612fa783398151915284604051611e0091815260200190565b60405180910390a350505050565b6001600160a01b0382165f90815260208190526040902054811115611e465760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612fa7833981519152910160405180910390a35050565b611e99612c63565b611ea1612c63565b6040805180820182525f8082526020808301829052835160808101855282815290810182905292830181905260608301529042611ede8989612914565b67ffffffffffffffff1688602001818151611ef99190612e39565b6001600160601b031690525065ffffffffffff811660208a0152606086015115611fa9575f805f611f2989612956565b925092509250826001600160801b03168a602001818151611f4a9190612de8565b9052508015611f9e5782895f01818151611f649190612eb2565b6001600160801b0316905250604089018051839190611f84908390612ed2565b65ffffffffffff908116909152851660208b015250611fa5565b5f60608a01525b5050505b509597949550929392505050565b5f670de0b6b3a7640000611fcb84846129e7565b611fd59086612dfb565b611fdf9190612e26565b949350505050565b305f9081526020819052604081205482111561201657604051635e36b3df60e01b815260040160405180910390fd5b506001600160a01b0382165f818152602081815260408083208054860190553080845292819020805486900390555184815260019392915f80516020612fa7833981519152910160405180910390a392915050565b612073612c63565b604080518082019091525f808252602082015261208e612c63565b604080516080810182525f8082526020820181905291810182905260608101919091526120de6040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b608088015188516120ef9190612ef1565b65ffffffffffff168b65ffffffffffff161061225c578851612112908c90612ed2565b65ffffffffffff1681526020808a0151908b015161213a91906001600160601b031688611fb7565b602082015289516001600160601b031660408201819052815160608a0151909161216c9165ffffffffffff1690612dfb565b6121769190612e26565b6001600160601b03166040808c01919091528151898201519183015190916121a89165ffffffffffff90911690612dfb565b6121b29190612e26565b6060820181905260208201516121c9908890612dfb565b6121d39190612e26565b6080820181905260208a01511115612245575f81608001518a602001516121fa9190612de8565b90506040518060800160405280826001600160801b031681526020018d65ffffffffffff1681526020018a6080015165ffffffffffff16815260200160011515815250975050612250565b608081015160208a01525b65ffffffffffff8b1688525b50979996985094965092949350505050565b5f805f805f85875af19050806122c05760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b5f811561235a57600b54604080516080810182526005546001600160801b0381168252600160801b810465ffffffffffff9081166020840152600160b01b82041692820192909252600160e01b90910460ff161515606082015261071c9161232c91612a05565b60075460045461234c91600160601b90046001600160601b0316906129e7565b670de0b6b3a764000061286a565b60125460408051608081018252600c546001600160801b0381168252600160801b810465ffffffffffff9081166020840152600160b01b82041692820192909252600160e01b90910460ff161515606082015261071c916123ba91612a05565b600e5460045461234c91600160601b90046001600160601b0316906129e7565b919050565b6013548015612619575f6123f1612a27565b9050815f62093a806124068362015180612f10565b6001600160601b03166124199190612e26565b90505f846001600160601b0316600454856124349190612dfb565b61243e9190612e26565b90505f612454846001600160601b031686612b01565b90505f61246462093a8042612e80565b905081156125c3576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600780546001600160c01b03199081168617600160601b90950294909417905560088054909316909117909155600980546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c9052600a805465ffffffffffff191683179055600b8c9055885196870189524290811680885287870181905262093a80888b015262015180888601526107089790980196909652600680549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000002a300000000127560671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612612565b6125d630866001600160601b0316611e0e565b6125e362093a8042612e80565b600a805465ffffffffffff191665ffffffffffff92909216919091179055600780546001600160601b03191690555b5050505050505b505f601355565b6014546001600160601b03811615612863575f61263b612b7e565b9050815f62093a806126508362015180612f10565b6001600160601b03166126639190612e26565b90505f846001600160601b03166004548561267e9190612dfb565b6126889190612e26565b90505f61269e846001600160601b031686612b01565b90505f6126ae62093a8042612e80565b9050811561280d576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600e80546001600160c01b03199081168617600160601b909502949094179055600f8054909316909117909155601080546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c90526011805465ffffffffffff19168317905560128c9055885196870189524290811680885287870181905262093a80888b015262015180888601526107089790980196909652600d80549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000002a300000000127560671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a161285c565b61282030866001600160601b0316611e0e565b61282d62093a8042612e80565b6011805465ffffffffffff191665ffffffffffff92909216919091179055600e80546001600160601b03191690555b5050505050505b505f601455565b5f80805f19858709858702925082811083820303915050805f0361289e575f8411612893575f80fd5b5082900490506107ef565b8084116128a9575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f80836020015165ffffffffffff164261292e9190612de8565b9050836040015165ffffffffffff168184602001516001600160601b0316611fd59190612dfb565b5f805f836060015161296f57505f9150819050806129e0565b5f8460200151426129809190612ed2565b90505f856040015165ffffffffffff168265ffffffffffff161090505f816129a95786516129d7565b866040015165ffffffffffff168365ffffffffffff16885f01516129cd9190612f3b565b6129d79190612f5e565b95509193509150505b9193909250565b5f816129fb84670de0b6b3a7640000612dfb565b6107ef9190612e26565b5f80612a1083612956565b50506001600160801b03169050611fdf8185612de8565b5f807f00000000000000000000000047287d8d7c1a5854aa11868e7d2186b138069f8490505f80604051630240bc6b60e21b81525f80600483875afa905080612a6e575f80fd5b5060205f803e60208060203e50505f516020517f000000000000000000000000000000000000000000000000000000000000000115612ad357612acc816001600160701b0316670de0b6b3a7640000846001600160701b031661286a565b9350612afb565b612af8826001600160701b0316670de0b6b3a7640000836001600160701b031661286a565b93505b50505090565b6004545f9081612b118583612de8565b612b2347670de0b6b3a7640000612dfb565b612b2d9190612e26565b90505f82612b3b8688612dfb565b612b4d47670de0b6b3a7640000612dfb565b612b579190612e80565b612b619190612e26565b905080821015612b72576001612b74565b5f5b9695505050505050565b5f807f00000000000000000000000047287d8d7c1a5854aa11868e7d2186b138069f8490505f805f604051630240bc6b60e21b81525f80600483885afa80612bc4575f80fd5b5060205f803e60208060203e5f51935060205192506318160ddd60e01b602082015260205f600460208401885afa50505f5190507f000000000000000000000000000000000000000000000000000000000000000115612c4b57612c44612c2c846002612f83565b6001600160701b0316670de0b6b3a76400008361286a565b9450612c5c565b612c59612c2c836002612f83565b94505b5050505090565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290565b5f602080835283518060208501525f5b81811015612cbc57858101830151858201604001528201612ca0565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146123da575f80fd5b5f8060408385031215612d03575f80fd5b612d0c83612cdc565b946020939093013593505050565b5f805f60608486031215612d2c575f80fd5b612d3584612cdc565b9250612d4360208501612cdc565b9150604084013590509250925092565b5f60208284031215612d63575f80fd5b5035919050565b5f60208284031215612d7a575f80fd5b6107ef82612cdc565b5f8060408385031215612d94575f80fd5b50508035926020909101359150565b5f8060408385031215612db4575f80fd5b612dbd83612cdc565b9150612dcb60208401612cdc565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561071c5761071c612dd4565b808202811582820484141761071c5761071c612dd4565b634e487b7160e01b5f52601260045260245ffd5b5f82612e3457612e34612e12565b500490565b6001600160601b03828116828216039080821115612e5957612e59612dd4565b5092915050565b6001600160601b03818116838216019080821115612e5957612e59612dd4565b8082018082111561071c5761071c612dd4565b5f60208284031215612ea3575f80fd5b815180151581146107ef575f80fd5b6001600160801b03828116828216039080821115612e5957612e59612dd4565b65ffffffffffff828116828216039080821115612e5957612e59612dd4565b65ffffffffffff818116838216019080821115612e5957612e59612dd4565b6001600160601b03818116838216028082169190828114612f3357612f33612dd4565b505092915050565b6001600160801b03818116838216028082169190828114612f3357612f33612dd4565b5f6001600160801b0380841680612f7757612f77612e12565b92169190910492915050565b6001600160701b03818116838216028082169190828114612f3357612f33612dd456feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220caf4e3b4220f06c011dec8269de8b0005be17a0e02575fba2b57079b228073c064736f6c63430008170033

Deployed Bytecode Sourcemap

936:25720:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12742:232;;;;;;;;;;;;;:::i;:::-;;11438:203;;;;;;;;;;;;;:::i;:::-;;;;420:13:7;;-1:-1:-1;;;;;416:22:7;;;398:41;;499:4;487:17;;;481:24;477:33;;455:20;;;448:63;559:17;;;553:24;549:33;;527:20;;;520:63;643:4;631:17;;;625:24;621:33;;599:20;;;592:63;715:4;703:17;;;697:24;693:33;;;671:20;;;664:63;801:13;;746:14;797:22;;;791:3;776:19;;769:51;863:17;;;857:24;851:3;836:19;;829:53;923:13;;919:22;;913:3;898:19;;891:51;989:17;;983:24;979:33;;973:3;958:19;;951:62;1060:17;;;1054:24;1050:33;;1044:3;1029:19;;1022:62;1131:17;;;1125:24;1121:33;;1115:3;1100:19;;1093:62;1202:17;;1196:24;1192:33;1186:3;1171:19;;1164:62;340:3;325:19;11438:203:2;;;;;;;;9532:80;;;;;;;;;;-1:-1:-1;9601:4:2;;;;;;;;;;;;-1:-1:-1;;;9601:4:2;;;;9532:80;;;;;;;:::i;4350:192::-;;;;;;;;;;-1:-1:-1;4350:192:2;;;;;:::i;:::-;;:::i;:::-;;;2392:14:7;;2385:22;2367:41;;2355:2;2340:18;4350:192:2;2227:187:7;10637:76:2;;;;;;;;;;-1:-1:-1;10702:4:2;10637:76;;;-1:-1:-1;;;;;2583:32:7;;;2565:51;;2553:2;2538:18;10637:76:2;2419:203:7;9913:89:2;;;;;;;;;;-1:-1:-1;9983:12:2;;9913:89;;;2773:25:7;;;2761:2;2746:18;9913:89:2;2627:177:7;3922:422:2;;;;;;;;;;-1:-1:-1;3922:422:2;;;;;:::i;:::-;;:::i;11647:211::-;;;;;;;;;;;;;:::i;9784:80::-;;;;;;;;;;-1:-1:-1;9784:80:2;;2093:2;3284:36:7;;3272:2;3257:18;9784:80:2;3142:184:7;9230:183:2;;;;;;;;;;-1:-1:-1;9230:183:2;;;;;:::i;:::-;;:::i;12249:165::-;;;;;;;;;;-1:-1:-1;12249:165:2;;;;;:::i;:::-;;:::i;10884:82::-;;;;;;;;;;-1:-1:-1;2520:42:2;10884:82;;4726:1896;;;:::i;10118:106::-;;;;;;;;;;-1:-1:-1;10118:106:2;;;;;:::i;:::-;-1:-1:-1;;;;;10200:17:2;10174:7;10200:17;;;;;;;;;;;;10118:106;11120:105;;;;;;;;;;;;;:::i;9655:84::-;;;;;;;;;;-1:-1:-1;9726:6:2;;;;;;;;;;;;-1:-1:-1;;;9726:6:2;;;;9655:84;;13236:991;;;;;;;;;;-1:-1:-1;13236:991:2;;;;;:::i;:::-;;:::i;3695:221::-;;;;;;;;;;-1:-1:-1;3695:221:2;;;;;:::i;:::-;;:::i;11864:93::-;;;;;;;;;;-1:-1:-1;2611:42:2;11864:93;;11302:130;;;;;;;;;;;;;:::i;11012:102::-;;;;;;;;;;;;;:::i;12515:159::-;;;;;;;;;;-1:-1:-1;12515:159:2;;;;;:::i;:::-;;:::i;8719:405::-;;;;;;;;;;-1:-1:-1;8719:405:2;;;;;:::i;:::-;;:::i;10441:140::-;;;;;;;;;;-1:-1:-1;10441:140:2;;;;;:::i;:::-;-1:-1:-1;;;;;10547:18:2;;;10521:7;10547:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;10441:140;6628:1864;;;;;;;;;;-1:-1:-1;6628:1864:2;;;;;:::i;:::-;;:::i;12742:232::-;12783:10;2520:42;12783:19;12779:43;;12811:11;;-1:-1:-1;;;12811:11:2;;;;;;;;;;;12779:43;12836:8;;;;;;;12832:38;;;12853:17;;-1:-1:-1;;;12853:17:2;;;;;;;;;;;12832:38;12880:22;:20;:22::i;:::-;12912:8;:15;;-1:-1:-1;;12912:15:2;;;;;12942:25;;;;;;12951:15;2773:25:7;;2761:2;2746:18;;2627:177;12942:25:2;;;;;;;;12742:232::o;11438:203::-;11507:28;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;11565:26:2;;:::i;:::-;-1:-1:-1;;11607:27:2;;;;;;;;;11615:6;11607:27;-1:-1:-1;;;;;11607:27:2;;;;;-1:-1:-1;;;11607:27:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11623:4;11607:27;;;;;;;;;;;;;;;;;;;;11629:4;11607:27;;;;;;-1:-1:-1;;;11607:27:2;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11607:27:2;;;;;;;;;;;-1:-1:-1;;;11607:27:2;;;;;;;;;;;;;-1:-1:-1;11607:27:2;11438:203::o;4350:192::-;4457:10;4417:12;4477:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4477:28:2;;;;;;;;;;:37;;;4350:192;;;;;:::o;3922:422::-;4004:12;-1:-1:-1;;;;;4032:17:2;;;;:32;;-1:-1:-1;4053:11:2;;4032:32;4028:62;;;4073:17;;-1:-1:-1;;;4073:17:2;;;;;;;;;;;4028:62;-1:-1:-1;;;;;4104:19:2;;4113:10;4104:19;4100:178;;-1:-1:-1;;;;;4143:18:2;;;;;;:11;:18;;;;;;;;4162:10;4143:30;;;;;;;;:39;-1:-1:-1;4139:74:2;;;4191:22;;-1:-1:-1;;;4191:22:2;;;;;;;;;;;4139:74;-1:-1:-1;;;;;4227:18:2;;;;;;:11;:18;;;;;;;;4246:10;4227:30;;;;;;;:40;;4261:6;;4227:18;:40;;4261:6;;4227:40;:::i;:::-;;;;-1:-1:-1;;4100:178:2;4287:29;4297:5;4304:3;4309:6;4287:9;:29::i;:::-;-1:-1:-1;4333:4:2;3922:422;;;;;;:::o;11647:211::-;11718:28;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;11776:26:2;;:::i;:::-;-1:-1:-1;;11818:33:2;;;;;;;;;11826:8;11818:33;-1:-1:-1;;;;;11818:33:2;;;;;-1:-1:-1;;;11818:33:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11836:6;11818:33;;;;;;;;;;;;;;;;;;;;11844:6;11818:33;;;;;;-1:-1:-1;;;11818:33:2;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11818:33:2;;;;;;;;;;;-1:-1:-1;;;11818:33:2;;;;;;;;;;;;;-1:-1:-1;11818:33:2;11647:211::o;9230:183::-;9278:12;9302:25;9308:10;9320:6;9302:5;:25::i;:::-;-1:-1:-1;9366:40:2;;2773:25:7;;;9347:4:2;;9395:1;;9375:10;;-1:-1:-1;;;;;;;;;;;9366:40:2;2761:2:7;2746:18;9366:40:2;;;;;;;9230:183;;;:::o;12249:165::-;12303:10;2520:42;12303:19;12299:43;;12331:11;;-1:-1:-1;;;12331:11:2;;;;;;;;;;;12299:43;-1:-1:-1;;;;;12352:15:2;;;;;;:9;:15;;;;;;:22;;-1:-1:-1;;12352:22:2;12370:4;12352:22;;;12389:18;;;12352:15;12389:18;12249:165;:::o;4726:1896::-;2946:6;;4771:14;;2946:6;;2956:1;2946:11;2942:36;;2966:12;;-1:-1:-1;;;2966:12:2;;;;;;;;;;;2942:36;2988:6;:10;;-1:-1:-1;;2988:10:2;2997:1;2988:10;;;4819:4:::1;:15:::0;::::1;;4801;:33;4797:60;;;4843:14;;-1:-1:-1::0;;;4843:14:2::1;;;;;;;;;;;4797:60;4871:6;:15:::0;-1:-1:-1;;;;;4871:15:2::1;:20:::0;4867:1749:::1;;4978:36;5017:6;4978:45;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;-1:-1:-1::0;;;;;4978:45:2::1;;;::::0;::::1;;;5037:32;5072:4;5037:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5090:32;5125:4;5090:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5143:44;5190:10;5143:57;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5143:57:2::1;-1:-1:-1::0;;;;;5143:57:2::1;-1:-1:-1::0;;;;;5143:57:2::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5214:15;5232:12;;5214:30;;5258:11;5279:15;5258:37;;5421:55;5442:4;5421:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;5448:7;5457:5;5464:11;5421:20;:55::i;:::-;5382:94;;;;;;;;;;;;;;;;5491:13;5507:77;5534:5;:21;;;5557:7;:17;;;-1:-1:-1::0;;;;;5507:77:2::1;5576:7;5507:26;:77::i;:::-;5491:93:::0;-1:-1:-1;5491:93:2;5609:16:::1;:9;5621:4;5609:16;:::i;:::-;:24;;;;:::i;:::-;5661:16:::0;;5599:35;;-1:-1:-1;;;;;;5661:16:2::1;5652:25:::0;::::1;5648:49;;;5686:11;;-1:-1:-1::0;;;5686:11:2::1;;;;;;;;;;;5648:49;5778:6;5751:7;:16;;:34;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5751:34:2::1;::::0;;-1:-1:-1;5799:17:2::1;::::0;::::1;:38:::0;;5827:9:::1;::::0;5799:17;:38:::1;::::0;5827:9;;5799:38:::1;:::i;:::-;-1:-1:-1::0;;;;;5799:38:2::1;::::0;;-1:-1:-1;5851:12:2::1;::::0;::::1;:30:::0;;5874:6;;5851:12;:30:::1;::::0;5874:6;;5851:30:::1;:::i;:::-;-1:-1:-1::0;;;;;5851:30:2::1;::::0;;-1:-1:-1;5895:17:2::1;::::0;::::1;:35:::0;;5923:6;;5895:17;:35:::1;::::0;5923:6;;5895:35:::1;:::i;:::-;-1:-1:-1::0;;;;;5895:35:2::1;::::0;;-1:-1:-1;5945:12:2::1;5960:25;5966:10;5978:6:::0;5960:5:::1;:25::i;:::-;5945:40;;6004:7;5999:33;;6020:12;;-1:-1:-1::0;;;6020:12:2::1;;;;;;;;;;;5999:33;6051:31;::::0;;5483:25:7;;;5539:2;5524:18;;5517:34;;;6056:10:2::1;::::0;6051:31:::1;::::0;5456:18:7;6051:31:2::1;;;;;;;6211:70;6231:4;6237:7;6246:5;6253;6260:11;6273:7;6211:19;:70::i;:::-;6337:16:::0;;:6:::1;:16:::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;6337:16:2;;::::1;-1:-1:-1::0;;;;;;6337:16:2;;;;-1:-1:-1;;;6337:16:2;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;;6337:16:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;6367:12;;:4:::1;:12:::0;;-1:-1:-1;;6367:12:2::1;;::::0;;::::1;;::::0;;;;::::1;::::0;;;6393;;:4:::1;:12:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;6393:12:2;;::::1;::::0;;;;;;;;-1:-1:-1;;;6393:12:2;;::::1;::::0;;;::::1;;::::0;;;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;6393:12:2;;;;;-1:-1:-1;;;6393:12:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;6393:12:2::1;-1:-1:-1::0;;;6393:12:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;6419:24;;-1:-1:-1;6419:24:2;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;;6419:24:2;;::::1;-1:-1:-1::0;;;;;;6419:24:2;;;;;;;-1:-1:-1;;;6419:24:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;6419:24:2;-1:-1:-1;;;6419:24:2;;;::::1;;-1:-1:-1::0;;;;6419:24:2;;;;;-1:-1:-1;;;6419:24:2;::::1;;::::0;;;::::1;;::::0;;-1:-1:-1;4867:1749:2::1;::::0;-1:-1:-1;;;;;;;4867:1749:2::1;;6551:54;6583:10;6595:9;6551:31;:54::i;:::-;3019:6:::0;:10;;-1:-1:-1;;3019:10:2;3028:1;3019:10;;;4726:1896;:::o;11120:105::-;11166:7;11192:26;11212:5;11192:19;:26::i;:::-;11185:33;;11120:105;:::o;13236:991::-;13320:10;2520:42;13320:19;;;;:52;;-1:-1:-1;13343:10:2;2611:42;13343:29;;13320:52;13316:80;;;13381:15;;-1:-1:-1;;;13381:15:2;;;;;;;;;;;13316:80;13410:4;:15;13428;13410;;;;:33;13406:60;;;13452:14;;-1:-1:-1;;;13452:14:2;;;;;;;;;;;13406:60;13718:4;13675:22;13700:24;;;;;;;;;;;13738:18;;13734:251;;13818:4;13800:9;:24;;;;;;;;;;;:42;;;;;;;13860:12;:30;;;;;;;13923:51;2773:25:7;;;13800:9:2;;13818:4;-1:-1:-1;;;;;;;;;;;13923:51:2;2746:18:7;13923:51:2;;;;;;;13734:251;13994:13;14010:28;14026:12;14010:13;:28;:::i;:::-;13994:44;;14048:46;14061:10;14081:4;14088:5;14048:12;:46::i;:::-;-1:-1:-1;14104:15:2;:31;;;14145:14;:29;;;14184:9;:7;:9::i;:::-;14203:17;:15;:17::i;:::-;13306:921;;13236:991;;:::o;3695:221::-;3758:12;-1:-1:-1;;;;;3786:17:2;;;;:32;;-1:-1:-1;3807:11:2;;3786:32;3782:62;;;3827:17;;-1:-1:-1;;;3827:17:2;;;;;;;;;;;3782:62;3854:34;3864:10;3876:3;3881:6;3854:9;:34::i;:::-;-1:-1:-1;3905:4:2;3695:221;;;;:::o;11302:130::-;11412:12;;11352:7;;11380:28;:21;11404:4;11380:28;:::i;:::-;11379:45;;;;:::i;11012:102::-;11056:7;11082:25;11102:4;11082:19;:25::i;12515:159::-;12569:10;2520:42;12569:19;12565:43;;12597:11;;-1:-1:-1;;;12597:11:2;;;;;;;;;;;12565:43;-1:-1:-1;;;;;12618:12:2;;;;;;:5;:12;;;;;;;;;:19;;-1:-1:-1;;12618:19:2;12633:4;12618:19;;;12652:15;;2565:51:7;;;12652:15:2;;2538:18:7;12652:15:2;;;;;;;12515:159;:::o;8719:405::-;8769:14;8836:13;8852:58;8868:21;8891:4;8897:12;;8852:15;:58::i;:::-;8836:74;;8929:36;8945:5;8952:6;8960:4;8929:15;:36::i;:::-;8920:45;;8975:25;8981:10;8993:6;8975:5;:25::i;:::-;9010:51;9042:10;9054:6;9010:31;:51::i;:::-;9076:41;;;5894:25:7;;;5950:2;5935:18;;5928:34;;;5978:18;;;5971:34;;;9083:10:2;;9076:41;;5882:2:7;5867:18;9076:41:2;;;;;;;8785:339;8719:405;;;:::o;6628:1864::-;2946:6;;6684:14;;2946:6;;2956:1;2946:11;2942:36;;2966:12;;-1:-1:-1;;;2966:12:2;;;;;;;;;;;2942:36;2988:6;:10;;-1:-1:-1;;2988:10:2;2997:1;2988:10;;;6732:6:::1;:17:::0;::::1;;6714:15;:35;6710:62;;;6758:14;;-1:-1:-1::0;;;6758:14:2::1;;;;;;;;;;;6710:62;6786:8;:17:::0;-1:-1:-1;;;;;6786:17:2::1;:22:::0;6782:1704:::1;;6824:81;::::0;-1:-1:-1;;;6824:81:2;;6857:10:::1;6824:81;::::0;::::1;6256:34:7::0;2611:42:2::1;6306:18:7::0;;;6299:43;6358:18;;;6351:34;;;6838:4:2::1;-1:-1:-1::0;;;;;6824:32:2::1;::::0;::::1;::::0;6191:18:7;;6824:81:2::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6990:36;7029:8;6990:47;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;-1:-1:-1::0;;;;;6990:47:2::1;;;::::0;::::1;;;7051:32;7086:6;7051:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7106:32;7141:6;7106:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7161:44;7208:12;7161:59;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7161:59:2::1;-1:-1:-1::0;;;;;7161:59:2::1;-1:-1:-1::0;;;;;7161:59:2::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7234:15;7252:12;;7234:30;;7278:11;7299:15;7278:37;;7441:57;7462:6;7441:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;7470:7;7479:5;7486:11;7441:20;:57::i;:::-;7402:96;;;;;;;;;;;;;;;;7513:13;7529:77;7556:5;:21;;;7579:7;:17;;;-1:-1:-1::0;;;;;7529:77:2::1;7598:7;7529:26;:77::i;:::-;7513:93:::0;-1:-1:-1;7513:93:2;7631:16:::1;:9:::0;7643:4:::1;7631:16;:::i;:::-;:24;;;;:::i;:::-;7683:18:::0;;7621:35;;-1:-1:-1;;;;;;7683:18:2::1;7674:27:::0;::::1;7670:51;;;7710:11;;-1:-1:-1::0;;;7710:11:2::1;;;;;;;;;;;7670:51;7802:6;7775:7;:16;;:34;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;7775:34:2::1;::::0;;-1:-1:-1;7823:17:2::1;::::0;::::1;:38:::0;;7851:9;;7823:17;:38:::1;::::0;7851:9;;7823:38:::1;:::i;:::-;-1:-1:-1::0;;;;;7823:38:2::1;::::0;;-1:-1:-1;7875:12:2::1;::::0;::::1;:30:::0;;7898:6;;7875:12;:30:::1;::::0;7898:6;;7875:30:::1;:::i;:::-;-1:-1:-1::0;;;;;7875:30:2::1;::::0;;-1:-1:-1;7919:17:2::1;::::0;::::1;:35:::0;;7947:6;;7919:17;:35:::1;::::0;7947:6;;7919:35:::1;:::i;:::-;-1:-1:-1::0;;;;;7919:35:2::1;::::0;;-1:-1:-1;7969:12:2::1;7984:25;7990:10;8002:6:::0;7984:5:::1;:25::i;:::-;7969:40;;8028:7;8023:33;;8044:12;;-1:-1:-1::0;;;8044:12:2::1;;;;;;;;;;;8023:33;8075:31;::::0;;5483:25:7;;;5539:2;5524:18;;5517:34;;;8080:10:2::1;::::0;8075:31:::1;::::0;5456:18:7;8075:31:2::1;;;;;;;8235:70;8255:4;8261:7;8270:5;8277;8284:11;8297:7;8235:19;:70::i;:::-;8361:18:::0;;:8:::1;:18:::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;8361:18:2;;::::1;-1:-1:-1::0;;;;;;8361:18:2;;;;-1:-1:-1;;;8361:18:2;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;;8361:18:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8393:14;;:6:::1;:14:::0;;-1:-1:-1;;8393:14:2::1;;::::0;;::::1;;::::0;;;;::::1;::::0;;;8421;;:6:::1;:14:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;8421:14:2;;::::1;::::0;;;;;;;;-1:-1:-1;;;8421:14:2;;::::1;::::0;;;::::1;;::::0;;;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;8421:14:2;;;;;-1:-1:-1;;;8421:14:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;8421:14:2::1;-1:-1:-1::0;;;8421:14:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8449:26;;8361:18:::1;8449:26:::0;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;;8449:26:2;;::::1;-1:-1:-1::0;;;;;;8449:26:2;;;;;;;-1:-1:-1;;;8449:26:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;8449:26:2;-1:-1:-1;;;8449:26:2;;;::::1;;-1:-1:-1::0;;;;8449:26:2;;;;;-1:-1:-1;;;8449:26:2;::::1;;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;;;;6782:1704:2::1;3019:6:::0;:10;;-1:-1:-1;;3019:10:2;3028:1;3019:10;;;6628:1864;;-1:-1:-1;6628:1864:2:o;15136:708::-;15186:19;15208:9;:24;15226:4;-1:-1:-1;;;;;15208:24:2;-1:-1:-1;;;;;15208:24:2;;;;;;;;;;;;;15186:46;;15282:4;15276:11;-1:-1:-1;;;15307:3:2;15300:79;-1:-1:-1;;;;;15416:9:2;15412:58;15408:1;15403:3;15399:11;15392:79;15505:11;15500:2;15495:3;15491:12;15484:33;15551:1;15546:2;15541:3;15537:12;15530:23;15588:1;15582:3;15577;15573:13;15566:24;15625:15;15619:3;15614;15610:13;15603:38;15676:11;15670:3;15665;15661:13;15654:34;15779:1;15776;15771:3;15766;15754:9;15746:18;15727:17;15720:5;15715:66;15701:80;;15804:6;15794:34;;15824:1;15821;15814:12;15794:34;;15251:587;15136:708::o;20113:856::-;-1:-1:-1;;;;;20205:15:2;;:9;:15;;;;;;;;;;;20196:24;;20192:57;;;20229:20;;-1:-1:-1;;;20229:20:2;;;;;;;;;;;20192:57;-1:-1:-1;;;;;20282:9:2;;20259;20282;;;:5;:9;;;;;;;;;:24;;-1:-1:-1;;;;;;20295:11:2;;;;;;:5;:11;;;;;;;;20282:24;20278:187;;;-1:-1:-1;;;;;20326:13:2;;;;;;:9;:13;;;;;;;;;:32;;-1:-1:-1;;;;;;20343:15:2;;;;;;:9;:15;;;;;;;;20326:32;20322:133;;;-1:-1:-1;20385:5:2;20322:133;;;-1:-1:-1;20436:4:2;20322:133;20478:4;20474:448;;;20498:11;20529:4;20513:12;2173:2;20513:6;:12;:::i;:::-;20512:21;;;;:::i;:::-;-1:-1:-1;;;;;20576:15:2;;:9;:15;;;;;;;;;;:25;;;;;;;2611:42;20619:26;;;:33;;;;;;20498:35;-1:-1:-1;20680:13:2;20498:35;20595:6;20680:13;:::i;:::-;-1:-1:-1;;;;;20735:13:2;;:9;:13;;;;;;;;;;:23;;;;;;20680:13;-1:-1:-1;20474:448:2;;-1:-1:-1;20474:448:2;;-1:-1:-1;;;;;20831:15:2;;;:9;:15;;;;;;;;;;;:25;;;;;;;20874:13;;;;;;:23;;;;;;20474:448;20951:2;-1:-1:-1;;;;;20936:26:2;20945:4;-1:-1:-1;;;;;20936:26:2;-1:-1:-1;;;;;;;;;;;20955:6:2;20936:26;;;;2773:25:7;;2761:2;2746:18;;2627:177;20936:26:2;;;;;;;;20182:787;20113:856;;;:::o;21571:276::-;-1:-1:-1;;;;;21637:15:2;;:9;:15;;;;;;;;;;;:23;-1:-1:-1;21633:56:2;;;21669:20;;-1:-1:-1;;;21669:20:2;;;;;;;;;;;21633:56;-1:-1:-1;;;;;21723:15:2;;:9;:15;;;;;;;;;;;:24;;;;;;;21761:12;:21;;;;;;;21807:33;2773:25:7;;;21723:9:2;;:15;-1:-1:-1;;;;;;;;;;;21807:33:2;2746:18:7;21807:33:2;;;;;;;21571:276;;:::o;1054:845:3:-;1206:13;;:::i;:::-;1221:11;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1301:15:3;1347:23;1357:4;1363:6;1347:9;:23::i;:::-;1327:43;;:6;:16;;:43;;;;;;;:::i;:::-;-1:-1:-1;;;;;1327:43:3;;;-1:-1:-1;1380:21:3;;;:14;;;:21;1416:18;;;;1412:430;;;1451:16;1469:9;1480:16;1500:25;1513:11;1500:12;:25::i;:::-;1450:75;;;;;;1564:8;-1:-1:-1;;;;;1539:33:3;:5;:21;;:33;;;;;;;:::i;:::-;;;-1:-1:-1;1586:246:3;;;;1643:8;1621:11;:18;;:30;;;;;;;:::i;:::-;-1:-1:-1;;;;;1621:30:3;;;-1:-1:-1;1669:26:3;;;:32;;1699:2;;1669:26;:32;;1699:2;;1669:32;:::i;:::-;;;;;;;;1719:33;;:26;;;:33;-1:-1:-1;1586:246:3;;;1812:5;1791:18;;;:26;1586:246;1436:406;;;1412:430;-1:-1:-1;1859:6:3;;1873:5;;-1:-1:-1;1880:11:3;;1054:845;-1:-1:-1;;;1054:845:3:o;2341:238::-;2477:7;2567:4;2528:35;2538:10;2550:12;2528:9;:35::i;:::-;2509:54;;:16;:54;:::i;:::-;2508:63;;;;:::i;:::-;2500:72;2341:238;-1:-1:-1;;;;2341:238:3:o;22085:348:2:-;22198:4;22144:12;22180:24;;;;;;;;;;;22172:32;;22168:72;;;22213:27;;-1:-1:-1;;;22213:27:2;;;;;;;;;;;22168:72;-1:-1:-1;;;;;;22274:13:2;;:9;:13;;;;;;;;;;;:22;;;;;;22328:4;22310:24;;;;;;;:33;;;;;;;22392:34;2773:25:7;;;-1:-1:-1;;22274:13:2;22328:4;-1:-1:-1;;;;;;;;;;;22392:34:2;2746:18:7;22392:34:2;;;;;;;22085:348;;;;:::o;3139:1200:3:-;3353:13;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;3381:11:3;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3423:22:3;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3423:22:3;3483:17;;;;3467:13;;:33;;3483:17;3467:33;:::i;:::-;3459:41;;:4;:41;;;3455:829;;3534:15;;:22;;3552:4;;3534:22;:::i;:::-;3516:40;;;;3596:20;;;;;3618:16;;;;3584:65;;3596:20;-1:-1:-1;;;;;3584:65:3;3636:12;3584:11;:65::i;:::-;3570:11;;;:79;3680:15;;-1:-1:-1;;;;;3663:32:3;:14;;;:32;;;3776:15;;3753:20;;;;3776:15;;3736:37;;;;;;:::i;:::-;:55;;;;:::i;:::-;-1:-1:-1;;;;;3709:84:3;:16;;;;:84;;;;3857:15;;3843:11;;;;3826:14;;;;3857:15;;3826:28;;;;;;;;:::i;:::-;:46;;;;:::i;:::-;3807:16;;;:65;;;3899:11;;;;:26;;3913:12;;3899:26;:::i;:::-;3898:47;;;;:::i;:::-;3886:9;;;:59;;;3976:20;;;;-1:-1:-1;3960:280:3;;;4016:14;4064:5;:9;;;4041:4;:20;;;:32;;;;:::i;:::-;4016:58;;4105:49;;;;;;;;4116:6;-1:-1:-1;;;;;4105:49:3;;;;;4124:4;4105:49;;;;;;4130:4;:17;;;4105:49;;;;;;4149:4;4105:49;;;;;4092:62;;3998:171;3960:280;;;4216:9;;;;4193:20;;;:32;3960:280;4253:20;;;;;3455:829;-1:-1:-1;4301:6:3;;4309:4;;-1:-1:-1;4315:4:3;;-1:-1:-1;4321:10:3;;3139:1200;-1:-1:-1;;;;3139:1200:3:o;799:339:1:-;871:12;1070:1;1067;1064;1061;1053:6;1049:2;1042:5;1037:35;1026:46;;1100:7;1092:39;;;;-1:-1:-1;;;1092:39:1;;7450:2:7;1092:39:1;;;7432:21:7;7489:2;7469:18;;;7462:30;-1:-1:-1;;;7508:18:7;;;7501:49;7567:18;;1092:39:1;;;;;;;;861:277;799:339;;:::o;25680:667:2:-;25741:7;25764:3;25760:581;;;25869:20;;25845:57;;;;;;;;25891:10;25845:57;-1:-1:-1;;;;;25845:57:2;;;;-1:-1:-1;;;25845:57:2;;;;;;;;;;-1:-1:-1;;;25845:57:2;;;;;;;;;;-1:-1:-1;;;25845:57:2;;;;;;;;;;;25808:216;;25845:57;;:23;:57::i;:::-;25949:6;:16;25967:12;;25924:56;;-1:-1:-1;;;25949:16:2;;-1:-1:-1;;;;;25949:16:2;;25924:24;:56::i;:::-;26002:4;25808:15;:216::i;25760:581::-;26155:22;;26131:61;;;;;;;;26179:12;26131:61;-1:-1:-1;;;;;26131:61:2;;;;-1:-1:-1;;;26131:61:2;;;;;;;;;;-1:-1:-1;;;26131:61:2;;;;;;;;;;-1:-1:-1;;;26131:61:2;;;;;;;;;;;26094:222;;26131:61;;:23;:61::i;:::-;26239:8;:18;26259:12;;26214:58;;-1:-1:-1;;;26239:18:2;;-1:-1:-1;;;;;26239:18:2;;26214:24;:58::i;25760:581::-;25680:667;;;:::o;16169:1394::-;16294:15;;16324:19;;16320:1208;;16359:20;16382:11;:9;:11::i;:::-;16359:34;-1:-1:-1;16426:10:2;16408:15;2807:6;16476:18;16426:10;16489:5;16476:18;:::i;:::-;-1:-1:-1;;;;;16476:29:2;;;;;:::i;:::-;16450:56;;16520:23;16576:10;-1:-1:-1;;;;;16546:40:2;16561:12;;16546;:27;;;;:::i;:::-;:40;;;;:::i;:::-;16520:66;;16600:11;16614:31;16622:8;-1:-1:-1;;;;;16614:31:2;16632:12;16614:7;:31::i;:::-;16600:45;-1:-1:-1;16659:17:2;16686:26;2807:6;16686:15;:26;:::i;:::-;16659:54;;16732:6;16728:790;;;16767:60;;;;;;;;;-1:-1:-1;;;;;16767:60:2;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16767:60:2;;;;;;;;;;;;;;;16758:6;:69;;-1:-1:-1;;;;;;16758:69:2;;;;;-1:-1:-1;;;16758:69:2;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16758:69:2;;;;;;16852:48;;;;;;;;;;;;;;;;;;;;16845:4;:55;;-1:-1:-1;;16845:55:2;;;;;;;;;16945:100;;;;;;;16972:15;16945:100;;;;;;;;;;;;2807:6;16945:100;;;;17033:5;16945:100;;;;17040:4;16945:100;;;;;;;;16918:4;:127;;;;;;;-1:-1:-1;;;16918:127:2;;;;;;;-1:-1:-1;;;;;;;;16918:127:2;-1:-1:-1;;;16918:127:2;;;17068:51;;8065:58:7;;;8139:18;;;8132:34;;;;8182:18;;;8175:55;;;;17068:51:2;;8038:18:7;17068:51:2;;;;;;;16728:790;;;17158:30;17172:4;17179:8;-1:-1:-1;;;;;17158:30:2;:5;:30::i;:::-;17439:26;2807:6;17439:15;:26;:::i;:::-;17414:4;:52;;-1:-1:-1;;17414:52:2;;;;;;;;;;;;17484:6;:19;;-1:-1:-1;;;;;;17484:19:2;;;16728:790;16345:1183;;;;;;16320:1208;-1:-1:-1;17555:1:2;17537:15;:19;16169:1394::o;17634:1345::-;17706:14;;-1:-1:-1;;;;;17735:14:2;;;17731:1214;;17765:20;17788:13;:11;:13::i;:::-;17765:36;-1:-1:-1;17833:10:2;17815:15;2807:6;17883:18;17833:10;17896:5;17883:18;:::i;:::-;-1:-1:-1;;;;;17883:29:2;;;;;:::i;:::-;17857:56;;17927:23;17983:10;-1:-1:-1;;;;;17953:40:2;17968:12;;17953;:27;;;;:::i;:::-;:40;;;;:::i;:::-;17927:66;;18007:11;18021:31;18029:8;-1:-1:-1;;;;;18021:31:2;18039:12;18021:7;:31::i;:::-;18007:45;-1:-1:-1;18066:17:2;18093:26;2807:6;18093:15;:26;:::i;:::-;18066:54;;18139:6;18135:800;;;18176:60;;;;;;;;;-1:-1:-1;;;;;18176:60:2;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18176:60:2;;;;;;;;;;;;;;;18165:8;:71;;-1:-1:-1;;;;;;18165:71:2;;;;;-1:-1:-1;;;18165:71:2;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;18165:71:2;;;;;;18263:48;;;;;;;;;;;;;;;;;;;;18254:6;:57;;-1:-1:-1;;18254:57:2;;;;;;;;;18358:100;;;;;;;18385:15;18358:100;;;;;;;;;;;;2807:6;18358:100;;;;18446:5;18358:100;;;;18453:4;18358:100;;;;;;;;18329:6;:129;;;;;;;-1:-1:-1;;;18329:129:2;;;;;;;-1:-1:-1;;;;;;;;18329:129:2;-1:-1:-1;;;18329:129:2;;;18481:51;;8065:58:7;;;8139:18;;;8132:34;;;;8182:18;;;8175:55;;;;18481:51:2;;8038:18:7;18481:51:2;;;;;;;18135:800;;;18571:30;18585:4;18592:8;-1:-1:-1;;;;;18571:30:2;:5;:30::i;:::-;18854:26;2807:6;18854:15;:26;:::i;:::-;18827:6;:54;;-1:-1:-1;;18827:54:2;;;;;;;;;;;;18899:8;:21;;-1:-1:-1;;;;;;18899:21:2;;;18135:800;17751:1194;;;;;;17731:1214;-1:-1:-1;18971:1:2;18954:14;:18;17634:1345::o;741:4097:6:-;823:14;;;-1:-1:-1;;1386:1:6;1383;1376:20;1429:1;1426;1422:9;1413:18;;1484:5;1480:2;1477:13;1469:5;1465:2;1461:14;1457:34;1448:43;;;1585:5;1594:1;1585:10;1581:203;;1637:1;1623:11;:15;1615:24;;;;;;-1:-1:-1;1698:23:6;;;;-1:-1:-1;1756:13:6;;1581:203;1923:5;1909:11;:19;1901:28;;;;;;2230:17;2314:11;2311:1;2308;2301:25;2706:12;2722:15;;;2721:31;;2858:22;;;;;3733:1;3714;:15;;3713:21;;3976:17;;;3972:21;;3965:28;4038:17;;;4034:21;;4027:28;4101:17;;;4097:21;;4090:28;4164:17;;;4160:21;;4153:28;4227:17;;;4223:21;;4216:28;4291:17;;;4287:21;;;4280:28;3270:12;;;;3266:23;;;3291:1;3262:31;2459:20;;;2448:32;;;3329:12;;;;2506:21;;;;3002:16;;;;3320:21;;;;4783:11;;;;;-1:-1:-1;;741:4097:6;;;;;:::o;2744:234:3:-;2826:6;2844:20;2885:4;:14;;;2867:32;;:15;:32;;;;:::i;:::-;2844:55;;2959:4;:11;;;2923:47;;2943:12;2924:6;:16;;;-1:-1:-1;;;;;2924:31:3;;;;;:::i;1905:430::-;1974:7;1983:6;1991:4;2012;:11;;;2007:38;;-1:-1:-1;2033:1:3;;-1:-1:-1;2033:1:3;;-1:-1:-1;2033:1:3;2025:20;;2007:38;2056:19;2104:4;:19;;;2085:15;2078:45;;;;:::i;:::-;2056:67;;2133:11;2162:4;:19;;;2147:34;;:12;:34;;;2133:48;;2191:14;2208:6;:73;;2270:11;;2208:73;;;2248:4;:19;;;2217:50;;2232:12;2218:26;;:4;:11;;;:26;;;;:::i;:::-;2217:50;;;;:::i;:::-;2191:90;-1:-1:-1;2307:12:3;;-1:-1:-1;2321:6:3;-1:-1:-1;;1905:430:3;;;;;;:::o;2585:153::-;2669:7;2718:12;2697:17;:10;2710:4;2697:17;:::i;:::-;2696:34;;;;:::i;26353:266:2:-;26496:7;26520:13;26539:33;26567:4;26539:27;:33::i;:::-;-1:-1:-1;;;;;;;26519:53:2;;-1:-1:-1;26589:23:2;26519:53;26589:15;:23;:::i;22631:788::-;22674:13;22699;22715:4;22699:20;;22729:16;22755;22821:4;22815:11;-1:-1:-1;;;22846:3:2;22839:79;22982:1;22979;22976;22971:3;22964:5;22957;22946:38;22931:53;;23007:7;22997:35;;23028:1;23025;23018:12;22997:35;;23069:2;23066:1;23060:4;23045:27;23112:2;23106:4;23100;23085:30;-1:-1:-1;;23146:4:2;23140:11;23182:4;23176:11;23211:10;23207:206;;;23245:59;23269:8;-1:-1:-1;;;;;23261:17:2;23280:4;23294:8;-1:-1:-1;;;;;23286:17:2;23245:15;:59::i;:::-;23237:67;;23207:206;;;23343:59;23367:8;-1:-1:-1;;;;;23359:17:2;23378:4;23392:8;-1:-1:-1;;;;;23384:17:2;23343:15;:59::i;:::-;23335:67;;23207:206;22689:730;;;22631:788;:::o;19657:379::-;19771:12;;19729:13;;;19850:17;19859:8;19771:12;19850:17;:::i;:::-;19817:28;:21;19841:4;19817:28;:::i;:::-;19816:52;;;;:::i;:::-;19793:75;-1:-1:-1;19878:20:2;19959:6;19937:16;19948:5;19937:8;:16;:::i;:::-;19903:28;:21;19927:4;19903:28;:::i;:::-;19902:53;;;;:::i;:::-;19901:64;;;;:::i;:::-;19878:87;;20002:12;19986;:28;;:43;;20025:4;19986:43;;;20017:5;19986:43;19975:54;19657:379;-1:-1:-1;;;;;;19657:379:2:o;23488:1151::-;23533:16;23561:13;23577:4;23561:20;;23591:16;23617;23643:21;23714:4;23708:11;-1:-1:-1;;;23739:3:2;23732:79;23875:1;23872;23869;23864:3;23857:5;23850;23839:38;23900:7;23890:35;;23921:1;23918;23911:12;23890:35;;23962:2;23959:1;23953:4;23938:27;24005:2;23999:4;23993;23978:30;24039:4;24033:11;24021:23;;24075:4;24069:11;24057:23;;-1:-1:-1;;;24109:4:2;24104:3;24100:14;24093:90;24257:2;24254:1;24251;24244:4;24239:3;24235:14;24228:5;24221;24210:50;24196:64;;24296:4;24290:11;24273:28;;24443:10;24439:194;;;24480:50;24496:12;:8;24507:1;24496:12;:::i;:::-;-1:-1:-1;;;;;24480:50:2;24510:4;24516:13;24480:15;:50::i;:::-;24469:61;;24439:194;;;24572:50;24588:12;:8;24599:1;24588:12;:::i;24572:50::-;24561:61;;24439:194;23551:1088;;;;23488:1151;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1237:548:7:-;1349:4;1378:2;1407;1396:9;1389:21;1439:6;1433:13;1482:6;1477:2;1466:9;1462:18;1455:34;1507:1;1517:140;1531:6;1528:1;1525:13;1517:140;;;1626:14;;;1622:23;;1616:30;1592:17;;;1611:2;1588:26;1581:66;1546:10;;1517:140;;;1521:3;1706:1;1701:2;1692:6;1681:9;1677:22;1673:31;1666:42;1776:2;1769;1765:7;1760:2;1752:6;1748:15;1744:29;1733:9;1729:45;1725:54;1717:62;;;;1237:548;;;;:::o;1790:173::-;1858:20;;-1:-1:-1;;;;;1907:31:7;;1897:42;;1887:70;;1953:1;1950;1943:12;1968:254;2036:6;2044;2097:2;2085:9;2076:7;2072:23;2068:32;2065:52;;;2113:1;2110;2103:12;2065:52;2136:29;2155:9;2136:29;:::i;:::-;2126:39;2212:2;2197:18;;;;2184:32;;-1:-1:-1;;;1968:254:7:o;2809:328::-;2886:6;2894;2902;2955:2;2943:9;2934:7;2930:23;2926:32;2923:52;;;2971:1;2968;2961:12;2923:52;2994:29;3013:9;2994:29;:::i;:::-;2984:39;;3042:38;3076:2;3065:9;3061:18;3042:38;:::i;:::-;3032:48;;3127:2;3116:9;3112:18;3099:32;3089:42;;2809:328;;;;;:::o;3331:180::-;3390:6;3443:2;3431:9;3422:7;3418:23;3414:32;3411:52;;;3459:1;3456;3449:12;3411:52;-1:-1:-1;3482:23:7;;3331:180;-1:-1:-1;3331:180:7:o;3516:186::-;3575:6;3628:2;3616:9;3607:7;3603:23;3599:32;3596:52;;;3644:1;3641;3634:12;3596:52;3667:29;3686:9;3667:29;:::i;3707:248::-;3775:6;3783;3836:2;3824:9;3815:7;3811:23;3807:32;3804:52;;;3852:1;3849;3842:12;3804:52;-1:-1:-1;;3875:23:7;;;3945:2;3930:18;;;3917:32;;-1:-1:-1;3707:248:7:o;3960:260::-;4028:6;4036;4089:2;4077:9;4068:7;4064:23;4060:32;4057:52;;;4105:1;4102;4095:12;4057:52;4128:29;4147:9;4128:29;:::i;:::-;4118:39;;4176:38;4210:2;4199:9;4195:18;4176:38;:::i;:::-;4166:48;;3960:260;;;;;:::o;4225:127::-;4286:10;4281:3;4277:20;4274:1;4267:31;4317:4;4314:1;4307:15;4341:4;4338:1;4331:15;4357:128;4424:9;;;4445:11;;;4442:37;;;4459:18;;:::i;4490:168::-;4563:9;;;4594;;4611:15;;;4605:22;;4591:37;4581:71;;4632:18;;:::i;4663:127::-;4724:10;4719:3;4715:20;4712:1;4705:31;4755:4;4752:1;4745:15;4779:4;4776:1;4769:15;4795:120;4835:1;4861;4851:35;;4866:18;;:::i;:::-;-1:-1:-1;4900:9:7;;4795:120::o;4920:191::-;-1:-1:-1;;;;;5047:10:7;;;5035;;;5031:27;;5070:12;;;5067:38;;;5085:18;;:::i;:::-;5067:38;4920:191;;;;:::o;5116:188::-;-1:-1:-1;;;;;5229:10:7;;;5241;;;5225:27;;5264:11;;;5261:37;;;5278:18;;:::i;5562:125::-;5627:9;;;5648:10;;;5645:36;;;5661:18;;:::i;6396:277::-;6463:6;6516:2;6504:9;6495:7;6491:23;6487:32;6484:52;;;6532:1;6529;6522:12;6484:52;6564:9;6558:16;6617:5;6610:13;6603:21;6596:5;6593:32;6583:60;;6639:1;6636;6629:12;6678:200;-1:-1:-1;;;;;6814:10:7;;;6802;;;6798:27;;6837:12;;;6834:38;;;6852:18;;:::i;6883:179::-;6951:14;6998:10;;;6986;;;6982:27;;7021:12;;;7018:38;;;7036:18;;:::i;7067:176::-;7134:14;7168:10;;;7180;;;7164:27;;7203:11;;;7200:37;;;7217:18;;:::i;7596:265::-;-1:-1:-1;;;;;7725:10:7;;;7737;;;7721:27;7768:20;;;;7667:26;7807:24;;;7797:58;;7835:18;;:::i;:::-;7797:58;;7596:265;;;;:::o;8241:274::-;-1:-1:-1;;;;;8379:10:7;;;8391;;;8375:27;8422:20;;;;8313:34;8461:24;;;8451:58;;8489:18;;:::i;8520:216::-;8560:1;-1:-1:-1;;;;;8647:2:7;8644:1;8640:10;8669:3;8659:37;;8676:18;;:::i;:::-;8714:10;;8710:20;;;;;8520:216;-1:-1:-1;;8520:216:7:o;8741:270::-;-1:-1:-1;;;;;8875:10:7;;;8887;;;8871:27;8918:20;;;;8813:30;8957:24;;;8947:58;;8985:18;;:::i

Swarm Source

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

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