ETH Price: $3,683.99 (+3.21%)

Token

ERC-20: Koto V2 (KOTOV2)
 

Overview

Max Total Supply

8,366,179.315783842535630346 KOTOV2

Holders

453

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
25,000 KOTOV2

Value
$0.00
0x603602e9a2ac7f1e26717c2b2193fd68f5fafff6
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:
KotoV2

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion, MIT license
File 1 of 6 : KotoV2.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 carry over to the next day.
/// 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.22;

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";

contract KotoV2 {
    // ========================== 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 V2";
    string private constant SYMBOL = "KOTOV2";
    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 = 0x298ECA8683000B3911B2e7Dd07FD496D8019043E;
    address private immutable pair;
    address private immutable token0;
    address private immutable token1;
    uint256 private constant INTERVAL = 86400; // 1 day 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, 8_500_000e18); //
        (token0, token1) = _getTokens(pair);
        zeroForOne = address(this) == token0 ? true : false;
        _allowances[address(this)][UNISWAP_V2_ROUTER] = type(uint256).max;
        ///@dev set term conclusion to type uint48 max to prevent bonds being created before opening them to the public
        term.conclusion = type(uint48).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 the previous market has ended create a new market.
        if (block.timestamp > term.conclusion) {
            _create();
        }
        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 the previous market has ended create a new market.
        if (block.timestamp > term.conclusion) {
            _createLpMarket();
        }
        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 = (address(this).balance * 1e18) / _totalSupply;
        payout = (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 PricingLibrary.marketPrice(term.controlVariable, market.totalDebt, _totalSupply);
    }

    function bondPriceLp() external view returns (uint256) {
        return PricingLibrary.marketPrice(lpTerm.controlVariable, lpMarket.totalDebt, _totalSupply);
    }

    ///@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 opens the bond market
    ///@dev the liquidity pool must already be launched and initialized. As well as tokens sent to this contract from
    /// the bond depository.
    function open() external {
        if (msg.sender != OWNER) revert OnlyOwner();
        _create();
        _createLpMarket();
        emit OpenBondMarket(block.timestamp);
    }

    ///TODO: change back to permissioned prior to launch.
    function create(uint256 ethBondAmount, uint256 lpBondAmount) external {
        if (msg.sender != OWNER && msg.sender != BOND_DEPOSITORY) revert InvalidSender();
        uint256 total = ethBondAmount + lpBondAmount;
        transferFrom(msg.sender, address(this), total);
        ethCapacityNext = ethBondAmount;
        lpCapacityNext = lpBondAmount;
    }

    // ========================= 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)
        }
    }

    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 * 14400 / 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), 14400, 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;
    }

    function _createLpMarket() private {
        uint96 targetDebt = uint96(lpCapacityNext);
        if (targetDebt > 0) {
            uint256 initialPrice = _getLpPrice();
            uint96 capacity = targetDebt;
            uint96 maxPayout = uint96(targetDebt * 14400 / 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), 14400, 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;
    }

    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 = (uint256(reserve1) * 1e18) / uint256(reserve0);
        } else {
            price = (uint256(reserve0) * 1e18) / uint256(reserve1);
        }
    }

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

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

    // ========================= 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 OnlyOwner();
    error RedeemFailed();
    error Reentrancy();

    receive() external payable {}
}

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

pragma solidity =0.8.22;

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 6 : 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 6 : 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 6 : IERC20Minimal.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.22;

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

File 6 of 6 : 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":"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":"open","outputs":[],"stateMutability":"nonpayable","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"}]

