ETH Price: $3,690.81 (+2.93%)
Gas: 7.5 Gwei

Token

ERC-20: Integral LP (ITGR-LP)
 

Overview

Max Total Supply

725.752073881582289022 ITGR-LP

Holders

16

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0 ITGR-LP

Value
$0.00
0x8743cc30727e9e460a5e69e217893f42dfad1650
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:
IntegralPair

Compiler Version
v0.7.5+commit.eb77ed08

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
File 1 of 13 : IntegralPair.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IIntegralPair.sol';
import 'Reserves.sol';
import 'IntegralERC20.sol';
import 'Math.sol';
import 'IERC20.sol';
import 'IIntegralFactory.sol';
import 'IIntegralOracle.sol';
import 'Normalizer.sol';

contract IntegralPair is Reserves, IntegralERC20, IIntegralPair {
    using SafeMath for uint256;
    using Normalizer for uint256;

    uint256 private constant PRECISION = 10**18;

    uint256 public override mintFee = 0;
    uint256 public override burnFee = 0;
    uint256 public override swapFee = 0;

    uint256 public constant override MINIMUM_LIQUIDITY = 10**3;
    uint256 private constant TRADE_MOE = 100000001 * 10**10; // Margin Of Error

    bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));

    address public override factory;
    address public override token0;
    address public override token1;
    address public override oracle;
    address public override trader;

    uint256 private lastPrice;

    uint256 public override token0AbsoluteLimit = uint256(-1);
    uint256 public override token1AbsoluteLimit = uint256(-1);
    uint256 public override token0RelativeLimit = PRECISION; // 100%
    uint256 public override token1RelativeLimit = PRECISION; // 100%
    uint256 public override priceDeviationLimit = uint256(-1);

    uint256 private unlocked = 1;
    modifier lock() {
        require(unlocked == 1, 'IP_LOCKED');
        unlocked = 0;
        _;
        unlocked = 1;
    }

    function isContract(address addr) private view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(addr)
        }
        return size > 0;
    }

    function setMintFee(uint256 fee) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        mintFee = fee;
        emit SetMintFee(mintFee);
    }

    function setBurnFee(uint256 fee) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        burnFee = fee;
        emit SetBurnFee(burnFee);
    }

    function setSwapFee(uint256 fee) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        swapFee = fee;
        emit SetSwapFee(swapFee);
    }

    function setOracle(address _oracle) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        require(_oracle != address(0), 'IP_ADDRESS_ZERO');
        require(isContract(_oracle), 'IP_ORACLE_MUST_BE_CONTRACT');
        oracle = _oracle;
        setReferencesToReserves(0);
        emit SetOracle(oracle);
    }

    function setTrader(address _trader) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        trader = _trader;
        emit SetTrader(trader);
    }

    function setToken0AbsoluteLimit(uint256 _token0AbsoluteLimit) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        token0AbsoluteLimit = _token0AbsoluteLimit;
        emit SetToken0AbsoluteLimit(token0AbsoluteLimit);
    }

    function setToken1AbsoluteLimit(uint256 _token1AbsoluteLimit) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        token1AbsoluteLimit = _token1AbsoluteLimit;
        emit SetToken1AbsoluteLimit(token1AbsoluteLimit);
    }

    function setToken0RelativeLimit(uint256 _token0RelativeLimit) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        token0RelativeLimit = _token0RelativeLimit;
        emit SetToken0RelativeLimit(token0RelativeLimit);
    }

    function setToken1RelativeLimit(uint256 _token1RelativeLimit) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        token1RelativeLimit = _token1RelativeLimit;
        emit SetToken1RelativeLimit(token1RelativeLimit);
    }

    function setPriceDeviationLimit(uint256 _priceDeviationLimit) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        priceDeviationLimit = _priceDeviationLimit;
        emit SetPriceDeviationLimit(priceDeviationLimit);
    }

    function collect(address to) external override lock {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        require(to != address(0), 'IP_ADDRESS_ZERO');
        (uint256 fee0, uint256 fee1) = getFees();
        if (fee0 > 0) _safeTransfer(token0, to, fee0);
        if (fee1 > 0) _safeTransfer(token1, to, fee1);
        setFees(0, 0);
        _sync();
    }

    function _safeTransfer(
        address token,
        address to,
        uint256 value
    ) private {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'IP_TRANSFER_FAILED');
    }

    function canTrade(address user) private view returns (bool) {
        return user == trader || user == factory || trader == address(-1);
    }

    constructor() {
        factory = msg.sender;
    }

    // called once by the factory at time of deployment
    function initialize(
        address _token0,
        address _token1,
        address _oracle,
        address _trader
    ) external override {
        require(msg.sender == factory, 'IP_FORBIDDEN');
        require(_oracle != address(0), 'IP_ADDRESS_ZERO');
        require(isContract(_oracle), 'IP_ORACLE_MUST_BE_CONTRACT');
        require(isContract(_token0) && isContract(_token1), 'IP_TOKEN_MUST_BE_CONTRACT');
        token0 = _token0;
        token1 = _token1;
        oracle = _oracle;
        trader = _trader;
    }

    // this low-level function should be called from a contract which performs important safety checks
    function mint(address to) external override lock returns (uint256 liquidity) {
        require(canTrade(msg.sender), 'IP_UNAUTHORIZED_TRADER');
        require(to != address(0), 'IP_ADDRESS_ZERO');
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        (uint256 balance0, uint256 balance1) = getBalances(token0, token1);
        uint256 amount0 = balance0.sub(reserve0);
        uint256 amount1 = balance1.sub(reserve1);

        _syncWithOracle();

        uint256 _totalSupply = totalSupply; // gas savings
        if (_totalSupply == 0) {
            liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
            _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
        } else {
            liquidity = Math.min(amount0.mul(_totalSupply) / reserve0, amount1.mul(_totalSupply) / reserve1);
        }

        require(liquidity > 0, 'IP_INSUFFICIENT_LIQUIDITY_MINTED');
        uint256 fee = liquidity.mul(mintFee).div(PRECISION);
        uint256 effectiveLiquidity = liquidity.sub(fee);
        _mint(to, effectiveLiquidity);
        _mint(factory, fee);

        adjustReserves(balance0, balance1);

        emit Mint(msg.sender, to);
    }

    // this low-level function should be called from a contract which performs important safety checks
    function burn(address to) external override lock returns (uint256 amount0, uint256 amount1) {
        require(canTrade(msg.sender), 'IP_UNAUTHORIZED_TRADER');
        require(to != address(0), 'IP_ADDRESS_ZERO');
        address _token0 = token0; // gas savings
        address _token1 = token1; // gas savings
        (uint256 balance0, uint256 balance1) = getBalances(token0, token1);
        uint256 liquidity = balanceOf[address(this)];
        uint256 _totalSupply = totalSupply; // gas savings

        _syncWithOracle();

        uint256 fee = 0;
        if (msg.sender != factory) {
            fee = liquidity.mul(burnFee).div(PRECISION);
            _transfer(address(this), factory, fee);
        }
        uint256 effectiveLiquidity = liquidity.sub(fee);
        _burn(address(this), effectiveLiquidity);

        amount0 = effectiveLiquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
        amount1 = effectiveLiquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
        require(amount0 > 0 && amount1 > 0, 'IP_INSUFFICIENT_LIQUIDITY_BURNED');

        _safeTransfer(_token0, to, amount0);
        _safeTransfer(_token1, to, amount1);

        (balance0, balance1) = getBalances(token0, token1);
        adjustReserves(balance0, balance1);

        emit Burn(msg.sender, to);
    }

    // this low-level function should be called from a contract which performs important safety checks
    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to
    ) external override lock {
        require(canTrade(msg.sender), 'IP_UNAUTHORIZED_TRADER');
        require(to != address(0), 'IP_ADDRESS_ZERO');
        require(amount0Out > 0 || amount1Out > 0, 'IP_INSUFFICIENT_OUTPUT_AMOUNT');
        require(amount0Out == 0 || amount1Out == 0, 'IP_MULTIPLE_OUTPUTS_SPECIFIED');
        (uint112 _reserve0, uint112 _reserve1, ) = getReserves();
        require(amount0Out < _reserve0 && amount1Out < _reserve1, 'IP_INSUFFICIENT_LIQUIDITY');

        _syncWithOracle();

        {
            // scope for _token{0,1}, avoids stack too deep errors
            address _token0 = token0;
            address _token1 = token1;
            require(to != _token0 && to != _token1, 'IP_INVALID_TO');
            if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
            if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
        }
        (uint256 balance0, uint256 balance1) = getBalances(token0, token1);
        uint256 amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
        uint256 amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
        require(amount0In > 0 || amount1In > 0, 'IP_INSUFFICIENT_INPUT_AMOUNT');

        if (amount0Out > 0) {
            // trading token1 for token0
            (uint112 reference0, uint112 reference1, ) = getReferences();

            uint256 fee1 = amount1In.mul(swapFee).div(PRECISION);
            uint256 balance0After = IIntegralOracle(oracle).tradeY(balance1.sub(fee1), reference0, reference1);
            require(balance0 >= balance0After, 'IP_INVALID_SWAP');
            _checkToken0Limits(balance0After, reference0);
            uint256 fee0 = balance0.sub(balance0After);
            addFees(fee0, fee1);
            updateReserves(balance0.sub(fee0), balance1.sub(fee1));
        } else {
            // trading token0 for token1
            (uint112 reference0, uint112 reference1, ) = getReferences();

            uint256 fee0 = amount0In.mul(swapFee).div(PRECISION);
            uint256 balance1After = IIntegralOracle(oracle).tradeX(balance0.sub(fee0), reference0, reference1);
            require(balance1 >= balance1After, 'IP_INVALID_SWAP');
            _checkToken1Limits(balance1After, reference1);
            uint256 fee1 = balance1.sub(balance1After);
            addFees(fee0, fee1);
            updateReserves(balance0.sub(fee0), balance1.sub(fee1));
        }

        _checkPriceDeviationLimit();
        emit Swap(msg.sender, to);
    }

    function _checkPriceDeviationLimit() private view {
        uint256 currentPrice = getSpotPrice();

        if (lastPrice > 0) {
            uint256 difference = lastPrice > currentPrice ? lastPrice.sub(currentPrice) : currentPrice.sub(lastPrice);

            require(difference.mul(PRECISION).div(lastPrice) <= priceDeviationLimit, 'IP_P_LIMIT_EXCEEDED');
        }
    }

    function _checkToken0Limits(uint256 balance0After, uint112 reference0) private view {
        if (balance0After < reference0) {
            uint256 difference = uint256(reference0).sub(balance0After);
            require(difference <= token0AbsoluteLimit, 'IP_A0_LIQUIDITY_LIMIT_EXCEEDED');
            require(difference.mul(PRECISION).div(reference0) <= token0RelativeLimit, 'IP_R0_LIQUIDITY_LIMIT_EXCEEDED');
        }
    }

    function _checkToken1Limits(uint256 balance1After, uint112 reference1) private view {
        if (balance1After < reference1) {
            uint256 difference = uint256(reference1).sub(balance1After);
            require(difference <= token1AbsoluteLimit, 'IP_A1_LIQUIDITY_LIMIT_EXCEEDED');
            require(difference.mul(PRECISION).div(reference1) <= token1RelativeLimit, 'IP_R1_LIQUIDITY_LIMIT_EXCEEDED');
        }
    }

    function sync() public override lock {
        require(canTrade(msg.sender), 'IP_UNAUTHORIZED_TRADER');
        _sync();
    }

    // force reserves to match balances
    function _sync() internal {
        syncReserves(token0, token1);
        uint256 tokens = balanceOf[address(this)];
        if (tokens > 0) {
            _transfer(address(this), factory, tokens);
        }
    }

    function syncWithOracle() external override {
        _syncWithOracle();
    }

    function fullSync() external override {
        require(canTrade(msg.sender), 'IP_UNAUTHORIZED_TRADER');
        _sync();
        _syncWithOracle();
    }

    function _syncWithOracle() internal {
        uint32 epoch = IIntegralOracle(oracle).updatePrice();
        (, , uint32 lastEpoch) = getReferences();
        if (epoch != lastEpoch) {
            setReferencesToReserves(epoch);
            lastPrice = getSpotPrice();
        }
    }

    function getSpotPrice() public view override returns (uint256 spotPrice) {
        (uint112 reserve0, , ) = getReserves();
        (uint112 reference0, , ) = getReferences();
        return IIntegralOracle(oracle).getSpotPrice(reserve0, reference0);
    }

    function getSwapAmount0In(uint256 amount1Out) public view override returns (uint256 swapAmount0In) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        (uint112 reference0, uint112 reference1, ) = getReferences();
        uint256 balance1After = uint256(reserve1).sub(amount1Out);
        uint256 balance0After = IIntegralOracle(oracle).tradeY(balance1After, reference0, reference1);
        return balance0After.sub(uint256(reserve0)).mul(TRADE_MOE).div(PRECISION.sub(swapFee));
    }

    function getSwapAmount1In(uint256 amount0Out) public view override returns (uint256 swapAmount1In) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        (uint112 reference0, uint112 reference1, ) = getReferences();
        uint256 balance0After = uint256(reserve0).sub(amount0Out);
        uint256 balance1After = IIntegralOracle(oracle).tradeX(balance0After, reference0, reference1);
        return balance1After.sub(uint256(reserve1)).mul(TRADE_MOE).div(PRECISION.sub(swapFee));
    }

    function getSwapAmount0Out(uint256 amount1In) public view override returns (uint256 swapAmount0Out) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        (uint112 reference0, uint112 reference1, ) = getReferences();
        uint256 fee = amount1In.mul(swapFee).div(PRECISION);
        uint256 balance0After = IIntegralOracle(oracle).tradeY(
            uint256(reserve1).add(amount1In).sub(fee),
            reference0,
            reference1
        );
        return uint256(reserve0).sub(balance0After);
    }

    function getSwapAmount1Out(uint256 amount0In) public view override returns (uint256 swapAmount1Out) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        (uint112 reference0, uint112 reference1, ) = getReferences();
        uint256 fee = amount0In.mul(swapFee).div(PRECISION);
        uint256 balance1After = IIntegralOracle(oracle).tradeX(
            uint256(reserve0).add(amount0In).sub(fee),
            reference0,
            reference1
        );
        return uint256(reserve1).sub(balance1After);
    }

    function getDepositAmount0In(uint256 amount0) external view override returns (uint256) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        if (reserve0 == 0 || reserve1 == 0) {
            return 0;
        }
        uint8 decimals0 = IIntegralOracle(oracle).xDecimals();
        uint8 decimals1 = IIntegralOracle(oracle).yDecimals();

        uint256 P = getSpotPrice();
        uint256 a = amount0.normalize(decimals0);
        uint256 A = uint256(reserve0).normalize(decimals0);
        uint256 B = uint256(reserve1).normalize(decimals1);

        // ratio after swap = ratio after second mint
        // (A + x) / (B - x * P) = (A + a) / B
        // x = a * B / (P * (a + A) + B)
        uint256 numeratorTimes1e18 = a.mul(B);
        uint256 denominator = P.mul(a.add(A)).div(1e18).add(B);
        uint256 x = numeratorTimes1e18.div(denominator);
        // Don't swap when numbers are too large. This should actually never happen
        if (x.mul(P).div(1e18) >= B || x >= a) {
            return 0;
        }
        return x.denormalize(decimals0);
    }

    function getDepositAmount1In(uint256 amount1) external view override returns (uint256) {
        (uint112 reserve0, uint112 reserve1, ) = getReserves();
        if (reserve0 == 0 || reserve1 == 0) {
            return 0;
        }
        uint8 decimals0 = IIntegralOracle(oracle).xDecimals();
        uint8 decimals1 = IIntegralOracle(oracle).yDecimals();

        uint256 P = getSpotPrice();
        uint256 b = amount1.normalize(decimals1);
        uint256 A = uint256(reserve0).normalize(decimals0);
        uint256 B = uint256(reserve1).normalize(decimals1);

        // ratio after swap = ratio after second mint
        // (A - x / P) / (B + x) = A / (B + b)
        // x = A * b * P / (A * P + b + B)
        uint256 numeratorTimes1e18 = A.mul(b).div(1e18).mul(P);
        uint256 denominator = A.mul(P).div(1e18).add(b).add(B);
        uint256 x = numeratorTimes1e18.div(denominator);
        // Don't swap when numbers are too large. This should actually never happen
        if (x.mul(1e18).div(P) >= A || x >= b) {
            return 0;
        }
        return x.denormalize(decimals1);
    }
}