61010060405234801562000011575f80fd5b50620000323073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc262000177565b6001600160a01b031660a0819052600260209081527fd1c69375fae4db1f9bc09d344dd4ca5ec7325a49ae090b3810917b7940a06d4b8054600160ff1991821681179092557f1527fa3601407431dc1350e50671df29929c263a9b11099e7461674bfb23b0548054821683179055305f908152604080822080548416851790559481526003909352929091208054909216179055620000f173946ef43867225695e29241813a8f41519634b36b6a0707f1ec5dcde3d8800000620001d7565b60a051620000ff9062000230565b6001600160a01b0390811660e0521660c0819052301462000121575f62000124565b60015b1515608052305f908152600160209081526040808320737a250d5630b4cf539739df2c5dacb4c659f2488d845290915290205f199055600a805465ffffffffffff191665ffffffffffff17905562000281565b5f6040516364e329cb60e11b81526001600160a01b03841660048201526001600160a01b038316602482015260205f6044835f735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f5af1905080620001cd575f80fd5b50505f5192915050565b6001600160a01b0382165f818152602081815260408083208054860190556004805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f80604051630dfe168160e01b815260205f600483875afa63d21220a760e01b60048301526020806004808501885afa915081158115171562000271575f80fd5b50505f5191506020519050915091565b60805160a05160c05160e051612f1c620002cb5f395f50505f50505f81816102c80152818161140d0152818161279301526129f301525f81816127eb0152612a6b0152612f1c5ff3fe60806040526004361061017e575f3560e01c806370a08231116100cd578063c5b748c011610087578063db006a7511610062578063db006a75146104f9578063dd62ed3e14610518578063df8980b31461055c578063fcfff16f1461057b575f80fd5b8063c5b748c0146104b2578063d7ccfb0b146104c6578063d926de1c146104da575f80fd5b806370a08231146103d85780637b16c21e1461040c57806395d89b41146104205780639f7b45791461044e578063a9059cbb1461046d578063bedd12a51461048c575f80fd5b806323b872dd1161013857806342966c681161011357806342966c681461036c5780634febf53d1461038b5780635d03147a146103aa57806364c9ec6f146103d0575f80fd5b806323b872dd1461031e57806326749e871461033d578063313ce56714610351575f80fd5b806301339c2114610189578063031bee001461019f57806306fdde0314610253578063095ea7b31461028b57806316f0115b146102ba57806318160ddd14610300575f80fd5b3661018557005b5f80fd5b348015610194575f80fd5b5061019d61058f565b005b3480156101aa575f80fd5b506101b361063f565b6040805184516001600160601b0390811682526020808701518216818401528684015182168385015260608088015183168185015260809788015190921687840152855165ffffffffffff90811660a08501529581015160c08401528451861660e0840152840151851661010083015291830151841661012082015290820151831661014082015292015116610160820152610180015b60405180910390f35b34801561025e575f80fd5b5060408051808201909152600781526625b7ba37902b1960c91b60208201525b60405161024a9190612bab565b348015610296575f80fd5b506102aa6102a5366004612c12565b610728565b604051901515815260200161024a565b3480156102c5575f80fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b03909116815260200161024a565b34801561030b575f80fd5b506004545b60405190815260200161024a565b348015610329575f80fd5b506102aa610338366004612c3a565b610755565b348015610348575f80fd5b506101b3610829565b34801561035c575f80fd5b506040516012815260200161024a565b348015610377575f80fd5b506102aa610386366004612c73565b610912565b348015610396575f80fd5b5061019d6103a5366004612c8a565b61094a565b3480156103b5575f80fd5b5073946ef43867225695e29241813a8f41519634b36b6102e8565b6103106109c9565b3480156103e3575f80fd5b506103106103f2366004612c8a565b6001600160a01b03165f9081526020819052604090205490565b348015610417575f80fd5b50610310611111565b34801561042b575f80fd5b5060408051808201909152600681526525a7aa27ab1960d11b602082015261027e565b348015610459575f80fd5b5061019d610468366004612ca3565b61113e565b348015610478575f80fd5b506102aa610487366004612c12565b6111b9565b348015610497575f80fd5b5073298eca8683000b3911b2e7dd07fd496d8019043e6102e8565b3480156104bd575f80fd5b50610310611200565b3480156104d1575f80fd5b50610310611221565b3480156104e5575f80fd5b5061019d6104f4366004612c8a565b611249565b348015610504575f80fd5b50610310610513366004612c73565b6112d6565b348015610523575f80fd5b50610310610532366004612cc3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610567575f80fd5b50610310610576366004612c73565b611377565b348015610586575f80fd5b5061019d611b5b565b3373946ef43867225695e29241813a8f41519634b36b146105c357604051635fc483c560e01b815260040160405180910390fd5b601554610100900460ff16156105ec576040516319f4db0f60e31b815260040160405180910390fd5b6105f4611bcf565b6015805461ff0019166101001790556040517feca0dfbda743d141662328d4d48393e344b2c60df0430297221df823f2926dba906106359042815260200190565b60405180910390a1565b610647612b7e565b604080518082019091525f8082526020820152610662612b7e565b50506040805160a080820183526007546001600160601b038082168452600160601b91829004811660208086019190915260085480831686880152839004821660608087019190915260095490921660808087019190915286518088018852600a5465ffffffffffff9081168252600b5482850152885196870189526006548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b335f9081526001602081815260408084206001600160a01b03871685529091529091208290555b92915050565b5f6001600160a01b038316158061076a575081155b1561078857604051632f35253160e01b815260040160405180910390fd5b6001600160a01b0384163314610813576001600160a01b0384165f9081526001602090815260408083203384529091529020548211156107db576040516358d246fb60e11b815260040160405180910390fd5b6001600160a01b0384165f9081526001602090815260408083203384529091528120805484929061080d908490612d08565b90915550505b61081e848484611c70565b5060015b9392505050565b610831612b7e565b604080518082019091525f808252602082015261084c612b7e565b50506040805160a08082018352600e546001600160601b038082168452600160601b918290048116602080860191909152600f548083168688015283900482166060808701919091526010549092166080808701919091528651808801885260115465ffffffffffff90811682526012548285015288519687018952600d548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b5f61091d3383611e51565b506040518181526001905f9033905f80516020612ec78339815191529060200160405180910390a3919050565b3373946ef43867225695e29241813a8f41519634b36b1461097e57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260026020526040808220805460ff19166001179055517fec2dffa455deca3e695cce255e2b110b5ca334fb5b166f3159bbaad319ce0f1b9190a250565b6015545f9060ff166002036109f15760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff16421115610a1857610a18611ed4565b6007546001600160601b0316156110f7575f60076040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f600a6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f60056040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050610dee60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786612113565b809650819850829750839950505050505f610e1b866020015188602001516001600160601b031685612239565b905080610e3034670de0b6b3a7640000612d1b565b610e3a9190612d46565b6008549098506001600160601b0316881115610e69576040516305c250cf60e11b815260040160405180910390fd5b87875f01818151610e7a9190612d59565b6001600160601b0316905250608087018051349190610e9a908390612d80565b6001600160601b0316905250606087018051899190610eba908390612d80565b6001600160601b0316905250602087018051899190610eda908390612d80565b6001600160601b03169052505f610ef1338a612269565b905080610f115760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a2610f5a8389898989896122ed565b8351600780546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600880546060808d015193891691909616179187168602919091179055608098890151600980546001600160601b0319908116929097169190911790558751600a805465ffffffffffff191665ffffffffffff92831617905597820151600b55865160068054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b93871693909302929092179055815160058054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b91151591909102179055506111019650505050505050565b61110133346124f0565b6015805460ff1916600117905590565b601254600e546004545f92611139929091600160601b9091046001600160601b031690612239565b905090565b3373946ef43867225695e29241813a8f41519634b36b1480159061117657503373298eca8683000b3911b2e7dd07fd496d8019043e14155b1561119457604051636edaef2f60e11b815260040160405180910390fd5b5f61119f8284612da0565b90506111ac333083610755565b5050601391909155601455565b5f6001600160a01b03831615806111ce575081155b156111ec57604051632f35253160e01b815260040160405180910390fd5b6111f7338484611c70565b50600192915050565b6004545f9061121747670de0b6b3a7640000612d1b565b6111399190612d46565b600b546007546004545f92611139929091600160601b9091046001600160601b031690612239565b3373946ef43867225695e29241813a8f41519634b36b1461127d57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260036020908152604091829020805460ff1916600117905590519182527f10cdbb821aa416c854add806e1d7e8138afe2a538921cebe99b1351362ae38b2910160405180910390a150565b5f8060045447670de0b6b3a76400006112ef9190612d1b565b6112f99190612d46565b9050670de0b6b3a764000061130e8483612d1b565b6113189190612d46565b91506113243384611e51565b61132e33836124f0565b604080518481526020810184905290810182905233907fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469060600160405180910390a250919050565b6015545f9060ff1660020361139f5760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff164211156113c6576113c6612547565b600e546001600160601b031615611b49576040516323b872dd60e01b815233600482015273298eca8683000b3911b2e7dd07fd496d8019043e6024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af115801561145b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061147f9190612db3565b505f600e6040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f60116040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f600c6040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050611845600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786612113565b809650819850829750839950505050505f611872866020015188602001516001600160601b031685612239565b9050806118878a670de0b6b3a7640000612d1b565b6118919190612d46565b600f549098506001600160601b03168811156118c0576040516305c250cf60e11b815260040160405180910390fd5b87875f018181516118d19190612d59565b6001600160601b03169052506080870180518a91906118f1908390612d80565b6001600160601b0316905250606087018051899190611911908390612d80565b6001600160601b0316905250602087018051899190611931908390612d80565b6001600160601b03169052505f611948338a612269565b9050806119685760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a26119b18389898989896122ed565b8351600e80546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600f80546060808d015193891691909616179187168602919091179055608098890151601080546001600160601b03199081169290971691909117905587516011805465ffffffffffff191665ffffffffffff928316179055978201516012558651600d8054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b938716939093029290921790558151600c8054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b9115159190910217905550505050505050505b6015805460ff19166001179055919050565b3373946ef43867225695e29241813a8f41519634b36b14611b8f57604051635fc483c560e01b815260040160405180910390fd5b611b97611ed4565b611b9f612547565b6040514281527fcb952d4b0fcf5915a9cc714f93cda275771363c8e7fb92af67c20638187b14d390602001610635565b5f805f306001600160a01b03166001600160a01b031681526020019081526020015f2054905060405163f305d71960e01b81526001600160a01b03301660048201528160248201525f60448201525f606482015273298eca8683000b3911b2e7dd07fd496d8019043e60848201524260a48201525f8060c4833031737a250d5630b4cf539739df2c5dacb4c659f2488d5af1905080611c6c575f80fd5b5050565b6001600160a01b0383165f90815260208190526040902054811115611ca85760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f9081526003602052604081205460ff1680611ce557506001600160a01b0384165f9081526003602052604090205460ff165b15611d37576001600160a01b0383165f9081526002602052604090205460ff1680611d2757506001600160a01b0384165f9081526002602052604090205460ff165b15611d3357505f611d37565b5060015b8015611de4575f6103e8611d4c603285612d1b565b611d569190612d46565b6001600160a01b0386165f9081526020819052604081208054869003905573298eca8683000b3911b2e7dd07fd496d8019043e90527f53255b9766a7b4dec69b0f4028a04a78db33a7b0884c22bd3c7db8f24cea5dac8054820190559050611dbe8184612d08565b6001600160a01b0385165f9081526020819052604090208054820190559250611e119050565b6001600160a01b038085165f90815260208190526040808220805486900390559185168152208054830190555b826001600160a01b0316846001600160a01b03165f80516020612ec783398151915284604051611e4391815260200190565b60405180910390a350505050565b6001600160a01b0382165f90815260208190526040902054811115611e895760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612ec7833981519152910160405180910390a35050565b601354801561210c575f611ee661278f565b9050815f62015180611efa83613840612dd2565b6001600160601b0316611f0d9190612d46565b90505f846001600160601b031660045485611f289190612d1b565b611f329190612d46565b90505f611f48846001600160601b031686612881565b90505f611f586201518042612da0565b905081156120b6576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600780546001600160c01b03199081168617600160601b90950294909417905560088054909316909117909155600980546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c9052600a805465ffffffffffff191683179055600b8c9055885196870189524290811680885287870181905262015180888b0152613840888601526107089790980196909652600680549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000000708000000002a360671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612105565b6120c930866001600160601b0316611e51565b6120d66201518042612da0565b600a805465ffffffffffff191665ffffffffffff92909216919091179055600780546001600160601b03191690555b5050505050505b505f601355565b61211b612b7e565b612123612b7e565b6040805180820182525f808252602080830182905283516080810185528281529081018290529283018190526060830152904261216089896128fe565b67ffffffffffffffff168860200181815161217b9190612d59565b6001600160601b031690525065ffffffffffff811660208a015260608601511561222b575f805f6121ab89612940565b925092509250826001600160801b03168a6020018181516121cc9190612d08565b90525080156122205782895f018181516121e69190612dfd565b6001600160801b0316905250604089018051839190612206908390612e1d565b65ffffffffffff908116909152851660208b015250612227565b5f60608a01525b5050505b509597949550929392505050565b5f670de0b6b3a764000061224d84846129d1565b6122579086612d1b565b6122619190612d46565b949350505050565b305f9081526020819052604081205482111561229857604051635e36b3df60e01b815260040160405180910390fd5b506001600160a01b0382165f818152602081815260408083208054860190553080845292819020805486900390555184815260019392915f80516020612ec7833981519152910160405180910390a392915050565b6122f5612b7e565b604080518082019091525f8082526020820152612310612b7e565b604080516080810182525f8082526020820181905291810182905260608101919091526123606040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b608088015188516123719190612e3c565b65ffffffffffff168b65ffffffffffff16106124de578851612394908c90612e1d565b65ffffffffffff1681526020808a0151908b01516123bc91906001600160601b031688612239565b602082015289516001600160601b031660408201819052815160608a015190916123ee9165ffffffffffff1690612d1b565b6123f89190612d46565b6001600160601b03166040808c019190915281518982015191830151909161242a9165ffffffffffff90911690612d1b565b6124349190612d46565b60608201819052602082015161244b908890612d1b565b6124559190612d46565b6080820181905260208a015111156124c7575f81608001518a6020015161247c9190612d08565b90506040518060800160405280826001600160801b031681526020018d65ffffffffffff1681526020018a6080015165ffffffffffff168152602001600115158152509750506124d2565b608081015160208a01525b65ffffffffffff8b1688525b50979996985094965092949350505050565b5f805f805f85875af19050806125425760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b6014546001600160601b03811615612788575f6125626129ef565b9050815f6201518061257683613840612dd2565b6001600160601b03166125899190612d46565b90505f846001600160601b0316600454856125a49190612d1b565b6125ae9190612d46565b90505f6125c4846001600160601b031686612881565b90505f6125d46201518042612da0565b90508115612732576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600e80546001600160c01b03199081168617600160601b909502949094179055600f8054909316909117909155601080546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c90526011805465ffffffffffff19168317905560128c9055885196870189524290811680885287870181905262015180888b0152613840888601526107089790980196909652600d80549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000000708000000002a360671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612781565b61274530866001600160601b0316611e51565b6127526201518042612da0565b6011805465ffffffffffff191665ffffffffffff92909216919091179055600e80546001600160601b03191690555b5050505050505b505f601455565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f80604051630240bc6b60e21b81525f80600483875afa9050806127d6575f80fd5b5060205f803e60208060203e50505f516020517f00000000000000000000000000000000000000000000000000000000000000001561284757816001600160701b0316816001600160701b0316670de0b6b3a76400006128369190612d1b565b6128409190612d46565b935061287b565b806001600160701b0316826001600160701b0316670de0b6b3a764000061286e9190612d1b565b6128789190612d46565b93505b50505090565b6004545f90816128918583612d08565b6128a347670de0b6b3a7640000612d1b565b6128ad9190612d46565b90505f826128bb8688612d1b565b6128cd47670de0b6b3a7640000612d1b565b6128d79190612da0565b6128e19190612d46565b9050808210156128f25760016128f4565b5f5b9695505050505050565b5f80836020015165ffffffffffff16426129189190612d08565b9050836040015165ffffffffffff168184602001516001600160601b03166122579190612d1b565b5f805f836060015161295957505f9150819050806129ca565b5f84602001514261296a9190612e1d565b90505f856040015165ffffffffffff168265ffffffffffff161090505f816129935786516129c1565b866040015165ffffffffffff168365ffffffffffff16885f01516129b79190612e5b565b6129c19190612e7e565b95509193509150505b9193909250565b5f816129e584670de0b6b3a7640000612d1b565b6108229190612d46565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f805f604051630240bc6b60e21b81525f80600483885afa80612a35575f80fd5b5060205f803e60208060203e5f51935060205192506318160ddd60e01b602082015260205f600460208401885afa50505f5190507f000000000000000000000000000000000000000000000000000000000000000015612abc57612ab5612a9d846002612ea3565b6001600160701b0316670de0b6b3a764000083612ad4565b9450612acd565b612aca612a9d836002612ea3565b94505b5050505090565b5f80805f19858709858702925082811083820303915050805f03612b08575f8411612afd575f80fd5b508290049050610822565b808411612b13575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290565b5f602080835283518060208501525f5b81811015612bd757858101830151858201604001528201612bbb565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114612c0d575f80fd5b919050565b5f8060408385031215612c23575f80fd5b612c2c83612bf7565b946020939093013593505050565b5f805f60608486031215612c4c575f80fd5b612c5584612bf7565b9250612c6360208501612bf7565b9150604084013590509250925092565b5f60208284031215612c83575f80fd5b5035919050565b5f60208284031215612c9a575f80fd5b61082282612bf7565b5f8060408385031215612cb4575f80fd5b50508035926020909101359150565b5f8060408385031215612cd4575f80fd5b612cdd83612bf7565b9150612ceb60208401612bf7565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561074f5761074f612cf4565b808202811582820484141761074f5761074f612cf4565b634e487b7160e01b5f52601260045260245ffd5b5f82612d5457612d54612d32565b500490565b6001600160601b03828116828216039080821115612d7957612d79612cf4565b5092915050565b6001600160601b03818116838216019080821115612d7957612d79612cf4565b8082018082111561074f5761074f612cf4565b5f60208284031215612dc3575f80fd5b81518015158114610822575f80fd5b6001600160601b03818116838216028082169190828114612df557612df5612cf4565b505092915050565b6001600160801b03828116828216039080821115612d7957612d79612cf4565b65ffffffffffff828116828216039080821115612d7957612d79612cf4565b65ffffffffffff818116838216019080821115612d7957612d79612cf4565b6001600160801b03818116838216028082169190828114612df557612df5612cf4565b5f6001600160801b0380841680612e9757612e97612d32565b92169190910492915050565b6001600160701b03818116838216028082169190828114612df557612df5612cf456feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220afcbc2e2988b20d46fa776fb380f2dab45fdbe73baf76659fb97e576a0841a8764736f6c63430008160033