File 2 of 13 : IERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

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

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

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

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

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

File 3 of 13 : IIntegralERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IERC20.sol';

interface IIntegralERC20 is IERC20 {
    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function increaseAllowance(address spender, uint256 addedValue) external returns (bool);

    function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
}

File 4 of 13 : IReserves.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

interface IReserves {
    event Sync(uint112 reserve0, uint112 reserve1);
    event Fees(uint256 fee0, uint256 fee1);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 lastTimestamp
        );

    function getReferences()
        external
        view
        returns (
            uint112 reference0,
            uint112 reference1,
            uint32 epoch
        );

    function getFees() external view returns (uint256 fee0, uint256 fee1);
}

File 5 of 13 : IIntegralPair.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IIntegralERC20.sol';
import 'IReserves.sol';

interface IIntegralPair is IIntegralERC20, IReserves {
    event Mint(address indexed sender, address indexed to);
    event Burn(address indexed sender, address indexed to);
    event Swap(address indexed sender, address indexed to);
    event SetMintFee(uint256 fee);
    event SetBurnFee(uint256 fee);
    event SetSwapFee(uint256 fee);
    event SetOracle(address account);
    event SetTrader(address trader);
    event SetToken0AbsoluteLimit(uint256 limit);
    event SetToken1AbsoluteLimit(uint256 limit);
    event SetToken0RelativeLimit(uint256 limit);
    event SetToken1RelativeLimit(uint256 limit);
    event SetPriceDeviationLimit(uint256 limit);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function oracle() external view returns (address);

    function trader() external view returns (address);

    function mintFee() external view returns (uint256);

    function setMintFee(uint256 fee) external;

    function mint(address to) external returns (uint256 liquidity);

    function burnFee() external view returns (uint256);

    function setBurnFee(uint256 fee) external;

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

    function swapFee() external view returns (uint256);

    function setSwapFee(uint256 fee) external;

    function setOracle(address account) external;

    function setTrader(address account) external;

    function token0AbsoluteLimit() external view returns (uint256);

    function setToken0AbsoluteLimit(uint256 limit) external;

    function token1AbsoluteLimit() external view returns (uint256);

    function setToken1AbsoluteLimit(uint256 limit) external;

    function token0RelativeLimit() external view returns (uint256);

    function setToken0RelativeLimit(uint256 limit) external;

    function token1RelativeLimit() external view returns (uint256);

    function setToken1RelativeLimit(uint256 limit) external;

    function priceDeviationLimit() external view returns (uint256);

    function setPriceDeviationLimit(uint256 limit) external;

    function collect(address to) external;

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to
    ) external;

    function sync() external;

    function initialize(
        address _token0,
        address _token1,
        address _oracle,
        address _trader
    ) external;

    function syncWithOracle() external;

    function fullSync() external;

    function getSpotPrice() external view returns (uint256 spotPrice);

    function getSwapAmount0In(uint256 amount1Out) external view returns (uint256 swapAmount0In);

    function getSwapAmount1In(uint256 amount0Out) external view returns (uint256 swapAmount1In);

    function getSwapAmount0Out(uint256 amount1In) external view returns (uint256 swapAmount0Out);

    function getSwapAmount1Out(uint256 amount0In) external view returns (uint256 swapAmount1Out);

    function getDepositAmount0In(uint256 amount0) external view returns (uint256 depositAmount0In);

    function getDepositAmount1In(uint256 amount1) external view returns (uint256 depositAmount1In);
}

File 6 of 13 : SafeMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, 'SM_ADD_OVERFLOW');
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = sub(x, y, 'SM_SUB_UNDERFLOW');
    }

    function sub(
        uint256 x,
        uint256 y,
        string memory message
    ) internal pure returns (uint256 z) {
        require((z = x - y) <= x, message);
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW');
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, 'SM_DIV_BY_ZERO');
        uint256 c = a / b;
        return c;
    }
}

File 7 of 13 : Reserves.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IReserves.sol';
import 'IERC20.sol';
import 'SafeMath.sol';