Deployed Bytecode

0x60806040526004361061017e575f3560e01c806370a08231116100cd578063c5b748c011610087578063db006a7511610062578063db006a75146104f9578063dd62ed3e14610518578063df8980b31461055c578063fcfff16f1461057b575f80fd5b8063c5b748c0146104b2578063d7ccfb0b146104c6578063d926de1c146104da575f80fd5b806370a08231146103d85780637b16c21e1461040c57806395d89b41146104205780639f7b45791461044e578063a9059cbb1461046d578063bedd12a51461048c575f80fd5b806323b872dd1161013857806342966c681161011357806342966c681461036c5780634febf53d1461038b5780635d03147a146103aa57806364c9ec6f146103d0575f80fd5b806323b872dd1461031e57806326749e871461033d578063313ce56714610351575f80fd5b806301339c2114610189578063031bee001461019f57806306fdde0314610253578063095ea7b31461028b57806316f0115b146102ba57806318160ddd14610300575f80fd5b3661018557005b5f80fd5b348015610194575f80fd5b5061019d61058f565b005b3480156101aa575f80fd5b506101b361063f565b6040805184516001600160601b0390811682526020808701518216818401528684015182168385015260608088015183168185015260809788015190921687840152855165ffffffffffff90811660a08501529581015160c08401528451861660e0840152840151851661010083015291830151841661012082015290820151831661014082015292015116610160820152610180015b60405180910390f35b34801561025e575f80fd5b5060408051808201909152600781526625b7ba37902b1960c91b60208201525b60405161024a9190612bab565b348015610296575f80fd5b506102aa6102a5366004612c12565b610728565b604051901515815260200161024a565b3480156102c5575f80fd5b507f000000000000000000000000c9ee693668236fa059cf56cfbedc653766b885de5b6040516001600160a01b03909116815260200161024a565b34801561030b575f80fd5b506004545b60405190815260200161024a565b348015610329575f80fd5b506102aa610338366004612c3a565b610755565b348015610348575f80fd5b506101b3610829565b34801561035c575f80fd5b506040516012815260200161024a565b348015610377575f80fd5b506102aa610386366004612c73565b610912565b348015610396575f80fd5b5061019d6103a5366004612c8a565b61094a565b3480156103b5575f80fd5b5073946ef43867225695e29241813a8f41519634b36b6102e8565b6103106109c9565b3480156103e3575f80fd5b506103106103f2366004612c8a565b6001600160a01b03165f9081526020819052604090205490565b348015610417575f80fd5b50610310611111565b34801561042b575f80fd5b5060408051808201909152600681526525a7aa27ab1960d11b602082015261027e565b348015610459575f80fd5b5061019d610468366004612ca3565b61113e565b348015610478575f80fd5b506102aa610487366004612c12565b6111b9565b348015610497575f80fd5b5073298eca8683000b3911b2e7dd07fd496d8019043e6102e8565b3480156104bd575f80fd5b50610310611200565b3480156104d1575f80fd5b50610310611221565b3480156104e5575f80fd5b5061019d6104f4366004612c8a565b611249565b348015610504575f80fd5b50610310610513366004612c73565b6112d6565b348015610523575f80fd5b50610310610532366004612cc3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610567575f80fd5b50610310610576366004612c73565b611377565b348015610586575f80fd5b5061019d611b5b565b3373946ef43867225695e29241813a8f41519634b36b146105c357604051635fc483c560e01b815260040160405180910390fd5b601554610100900460ff16156105ec576040516319f4db0f60e31b815260040160405180910390fd5b6105f4611bcf565b6015805461ff0019166101001790556040517feca0dfbda743d141662328d4d48393e344b2c60df0430297221df823f2926dba906106359042815260200190565b60405180910390a1565b610647612b7e565b604080518082019091525f8082526020820152610662612b7e565b50506040805160a080820183526007546001600160601b038082168452600160601b91829004811660208086019190915260085480831686880152839004821660608087019190915260095490921660808087019190915286518088018852600a5465ffffffffffff9081168252600b5482850152885196870189526006548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b335f9081526001602081815260408084206001600160a01b03871685529091529091208290555b92915050565b5f6001600160a01b038316158061076a575081155b1561078857604051632f35253160e01b815260040160405180910390fd5b6001600160a01b0384163314610813576001600160a01b0384165f9081526001602090815260408083203384529091529020548211156107db576040516358d246fb60e11b815260040160405180910390fd5b6001600160a01b0384165f9081526001602090815260408083203384529091528120805484929061080d908490612d08565b90915550505b61081e848484611c70565b5060015b9392505050565b610831612b7e565b604080518082019091525f808252602082015261084c612b7e565b50506040805160a08082018352600e546001600160601b038082168452600160601b918290048116602080860191909152600f548083168688015283900482166060808701919091526010549092166080808701919091528651808801885260115465ffffffffffff90811682526012548285015288519687018952600d548082168852600160301b8104821694880194909452948304851697860197909752600160901b8204841692850192909252600160c01b900490911690820152909391925090565b5f61091d3383611e51565b506040518181526001905f9033905f80516020612ec78339815191529060200160405180910390a3919050565b3373946ef43867225695e29241813a8f41519634b36b1461097e57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260026020526040808220805460ff19166001179055517fec2dffa455deca3e695cce255e2b110b5ca334fb5b166f3159bbaad319ce0f1b9190a250565b6015545f9060ff166002036109f15760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff16421115610a1857610a18611ed4565b6007546001600160601b0316156110f7575f60076040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f600a6040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f60056040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050610dee60066040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786612113565b809650819850829750839950505050505f610e1b866020015188602001516001600160601b031685612239565b905080610e3034670de0b6b3a7640000612d1b565b610e3a9190612d46565b6008549098506001600160601b0316881115610e69576040516305c250cf60e11b815260040160405180910390fd5b87875f01818151610e7a9190612d59565b6001600160601b0316905250608087018051349190610e9a908390612d80565b6001600160601b0316905250606087018051899190610eba908390612d80565b6001600160601b0316905250602087018051899190610eda908390612d80565b6001600160601b03169052505f610ef1338a612269565b905080610f115760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a2610f5a8389898989896122ed565b8351600780546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600880546060808d015193891691909616179187168602919091179055608098890151600980546001600160601b0319908116929097169190911790558751600a805465ffffffffffff191665ffffffffffff92831617905597820151600b55865160068054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b93871693909302929092179055815160058054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b91151591909102179055506111019650505050505050565b61110133346124f0565b6015805460ff1916600117905590565b601254600e546004545f92611139929091600160601b9091046001600160601b031690612239565b905090565b3373946ef43867225695e29241813a8f41519634b36b1480159061117657503373298eca8683000b3911b2e7dd07fd496d8019043e14155b1561119457604051636edaef2f60e11b815260040160405180910390fd5b5f61119f8284612da0565b90506111ac333083610755565b5050601391909155601455565b5f6001600160a01b03831615806111ce575081155b156111ec57604051632f35253160e01b815260040160405180910390fd5b6111f7338484611c70565b50600192915050565b6004545f9061121747670de0b6b3a7640000612d1b565b6111399190612d46565b600b546007546004545f92611139929091600160601b9091046001600160601b031690612239565b3373946ef43867225695e29241813a8f41519634b36b1461127d57604051635fc483c560e01b815260040160405180910390fd5b6001600160a01b0381165f81815260036020908152604091829020805460ff1916600117905590519182527f10cdbb821aa416c854add806e1d7e8138afe2a538921cebe99b1351362ae38b2910160405180910390a150565b5f8060045447670de0b6b3a76400006112ef9190612d1b565b6112f99190612d46565b9050670de0b6b3a764000061130e8483612d1b565b6113189190612d46565b91506113243384611e51565b61132e33836124f0565b604080518481526020810184905290810182905233907fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469060600160405180910390a250919050565b6015545f9060ff1660020361139f5760405163558a1e0360e11b815260040160405180910390fd5b6015805460ff19166002179055600a5465ffffffffffff164211156113c6576113c6612547565b600e546001600160601b031615611b49576040516323b872dd60e01b815233600482015273298eca8683000b3911b2e7dd07fd496d8019043e6024820152604481018390527f000000000000000000000000c9ee693668236fa059cf56cfbedc653766b885de6001600160a01b0316906323b872dd906064016020604051808303815f875af115801561145b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061147f9190612db3565b505f600e6040518060a00160405290815f82015f9054906101000a90046001600160601b03166001600160601b03166001600160601b031681526020015f8201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600182015f9054906101000a90046001600160601b03166001600160601b03166001600160601b0316815260200160018201600c9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152602001600282015f9054906101000a90046001600160601b03166001600160601b03166001600160601b03168152505090505f60116040518060400160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815260200160018201548152505090505f600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff168152505090505f600c6040518060800160405290815f82015f9054906101000a90046001600160801b03166001600160801b03166001600160801b031681526020015f820160109054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160169054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201601c9054906101000a900460ff16151515158152505090505f60045490505f429050611845600d6040518060a00160405290815f82015f9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160069054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f8201600c9054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160129054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681526020015f820160189054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff1681525050878786612113565b809650819850829750839950505050505f611872866020015188602001516001600160601b031685612239565b9050806118878a670de0b6b3a7640000612d1b565b6118919190612d46565b600f549098506001600160601b03168811156118c0576040516305c250cf60e11b815260040160405180910390fd5b87875f018181516118d19190612d59565b6001600160601b03169052506080870180518a91906118f1908390612d80565b6001600160601b0316905250606087018051899190611911908390612d80565b6001600160601b0316905250602087018051899190611931908390612d80565b6001600160601b03169052505f611948338a612269565b9050806119685760405163dde1446d60e01b815260040160405180910390fd5b604080518a81526020810184905233917f3ae9ad26d7d47616d306d7757b947fe7b0f9a7c61a5f0dc784b0ddb6c7c40b5a910160405180910390a26119b18389898989896122ed565b8351600e80546020808801516001600160601b039485166001600160c01b031993841617600160601b918616820217909355604080890151600f80546060808d015193891691909616179187168602919091179055608098890151601080546001600160601b03199081169290971691909117905587516011805465ffffffffffff191665ffffffffffff928316179055978201516012558651600d8054898501518a8501518b8801519b909d01516bffffffffffffffffffffffff60601b19948d169290991691909117600160301b918c1691909102179190911699891690940265ffffffffffff60901b191698909817600160901b968816969096029590951765ffffffffffff60c01b1916600160c01b938716939093029290921790558151600c8054948401519684015193909201516001600160801b039091166001600160b01b031990941693909317600160801b958516959095029490941766ffffffffffffff60b01b1916600160b01b919093160260ff60e01b191691909117600160e01b9115159190910217905550505050505050505b6015805460ff19166001179055919050565b3373946ef43867225695e29241813a8f41519634b36b14611b8f57604051635fc483c560e01b815260040160405180910390fd5b611b97611ed4565b611b9f612547565b6040514281527fcb952d4b0fcf5915a9cc714f93cda275771363c8e7fb92af67c20638187b14d390602001610635565b5f805f306001600160a01b03166001600160a01b031681526020019081526020015f2054905060405163f305d71960e01b81526001600160a01b03301660048201528160248201525f60448201525f606482015273298eca8683000b3911b2e7dd07fd496d8019043e60848201524260a48201525f8060c4833031737a250d5630b4cf539739df2c5dacb4c659f2488d5af1905080611c6c575f80fd5b5050565b6001600160a01b0383165f90815260208190526040902054811115611ca85760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f9081526003602052604081205460ff1680611ce557506001600160a01b0384165f9081526003602052604090205460ff165b15611d37576001600160a01b0383165f9081526002602052604090205460ff1680611d2757506001600160a01b0384165f9081526002602052604090205460ff165b15611d3357505f611d37565b5060015b8015611de4575f6103e8611d4c603285612d1b565b611d569190612d46565b6001600160a01b0386165f9081526020819052604081208054869003905573298eca8683000b3911b2e7dd07fd496d8019043e90527f53255b9766a7b4dec69b0f4028a04a78db33a7b0884c22bd3c7db8f24cea5dac8054820190559050611dbe8184612d08565b6001600160a01b0385165f9081526020819052604090208054820190559250611e119050565b6001600160a01b038085165f90815260208190526040808220805486900390559185168152208054830190555b826001600160a01b0316846001600160a01b03165f80516020612ec783398151915284604051611e4391815260200190565b60405180910390a350505050565b6001600160a01b0382165f90815260208190526040902054811115611e895760405163064c392760e21b815260040160405180910390fd5b6001600160a01b0382165f8181526020818152604080832080548690039055600480548690039055518481529192915f80516020612ec7833981519152910160405180910390a35050565b601354801561210c575f611ee661278f565b9050815f62015180611efa83613840612dd2565b6001600160601b0316611f0d9190612d46565b90505f846001600160601b031660045485611f289190612d1b565b611f329190612d46565b90505f611f48846001600160601b031686612881565b90505f611f586201518042612da0565b905081156120b6576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600780546001600160c01b03199081168617600160601b90950294909417905560088054909316909117909155600980546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c9052600a805465ffffffffffff191683179055600b8c9055885196870189524290811680885287870181905262015180888b0152613840888601526107089790980196909652600680549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000000708000000002a360671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612105565b6120c930866001600160601b0316611e51565b6120d66201518042612da0565b600a805465ffffffffffff191665ffffffffffff92909216919091179055600780546001600160601b03191690555b5050505050505b505f601355565b61211b612b7e565b612123612b7e565b6040805180820182525f808252602080830182905283516080810185528281529081018290529283018190526060830152904261216089896128fe565b67ffffffffffffffff168860200181815161217b9190612d59565b6001600160601b031690525065ffffffffffff811660208a015260608601511561222b575f805f6121ab89612940565b925092509250826001600160801b03168a6020018181516121cc9190612d08565b90525080156122205782895f018181516121e69190612dfd565b6001600160801b0316905250604089018051839190612206908390612e1d565b65ffffffffffff908116909152851660208b015250612227565b5f60608a01525b5050505b509597949550929392505050565b5f670de0b6b3a764000061224d84846129d1565b6122579086612d1b565b6122619190612d46565b949350505050565b305f9081526020819052604081205482111561229857604051635e36b3df60e01b815260040160405180910390fd5b506001600160a01b0382165f818152602081815260408083208054860190553080845292819020805486900390555184815260019392915f80516020612ec7833981519152910160405180910390a392915050565b6122f5612b7e565b604080518082019091525f8082526020820152612310612b7e565b604080516080810182525f8082526020820181905291810182905260608101919091526123606040518060a001604052805f81526020015f81526020015f81526020015f81526020015f81525090565b608088015188516123719190612e3c565b65ffffffffffff168b65ffffffffffff16106124de578851612394908c90612e1d565b65ffffffffffff1681526020808a0151908b01516123bc91906001600160601b031688612239565b602082015289516001600160601b031660408201819052815160608a015190916123ee9165ffffffffffff1690612d1b565b6123f89190612d46565b6001600160601b03166040808c019190915281518982015191830151909161242a9165ffffffffffff90911690612d1b565b6124349190612d46565b60608201819052602082015161244b908890612d1b565b6124559190612d46565b6080820181905260208a015111156124c7575f81608001518a6020015161247c9190612d08565b90506040518060800160405280826001600160801b031681526020018d65ffffffffffff1681526020018a6080015165ffffffffffff168152602001600115158152509750506124d2565b608081015160208a01525b65ffffffffffff8b1688525b50979996985094965092949350505050565b5f805f805f85875af19050806125425760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b604482015260640160405180910390fd5b505050565b6014546001600160601b03811615612788575f6125626129ef565b9050815f6201518061257683613840612dd2565b6001600160601b03166125899190612d46565b90505f846001600160601b0316600454856125a49190612d1b565b6125ae9190612d46565b90505f6125c4846001600160601b031686612881565b90505f6125d46201518042612da0565b90508115612732576040805160a080820183526001600160601b038881168084528b82166020808601829052928a168587018190525f6060808801829052608097880191909152600e80546001600160c01b03199081168617600160601b909502949094179055600f8054909316909117909155601080546001600160601b03199081169091558651808801885265ffffffffffff8981168083529186018c90526011805465ffffffffffff19168317905560128c9055885196870189524290811680885287870181905262015180888b0152613840888601526107089790980196909652600d80549092168717600160301b90970296909617600160601b600160f01b0319166c0e1000000000708000000002a360671b179055855191825291810192909252928101919091527f035d6743050a54c5c545b7f45bddbd082bf97e098d81e6eb10045ab6a10ab510910160405180910390a1612781565b61274530866001600160601b0316611e51565b6127526201518042612da0565b6011805465ffffffffffff191665ffffffffffff92909216919091179055600e80546001600160601b03191690555b5050505050505b505f601455565b5f807f000000000000000000000000c9ee693668236fa059cf56cfbedc653766b885de90505f80604051630240bc6b60e21b81525f80600483875afa9050806127d6575f80fd5b5060205f803e60208060203e50505f516020517f00000000000000000000000000000000000000000000000000000000000000001561284757816001600160701b0316816001600160701b0316670de0b6b3a76400006128369190612d1b565b6128409190612d46565b935061287b565b806001600160701b0316826001600160701b0316670de0b6b3a764000061286e9190612d1b565b6128789190612d46565b93505b50505090565b6004545f90816128918583612d08565b6128a347670de0b6b3a7640000612d1b565b6128ad9190612d46565b90505f826128bb8688612d1b565b6128cd47670de0b6b3a7640000612d1b565b6128d79190612da0565b6128e19190612d46565b9050808210156128f25760016128f4565b5f5b9695505050505050565b5f80836020015165ffffffffffff16426129189190612d08565b9050836040015165ffffffffffff168184602001516001600160601b03166122579190612d1b565b5f805f836060015161295957505f9150819050806129ca565b5f84602001514261296a9190612e1d565b90505f856040015165ffffffffffff168265ffffffffffff161090505f816129935786516129c1565b866040015165ffffffffffff168365ffffffffffff16885f01516129b79190612e5b565b6129c19190612e7e565b95509193509150505b9193909250565b5f816129e584670de0b6b3a7640000612d1b565b6108229190612d46565b5f807f000000000000000000000000c9ee693668236fa059cf56cfbedc653766b885de90505f805f604051630240bc6b60e21b81525f80600483885afa80612a35575f80fd5b5060205f803e60208060203e5f51935060205192506318160ddd60e01b602082015260205f600460208401885afa50505f5190507f000000000000000000000000000000000000000000000000000000000000000015612abc57612ab5612a9d846002612ea3565b6001600160701b0316670de0b6b3a764000083612ad4565b9450612acd565b612aca612a9d836002612ea3565b94505b5050505090565b5f80805f19858709858702925082811083820303915050805f03612b08575f8411612afd575f80fd5b508290049050610822565b808411612b13575f80fd5b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290565b5f602080835283518060208501525f5b81811015612bd757858101830151858201604001528201612bbb565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114612c0d575f80fd5b919050565b5f8060408385031215612c23575f80fd5b612c2c83612bf7565b946020939093013593505050565b5f805f60608486031215612c4c575f80fd5b612c5584612bf7565b9250612c6360208501612bf7565b9150604084013590509250925092565b5f60208284031215612c83575f80fd5b5035919050565b5f60208284031215612c9a575f80fd5b61082282612bf7565b5f8060408385031215612cb4575f80fd5b50508035926020909101359150565b5f8060408385031215612cd4575f80fd5b612cdd83612bf7565b9150612ceb60208401612bf7565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561074f5761074f612cf4565b808202811582820484141761074f5761074f612cf4565b634e487b7160e01b5f52601260045260245ffd5b5f82612d5457612d54612d32565b500490565b6001600160601b03828116828216039080821115612d7957612d79612cf4565b5092915050565b6001600160601b03818116838216019080821115612d7957612d79612cf4565b8082018082111561074f5761074f612cf4565b5f60208284031215612dc3575f80fd5b81518015158114610822575f80fd5b6001600160601b03818116838216028082169190828114612df557612df5612cf4565b505092915050565b6001600160801b03828116828216039080821115612d7957612d79612cf4565b65ffffffffffff828116828216039080821115612d7957612d79612cf4565b65ffffffffffff818116838216019080821115612d7957612d79612cf4565b6001600160801b03818116838216028082169190828114612df557612df5612cf4565b5f6001600160801b0380841680612e9757612e97612d32565b92169190910492915050565b6001600160701b03818116838216028082169190828114612df557612df5612cf456feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220afcbc2e2988b20d46fa776fb380f2dab45fdbe73baf76659fb97e576a0841a8764736f6c63430008160033

Deployed Bytecode Sourcemap

904:25190:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13057:232;;;;;;;;;;;;;:::i;:::-;;11753:203;;;;;;;;;;;;;:::i;:::-;;;;420:13:6;;-1:-1:-1;;;;;416:22:6;;;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;11753:203:2;;;;;;;;9734:80;;;;;;;;;;-1:-1:-1;9803:4:2;;;;;;;;;;;;-1:-1:-1;;;9803:4:2;;;;9734:80;;;;;;;:::i;4418:192::-;;;;;;;;;;-1:-1:-1;4418:192:2;;;;;:::i;:::-;;:::i;:::-;;;2392:14:6;;2385:22;2367:41;;2355:2;2340:18;4418:192:2;2227:187:6;10839:76:2;;;;;;;;;;-1:-1:-1;10904:4:2;10839:76;;;-1:-1:-1;;;;;2583:32:6;;;2565:51;;2553:2;2538:18;10839:76:2;2419:203:6;10115:89:2;;;;;;;;;;-1:-1:-1;10185:12:2;;10115:89;;;2773:25:6;;;2761:2;2746:18;10115:89:2;2627:177:6;3990:422:2;;;;;;;;;;-1:-1:-1;3990:422:2;;;;;:::i;:::-;;:::i;11962:211::-;;;;;;;;;;;;;:::i;9986:80::-;;;;;;;;;;-1:-1:-1;9986:80:2;;2055:2;3284:36:6;;3272:2;3257:18;9986:80:2;3142:184:6;9432:183:2;;;;;;;;;;-1:-1:-1;9432:183:2;;;;;:::i;:::-;;:::i;12564:165::-;;;;;;;;;;-1:-1:-1;12564:165:2;;;;;:::i;:::-;;:::i;11086:82::-;;;;;;;;;;-1:-1:-1;2482:42:2;11086:82;;4794:1973;;;:::i;10320:106::-;;;;;;;;;;-1:-1:-1;10320:106:2;;;;;:::i;:::-;-1:-1:-1;;;;;10402:17:2;10376:7;10402:17;;;;;;;;;;;;10320:106;11377:163;;;;;;;;;;;;;:::i;9857:84::-;;;;;;;;;;-1:-1:-1;9928:6:2;;;;;;;;;;;;-1:-1:-1;;;9928:6:2;;;;9857:84;;13720:357;;;;;;;;;;-1:-1:-1;13720:357:2;;;;;:::i;:::-;;:::i;3763:221::-;;;;;;;;;;-1:-1:-1;3763:221:2;;;;;:::i;:::-;;:::i;12179:93::-;;;;;;;;;;-1:-1:-1;2573:42:2;12179:93;;11617:130;;;;;;;;;;;;;:::i;11214:157::-;;;;;;;;;;;;;:::i;12830:159::-;;;;;;;;;;-1:-1:-1;12830:159:2;;;;;:::i;:::-;;:::i;8947:379::-;;;;;;;;;;-1:-1:-1;8947:379:2;;;;;:::i;:::-;;:::i;10643:140::-;;;;;;;;;;-1:-1:-1;10643:140:2;;;;;:::i;:::-;-1:-1:-1;;;;;10749:18:2;;;10723:7;10749:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;10643:140;6773:1947;;;;;;;;;;-1:-1:-1;6773:1947:2;;;;;:::i;:::-;;:::i;13479:177::-;;;;;;;;;;;;;:::i;13057:232::-;13098:10;2482:42;13098:19;13094:43;;13126:11;;-1:-1:-1;;;13126:11:2;;;;;;;;;;;13094:43;13151:8;;;;;;;13147:38;;;13168:17;;-1:-1:-1;;;13168:17:2;;;;;;;;;;;13147:38;13195:22;:20;:22::i;:::-;13227:8;:15;;-1:-1:-1;;13227:15:2;;;;;13257:25;;;;;;13266:15;2773:25:6;;2761:2;2746:18;;2627:177;13257:25:2;;;;;;;;13057:232::o;11753:203::-;11822:28;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;11880:26:2;;:::i;:::-;-1:-1:-1;;11922:27:2;;;;;;;;;11930:6;11922:27;-1:-1:-1;;;;;11922:27:2;;;;;-1:-1:-1;;;11922:27:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11938:4;11922:27;;;;;;;;;;;;;;;;;;;;11944:4;11922:27;;;;;;-1:-1:-1;;;11922:27:2;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11922:27:2;;;;;;;;;;;-1:-1:-1;;;11922:27:2;;;;;;;;;;;;;-1:-1:-1;11922:27:2;11753:203::o;4418:192::-;4525:10;4485:12;4545:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4545:28:2;;;;;;;;;;:37;;;4418:192;;;;;:::o;3990:422::-;4072:12;-1:-1:-1;;;;;4100:17:2;;;;:32;;-1:-1:-1;4121:11:2;;4100:32;4096:62;;;4141:17;;-1:-1:-1;;;4141:17:2;;;;;;;;;;;4096:62;-1:-1:-1;;;;;4172:19:2;;4181:10;4172:19;4168:178;;-1:-1:-1;;;;;4211:18:2;;;;;;:11;:18;;;;;;;;4230:10;4211:30;;;;;;;;:39;-1:-1:-1;4207:74:2;;;4259:22;;-1:-1:-1;;;4259:22:2;;;;;;;;;;;4207:74;-1:-1:-1;;;;;4295:18:2;;;;;;:11;:18;;;;;;;;4314:10;4295:30;;;;;;;:40;;4329:6;;4295:18;:40;;4329:6;;4295:40;:::i;:::-;;;;-1:-1:-1;;4168:178:2;4355:29;4365:5;4372:3;4377:6;4355:9;:29::i;:::-;-1:-1:-1;4401:4:2;3990:422;;;;;;:::o;11962:211::-;12033:28;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;12091:26:2;;:::i;:::-;-1:-1:-1;;12133:33:2;;;;;;;;;12141:8;12133:33;-1:-1:-1;;;;;12133:33:2;;;;;-1:-1:-1;;;12133:33:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12151:6;12133:33;;;;;;;;;;;;;;;;;;;;12159:6;12133:33;;;;;;-1:-1:-1;;;12133:33:2;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;12133:33:2;;;;;;;;;;;-1:-1:-1;;;12133:33:2;;;;;;;;;;;;;-1:-1:-1;12133:33:2;11962:211::o;9432:183::-;9480:12;9504:25;9510:10;9522:6;9504:5;:25::i;:::-;-1:-1:-1;9568:40:2;;2773:25:6;;;9549:4:2;;9597:1;;9577:10;;-1:-1:-1;;;;;;;;;;;9568:40:2;2761:2:6;2746:18;9568:40:2;;;;;;;9432:183;;;:::o;12564:165::-;12618:10;2482:42;12618:19;12614:43;;12646:11;;-1:-1:-1;;;12646:11:2;;;;;;;;;;;12614:43;-1:-1:-1;;;;;12667:15:2;;;;;;:9;:15;;;;;;:22;;-1:-1:-1;;12667:22:2;12685:4;12667:22;;;12704:18;;;12667:15;12704:18;12564:165;:::o;4794:1973::-;2906:6;;4839:14;;2906:6;;2916:1;2906:11;2902:36;;2926:12;;-1:-1:-1;;;2926:12:2;;;;;;;;;;;2902:36;2948:6;:10;;-1:-1:-1;;2948:10:2;2957:1;2948:10;;;4952:4:::1;:15:::0;::::1;;4934;:33;4930:73;;;4983:9;:7;:9::i;:::-;5016:6;:15:::0;-1:-1:-1;;;;;5016:15:2::1;:20:::0;5012:1749:::1;;5123:36;5162:6;5123:45;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;-1:-1:-1::0;;;;;5123:45:2::1;;;::::0;::::1;;;5182:32;5217:4;5182:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5235:32;5270:4;5235:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5288:44;5335:10;5288:57;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;5288:57:2::1;-1:-1:-1::0;;;;;5288:57:2::1;-1:-1:-1::0;;;;;5288:57:2::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;5359:15;5377:12;;5359:30;;5403:11;5424:15;5403:37;;5566:55;5587:4;5566:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;5593:7;5602:5;5609:11;5566:20;:55::i;:::-;5527:94;;;;;;;;;;;;;;;;5636:13;5652:77;5679:5;:21;;;5702:7;:17;;;-1:-1:-1::0;;;;;5652:77:2::1;5721:7;5652:26;:77::i;:::-;5636:93:::0;-1:-1:-1;5636:93:2;5754:16:::1;:9;5766:4;5754:16;:::i;:::-;:24;;;;:::i;:::-;5806:16:::0;;5744:35;;-1:-1:-1;;;;;;5806:16:2::1;5797:25:::0;::::1;5793:49;;;5831:11;;-1:-1:-1::0;;;5831:11:2::1;;;;;;;;;;;5793:49;5923:6;5896:7;:16;;:34;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5896:34:2::1;::::0;;-1:-1:-1;5944:17:2::1;::::0;::::1;:38:::0;;5972:9:::1;::::0;5944:17;:38:::1;::::0;5972:9;;5944:38:::1;:::i;:::-;-1:-1:-1::0;;;;;5944:38:2::1;::::0;;-1:-1:-1;5996:12:2::1;::::0;::::1;:30:::0;;6019:6;;5996:12;:30:::1;::::0;6019:6;;5996:30:::1;:::i;:::-;-1:-1:-1::0;;;;;5996:30:2::1;::::0;;-1:-1:-1;6040:17:2::1;::::0;::::1;:35:::0;;6068:6;;6040:17;:35:::1;::::0;6068:6;;6040:35:::1;:::i;:::-;-1:-1:-1::0;;;;;6040:35:2::1;::::0;;-1:-1:-1;6090:12:2::1;6105:25;6111:10;6123:6:::0;6105:5:::1;:25::i;:::-;6090:40;;6149:7;6144:33;;6165:12;;-1:-1:-1::0;;;6165:12:2::1;;;;;;;;;;;6144:33;6196:31;::::0;;5483:25:6;;;5539:2;5524:18;;5517:34;;;6201:10:2::1;::::0;6196:31:::1;::::0;5456:18:6;6196:31:2::1;;;;;;;6356:70;6376:4;6382:7;6391:5;6398;6405:11;6418:7;6356:19;:70::i;:::-;6482:16:::0;;:6:::1;:16:::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;6482:16:2;;::::1;-1:-1:-1::0;;;;;;6482:16:2;;;;-1:-1:-1;;;6482: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;;;;;;6482:16:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;6512:12;;:4:::1;:12:::0;;-1:-1:-1;;6512:12:2::1;;::::0;;::::1;;::::0;;;;::::1;::::0;;;6538;;:4:::1;:12:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;6538:12:2;;::::1;::::0;;;;;;;;-1:-1:-1;;;6538:12:2;;::::1;::::0;;;::::1;;::::0;;;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;6538:12:2;;;;;-1:-1:-1;;;6538:12:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;6538:12:2::1;-1:-1:-1::0;;;6538:12:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;6564:24;;-1:-1:-1;6564:24:2;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;;6564:24:2;;::::1;-1:-1:-1::0;;;;;;6564:24:2;;;;;;;-1:-1:-1;;;6564:24:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;6564:24:2;-1:-1:-1;;;6564:24:2;;;::::1;;-1:-1:-1::0;;;;6564:24:2;;;;;-1:-1:-1;;;6564:24:2;::::1;;::::0;;;::::1;;::::0;;-1:-1:-1;5012:1749:2::1;::::0;-1:-1:-1;;;;;;;5012:1749:2::1;;6696:54;6728:10;6740:9;6696:31;:54::i;:::-;2979:6:::0;:10;;-1:-1:-1;;2979:10:2;2988:1;2979:10;;;4794:1973;:::o;11377:163::-;11476:22;;11500:8;:18;11520:12;;11423:7;;11449:84;;11476:22;;-1:-1:-1;;;11500:18:2;;;-1:-1:-1;;;;;11500:18:2;;11449:26;:84::i;:::-;11442:91;;11377:163;:::o;13720:357::-;13804:10;2482:42;13804:19;;;;:52;;-1:-1:-1;13827:10:2;2573:42;13827:29;;13804:52;13800:80;;;13865:15;;-1:-1:-1;;;13865:15:2;;;;;;;;;;;13800:80;13890:13;13906:28;13922:12;13906:13;:28;:::i;:::-;13890:44;;13944:46;13957:10;13977:4;13984:5;13944:12;:46::i;:::-;-1:-1:-1;;14000:15:2;:31;;;;14041:14;:29;13720:357::o;3763:221::-;3826:12;-1:-1:-1;;;;;3854:17:2;;;;:32;;-1:-1:-1;3875:11:2;;3854:32;3850:62;;;3895:17;;-1:-1:-1;;;3895:17:2;;;;;;;;;;;3850:62;3922:34;3932:10;3944:3;3949:6;3922:9;:34::i;:::-;-1:-1:-1;3973:4:2;3763:221;;;;:::o;11617:130::-;11727:12;;11667:7;;11695:28;:21;11719:4;11695:28;:::i;:::-;11694:45;;;;:::i;11214:157::-;11311:20;;11333:6;:16;11351:12;;11258:7;;11284:80;;11311:20;;-1:-1:-1;;;11333:16:2;;;-1:-1:-1;;;;;11333:16:2;;11284:26;:80::i;12830:159::-;12884:10;2482:42;12884:19;12880:43;;12912:11;;-1:-1:-1;;;12912:11:2;;;;;;;;;;;12880:43;-1:-1:-1;;;;;12933:12:2;;;;;;:5;:12;;;;;;;;;:19;;-1:-1:-1;;12933:19:2;12948:4;12933:19;;;12967:15;;2565:51:6;;;12967:15:2;;2538:18:6;12967:15:2;;;;;;;12830:159;:::o;8947:379::-;8997:14;9064:13;9113:12;;9081:21;9105:4;9081:28;;;;:::i;:::-;9080:45;;;;:::i;:::-;9064:61;-1:-1:-1;9163:4:2;9145:14;9153:6;9064:61;9145:14;:::i;:::-;9144:23;;;;:::i;:::-;9135:32;;9177:25;9183:10;9195:6;9177:5;:25::i;:::-;9212:51;9244:10;9256:6;9212:31;:51::i;:::-;9278:41;;;5894:25:6;;;5950:2;5935:18;;5928:34;;;5978:18;;;5971:34;;;9285:10:2;;9278:41;;5882:2:6;5867:18;9278:41:2;;;;;;;9013:313;8947:379;;;:::o;6773:1947::-;2906:6;;6829:14;;2906:6;;2916:1;2906:11;2902:36;;2926:12;;-1:-1:-1;;;2926:12:2;;;;;;;;;;;2902:36;2948:6;:10;;-1:-1:-1;;2948:10:2;2957:1;2948:10;;;6942:4:::1;:15:::0;::::1;;6924;:33;6920:81;;;6973:17;:15;:17::i;:::-;7014:8;:17:::0;-1:-1:-1;;;;;7014:17:2::1;:22:::0;7010:1704:::1;;7052:81;::::0;-1:-1:-1;;;7052:81:2;;7085:10:::1;7052:81;::::0;::::1;6256:34:6::0;2573:42:2::1;6306:18:6::0;;;6299:43;6358:18;;;6351:34;;;7066:4:2::1;-1:-1:-1::0;;;;;7052:32:2::1;::::0;::::1;::::0;6191:18:6;;7052:81:2::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7218:36;7257:8;7218:47;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;-1:-1:-1::0;;;;;7218:47:2::1;;;::::0;::::1;;;7279:32;7314:6;7279:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7334:32;7369:6;7334:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7389:44;7436:12;7389:59;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;7389:59:2::1;-1:-1:-1::0;;;;;7389:59:2::1;-1:-1:-1::0;;;;;7389:59:2::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;7462:15;7480:12;;7462:30;;7506:11;7527:15;7506:37;;7669:57;7690:6;7669:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;7698:7;7707:5;7714:11;7669:20;:57::i;:::-;7630:96;;;;;;;;;;;;;;;;7741:13;7757:77;7784:5;:21;;;7807:7;:17;;;-1:-1:-1::0;;;;;7757:77:2::1;7826:7;7757:26;:77::i;:::-;7741:93:::0;-1:-1:-1;7741:93:2;7859:16:::1;:9:::0;7871:4:::1;7859:16;:::i;:::-;:24;;;;:::i;:::-;7911:18:::0;;7849:35;;-1:-1:-1;;;;;;7911:18:2::1;7902:27:::0;::::1;7898:51;;;7938:11;;-1:-1:-1::0;;;7938:11:2::1;;;;;;;;;;;7898:51;8030:6;8003:7;:16;;:34;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8003:34:2::1;::::0;;-1:-1:-1;8051:17:2::1;::::0;::::1;:38:::0;;8079:9;;8051:17;:38:::1;::::0;8079:9;;8051:38:::1;:::i;:::-;-1:-1:-1::0;;;;;8051:38:2::1;::::0;;-1:-1:-1;8103:12:2::1;::::0;::::1;:30:::0;;8126:6;;8103:12;:30:::1;::::0;8126:6;;8103:30:::1;:::i;:::-;-1:-1:-1::0;;;;;8103:30:2::1;::::0;;-1:-1:-1;8147:17:2::1;::::0;::::1;:35:::0;;8175:6;;8147:17;:35:::1;::::0;8175:6;;8147:35:::1;:::i;:::-;-1:-1:-1::0;;;;;8147:35:2::1;::::0;;-1:-1:-1;8197:12:2::1;8212:25;8218:10;8230:6:::0;8212:5:::1;:25::i;:::-;8197:40;;8256:7;8251:33;;8272:12;;-1:-1:-1::0;;;8272:12:2::1;;;;;;;;;;;8251:33;8303:31;::::0;;5483:25:6;;;5539:2;5524:18;;5517:34;;;8308:10:2::1;::::0;8303:31:::1;::::0;5456:18:6;8303:31:2::1;;;;;;;8463:70;8483:4;8489:7;8498:5;8505;8512:11;8525:7;8463:19;:70::i;:::-;8589:18:::0;;:8:::1;:18:::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;8589:18:2;;::::1;-1:-1:-1::0;;;;;;8589:18:2;;;;-1:-1:-1;;;8589: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;;;;;;8589:18:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8621:14;;:6:::1;:14:::0;;-1:-1:-1;;8621:14:2::1;;::::0;;::::1;;::::0;;;;::::1;::::0;;;8649;;:6:::1;:14:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;8649:14:2;;::::1;::::0;;;;;;;;-1:-1:-1;;;8649:14:2;;::::1;::::0;;;::::1;;::::0;;;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;8649:14:2;;;;;-1:-1:-1;;;8649:14:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;8649:14:2::1;-1:-1:-1::0;;;8649:14:2;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8677:26;;8589:18:::1;8677:26:::0;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;-1:-1:-1;;;;;8677:26:2;;::::1;-1:-1:-1::0;;;;;;8677:26:2;;;;;;;-1:-1:-1;;;8677:26:2;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;8677:26:2;-1:-1:-1;;;8677:26:2;;;::::1;;-1:-1:-1::0;;;;8677:26:2;;;;;-1:-1:-1;;;8677:26:2;::::1;;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;;;;7010:1704:2::1;2979:6:::0;:10;;-1:-1:-1;;2979:10:2;2988:1;2979:10;;;6773:1947;;-1:-1:-1;6773:1947:2:o;13479:177::-;13518:10;2482:42;13518:19;13514:43;;13546:11;;-1:-1:-1;;;13546:11:2;;;;;;;;;;;13514:43;13567:9;:7;:9::i;:::-;13586:17;:15;:17::i;:::-;13618:31;;13633:15;2773:25:6;;13618:31:2;;2761:2:6;2746:18;13618:31:2;2627:177:6;14932:708:2;14982:19;15004:9;:24;15022:4;-1:-1:-1;;;;;15004:24:2;-1:-1:-1;;;;;15004:24:2;;;;;;;;;;;;;14982:46;;15078:4;15072:11;-1:-1:-1;;;15103:3:2;15096:79;-1:-1:-1;;;;;15212:9:2;15208:58;15204:1;15199:3;15195:11;15188:79;15301:11;15296:2;15291:3;15287:12;15280:33;15347:1;15342:2;15337:3;15333:12;15326:23;15384:1;15378:3;15373;15369:13;15362:24;15421:15;15415:3;15410;15406:13;15399:38;15472:11;15466:3;15461;15457:13;15450:34;15575:1;15572;15567:3;15562;15550:9;15542:18;15523:17;15516:5;15511:66;15497:80;;15600:6;15590:34;;15620:1;15617;15610:12;15590:34;;15047:587;14932:708::o;19773:856::-;-1:-1:-1;;;;;19865:15:2;;:9;:15;;;;;;;;;;;19856:24;;19852:57;;;19889:20;;-1:-1:-1;;;19889:20:2;;;;;;;;;;;19852:57;-1:-1:-1;;;;;19942:9:2;;19919;19942;;;:5;:9;;;;;;;;;:24;;-1:-1:-1;;;;;;19955:11:2;;;;;;:5;:11;;;;;;;;19942:24;19938:187;;;-1:-1:-1;;;;;19986:13:2;;;;;;:9;:13;;;;;;;;;:32;;-1:-1:-1;;;;;;20003:15:2;;;;;;:9;:15;;;;;;;;19986:32;19982:133;;;-1:-1:-1;20045:5:2;19982:133;;;-1:-1:-1;20096:4:2;19982:133;20138:4;20134:448;;;20158:11;20189:4;20173:12;2135:2;20173:6;:12;:::i;:::-;20172:21;;;;:::i;:::-;-1:-1:-1;;;;;20236:15:2;;:9;:15;;;;;;;;;;:25;;;;;;;2573:42;20279:26;;;:33;;;;;;20158:35;-1:-1:-1;20340:13:2;20158:35;20255:6;20340:13;:::i;:::-;-1:-1:-1;;;;;20395:13:2;;:9;:13;;;;;;;;;;:23;;;;;;20340:13;-1:-1:-1;20134:448:2;;-1:-1:-1;20134:448:2;;-1:-1:-1;;;;;20491:15:2;;;:9;:15;;;;;;;;;;;:25;;;;;;;20534:13;;;;;;:23;;;;;;20134:448;20611:2;-1:-1:-1;;;;;20596:26:2;20605:4;-1:-1:-1;;;;;20596:26:2;-1:-1:-1;;;;;;;;;;;20615:6:2;20596:26;;;;2773:25:6;;2761:2;2746:18;;2627:177;20596:26:2;;;;;;;;19842:787;19773:856;;;:::o;21231:276::-;-1:-1:-1;;;;;21297:15:2;;:9;:15;;;;;;;;;;;:23;-1:-1:-1;21293:56:2;;;21329:20;;-1:-1:-1;;;21329:20:2;;;;;;;;;;;21293:56;-1:-1:-1;;;;;21383:15:2;;:9;:15;;;;;;;;;;;:24;;;;;;;21421:12;:21;;;;;;;21467:33;2773:25:6;;;21383:9:2;;:15;-1:-1:-1;;;;;;;;;;;21467:33:2;2746:18:6;21467:33:2;;;;;;;21231:276;;:::o;15965:1394::-;16090:15;;16120:19;;16116:1208;;16155:20;16178:11;:9;:11::i;:::-;16155:34;-1:-1:-1;16222:10:2;16204:15;2769:5;16272:18;16222:10;16285:5;16272:18;:::i;:::-;-1:-1:-1;;;;;16272:29:2;;;;;:::i;:::-;16246:56;;16316:23;16372:10;-1:-1:-1;;;;;16342:40:2;16357:12;;16342;:27;;;;:::i;:::-;:40;;;;:::i;:::-;16316:66;;16396:11;16410:31;16418:8;-1:-1:-1;;;;;16410:31:2;16428:12;16410:7;:31::i;:::-;16396:45;-1:-1:-1;16455:17:2;16482:26;2769:5;16482:15;:26;:::i;:::-;16455:54;;16528:6;16524:790;;;16563:60;;;;;;;;;-1:-1:-1;;;;;16563:60:2;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16563:60:2;;;;;;;;;;;;;;;16554:6;:69;;-1:-1:-1;;;;;;16554:69:2;;;;;-1:-1:-1;;;16554:69:2;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16554:69:2;;;;;;16648:48;;;;;;;;;;;;;;;;;;;;16641:4;:55;;-1:-1:-1;;16641:55:2;;;;;;;;;16741:100;;;;;;;16768:15;16741:100;;;;;;;;;;;;2769:5;16741:100;;;;16829:5;16741:100;;;;16836:4;16741:100;;;;;;;;16714:4;:127;;;;;;;-1:-1:-1;;;16714:127:2;;;;;;;-1:-1:-1;;;;;;;;16714:127:2;-1:-1:-1;;;16714:127:2;;;16864:51;;7147:58:6;;;7221:18;;;7214:34;;;;7264:18;;;7257:55;;;;16864:51:2;;7120:18:6;16864:51:2;;;;;;;16524:790;;;16954:30;16968:4;16975:8;-1:-1:-1;;;;;16954:30:2;:5;:30::i;:::-;17235:26;2769:5;17235:15;:26;:::i;:::-;17210:4;:52;;-1:-1:-1;;17210:52:2;;;;;;;;;;;;17280:6;:19;;-1:-1:-1;;;;;;17280:19:2;;;16524:790;16141:1183;;;;;;16116:1208;-1:-1:-1;17351:1:2;17333:15;:19;15965:1394::o;1055:845:3:-;1207:13;;:::i;:::-;1222:11;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1302:15:3;1348:23;1358:4;1364:6;1348:9;:23::i;:::-;1328:43;;:6;:16;;:43;;;;;;;:::i;:::-;-1:-1:-1;;;;;1328:43:3;;;-1:-1:-1;1381:21:3;;;:14;;;:21;1417:18;;;;1413:430;;;1452:16;1470:9;1481:16;1501:25;1514:11;1501:12;:25::i;:::-;1451:75;;;;;;1565:8;-1:-1:-1;;;;;1540:33:3;:5;:21;;:33;;;;;;;:::i;:::-;;;-1:-1:-1;1587:246:3;;;;1644:8;1622:11;:18;;:30;;;;;;;:::i;:::-;-1:-1:-1;;;;;1622:30:3;;;-1:-1:-1;1670:26:3;;;:32;;1700:2;;1670:26;:32;;1700:2;;1670:32;:::i;:::-;;;;;;;;1720:33;;:26;;;:33;-1:-1:-1;1587:246:3;;;1813:5;1792:18;;;:26;1587:246;1437:406;;;1413:430;-1:-1:-1;1860:6:3;;1874:5;;-1:-1:-1;1881:11:3;;1055:845;-1:-1:-1;;;1055:845:3:o;2342:238::-;2478:7;2568:4;2529:35;2539:10;2551:12;2529:9;:35::i;:::-;2510:54;;:16;:54;:::i;:::-;2509:63;;;;:::i;:::-;2501:72;2342:238;-1:-1:-1;;;;2342:238:3:o;21745:348:2:-;21858:4;21804:12;21840:24;;;;;;;;;;;21832:32;;21828:72;;;21873:27;;-1:-1:-1;;;21873:27:2;;;;;;;;;;;21828:72;-1:-1:-1;;;;;;21934:13:2;;:9;:13;;;;;;;;;;;:22;;;;;;21988:4;21970:24;;;;;;;:33;;;;;;;22052:34;2773:25:6;;;-1:-1:-1;;21934:13:2;21988:4;-1:-1:-1;;;;;;;;;;;22052:34:2;2746:18:6;22052:34:2;;;;;;;21745:348;;;;:::o;3140:1200:3:-;3354:13;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;3382:11:3;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3424:22:3;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3424:22:3;3484:17;;;;3468:13;;:33;;3484:17;3468:33;:::i;:::-;3460:41;;:4;:41;;;3456:829;;3535:15;;:22;;3553:4;;3535:22;:::i;:::-;3517:40;;;;3597:20;;;;;3619:16;;;;3585:65;;3597:20;-1:-1:-1;;;;;3585:65:3;3637:12;3585:11;:65::i;:::-;3571:11;;;:79;3681:15;;-1:-1:-1;;;;;3664:32:3;:14;;;:32;;;3777:15;;3754:20;;;;3777:15;;3737:37;;;;;;:::i;:::-;:55;;;;:::i;:::-;-1:-1:-1;;;;;3710:84:3;:16;;;;:84;;;;3858:15;;3844:11;;;;3827:14;;;;3858:15;;3827:28;;;;;;;;:::i;:::-;:46;;;;:::i;:::-;3808:16;;;:65;;;3900:11;;;;:26;;3914:12;;3900:26;:::i;:::-;3899:47;;;;:::i;:::-;3887:9;;;:59;;;3977:20;;;;-1:-1:-1;3961:280:3;;;4017:14;4065:5;:9;;;4042:4;:20;;;:32;;;;:::i;:::-;4017:58;;4106:49;;;;;;;;4117:6;-1:-1:-1;;;;;4106:49:3;;;;;4125:4;4106:49;;;;;;4131:4;:17;;;4106:49;;;;;;4150:4;4106:49;;;;;4093:62;;3999:171;3961:280;;;4217:9;;;;4194:20;;;:32;3961:280;4254:20;;;;;3456:829;-1:-1:-1;4302:6:3;;4310:4;;-1:-1:-1;4316:4:3;;-1:-1:-1;4322:10:3;;3140:1200;-1:-1:-1;;;;3140: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;;8095:2:6;1092:39:1;;;8077:21:6;8134:2;8114:18;;;8107:30;-1:-1:-1;;;8153:18:6;;;8146:49;8212:18;;1092:39:1;;;;;;;;861:277;799:339;;:::o;17365:1345:2:-;17437:14;;-1:-1:-1;;;;;17466:14:2;;;17462:1214;;17496:20;17519:13;:11;:13::i;:::-;17496:36;-1:-1:-1;17564:10:2;17546:15;2769:5;17614:18;17564:10;17627:5;17614:18;:::i;:::-;-1:-1:-1;;;;;17614:29:2;;;;;:::i;:::-;17588:56;;17658:23;17714:10;-1:-1:-1;;;;;17684:40:2;17699:12;;17684;:27;;;;:::i;:::-;:40;;;;:::i;:::-;17658:66;;17738:11;17752:31;17760:8;-1:-1:-1;;;;;17752:31:2;17770:12;17752:7;:31::i;:::-;17738:45;-1:-1:-1;17797:17:2;17824:26;2769:5;17824:15;:26;:::i;:::-;17797:54;;17870:6;17866:800;;;17907:60;;;;;;;;;-1:-1:-1;;;;;17907:60:2;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17907:60:2;;;;;;;;;;;;;;;17896:8;:71;;-1:-1:-1;;;;;;17896:71:2;;;;;-1:-1:-1;;;17896:71:2;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;17896:71:2;;;;;;17994:48;;;;;;;;;;;;;;;;;;;;17985:6;:57;;-1:-1:-1;;17985:57:2;;;;;;;;;18089:100;;;;;;;18116:15;18089:100;;;;;;;;;;;;2769:5;18089:100;;;;18177:5;18089:100;;;;18184:4;18089:100;;;;;;;;18060:6;:129;;;;;;;-1:-1:-1;;;18060:129:2;;;;;;;-1:-1:-1;;;;;;;;18060:129:2;-1:-1:-1;;;18060:129:2;;;18212:51;;7147:58:6;;;7221:18;;;7214:34;;;;7264:18;;;7257:55;;;;18212:51:2;;7120:18:6;18212:51:2;;;;;;;17866:800;;;18302:30;18316:4;18323:8;-1:-1:-1;;;;;18302:30:2;:5;:30::i;:::-;18585:26;2769:5;18585:15;:26;:::i;:::-;18558:6;:54;;-1:-1:-1;;18558:54:2;;;;;;;;;;;;18630:8;:21;;-1:-1:-1;;;;;;18630:21:2;;;17866:800;17482:1194;;;;;;17462:1214;-1:-1:-1;18702:1:2;18685:14;:18;17365:1345::o;22291:762::-;22334:13;22359;22375:4;22359:20;;22389:16;22415;22481:4;22475:11;-1:-1:-1;;;22506:3:2;22499:79;22642:1;22639;22636;22631:3;22624:5;22617;22606:38;22591:53;;22667:7;22657:35;;22688:1;22685;22678:12;22657:35;;22729:2;22726:1;22720:4;22705:27;22772:2;22766:4;22760;22745:30;-1:-1:-1;;22806:4:2;22800:11;22842:4;22836:11;22871:10;22867:180;;;22942:8;-1:-1:-1;;;;;22934:17:2;22914:8;-1:-1:-1;;;;;22906:17:2;22926:4;22906:24;;;;:::i;:::-;22905:46;;;;:::i;:::-;22897:54;;22867:180;;;23027:8;-1:-1:-1;;;;;23019:17:2;22999:8;-1:-1:-1;;;;;22991:17:2;23011:4;22991:24;;;;:::i;:::-;22990:46;;;;:::i;:::-;22982:54;;22867:180;22349:704;;;22291:762;:::o;19388:379::-;19502:12;;19460:13;;;19581:17;19590:8;19502:12;19581:17;:::i;:::-;19548:28;:21;19572:4;19548:28;:::i;:::-;19547:52;;;;:::i;:::-;19524:75;-1:-1:-1;19609:20:2;19690:6;19668:16;19679:5;19668:8;:16;:::i;:::-;19634:28;:21;19658:4;19634:28;:::i;:::-;19633:53;;;;:::i;:::-;19632:64;;;;:::i;:::-;19609:87;;19733:12;19717;:28;;:43;;19756:4;19717:43;;;19748:5;19717:43;19706:54;19388:379;-1:-1:-1;;;;;;19388:379:2:o;2745:234:3:-;2827:6;2845:20;2886:4;:14;;;2868:32;;:15;:32;;;;:::i;:::-;2845:55;;2960:4;:11;;;2924:47;;2944:12;2925:6;:16;;;-1:-1:-1;;;;;2925:31:3;;;;;:::i;1906:430::-;1975:7;1984:6;1992:4;2013;:11;;;2008:38;;-1:-1:-1;2034:1:3;;-1:-1:-1;2034:1:3;;-1:-1:-1;2034:1:3;2026:20;;2008:38;2057:19;2105:4;:19;;;2086:15;2079:45;;;;:::i;:::-;2057:67;;2134:11;2163:4;:19;;;2148:34;;:12;:34;;;2134:48;;2192:14;2209:6;:73;;2271:11;;2209:73;;;2249:4;:19;;;2218:50;;2233:12;2219:26;;:4;:11;;;:26;;;;:::i;:::-;2218:50;;;;:::i;:::-;2192:90;-1:-1:-1;2308:12:3;;-1:-1:-1;2322:6:3;-1:-1:-1;;1906:430:3;;;;;;:::o;2586:153::-;2670:7;2719:12;2698:17;:10;2711:4;2698:17;:::i;:::-;2697:34;;;;:::i;23059:1151:2:-;23104:16;23132:13;23148:4;23132:20;;23162:16;23188;23214:21;23285:4;23279:11;-1:-1:-1;;;23310:3:2;23303:79;23446:1;23443;23440;23435:3;23428:5;23421;23410:38;23471:7;23461:35;;23492:1;23489;23482:12;23461:35;;23533:2;23530:1;23524:4;23509:27;23576:2;23570:4;23564;23549:30;23610:4;23604:11;23592:23;;23646:4;23640:11;23628:23;;-1:-1:-1;;;23680:4:2;23675:3;23671:14;23664:90;23828:2;23825:1;23822;23815:4;23810:3;23806:14;23799:5;23792;23781:50;23767:64;;23867:4;23861:11;23844:28;;24014:10;24010:194;;;24051:50;24067:12;:8;24078:1;24067:12;:::i;:::-;-1:-1:-1;;;;;24051:50:2;24081:4;24087:13;24051:15;:50::i;:::-;24040:61;;24010:194;;;24143:50;24159:12;:8;24170:1;24159:12;:::i;24143:50::-;24132:61;;24010:194;23122:1088;;;;23059:1151;:::o;741:4097:5:-;823:14;;;-1:-1:-1;;1386:1:5;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:5;;;;-1:-1:-1;1756:13:5;;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:5;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1237:548:6:-;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:6;;1897:42;;1887:70;;1953:1;1950;1943:12;1887:70;1790:173;;;:::o;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:6: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:6;;3331:180;-1:-1:-1;3331:180:6: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:6;;;3945:2;3930:18;;;3917:32;;-1:-1:-1;3707:248:6: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:6;;4795:120::o;4920:191::-;-1:-1:-1;;;;;5047:10:6;;;5035;;;5031:27;;5070:12;;;5067:38;;;5085:18;;:::i;:::-;5067:38;4920:191;;;;:::o;5116:188::-;-1:-1:-1;;;;;5229:10:6;;;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:265;-1:-1:-1;;;;;6807:10:6;;;6819;;;6803:27;6850:20;;;;6749:26;6889:24;;;6879:58;;6917:18;;:::i;:::-;6879:58;;6678:265;;;;:::o;7323:200::-;-1:-1:-1;;;;;7459:10:6;;;7447;;;7443:27;;7482:12;;;7479:38;;;7497:18;;:::i;7528:179::-;7596:14;7643:10;;;7631;;;7627:27;;7666:12;;;7663:38;;;7681:18;;:::i;7712:176::-;7779:14;7813:10;;;7825;;;7809:27;;7848:11;;;7845:37;;;7862:18;;:::i;8241:274::-;-1:-1:-1;;;;;8379:10:6;;;8391;;;8375:27;8422:20;;;;8313:34;8461:24;;;8451:58;;8489:18;;:::i;8520:216::-;8560:1;-1:-1:-1;;;;;8647:2:6;8644:1;8640:10;8669:3;8659:37;;8676:18;;:::i;:::-;8714:10;;8710:20;;;;;8520:216;-1:-1:-1;;8520:216:6:o;8741:270::-;-1:-1:-1;;;;;8875:10:6;;;8887;;;8871:27;8918:20;;;;8813:30;8957:24;;;8947:58;;8985:18;;:::i

Swarm Source

ipfs://afcbc2e2988b20d46fa776fb380f2dab45fdbe73baf76659fb97e576a0841a87
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.