contract Reserves is IReserves {
    using SafeMath for uint256;

    uint112 private reserve0;
    uint112 private reserve1;
    uint32 private lastTimestamp;

    uint112 private reference0;
    uint112 private reference1;
    uint32 private lastEpoch;

    uint256 private fee0;
    uint256 private fee1;

    function getReserves()
        public
        view
        override
        returns (
            uint112,
            uint112,
            uint32
        )
    {
        return (reserve0, reserve1, lastTimestamp);
    }

    function setReserves(
        uint112 _reserve0,
        uint112 _reserve1,
        uint32 _lastTimestamp
    ) private {
        require(_reserve0 != 0 && _reserve1 != 0, 'RS_ZERO');
        reserve0 = _reserve0;
        reserve1 = _reserve1;
        lastTimestamp = _lastTimestamp;
        emit Sync(reserve0, reserve1);
    }

    function getReferences()
        public
        view
        override
        returns (
            uint112,
            uint112,
            uint32
        )
    {
        return (reference0, reference1, lastEpoch);
    }

    function setReferencesToReserves(uint32 _lastEpoch) internal {
        reference0 = reserve0;
        reference1 = reserve1;
        lastEpoch = _lastEpoch;
    }

    function updateReserves(uint256 balance0, uint256 balance1) internal {
        require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'RS_OVERFLOW');
        uint32 blockTimestamp = uint32(block.timestamp % 2**32);
        setReserves(uint112(balance0), uint112(balance1), blockTimestamp);
    }

    function adjustReserves(uint256 balance0, uint256 balance1) internal {
        (uint112 _reserve0, uint112 _reserve1, ) = getReserves();
        if (_reserve0 != balance0 || _reserve1 != balance1) {
            updateReserves(balance0, balance1);
            updateReferences(
                uint256(reference0).add(reserve0).sub(_reserve0),
                uint256(reference1).add(reserve1).sub(_reserve1)
            );
        }
    }

    function syncReserves(address token0, address token1) internal {
        uint256 balance0 = IERC20(token0).balanceOf(address(this));
        uint256 balance1 = IERC20(token1).balanceOf(address(this));
        (uint112 _reserve0, uint112 _reserve1, ) = getReserves();

        uint256 oldBalance0 = fee0.add(_reserve0);
        uint256 oldBalance1 = fee1.add(_reserve1);
        fee0 = oldBalance0 != 0 ? fee0.mul(balance0).div(oldBalance0) : fee0;
        fee1 = oldBalance1 != 0 ? fee1.mul(balance1).div(oldBalance1) : fee1;

        uint256 newReserve0 = balance0.sub(fee0);
        uint256 newReserve1 = balance1.sub(fee1);
        if (_reserve0 != newReserve0 || _reserve1 != newReserve1) {
            updateReserves(newReserve0, newReserve1);
            updateReferences(
                uint256(reference0).add(reserve0).sub(_reserve0),
                uint256(reference1).add(reserve1).sub(_reserve1)
            );
        }
    }

    function updateReferences(uint256 _reference0, uint256 _reference1) private {
        require(_reference0 <= uint112(-1) && _reference1 <= uint112(-1), 'RS_OVERFLOW');
        reference0 = uint112(_reference0);
        reference1 = uint112(_reference1);
    }

    function getFees() public view override returns (uint256, uint256) {
        return (fee0, fee1);
    }

    function addFees(uint256 _fee0, uint256 _fee1) internal {
        setFees(fee0.add(_fee0), fee1.add(_fee1));
    }

    function setFees(uint256 _fee0, uint256 _fee1) internal {
        fee0 = _fee0;
        fee1 = _fee1;
        emit Fees(fee0, fee1);
    }

    function getBalances(address token0, address token1) internal returns (uint256, uint256) {
        uint256 balance0 = IERC20(token0).balanceOf(address(this));
        uint256 balance1 = IERC20(token1).balanceOf(address(this));
        if (fee0 > balance0) {
            fee0 = balance0;
            emit Fees(fee0, fee1);
        }
        if (fee1 > balance1) {
            fee1 = balance1;
            emit Fees(fee0, fee1);
        }
        return (balance0.sub(fee0), balance1.sub(fee1));
    }
}

File 8 of 13 : AbstractERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IIntegralERC20.sol';
import 'SafeMath.sol';

abstract contract AbstractERC20 is IIntegralERC20 {
    using SafeMath for uint256;

    uint256 public override totalSupply;
    mapping(address => uint256) public override balanceOf;
    mapping(address => mapping(address => uint256)) public override allowance;

    bytes32 public override DOMAIN_SEPARATOR;
    // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32
        public constant
        override PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
    mapping(address => uint256) public override nonces;

    function _init(string memory _name) internal {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                keccak256(bytes(_name)),
                keccak256(bytes('1')),
                chainId,
                address(this)
            )
        );
    }

    function _mint(address to, uint256 value) internal {
        totalSupply = totalSupply.add(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint256 value) internal {
        balanceOf[from] = balanceOf[from].sub(value);
        totalSupply = totalSupply.sub(value);
        emit Transfer(from, address(0), value);
    }

    function _approve(
        address owner,
        address spender,
        uint256 value
    ) internal {
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal {
        balanceOf[from] = balanceOf[from].sub(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(from, to, value);
    }

    function approve(address spender, uint256 value) external override returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {
        uint256 currentAllowance = allowance[msg.sender][spender];
        require(currentAllowance >= subtractedValue, 'IA_CANNOT_DECREASE');
        _approve(msg.sender, spender, currentAllowance.sub(subtractedValue));
        return true;
    }

    function transfer(address to, uint256 value) external override returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external override returns (bool) {
        if (allowance[from][msg.sender] != uint256(-1)) {
            allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
        }
        _transfer(from, to, value);
        return true;
    }

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external override {
        require(deadline >= block.timestamp, 'IA_EXPIRED');
        bytes32 digest = keccak256(
            abi.encodePacked(
                '\x19\x01',
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
            )
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        require(recoveredAddress != address(0) && recoveredAddress == owner, 'IA_INVALID_SIGNATURE');
        _approve(owner, spender, value);
    }
}

File 9 of 13 : IntegralERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'AbstractERC20.sol';

contract IntegralERC20 is AbstractERC20 {
    string public constant override name = 'Integral LP';
    string public constant override symbol = 'ITGR-LP';
    uint8 public constant override decimals = 18;

    constructor() {
        _init(name);
    }

    /**
     * @dev This function should be called on the forked chain to prevent
     * replay attacks
     */
    function updateDomainSeparator() external {
        _init(name);
    }
}

File 10 of 13 : Math.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

// a library for performing various math operations

library Math {
    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x < y ? x : y;
    }

    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x > y ? x : y;
    }

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
}

File 11 of 13 : IIntegralFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

interface IIntegralFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);
    event OwnerSet(address owner);

    function owner() external view returns (address);

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

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

    function allPairsLength() external view returns (uint256);

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

    function setOwner(address) external;

    function setMintFee(
        address tokenA,
        address tokenB,
        uint256 fee
    ) external;

    function setBurnFee(
        address tokenA,
        address tokenB,
        uint256 fee
    ) external;

    function setSwapFee(
        address tokenA,
        address tokenB,
        uint256 fee
    ) external;

    function setOracle(
        address tokenA,
        address tokenB,
        address oracle
    ) external;

    function setTrader(
        address tokenA,
        address tokenB,
        address trader
    ) external;

    function collect(
        address tokenA,
        address tokenB,
        address to
    ) external;

    function withdraw(
        address tokenA,
        address tokenB,
        uint256 amount,
        address to
    ) external;
}

File 12 of 13 : IIntegralOracle.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

interface IIntegralOracle {
    event OwnerSet(address owner);
    event UniswapPairSet(address uniswapPair);
    event PriceUpdateIntervalSet(uint32 interval);
    event ParametersSet(uint32 epoch, int256[] bidExponents, int256[] bidQs, int256[] askExponents, int256[] askQs);

    function owner() external view returns (address);

    function setOwner(address) external;

    function epoch() external view returns (uint32);

    function xDecimals() external view returns (uint8);

    function yDecimals() external view returns (uint8);

    function getParameters()
        external
        view
        returns (
            int256[] memory bidExponents,
            int256[] memory bidQs,
            int256[] memory askExponents,
            int256[] memory askQs
        );

    function setParameters(
        int256[] calldata bidExponents,
        int256[] calldata bidQs,
        int256[] calldata askExponents,
        int256[] calldata askQs
    ) external;

    function price() external view returns (int256);

    function priceUpdateInterval() external view returns (uint32);

    function updatePrice() external returns (uint32 _epoch);

    function setPriceUpdateInterval(uint32 interval) external;

    function price0CumulativeLast() external view returns (uint256);

    function blockTimestampLast() external view returns (uint32);

    function tradeX(
        uint256 xAfter,
        uint256 xBefore,
        uint256 yBefore
    ) external view returns (uint256 yAfter);

    function tradeY(
        uint256 yAfter,
        uint256 xBefore,
        uint256 yBefore
    ) external view returns (uint256 xAfter);

    function getSpotPrice(uint256 xCurrent, uint256 xBefore) external view returns (uint256 spotPrice);
}

File 13 of 13 : Normalizer.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'SafeMath.sol';

library Normalizer {
    using SafeMath for uint256;

    function normalize(uint256 amount, uint8 decimals) internal pure returns (uint256) {
        if (decimals == 18) {
            return amount;
        } else if (decimals > 18) {
            return amount.div(10**(decimals - 18));
        } else {
            return amount.mul(10**(18 - decimals));
        }
    }

    function denormalize(uint256 amount, uint8 decimals) internal pure returns (uint256) {
        if (decimals == 18) {
            return amount;
        } else if (decimals > 18) {
            return amount.mul(10**(decimals - 18));
        } else {
            return amount.div(10**(18 - decimals));
        }
    }
}

Settings
{
  "libraries": {
    "IERC20.sol": {},
    "IIntegralERC20.sol": {},
    "IReserves.sol": {},
    "IIntegralPair.sol": {},
    "SafeMath.sol": {},
    "Reserves.sol": {},
    "AbstractERC20.sol": {},
    "IntegralERC20.sol": {},
    "Math.sol": {},
    "IIntegralFactory.sol": {},
    "IIntegralOracle.sol": {},
    "Normalizer.sol": {},
    "IntegralPair.sol": {}
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee1","type":"uint256"}],"name":"Fees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetBurnFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetMintFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetPriceDeviationLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetSwapFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetToken0AbsoluteLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetToken0RelativeLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetToken1AbsoluteLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetToken1RelativeLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"}],"name":"SetTrader","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint112","name":"reserve0","type":"uint112"},{"indexed":false,"internalType":"uint112","name":"reserve1","type":"uint112"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"collect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullSync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"}],"name":"getDepositAmount0In","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"getDepositAmount1In","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferences","outputs":[{"internalType":"uint112","name":"","type":"uint112"},{"internalType":"uint112","name":"","type":"uint112"},{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"","type":"uint112"},{"internalType":"uint112","name":"","type":"uint112"},{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSpotPrice","outputs":[{"internalType":"uint256","name":"spotPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1Out","type":"uint256"}],"name":"getSwapAmount0In","outputs":[{"internalType":"uint256","name":"swapAmount0In","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1In","type":"uint256"}],"name":"getSwapAmount0Out","outputs":[{"internalType":"uint256","name":"swapAmount0Out","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"}],"name":"getSwapAmount1In","outputs":[{"internalType":"uint256","name":"swapAmount1In","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0In","type":"uint256"}],"name":"getSwapAmount1Out","outputs":[{"internalType":"uint256","name":"swapAmount1Out","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_trader","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceDeviationLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceDeviationLimit","type":"uint256"}],"name":"setPriceDeviationLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_token0AbsoluteLimit","type":"uint256"}],"name":"setToken0AbsoluteLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_token0RelativeLimit","type":"uint256"}],"name":"setToken0RelativeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_token1AbsoluteLimit","type":"uint256"}],"name":"setToken1AbsoluteLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_token1RelativeLimit","type":"uint256"}],"name":"setToken1RelativeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"}],"name":"setTrader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"syncWithOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0AbsoluteLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0RelativeLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1AbsoluteLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1RelativeLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trader","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateDomainSeparator","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006009556000600a556000600b55600019601255600019601355670de0b6b3a7640000601455670de0b6b3a764000060155560001960165560016017553480156200004f57600080fd5b5060408051808201909152600b81526a0496e74656772616c204c560ac1b60208201526200007d9062000095565b600c80546001600160a01b0319163317905562000132565b805160209182012060408051808201825260018152603160f81b9084015280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81850152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528151808403909101815260c090920190528051910120600755565b61419080620001426000396000f3fe608060405234801561001057600080fd5b506004361061038e5760003560e01c806384c150a6116101de578063c45a01551161010f578063dc76fabc116100ad578063fce589d81161007c578063fce589d8146109b6578063ff3549a3146109be578063ff91c78d146109db578063fff6cae9146109f85761038e565b8063dc76fabc14610925578063dd62ed3e1461092d578063eddd0d9c1461095b578063f8c8765e146109785761038e565b8063d505accf116100e9578063d505accf146108a7578063d727dfc9146108f8578063db8d55f114610900578063dc084e78146109085761038e565b8063c45a01551461088f578063caeba21714610897578063d21220a71461089f5761038e565b8063a6bc18f91161017c578063b81af61911610156578063b81af61914610845578063b8d3f31c1461084d578063ba9a7a561461086a578063bc103be8146108725761038e565b8063a6bc18f9146107d6578063a9059cbb146107fc578063afb600fe146108285761038e565b806395d89b41116101b857806395d89b411461077d57806399ce42bb14610785578063a457c2d71461078d578063a66f459a146107b95761038e565b806384c150a61461071957806389afcb441461073657806389ccfe89146107755761038e565b80633644e515116102c357806361556e1e116102615780637a6337fa116102305780637a6337fa146106bd5780637adbf973146106c55780637dc0d1d0146106eb5780637ecebe00146106f35761038e565b806361556e1e146106225780636a6278421461063f5780636d9a640a1461066557806370a08231146106975761038e565b80633c80f8a71161029d5780633c80f8a7146105c35780634bf2c7c9146105e05780634e775aad146105fd57806354cf2aeb1461061a5761038e565b80633644e5151461058757806336a2b5851461058f57806339509351146105975761038e565b80631758078b11610330578063283d8df71161030a578063283d8df71461053c57806330adf81f14610544578063313ce5671461054c57806334e199071461056a5761038e565b80631758078b146104f657806318160ddd146104fe57806323b872dd146105065761038e565b80630902f1ac1161036c5780630902f1ac14610452578063095ea7b31461048a5780630dfe1681146104ca57806313966db5146104ee5761038e565b80630699df581461039357806306ec16f8146103ad57806306fdde03146103d5575b600080fd5b61039b610a00565b60408051918252519081900360200190f35b6103d3600480360360208110156103c357600080fd5b50356001600160a01b0316610a06565b005b6103dd610b50565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104175781810151838201526020016103ff565b50505050905090810190601f1680156104445780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61045a610b77565b604080516001600160701b03948516815292909316602083015263ffffffff168183015290519081900360600190f35b6104b6600480360360408110156104a057600080fd5b506001600160a01b038135169060200135610ba1565b604080519115158252519081900360200190f35b6104d2610bb8565b604080516001600160a01b039092168252519081900360200190f35b61039b610bc7565b6104d2610bcd565b61039b610bdc565b6104b66004803603606081101561051c57600080fd5b506001600160a01b03813581169160208101359091169060400135610be2565b61039b610c76565b61039b610c7c565b610554610ca0565b6040805160ff9092168252519081900360200190f35b6103d36004803603602081101561058057600080fd5b5035610ca5565b61039b610d2e565b61039b610d34565b6104b6600480360360408110156105ad57600080fd5b506001600160a01b038135169060200135610d3a565b6103d3600480360360208110156105d957600080fd5b5035610d75565b6103d3600480360360208110156105f657600080fd5b5035610dfe565b6103d36004803603602081101561061357600080fd5b5035610e87565b61039b610f10565b6103d36004803603602081101561063857600080fd5b5035610f16565b61039b6004803603602081101561065557600080fd5b50356001600160a01b0316610f9f565b6103d36004803603606081101561067b57600080fd5b50803590602081013590604001356001600160a01b0316611276565b61039b600480360360208110156106ad57600080fd5b50356001600160a01b0316611937565b61045a611949565b6103d3600480360360208110156106db57600080fd5b50356001600160a01b0316611973565b6104d2611acf565b61039b6004803603602081101561070957600080fd5b50356001600160a01b0316611ade565b6103d36004803603602081101561072f57600080fd5b5035611af0565b61075c6004803603602081101561074c57600080fd5b50356001600160a01b0316611b79565b6040805192835260208301919091528051918290030190f35b6103d3611e26565b6103dd611e54565b6103d3611e77565b6104b6600480360360408110156107a357600080fd5b506001600160a01b038135169060200135611e7f565b61039b600480360360208110156107cf57600080fd5b5035611efc565b6103d3600480360360208110156107ec57600080fd5b50356001600160a01b0316612113565b6104b66004803603604081101561081257600080fd5b506001600160a01b0381351690602001356121bb565b61039b6004803603602081101561083e57600080fd5b50356121c8565b61039b6122de565b61039b6004803603602081101561086357600080fd5b50356122e4565b61039b6123ee565b61039b6004803603602081101561088857600080fd5b50356123f4565b6104d2612503565b6103d3612512565b6104d261256d565b6103d3600480360360e08110156108bd57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c0013561257c565b61039b61276d565b61075c612773565b61039b6004803603602081101561091e57600080fd5b503561277d565b61039b612886565b61039b6004803603604081101561094357600080fd5b506001600160a01b0381358116916020013516612933565b6103d36004803603602081101561097157600080fd5b5035612950565b6103d36004803603608081101561098e57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160600135166129d9565b61039b612b88565b6103d3600480360360208110156109d457600080fd5b5035612b8e565b61039b600480360360208110156109f157600080fd5b5035612c17565b6103d3612e1d565b60165481565b601754600114610a49576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755600c546001600160a01b03163314610a9c576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038116610ae9576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600080610af4612773565b90925090508115610b1657600d54610b16906001600160a01b03168484612ec7565b8015610b3357600e54610b33906001600160a01b03168483612ec7565b610b3e600080613056565b610b4661309f565b5050600160175550565b6040518060400160405280600b81526020016a0496e74656772616c204c560ac1b81525081565b6000546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000610bae3384846130ec565b5060015b92915050565b600d546001600160a01b031681565b60095481565b6010546001600160a01b031681565b60045481565b6001600160a01b038316600090815260066020908152604080832033845290915281205460001914610c61576001600160a01b0384166000908152600660209081526040808320338452909152902054610c3c908361314e565b6001600160a01b03851660009081526006602090815260408083203384529091529020555b610c6c84848461318a565b5060019392505050565b60145481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b600c546001600160a01b03163314610cf3576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b600b8190556040805182815290517fcda74150def0ede554aff5f677be9df0e226fddff9bd9ceddf732b9673b1c92d9181900360200190a150565b60075481565b60155481565b3360008181526006602090815260408083206001600160a01b03871684529091528120549091610bae918590610d709086613238565b6130ec565b600c546001600160a01b03163314610dc3576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60138190556040805182815290517fbecb607f688c25b67976d7ae1088f9c092d792c4acd14d1ab019e93dcddb4c0e9181900360200190a150565b600c546001600160a01b03163314610e4c576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b600a8190556040805182815290517f0476fcc77110b6ac2d8f2dd346f80d2c5cda54dae5c6ddd6f82b603a4d9b9dc99181900360200190a150565b600c546001600160a01b03163314610ed5576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60168190556040805182815290517f6147eb4c6e239797de749cd53345ceb99d1324d4a5be7c8c2a06c8fcfdb273e89181900360200190a150565b600b5481565b600c546001600160a01b03163314610f64576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60158190556040805182815290517f3b339c4ba98a20478eefc95650e25b07d84a3220f5fab02b19e5b49152a4bf109181900360200190a150565b6000601754600114610fe4576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755610ff233613282565b61103c576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b038216611089576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600080611094610b77565b50600d54600e5492945090925060009182916110bc916001600160a01b0391821691166132c9565b909250905060006110d6836001600160701b03871661314e565b905060006110ed836001600160701b03871661314e565b90506110f7613486565b600454806111315761111d6103e86111176111128686613534565b613592565b9061314e565b975061112c60006103e86135e3565b611174565b6111716001600160701b0388166111488584613534565b8161114f57fe5b046001600160701b0388166111648585613534565b8161116b57fe5b0461366e565b97505b600088116111c9576040805162461bcd60e51b815260206004820181905260248201527f49505f494e53554646494349454e545f4c49515549444954595f4d494e544544604482015290519081900360640190fd5b60006111f2670de0b6b3a76400006111ec6009548c61353490919063ffffffff16565b90613684565b905060006112008a8361314e565b905061120c8b826135e3565b600c54611222906001600160a01b0316836135e3565b61122c87876136df565b6040516001600160a01b038c169033907fc5004d0de103a4ce335ec7dfbb178f69e81ecd773d402c331dafc66c465a020a90600090a3505060016017555095979650505050505050565b6017546001146112b9576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b60006017556112c733613282565b611311576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b03811661135e576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600083118061136d5750600082115b6113be576040805162461bcd60e51b815260206004820152601d60248201527f49505f494e53554646494349454e545f4f55545055545f414d4f554e54000000604482015290519081900360640190fd5b8215806113c9575081155b61141a576040805162461bcd60e51b815260206004820152601d60248201527f49505f4d554c5449504c455f4f5554505554535f535045434946494544000000604482015290519081900360640190fd5b600080611425610b77565b5091509150816001600160701b03168510801561144a5750806001600160701b031684105b61149b576040805162461bcd60e51b815260206004820152601960248201527f49505f494e53554646494349454e545f4c495155494449545900000000000000604482015290519081900360640190fd5b6114a3613486565b600d54600e546001600160a01b039182169190811690851682148015906114dc5750806001600160a01b0316856001600160a01b031614155b61151d576040805162461bcd60e51b815260206004820152600d60248201526c49505f494e56414c49445f544f60981b604482015290519081900360640190fd5b861561152e5761152e828689612ec7565b851561153f5761153f818688612ec7565b5050600d54600e546000918291611562916001600160a01b0390811691166132c9565b91509150600087856001600160701b0316038311611581576000611590565b87856001600160701b03160383035b9050600087856001600160701b03160383116115ad5760006115bc565b87856001600160701b03160383035b905060008211806115cd5750600081115b61161e576040805162461bcd60e51b815260206004820152601c60248201527f49505f494e53554646494349454e545f494e5055545f414d4f554e5400000000604482015290519081900360640190fd5b881561178b5760008061162f611949565b50915091506000611657670de0b6b3a76400006111ec600b548761353490919063ffffffff16565b600f549091506000906001600160a01b031663071f0653611678898561314e565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b1580156116ce57600080fd5b505afa1580156116e2573d6000803e3d6000fd5b505050506040513d60208110156116f857600080fd5b5051905080881015611743576040805162461bcd60e51b815260206004820152600f60248201526e049505f494e56414c49445f5357415608c1b604482015290519081900360640190fd5b61174d8185613780565b6000611759898361314e565b90506117658184613879565b6117816117728a8361314e565b61177c8a8661314e565b61389c565b50505050506118e9565b600080611796611949565b509150915060006117be670de0b6b3a76400006111ec600b548861353490919063ffffffff16565b600f549091506000906001600160a01b0316634666c77a6117df8a8561314e565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b15801561183557600080fd5b505afa158015611849573d6000803e3d6000fd5b505050506040513d602081101561185f57600080fd5b50519050808710156118aa576040805162461bcd60e51b815260206004820152600f60248201526e049505f494e56414c49445f5357415608c1b604482015290519081900360640190fd5b6118b4818461390b565b60006118c0888361314e565b90506118cc8382613879565b6118e36118d98a8561314e565b61177c8a8461314e565b50505050505b6118f16139ff565b6040516001600160a01b0388169033907fe1d4504fa5e661f80f16e8d613b5bc290ee6afe00a96b833a972d8e4490976e190600090a35050600160175550505050505050565b60056020526000908152604090205481565b6001546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b600c546001600160a01b031633146119c1576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038116611a0e576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b611a1781613aae565b611a68576040805162461bcd60e51b815260206004820152601a60248201527f49505f4f5241434c455f4d5553545f42455f434f4e5452414354000000000000604482015290519081900360640190fd5b600f80546001600160a01b0319166001600160a01b038316179055611a8d6000613ab4565b600f54604080516001600160a01b039092168252517fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e080319181900360200190a150565b600f546001600160a01b031681565b60086020526000908152604090205481565b600c546001600160a01b03163314611b3e576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60128190556040805182815290517fb9ed71b42368ae3983f4c7f7e95d2a971bf1d0da90be88a1f2236251f228ed5a9181900360200190a150565b600080601754600114611bbf576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755611bcd33613282565b611c17576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b038316611c64576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600d54600e546001600160a01b039182169116600080611c8484846132c9565b3060009081526005602052604090205460045492945090925090611ca6613486565b600c546000906001600160a01b03163314611cf757611cdc670de0b6b3a76400006111ec600a548661353490919063ffffffff16565b600c54909150611cf79030906001600160a01b03168361318a565b6000611d03848361314e565b9050611d0f3082613b15565b82611d1a8288613534565b81611d2157fe5b04995082611d2f8287613534565b81611d3657fe5b04985060008a118015611d495750600089115b611d9a576040805162461bcd60e51b815260206004820181905260248201527f49505f494e53554646494349454e545f4c49515549444954595f4255524e4544604482015290519081900360640190fd5b611da5888c8c612ec7565b611db0878c8b612ec7565b600d54600e54611dcc916001600160a01b0390811691166132c9565b9096509450611ddb86866136df565b6040516001600160a01b038c169033907f4d0027a9041907e192071c137c856e360354ad357b52ca464608ed2c13d8f99790600090a350505050505050506001601781905550915091565b611e526040518060400160405280600b81526020016a0496e74656772616c204c560ac1b815250613ba6565b565b604051806040016040528060078152602001660495447522d4c560cc1b81525081565b611e52613486565b3360009081526006602090815260408083206001600160a01b038616845290915281205482811015611eed576040805162461bcd60e51b815260206004820152601260248201527149415f43414e4e4f545f444543524541534560701b604482015290519081900360640190fd5b610c6c3385610d70848761314e565b6000806000611f09610b77565b5091509150816001600160701b031660001480611f2d57506001600160701b038116155b15611f3d5760009250505061210e565b600f546040805163b16c524b60e01b815290516000926001600160a01b03169163b16c524b916004808301926020929190829003018186803b158015611f8257600080fd5b505afa158015611f96573d6000803e3d6000fd5b505050506040513d6020811015611fac57600080fd5b5051600f54604080516390c7204d60e01b815290519293506000926001600160a01b03909216916390c7204d91600480820192602092909190829003018186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d602081101561202357600080fd5b505190506000612031612886565b9050600061203f8885613c43565b905060006120566001600160701b03881686613c43565b9050600061206d6001600160701b03881686613c43565b9050600061207b8483613534565b905060006120a9836120a3670de0b6b3a76400006111ec61209c8a8a613238565b8b90613534565b90613238565b905060006120b78383613684565b9050836120d0670de0b6b3a76400006111ec848b613534565b1015806120dd5750858110155b156120f65760009b50505050505050505050505061210e565b612100818a613c93565b9b5050505050505050505050505b919050565b600c546001600160a01b03163314612161576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b601080546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f985b4dd4654f00a77259f8971c3a5aa21910e31ed411ffd8c4106d7e9a0c2285916020908290030190a150565b6000610bae33848461318a565b60008060006121d5610b77565b50915091506000806121e5611949565b5091509150600061220d670de0b6b3a76400006111ec600b548a61353490919063ffffffff16565b600f549091506000906001600160a01b0316634666c77a61223b846111176001600160701b038b168d613238565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b15801561229157600080fd5b505afa1580156122a5573d6000803e3d6000fd5b505050506040513d60208110156122bb57600080fd5b505190506122d26001600160701b0386168261314e565b98975050505050505050565b60135481565b60008060006122f1610b77565b5091509150600080612301611949565b50915091506000612329670de0b6b3a76400006111ec600b548a61353490919063ffffffff16565b600f549091506000906001600160a01b031663071f0653612357846111176001600160701b038a168d613238565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b1580156123ad57600080fd5b505afa1580156123c1573d6000803e3d6000fd5b505050506040513d60208110156123d757600080fd5b505190506122d26001600160701b0387168261314e565b6103e881565b6000806000612401610b77565b5091509150600080612411611949565b509092509050600061242c6001600160701b0386168861314e565b600f546040805163233363bd60e11b8152600481018490526001600160701b0380881660248301528616604482015290519293506000926001600160a01b0390921691634666c77a91606480820192602092909190829003018186803b15801561249557600080fd5b505afa1580156124a9573d6000803e3d6000fd5b505050506040513d60208110156124bf57600080fd5b5051600b549091506122d2906124de90670de0b6b3a76400009061314e565b6111ec670de0b6b5fb6fe4006124fd856001600160701b038b1661314e565b90613534565b600c546001600160a01b031681565b61251b33613282565b612565576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b611e7761309f565b600e546001600160a01b031681565b428410156125be576040805162461bcd60e51b815260206004820152600a602482015269125057d156141254915160b21b604482015290519081900360640190fd5b6007546001600160a01b0380891660008181526008602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e08501825280519083012061190160f01b6101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e280820193601f1981019281900390910190855afa1580156126d9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061270f5750886001600160a01b0316816001600160a01b0316145b612757576040805162461bcd60e51b815260206004820152601460248201527349415f494e56414c49445f5349474e415455524560601b604482015290519081900360640190fd5b6127628989896130ec565b505050505050505050565b60125481565b6002546003549091565b600080600061278a610b77565b509150915060008061279a611949565b50909250905060006127b56001600160701b0385168861314e565b600f546040805163071f065360e01b8152600481018490526001600160701b0380881660248301528616604482015290519293506000926001600160a01b039092169163071f065391606480820192602092909190829003018186803b15801561281e57600080fd5b505afa158015612832573d6000803e3d6000fd5b505050506040513d602081101561284857600080fd5b5051600b549091506122d29061286790670de0b6b3a76400009061314e565b6111ec670de0b6b5fb6fe4006124fd856001600160701b038c1661314e565b600080612891610b77565b50509050600061289f611949565b5050600f5460408051631fc0944160e11b81526001600160701b0380871660048301528416602482015290519293506001600160a01b0390911691633f81288291604480820192602092909190829003018186803b15801561290057600080fd5b505afa158015612914573d6000803e3d6000fd5b505050506040513d602081101561292a57600080fd5b50519250505090565b600660209081526000928352604080842090915290825290205481565b600c546001600160a01b0316331461299e576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60098190556040805182815290517f276a443d2b2c8332fc729f4de8847f12625c9f099e07b8501c91df8a4fcb12109181900360200190a150565b600c546001600160a01b03163314612a27576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038216612a74576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b612a7d82613aae565b612ace576040805162461bcd60e51b815260206004820152601a60248201527f49505f4f5241434c455f4d5553545f42455f434f4e5452414354000000000000604482015290519081900360640190fd5b612ad784613aae565b8015612ae75750612ae783613aae565b612b38576040805162461bcd60e51b815260206004820152601960248201527f49505f544f4b454e5f4d5553545f42455f434f4e545241435400000000000000604482015290519081900360640190fd5b600d80546001600160a01b039586166001600160a01b031991821617909155600e805494861694821694909417909355600f80549285169284169290921790915560108054919093169116179055565b600a5481565b600c546001600160a01b03163314612bdc576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60148190556040805182815290517fe966d8dc3048c1b7a968db22b3b768457971432a526a78d0b9923bd1c9c3e6219181900360200190a150565b6000806000612c24610b77565b5091509150816001600160701b031660001480612c4857506001600160701b038116155b15612c585760009250505061210e565b600f546040805163b16c524b60e01b815290516000926001600160a01b03169163b16c524b916004808301926020929190829003018186803b158015612c9d57600080fd5b505afa158015612cb1573d6000803e3d6000fd5b505050506040513d6020811015612cc757600080fd5b5051600f54604080516390c7204d60e01b815290519293506000926001600160a01b03909216916390c7204d91600480820192602092909190829003018186803b158015612d1457600080fd5b505afa158015612d28573d6000803e3d6000fd5b505050506040513d6020811015612d3e57600080fd5b505190506000612d4c612886565b90506000612d5a8884613c43565b90506000612d716001600160701b03881686613c43565b90506000612d886001600160701b03881686613c43565b90506000612da6856124fd670de0b6b3a76400006111ec8789613534565b90506000612dc6836120a38781670de0b6b3a76400006111ec8a8d613534565b90506000612dd48383613684565b905084612ded886111ec84670de0b6b3a7640000613534565b101580612dfa5750858110155b15612e135760009b50505050505050505050505061210e565b6121008189613c93565b601754600114612e60576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755612e6e33613282565b612eb8576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b612ec061309f565b6001601755565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b1781529251815160009460609489169392918291908083835b60208310612f745780518252601f199092019160209182019101612f55565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612fd6576040519150601f19603f3d011682016040523d82523d6000602084013e612fdb565b606091505b5091509150818015613009575080511580613009575080806020019051602081101561300657600080fd5b50515b61304f576040805162461bcd60e51b8152602060048201526012602482015271125417d514905394d1915497d1905253115160721b604482015290519081900360640190fd5b5050505050565b60028290556003819055604080518381526020810183905281517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b929181900390910190a15050565b600d54600e546130bb916001600160a01b039081169116613cdc565b3060009081526005602052604090205480156130e957600c546130e99030906001600160a01b03168361318a565b50565b6001600160a01b03808416600081815260066020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061318383836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250613f35565b9392505050565b6001600160a01b0383166000908152600560205260409020546131ad908261314e565b6001600160a01b0380851660009081526005602052604080822093909355908416815220546131dc9082613238565b6001600160a01b0380841660008181526005602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b80820182811015610bb2576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b6010546000906001600160a01b03838116911614806132ae5750600c546001600160a01b038381169116145b80610bb257506010546001600160a01b039081161492915050565b6000806000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561331b57600080fd5b505afa15801561332f573d6000803e3d6000fd5b505050506040513d602081101561334557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038716916370a08231916024808301926020929190829003018186803b15801561339357600080fd5b505afa1580156133a7573d6000803e3d6000fd5b505050506040513d60208110156133bd57600080fd5b505160025490915082101561341057600282905560035460408051848152602081019290925280517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b9281900390910190a15b80600354111561345d576003819055600254604080519182526020820183905280517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b9281900390910190a15b60025461346b90839061314e565b60035461347990839061314e565b9350935050509250929050565b600f5460408051630ce74fc560e31b815290516000926001600160a01b03169163673a7e2891600480830192602092919082900301818787803b1580156134cc57600080fd5b505af11580156134e0573d6000803e3d6000fd5b505050506040513d60208110156134f657600080fd5b505190506000613504611949565b925050508063ffffffff168263ffffffff16146135305761352482613ab4565b61352c612886565b6011555b5050565b600081158061354f5750508082028282828161354c57fe5b04145b610bb2576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b600060038211156135d5575080600160028204015b818110156135cf578091506002818285816135be57fe5b0401816135c757fe5b0490506135a7565b5061210e565b811561210e57506001919050565b6004546135f09082613238565b6004556001600160a01b0382166000908152600560205260409020546136169082613238565b6001600160a01b03831660008181526005602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600081831061367d5781613183565b5090919050565b60008082116136cb576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b60008284816136d657fe5b04949350505050565b6000806136ea610b77565b509150915083826001600160701b0316141580613710575082816001600160701b031614155b1561377a5761371f848461389c565b60005460015461377a91613746916001600160701b03808716926111179282169116613238565b600054600154613775916001600160701b038087169261111792600160701b9182900483169291900416613238565b613fcd565b50505050565b806001600160701b03168210156135305760006137a66001600160701b0383168461314e565b90506012548111156137ff576040805162461bcd60e51b815260206004820152601e60248201527f49505f41305f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6014546138216001600160701b0384166111ec84670de0b6b3a7640000613534565b1115613874576040805162461bcd60e51b815260206004820152601e60248201527f49505f52305f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b505050565b6002546135309061388a9084613238565b6003546138979084613238565b613056565b6001600160701b0382118015906138ba57506001600160701b038111155b6138f9576040805162461bcd60e51b815260206004820152600b60248201526a52535f4f564552464c4f5760a81b604482015290519081900360640190fd5b63ffffffff4216613874838383614065565b806001600160701b03168210156135305760006139316001600160701b0383168461314e565b905060135481111561398a576040805162461bcd60e51b815260206004820152601e60248201527f49505f41315f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6015546139ac6001600160701b0384166111ec84670de0b6b3a7640000613534565b1115613874576040805162461bcd60e51b815260206004820152601e60248201527f49505f52315f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6000613a09612886565b601154909150156130e95760008160115411613a3257601154613a2d90839061314e565b613a3f565b601154613a3f908361314e565b9050601654613a656011546111ec670de0b6b3a76400008561353490919063ffffffff16565b1115613530576040805162461bcd60e51b8152602060048201526013602482015272125417d417d31253525517d15610d151511151606a1b604482015290519081900360640190fd5b3b151590565b6000546001805463ffffffff909316600160e01b026001600160e01b03600160701b8085046001600160701b03908116909102600160701b600160e01b03196001600160701b03199097169190951617949094169290921792909216179055565b6001600160a01b038216600090815260056020526040902054613b38908261314e565b6001600160a01b038316600090815260056020526040902055600454613b5e908261314e565b6004556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b805160209182012060408051808201825260018152603160f81b9084015280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81850152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528151808403909101815260c090920190528051910120600755565b60008160ff1660121415613c58575081610bb2565b60128260ff161115613c7f57613c788360ff601119850116600a0a613684565b9050610bb2565b613c788360ff601285900316600a0a613534565b60008160ff1660121415613ca8575081610bb2565b60128260ff161115613cc857613c788360ff601119850116600a0a613534565b613c788360ff601285900316600a0a613684565b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613d2b57600080fd5b505afa158015613d3f573d6000803e3d6000fd5b505050506040513d6020811015613d5557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b158015613da357600080fd5b505afa158015613db7573d6000803e3d6000fd5b505050506040513d6020811015613dcd57600080fd5b50519050600080613ddc610b77565b50915091506000613e01836001600160701b031660025461323890919063ffffffff16565b90506000613e23836001600160701b031660035461323890919063ffffffff16565b905081613e3257600254613e4b565b613e4b826111ec8860025461353490919063ffffffff16565b60025580613e5b57600354613e74565b613e74816111ec8760035461353490919063ffffffff16565b600355600254600090613e8890889061314e565b90506000613ea16003548861314e90919063ffffffff16565b905081866001600160701b0316141580613ec4575080856001600160701b031614155b15613f2957613ed3828261389c565b600054600154613f2991613efa916001600160701b03808b16926111179282169116613238565b600054600154613775916001600160701b03808b169261111792600160701b9182900483169291900416613238565b50505050505050505050565b8183038184821115613fc55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f8a578181015183820152602001613f72565b50505050905090810190601f168015613fb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b6001600160701b038211801590613feb57506001600160701b038111155b61402a576040805162461bcd60e51b815260206004820152600b60248201526a52535f4f564552464c4f5760a81b604482015290519081900360640190fd5b600180546001600160701b03928316600160701b02600160701b600160e01b0319949093166001600160701b03199091161792909216179055565b6001600160701b0383161580159061408557506001600160701b03821615155b6140c0576040805162461bcd60e51b815260206004820152600760248201526652535f5a45524f60c81b604482015290519081900360640190fd5b600080546001600160701b0319166001600160701b0385811691909117600160701b600160e01b031916600160701b8583168102919091176001600160e01b0316600160e01b63ffffffff861602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a150505056fea26469706673582212200ac7429eaeb05513b956255ebb7ae31ef023b2e50a47923f0013925fa96b5fab64736f6c63430007050033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061038e5760003560e01c806384c150a6116101de578063c45a01551161010f578063dc76fabc116100ad578063fce589d81161007c578063fce589d8146109b6578063ff3549a3146109be578063ff91c78d146109db578063fff6cae9146109f85761038e565b8063dc76fabc14610925578063dd62ed3e1461092d578063eddd0d9c1461095b578063f8c8765e146109785761038e565b8063d505accf116100e9578063d505accf146108a7578063d727dfc9146108f8578063db8d55f114610900578063dc084e78146109085761038e565b8063c45a01551461088f578063caeba21714610897578063d21220a71461089f5761038e565b8063a6bc18f91161017c578063b81af61911610156578063b81af61914610845578063b8d3f31c1461084d578063ba9a7a561461086a578063bc103be8146108725761038e565b8063a6bc18f9146107d6578063a9059cbb146107fc578063afb600fe146108285761038e565b806395d89b41116101b857806395d89b411461077d57806399ce42bb14610785578063a457c2d71461078d578063a66f459a146107b95761038e565b806384c150a61461071957806389afcb441461073657806389ccfe89146107755761038e565b80633644e515116102c357806361556e1e116102615780637a6337fa116102305780637a6337fa146106bd5780637adbf973146106c55780637dc0d1d0146106eb5780637ecebe00146106f35761038e565b806361556e1e146106225780636a6278421461063f5780636d9a640a1461066557806370a08231146106975761038e565b80633c80f8a71161029d5780633c80f8a7146105c35780634bf2c7c9146105e05780634e775aad146105fd57806354cf2aeb1461061a5761038e565b80633644e5151461058757806336a2b5851461058f57806339509351146105975761038e565b80631758078b11610330578063283d8df71161030a578063283d8df71461053c57806330adf81f14610544578063313ce5671461054c57806334e199071461056a5761038e565b80631758078b146104f657806318160ddd146104fe57806323b872dd146105065761038e565b80630902f1ac1161036c5780630902f1ac14610452578063095ea7b31461048a5780630dfe1681146104ca57806313966db5146104ee5761038e565b80630699df581461039357806306ec16f8146103ad57806306fdde03146103d5575b600080fd5b61039b610a00565b60408051918252519081900360200190f35b6103d3600480360360208110156103c357600080fd5b50356001600160a01b0316610a06565b005b6103dd610b50565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104175781810151838201526020016103ff565b50505050905090810190601f1680156104445780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61045a610b77565b604080516001600160701b03948516815292909316602083015263ffffffff168183015290519081900360600190f35b6104b6600480360360408110156104a057600080fd5b506001600160a01b038135169060200135610ba1565b604080519115158252519081900360200190f35b6104d2610bb8565b604080516001600160a01b039092168252519081900360200190f35b61039b610bc7565b6104d2610bcd565b61039b610bdc565b6104b66004803603606081101561051c57600080fd5b506001600160a01b03813581169160208101359091169060400135610be2565b61039b610c76565b61039b610c7c565b610554610ca0565b6040805160ff9092168252519081900360200190f35b6103d36004803603602081101561058057600080fd5b5035610ca5565b61039b610d2e565b61039b610d34565b6104b6600480360360408110156105ad57600080fd5b506001600160a01b038135169060200135610d3a565b6103d3600480360360208110156105d957600080fd5b5035610d75565b6103d3600480360360208110156105f657600080fd5b5035610dfe565b6103d36004803603602081101561061357600080fd5b5035610e87565b61039b610f10565b6103d36004803603602081101561063857600080fd5b5035610f16565b61039b6004803603602081101561065557600080fd5b50356001600160a01b0316610f9f565b6103d36004803603606081101561067b57600080fd5b50803590602081013590604001356001600160a01b0316611276565b61039b600480360360208110156106ad57600080fd5b50356001600160a01b0316611937565b61045a611949565b6103d3600480360360208110156106db57600080fd5b50356001600160a01b0316611973565b6104d2611acf565b61039b6004803603602081101561070957600080fd5b50356001600160a01b0316611ade565b6103d36004803603602081101561072f57600080fd5b5035611af0565b61075c6004803603602081101561074c57600080fd5b50356001600160a01b0316611b79565b6040805192835260208301919091528051918290030190f35b6103d3611e26565b6103dd611e54565b6103d3611e77565b6104b6600480360360408110156107a357600080fd5b506001600160a01b038135169060200135611e7f565b61039b600480360360208110156107cf57600080fd5b5035611efc565b6103d3600480360360208110156107ec57600080fd5b50356001600160a01b0316612113565b6104b66004803603604081101561081257600080fd5b506001600160a01b0381351690602001356121bb565b61039b6004803603602081101561083e57600080fd5b50356121c8565b61039b6122de565b61039b6004803603602081101561086357600080fd5b50356122e4565b61039b6123ee565b61039b6004803603602081101561088857600080fd5b50356123f4565b6104d2612503565b6103d3612512565b6104d261256d565b6103d3600480360360e08110156108bd57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c0013561257c565b61039b61276d565b61075c612773565b61039b6004803603602081101561091e57600080fd5b503561277d565b61039b612886565b61039b6004803603604081101561094357600080fd5b506001600160a01b0381358116916020013516612933565b6103d36004803603602081101561097157600080fd5b5035612950565b6103d36004803603608081101561098e57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160600135166129d9565b61039b612b88565b6103d3600480360360208110156109d457600080fd5b5035612b8e565b61039b600480360360208110156109f157600080fd5b5035612c17565b6103d3612e1d565b60165481565b601754600114610a49576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755600c546001600160a01b03163314610a9c576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038116610ae9576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600080610af4612773565b90925090508115610b1657600d54610b16906001600160a01b03168484612ec7565b8015610b3357600e54610b33906001600160a01b03168483612ec7565b610b3e600080613056565b610b4661309f565b5050600160175550565b6040518060400160405280600b81526020016a0496e74656772616c204c560ac1b81525081565b6000546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000610bae3384846130ec565b5060015b92915050565b600d546001600160a01b031681565b60095481565b6010546001600160a01b031681565b60045481565b6001600160a01b038316600090815260066020908152604080832033845290915281205460001914610c61576001600160a01b0384166000908152600660209081526040808320338452909152902054610c3c908361314e565b6001600160a01b03851660009081526006602090815260408083203384529091529020555b610c6c84848461318a565b5060019392505050565b60145481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b600c546001600160a01b03163314610cf3576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b600b8190556040805182815290517fcda74150def0ede554aff5f677be9df0e226fddff9bd9ceddf732b9673b1c92d9181900360200190a150565b60075481565b60155481565b3360008181526006602090815260408083206001600160a01b03871684529091528120549091610bae918590610d709086613238565b6130ec565b600c546001600160a01b03163314610dc3576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60138190556040805182815290517fbecb607f688c25b67976d7ae1088f9c092d792c4acd14d1ab019e93dcddb4c0e9181900360200190a150565b600c546001600160a01b03163314610e4c576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b600a8190556040805182815290517f0476fcc77110b6ac2d8f2dd346f80d2c5cda54dae5c6ddd6f82b603a4d9b9dc99181900360200190a150565b600c546001600160a01b03163314610ed5576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60168190556040805182815290517f6147eb4c6e239797de749cd53345ceb99d1324d4a5be7c8c2a06c8fcfdb273e89181900360200190a150565b600b5481565b600c546001600160a01b03163314610f64576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60158190556040805182815290517f3b339c4ba98a20478eefc95650e25b07d84a3220f5fab02b19e5b49152a4bf109181900360200190a150565b6000601754600114610fe4576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755610ff233613282565b61103c576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b038216611089576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600080611094610b77565b50600d54600e5492945090925060009182916110bc916001600160a01b0391821691166132c9565b909250905060006110d6836001600160701b03871661314e565b905060006110ed836001600160701b03871661314e565b90506110f7613486565b600454806111315761111d6103e86111176111128686613534565b613592565b9061314e565b975061112c60006103e86135e3565b611174565b6111716001600160701b0388166111488584613534565b8161114f57fe5b046001600160701b0388166111648585613534565b8161116b57fe5b0461366e565b97505b600088116111c9576040805162461bcd60e51b815260206004820181905260248201527f49505f494e53554646494349454e545f4c49515549444954595f4d494e544544604482015290519081900360640190fd5b60006111f2670de0b6b3a76400006111ec6009548c61353490919063ffffffff16565b90613684565b905060006112008a8361314e565b905061120c8b826135e3565b600c54611222906001600160a01b0316836135e3565b61122c87876136df565b6040516001600160a01b038c169033907fc5004d0de103a4ce335ec7dfbb178f69e81ecd773d402c331dafc66c465a020a90600090a3505060016017555095979650505050505050565b6017546001146112b9576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b60006017556112c733613282565b611311576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b03811661135e576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600083118061136d5750600082115b6113be576040805162461bcd60e51b815260206004820152601d60248201527f49505f494e53554646494349454e545f4f55545055545f414d4f554e54000000604482015290519081900360640190fd5b8215806113c9575081155b61141a576040805162461bcd60e51b815260206004820152601d60248201527f49505f4d554c5449504c455f4f5554505554535f535045434946494544000000604482015290519081900360640190fd5b600080611425610b77565b5091509150816001600160701b03168510801561144a5750806001600160701b031684105b61149b576040805162461bcd60e51b815260206004820152601960248201527f49505f494e53554646494349454e545f4c495155494449545900000000000000604482015290519081900360640190fd5b6114a3613486565b600d54600e546001600160a01b039182169190811690851682148015906114dc5750806001600160a01b0316856001600160a01b031614155b61151d576040805162461bcd60e51b815260206004820152600d60248201526c49505f494e56414c49445f544f60981b604482015290519081900360640190fd5b861561152e5761152e828689612ec7565b851561153f5761153f818688612ec7565b5050600d54600e546000918291611562916001600160a01b0390811691166132c9565b91509150600087856001600160701b0316038311611581576000611590565b87856001600160701b03160383035b9050600087856001600160701b03160383116115ad5760006115bc565b87856001600160701b03160383035b905060008211806115cd5750600081115b61161e576040805162461bcd60e51b815260206004820152601c60248201527f49505f494e53554646494349454e545f494e5055545f414d4f554e5400000000604482015290519081900360640190fd5b881561178b5760008061162f611949565b50915091506000611657670de0b6b3a76400006111ec600b548761353490919063ffffffff16565b600f549091506000906001600160a01b031663071f0653611678898561314e565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b1580156116ce57600080fd5b505afa1580156116e2573d6000803e3d6000fd5b505050506040513d60208110156116f857600080fd5b5051905080881015611743576040805162461bcd60e51b815260206004820152600f60248201526e049505f494e56414c49445f5357415608c1b604482015290519081900360640190fd5b61174d8185613780565b6000611759898361314e565b90506117658184613879565b6117816117728a8361314e565b61177c8a8661314e565b61389c565b50505050506118e9565b600080611796611949565b509150915060006117be670de0b6b3a76400006111ec600b548861353490919063ffffffff16565b600f549091506000906001600160a01b0316634666c77a6117df8a8561314e565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b15801561183557600080fd5b505afa158015611849573d6000803e3d6000fd5b505050506040513d602081101561185f57600080fd5b50519050808710156118aa576040805162461bcd60e51b815260206004820152600f60248201526e049505f494e56414c49445f5357415608c1b604482015290519081900360640190fd5b6118b4818461390b565b60006118c0888361314e565b90506118cc8382613879565b6118e36118d98a8561314e565b61177c8a8461314e565b50505050505b6118f16139ff565b6040516001600160a01b0388169033907fe1d4504fa5e661f80f16e8d613b5bc290ee6afe00a96b833a972d8e4490976e190600090a35050600160175550505050505050565b60056020526000908152604090205481565b6001546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b600c546001600160a01b031633146119c1576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038116611a0e576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b611a1781613aae565b611a68576040805162461bcd60e51b815260206004820152601a60248201527f49505f4f5241434c455f4d5553545f42455f434f4e5452414354000000000000604482015290519081900360640190fd5b600f80546001600160a01b0319166001600160a01b038316179055611a8d6000613ab4565b600f54604080516001600160a01b039092168252517fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e080319181900360200190a150565b600f546001600160a01b031681565b60086020526000908152604090205481565b600c546001600160a01b03163314611b3e576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60128190556040805182815290517fb9ed71b42368ae3983f4c7f7e95d2a971bf1d0da90be88a1f2236251f228ed5a9181900360200190a150565b600080601754600114611bbf576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755611bcd33613282565b611c17576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b6001600160a01b038316611c64576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b600d54600e546001600160a01b039182169116600080611c8484846132c9565b3060009081526005602052604090205460045492945090925090611ca6613486565b600c546000906001600160a01b03163314611cf757611cdc670de0b6b3a76400006111ec600a548661353490919063ffffffff16565b600c54909150611cf79030906001600160a01b03168361318a565b6000611d03848361314e565b9050611d0f3082613b15565b82611d1a8288613534565b81611d2157fe5b04995082611d2f8287613534565b81611d3657fe5b04985060008a118015611d495750600089115b611d9a576040805162461bcd60e51b815260206004820181905260248201527f49505f494e53554646494349454e545f4c49515549444954595f4255524e4544604482015290519081900360640190fd5b611da5888c8c612ec7565b611db0878c8b612ec7565b600d54600e54611dcc916001600160a01b0390811691166132c9565b9096509450611ddb86866136df565b6040516001600160a01b038c169033907f4d0027a9041907e192071c137c856e360354ad357b52ca464608ed2c13d8f99790600090a350505050505050506001601781905550915091565b611e526040518060400160405280600b81526020016a0496e74656772616c204c560ac1b815250613ba6565b565b604051806040016040528060078152602001660495447522d4c560cc1b81525081565b611e52613486565b3360009081526006602090815260408083206001600160a01b038616845290915281205482811015611eed576040805162461bcd60e51b815260206004820152601260248201527149415f43414e4e4f545f444543524541534560701b604482015290519081900360640190fd5b610c6c3385610d70848761314e565b6000806000611f09610b77565b5091509150816001600160701b031660001480611f2d57506001600160701b038116155b15611f3d5760009250505061210e565b600f546040805163b16c524b60e01b815290516000926001600160a01b03169163b16c524b916004808301926020929190829003018186803b158015611f8257600080fd5b505afa158015611f96573d6000803e3d6000fd5b505050506040513d6020811015611fac57600080fd5b5051600f54604080516390c7204d60e01b815290519293506000926001600160a01b03909216916390c7204d91600480820192602092909190829003018186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d602081101561202357600080fd5b505190506000612031612886565b9050600061203f8885613c43565b905060006120566001600160701b03881686613c43565b9050600061206d6001600160701b03881686613c43565b9050600061207b8483613534565b905060006120a9836120a3670de0b6b3a76400006111ec61209c8a8a613238565b8b90613534565b90613238565b905060006120b78383613684565b9050836120d0670de0b6b3a76400006111ec848b613534565b1015806120dd5750858110155b156120f65760009b50505050505050505050505061210e565b612100818a613c93565b9b5050505050505050505050505b919050565b600c546001600160a01b03163314612161576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b601080546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f985b4dd4654f00a77259f8971c3a5aa21910e31ed411ffd8c4106d7e9a0c2285916020908290030190a150565b6000610bae33848461318a565b60008060006121d5610b77565b50915091506000806121e5611949565b5091509150600061220d670de0b6b3a76400006111ec600b548a61353490919063ffffffff16565b600f549091506000906001600160a01b0316634666c77a61223b846111176001600160701b038b168d613238565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b15801561229157600080fd5b505afa1580156122a5573d6000803e3d6000fd5b505050506040513d60208110156122bb57600080fd5b505190506122d26001600160701b0386168261314e565b98975050505050505050565b60135481565b60008060006122f1610b77565b5091509150600080612301611949565b50915091506000612329670de0b6b3a76400006111ec600b548a61353490919063ffffffff16565b600f549091506000906001600160a01b031663071f0653612357846111176001600160701b038a168d613238565b86866040518463ffffffff1660e01b815260040180848152602001836001600160701b03168152602001826001600160701b03168152602001935050505060206040518083038186803b1580156123ad57600080fd5b505afa1580156123c1573d6000803e3d6000fd5b505050506040513d60208110156123d757600080fd5b505190506122d26001600160701b0387168261314e565b6103e881565b6000806000612401610b77565b5091509150600080612411611949565b509092509050600061242c6001600160701b0386168861314e565b600f546040805163233363bd60e11b8152600481018490526001600160701b0380881660248301528616604482015290519293506000926001600160a01b0390921691634666c77a91606480820192602092909190829003018186803b15801561249557600080fd5b505afa1580156124a9573d6000803e3d6000fd5b505050506040513d60208110156124bf57600080fd5b5051600b549091506122d2906124de90670de0b6b3a76400009061314e565b6111ec670de0b6b5fb6fe4006124fd856001600160701b038b1661314e565b90613534565b600c546001600160a01b031681565b61251b33613282565b612565576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b611e7761309f565b600e546001600160a01b031681565b428410156125be576040805162461bcd60e51b815260206004820152600a602482015269125057d156141254915160b21b604482015290519081900360640190fd5b6007546001600160a01b0380891660008181526008602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e08501825280519083012061190160f01b6101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e280820193601f1981019281900390910190855afa1580156126d9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061270f5750886001600160a01b0316816001600160a01b0316145b612757576040805162461bcd60e51b815260206004820152601460248201527349415f494e56414c49445f5349474e415455524560601b604482015290519081900360640190fd5b6127628989896130ec565b505050505050505050565b60125481565b6002546003549091565b600080600061278a610b77565b509150915060008061279a611949565b50909250905060006127b56001600160701b0385168861314e565b600f546040805163071f065360e01b8152600481018490526001600160701b0380881660248301528616604482015290519293506000926001600160a01b039092169163071f065391606480820192602092909190829003018186803b15801561281e57600080fd5b505afa158015612832573d6000803e3d6000fd5b505050506040513d602081101561284857600080fd5b5051600b549091506122d29061286790670de0b6b3a76400009061314e565b6111ec670de0b6b5fb6fe4006124fd856001600160701b038c1661314e565b600080612891610b77565b50509050600061289f611949565b5050600f5460408051631fc0944160e11b81526001600160701b0380871660048301528416602482015290519293506001600160a01b0390911691633f81288291604480820192602092909190829003018186803b15801561290057600080fd5b505afa158015612914573d6000803e3d6000fd5b505050506040513d602081101561292a57600080fd5b50519250505090565b600660209081526000928352604080842090915290825290205481565b600c546001600160a01b0316331461299e576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60098190556040805182815290517f276a443d2b2c8332fc729f4de8847f12625c9f099e07b8501c91df8a4fcb12109181900360200190a150565b600c546001600160a01b03163314612a27576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038216612a74576040805162461bcd60e51b815260206004820152600f60248201526e49505f414444524553535f5a45524f60881b604482015290519081900360640190fd5b612a7d82613aae565b612ace576040805162461bcd60e51b815260206004820152601a60248201527f49505f4f5241434c455f4d5553545f42455f434f4e5452414354000000000000604482015290519081900360640190fd5b612ad784613aae565b8015612ae75750612ae783613aae565b612b38576040805162461bcd60e51b815260206004820152601960248201527f49505f544f4b454e5f4d5553545f42455f434f4e545241435400000000000000604482015290519081900360640190fd5b600d80546001600160a01b039586166001600160a01b031991821617909155600e805494861694821694909417909355600f80549285169284169290921790915560108054919093169116179055565b600a5481565b600c546001600160a01b03163314612bdc576040805162461bcd60e51b815260206004820152600c60248201526b24a82fa327a92124a22222a760a11b604482015290519081900360640190fd5b60148190556040805182815290517fe966d8dc3048c1b7a968db22b3b768457971432a526a78d0b9923bd1c9c3e6219181900360200190a150565b6000806000612c24610b77565b5091509150816001600160701b031660001480612c4857506001600160701b038116155b15612c585760009250505061210e565b600f546040805163b16c524b60e01b815290516000926001600160a01b03169163b16c524b916004808301926020929190829003018186803b158015612c9d57600080fd5b505afa158015612cb1573d6000803e3d6000fd5b505050506040513d6020811015612cc757600080fd5b5051600f54604080516390c7204d60e01b815290519293506000926001600160a01b03909216916390c7204d91600480820192602092909190829003018186803b158015612d1457600080fd5b505afa158015612d28573d6000803e3d6000fd5b505050506040513d6020811015612d3e57600080fd5b505190506000612d4c612886565b90506000612d5a8884613c43565b90506000612d716001600160701b03881686613c43565b90506000612d886001600160701b03881686613c43565b90506000612da6856124fd670de0b6b3a76400006111ec8789613534565b90506000612dc6836120a38781670de0b6b3a76400006111ec8a8d613534565b90506000612dd48383613684565b905084612ded886111ec84670de0b6b3a7640000613534565b101580612dfa5750858110155b15612e135760009b50505050505050505050505061210e565b6121008189613c93565b601754600114612e60576040805162461bcd60e51b8152602060048201526009602482015268125417d313d0d2d15160ba1b604482015290519081900360640190fd5b6000601755612e6e33613282565b612eb8576040805162461bcd60e51b815260206004820152601660248201527524a82faaa720aaaa2427a924ad22a22faa2920a222a960511b604482015290519081900360640190fd5b612ec061309f565b6001601755565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b1781529251815160009460609489169392918291908083835b60208310612f745780518252601f199092019160209182019101612f55565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612fd6576040519150601f19603f3d011682016040523d82523d6000602084013e612fdb565b606091505b5091509150818015613009575080511580613009575080806020019051602081101561300657600080fd5b50515b61304f576040805162461bcd60e51b8152602060048201526012602482015271125417d514905394d1915497d1905253115160721b604482015290519081900360640190fd5b5050505050565b60028290556003819055604080518381526020810183905281517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b929181900390910190a15050565b600d54600e546130bb916001600160a01b039081169116613cdc565b3060009081526005602052604090205480156130e957600c546130e99030906001600160a01b03168361318a565b50565b6001600160a01b03808416600081815260066020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061318383836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250613f35565b9392505050565b6001600160a01b0383166000908152600560205260409020546131ad908261314e565b6001600160a01b0380851660009081526005602052604080822093909355908416815220546131dc9082613238565b6001600160a01b0380841660008181526005602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b80820182811015610bb2576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b6010546000906001600160a01b03838116911614806132ae5750600c546001600160a01b038381169116145b80610bb257506010546001600160a01b039081161492915050565b6000806000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561331b57600080fd5b505afa15801561332f573d6000803e3d6000fd5b505050506040513d602081101561334557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038716916370a08231916024808301926020929190829003018186803b15801561339357600080fd5b505afa1580156133a7573d6000803e3d6000fd5b505050506040513d60208110156133bd57600080fd5b505160025490915082101561341057600282905560035460408051848152602081019290925280517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b9281900390910190a15b80600354111561345d576003819055600254604080519182526020820183905280517f2cc59d6e1281c9f122c4f6930ae083db22762e74c7aacbfeded26fcbb367936b9281900390910190a15b60025461346b90839061314e565b60035461347990839061314e565b9350935050509250929050565b600f5460408051630ce74fc560e31b815290516000926001600160a01b03169163673a7e2891600480830192602092919082900301818787803b1580156134cc57600080fd5b505af11580156134e0573d6000803e3d6000fd5b505050506040513d60208110156134f657600080fd5b505190506000613504611949565b925050508063ffffffff168263ffffffff16146135305761352482613ab4565b61352c612886565b6011555b5050565b600081158061354f5750508082028282828161354c57fe5b04145b610bb2576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b600060038211156135d5575080600160028204015b818110156135cf578091506002818285816135be57fe5b0401816135c757fe5b0490506135a7565b5061210e565b811561210e57506001919050565b6004546135f09082613238565b6004556001600160a01b0382166000908152600560205260409020546136169082613238565b6001600160a01b03831660008181526005602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600081831061367d5781613183565b5090919050565b60008082116136cb576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b60008284816136d657fe5b04949350505050565b6000806136ea610b77565b509150915083826001600160701b0316141580613710575082816001600160701b031614155b1561377a5761371f848461389c565b60005460015461377a91613746916001600160701b03808716926111179282169116613238565b600054600154613775916001600160701b038087169261111792600160701b9182900483169291900416613238565b613fcd565b50505050565b806001600160701b03168210156135305760006137a66001600160701b0383168461314e565b90506012548111156137ff576040805162461bcd60e51b815260206004820152601e60248201527f49505f41305f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6014546138216001600160701b0384166111ec84670de0b6b3a7640000613534565b1115613874576040805162461bcd60e51b815260206004820152601e60248201527f49505f52305f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b505050565b6002546135309061388a9084613238565b6003546138979084613238565b613056565b6001600160701b0382118015906138ba57506001600160701b038111155b6138f9576040805162461bcd60e51b815260206004820152600b60248201526a52535f4f564552464c4f5760a81b604482015290519081900360640190fd5b63ffffffff4216613874838383614065565b806001600160701b03168210156135305760006139316001600160701b0383168461314e565b905060135481111561398a576040805162461bcd60e51b815260206004820152601e60248201527f49505f41315f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6015546139ac6001600160701b0384166111ec84670de0b6b3a7640000613534565b1115613874576040805162461bcd60e51b815260206004820152601e60248201527f49505f52315f4c49515549444954595f4c494d49545f45584345454445440000604482015290519081900360640190fd5b6000613a09612886565b601154909150156130e95760008160115411613a3257601154613a2d90839061314e565b613a3f565b601154613a3f908361314e565b9050601654613a656011546111ec670de0b6b3a76400008561353490919063ffffffff16565b1115613530576040805162461bcd60e51b8152602060048201526013602482015272125417d417d31253525517d15610d151511151606a1b604482015290519081900360640190fd5b3b151590565b6000546001805463ffffffff909316600160e01b026001600160e01b03600160701b8085046001600160701b03908116909102600160701b600160e01b03196001600160701b03199097169190951617949094169290921792909216179055565b6001600160a01b038216600090815260056020526040902054613b38908261314e565b6001600160a01b038316600090815260056020526040902055600454613b5e908261314e565b6004556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b805160209182012060408051808201825260018152603160f81b9084015280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81850152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528151808403909101815260c090920190528051910120600755565b60008160ff1660121415613c58575081610bb2565b60128260ff161115613c7f57613c788360ff601119850116600a0a613684565b9050610bb2565b613c788360ff601285900316600a0a613534565b60008160ff1660121415613ca8575081610bb2565b60128260ff161115613cc857613c788360ff601119850116600a0a613534565b613c788360ff601285900316600a0a613684565b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613d2b57600080fd5b505afa158015613d3f573d6000803e3d6000fd5b505050506040513d6020811015613d5557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b158015613da357600080fd5b505afa158015613db7573d6000803e3d6000fd5b505050506040513d6020811015613dcd57600080fd5b50519050600080613ddc610b77565b50915091506000613e01836001600160701b031660025461323890919063ffffffff16565b90506000613e23836001600160701b031660035461323890919063ffffffff16565b905081613e3257600254613e4b565b613e4b826111ec8860025461353490919063ffffffff16565b60025580613e5b57600354613e74565b613e74816111ec8760035461353490919063ffffffff16565b600355600254600090613e8890889061314e565b90506000613ea16003548861314e90919063ffffffff16565b905081866001600160701b0316141580613ec4575080856001600160701b031614155b15613f2957613ed3828261389c565b600054600154613f2991613efa916001600160701b03808b16926111179282169116613238565b600054600154613775916001600160701b03808b169261111792600160701b9182900483169291900416613238565b50505050505050505050565b8183038184821115613fc55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f8a578181015183820152602001613f72565b50505050905090810190601f168015613fb75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b6001600160701b038211801590613feb57506001600160701b038111155b61402a576040805162461bcd60e51b815260206004820152600b60248201526a52535f4f564552464c4f5760a81b604482015290519081900360640190fd5b600180546001600160701b03928316600160701b02600160701b600160e01b0319949093166001600160701b03199091161792909216179055565b6001600160701b0383161580159061408557506001600160701b03821615155b6140c0576040805162461bcd60e51b815260206004820152600760248201526652535f5a45524f60c81b604482015290519081900360640190fd5b600080546001600160701b0319166001600160701b0385811691909117600160701b600160e01b031916600160701b8583168102919091176001600160e01b0316600160e01b63ffffffff861602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a150505056fea26469706673582212200ac7429eaeb05513b956255ebb7ae31ef023b2e50a47923f0013925fa96b5fab64736f6c63430007050033

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.