false
false
100

Contract Address Details

0xE72e10756f30b190e235E08A96612D05a646a73d

Contract Name
VaultPriceFeed
Creator
0x585914–e9aeb9 at 0x8fb447–13bf0e
Balance
0 KAVA ( )
Tokens
Fetching tokens...
Transactions
10 Transactions
Transfers
0 Transfers
Gas Used
569,357
Last Balance Update
9525158
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
VaultPriceFeed




Optimization enabled
true
Compiler version
v0.8.18+commit.87f61d96




Optimization runs
200
EVM Version
default




Verified at
2023-10-22T09:56:51.671781Z

contracts/core/VaultPriceFeed.sol

// SPDX-License-Identifier: BUSL-1.1

import "./interfaces/v0.8/IVaultPriceFeed.sol";
import "../oracle/interfaces/v0.8/ISecondaryPriceFeed.sol";
import "@api3/contracts/v0.8/interfaces/IProxy.sol";

pragma solidity ^0.8.0;

contract VaultPriceFeed is IVaultPriceFeed {

    uint256 public constant PRICE_PRECISION = 10**30;
    uint256 public constant ONE_USD = PRICE_PRECISION;
    uint256 public constant BASIS_POINTS_DIVISOR = 10000;
    uint256 public constant MAX_SPREAD_BASIS_POINTS = 50;
    uint256 public constant MAX_ADJUSTMENT_INTERVAL = 2 hours;
    uint256 public constant MAX_ADJUSTMENT_BASIS_POINTS = 20;

    address public gov;

    bool public isSecondaryPriceEnabled = true;
    bool public favorPrimaryPrice;
    uint256 public maxStrictPriceDeviation;
    address public secondaryPriceFeed;
    uint256 public spreadThresholdBasisPoints = 30;
    uint256 public expireTimeForPriceFeed = 1 days;


    mapping(address => address) public priceFeedProxies;
    mapping(address => uint256) public priceDecimals;
    mapping(address => uint256) public spreadBasisPoints;
    mapping(address => bool) public strictStableTokens;

    mapping(address => uint256) public override adjustmentBasisPoints;
    mapping(address => bool) public override isAdjustmentAdditive;
    mapping(address => uint256) public lastAdjustmentTimings;

    modifier onlyGov() {
        require(msg.sender == gov, "VaultPriceFeed: forbidden");
        _;
    }

    constructor()  {
        gov = msg.sender;
    }

    function setGov(address _gov) external onlyGov {
        require(_gov != address(0), "VaultPriceFeed: address(0)");
        gov = _gov;
    }

    function setAdjustment(
        address _token,
        bool _isAdditive,
        uint256 _adjustmentBps
    ) external override onlyGov {
        require(lastAdjustmentTimings[_token] + MAX_ADJUSTMENT_INTERVAL < block.timestamp, "VaultPriceFeed: adjustment frequency exceeded");
        require(_adjustmentBps <= MAX_ADJUSTMENT_BASIS_POINTS, "invalid _adjustmentBps");
        isAdjustmentAdditive[_token] = _isAdditive;
        adjustmentBasisPoints[_token] = _adjustmentBps;
        lastAdjustmentTimings[_token] = block.timestamp;
    }

    function setIsSecondaryPriceEnabled(bool _isEnabled) external override onlyGov {
        isSecondaryPriceEnabled = _isEnabled;
    }

    function setExpireTimeForPriceFeed(uint256 _expireTimeForPriceFeed) external override onlyGov {
        require(_expireTimeForPriceFeed >= 1 minutes,"invalid _expireTimeForPriceFeed");
        expireTimeForPriceFeed = _expireTimeForPriceFeed;
    }

    function setSecondaryPriceFeed(address _secondaryPriceFeed) external onlyGov {
        secondaryPriceFeed = _secondaryPriceFeed;
    }

    function setSpreadBasisPoints(address _token, uint256 _spreadBasisPoints) external override onlyGov {
        require(_spreadBasisPoints <= MAX_SPREAD_BASIS_POINTS, "VaultPriceFeed: invalid _spreadBasisPoints");
        spreadBasisPoints[_token] = _spreadBasisPoints;
    }

    function setSpreadThresholdBasisPoints(uint256 _spreadThresholdBasisPoints) external override onlyGov {
        spreadThresholdBasisPoints = _spreadThresholdBasisPoints;
    }

    function setFavorPrimaryPrice(bool _favorPrimaryPrice) external override onlyGov {
        favorPrimaryPrice = _favorPrimaryPrice;
    }

    function setMaxStrictPriceDeviation(uint256 _maxStrictPriceDeviation) external override onlyGov {
        maxStrictPriceDeviation = _maxStrictPriceDeviation;
    }

    function setTokenConfig(
        address _token,
        address _priceFeedProxy,
        uint256 _priceDecimals,
        bool _isStrictStable
    ) external override onlyGov {
        priceFeedProxies[_token] = _priceFeedProxy;
        priceDecimals[_token] = _priceDecimals;
        strictStableTokens[_token] = _isStrictStable;
    }

    function getPrice(
        address _token,
        bool _maximise,
        bool /*_includeAmmPrice */,
        bool /* _useSwapPricing */
    ) public view override returns (uint256) {
        uint256 price = getPriceV1(_token, _maximise);

        uint256 adjustmentBps = adjustmentBasisPoints[_token];
        if (adjustmentBps > 0) {
            bool isAdditive = isAdjustmentAdditive[_token];
            if (isAdditive) {
                price = (price * (BASIS_POINTS_DIVISOR + adjustmentBps)) / BASIS_POINTS_DIVISOR;
            } else {
                price = (price * (BASIS_POINTS_DIVISOR - adjustmentBps)) / BASIS_POINTS_DIVISOR;
            }
        }

        return price;
    }

    function getPriceV1(
        address _token,
        bool _maximise
    ) public view returns (uint256) {
        uint256 price = getPrimaryPrice(_token, _maximise);


        if (isSecondaryPriceEnabled) {
            price = getSecondaryPrice(_token, price, _maximise);
        }

        if (strictStableTokens[_token]) {
            uint256 delta = price > ONE_USD ? price - ONE_USD : ONE_USD - price;
            if (delta <= maxStrictPriceDeviation) {
                return ONE_USD;
            }

            // if _maximise and price is e.g. 1.02, return 1.02
            if (_maximise && price > ONE_USD) {
                return price;
            }

            // if !_maximise and price is e.g. 0.98, return 0.98
            if (!_maximise && price < ONE_USD) {
                return price;
            }

            return ONE_USD;
        }

        uint256 _spreadBasisPoints = spreadBasisPoints[_token];

        if (_maximise) {
            return (price * (BASIS_POINTS_DIVISOR + _spreadBasisPoints)) / BASIS_POINTS_DIVISOR;
        }

        return (price * (BASIS_POINTS_DIVISOR - _spreadBasisPoints)) / BASIS_POINTS_DIVISOR;
    }

    function getLatestPrimaryPrice(address _token) public override view returns (uint256) {
        return _getApi3Price(_token);
    }   

    function getPrimaryPrice(address _token, bool /*_maximise*/) public view override returns (uint256) {
        uint256 price = _getApi3Price(_token);

        uint256 _priceDecimals = priceDecimals[_token];
        return (price * PRICE_PRECISION) / 10 ** _priceDecimals;
    }

    function getSecondaryPrice(
        address _token,
        uint256 _referencePrice,
        bool _maximise
    ) public view returns (uint256) {
        if (secondaryPriceFeed == address(0)) {
            return _referencePrice;
        }
        return ISecondaryPriceFeed(secondaryPriceFeed).getPrice(_token, _referencePrice, _maximise);
    }

    function _getApi3Price(address _token) private view  returns (uint256) {
        address proxy = priceFeedProxies[_token];
        require(proxy != address(0), "VaultPriceFeed: invalid price feed proxy");
        (int224 price, uint256 timestamp) = IProxy(proxy).read();
        require(price > 0, "VaultPriceFeed: price not positive");
        require(
            timestamp + expireTimeForPriceFeed > block.timestamp,
            "VaultPriceFeed: expired"
        );
        return uint256(uint224(price));
    }
}
        

@api3/airnode-protocol-v1/contracts/api3-server-v1/proxies/interfaces/IProxy.sol

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

/// @dev See DapiProxy.sol for comments about usage
interface IProxy {
    function read() external view returns (int224 value, uint32 timestamp);

    function api3ServerV1() external view returns (address);
}
          

@api3/contracts/v0.8/interfaces/IProxy.sol

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

import "@api3/airnode-protocol-v1/contracts/api3-server-v1/proxies/interfaces/IProxy.sol";
          

contracts/core/interfaces/v0.8/IVaultPriceFeed.sol

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.0;

interface IVaultPriceFeed {
    function adjustmentBasisPoints(address _token)
        external
        view
        returns (uint256);

    function isAdjustmentAdditive(address _token) external view returns (bool);

    function setAdjustment(
        address _token,
        bool _isAdditive,
        uint256 _adjustmentBps
    ) external;

    function setIsSecondaryPriceEnabled(bool _isEnabled) external;

    function setExpireTimeForPriceFeed(uint256 _expireTimeForPriceFeed) external;

    function setSpreadBasisPoints(address _token, uint256 _spreadBasisPoints)
        external;

    function setSpreadThresholdBasisPoints(uint256 _spreadThresholdBasisPoints)
        external;

    function setFavorPrimaryPrice(bool _favorPrimaryPrice) external;

    function setMaxStrictPriceDeviation(uint256 _maxStrictPriceDeviation)
        external;

    function getPrice(
        address _token,
        bool _maximise,
        bool _includeAmmPrice,
        bool _useSwapPricing
    ) external view returns (uint256);

    function getPrimaryPrice(address _token, bool _maximise)
        external
        view
        returns (uint256);

    function setTokenConfig(
        address _token,
        address _priceFeedProxy,
        uint256 _priceDecimals,
        bool _isStrictStable
    ) external;

    function getLatestPrimaryPrice(address _token) external view returns (uint256);


}
          

contracts/oracle/interfaces/v0.8/ISecondaryPriceFeed.sol

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.0;

interface ISecondaryPriceFeed {
    function getPrice(address _token, uint256 _referencePrice, bool _maximise) external view returns (uint256);
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BASIS_POINTS_DIVISOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_ADJUSTMENT_BASIS_POINTS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_ADJUSTMENT_INTERVAL","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_SPREAD_BASIS_POINTS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ONE_USD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"PRICE_PRECISION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"adjustmentBasisPoints","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"expireTimeForPriceFeed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"favorPrimaryPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLatestPrimaryPrice","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPrice","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"bool","name":"_maximise","internalType":"bool"},{"type":"bool","name":"","internalType":"bool"},{"type":"bool","name":"","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPriceV1","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"bool","name":"_maximise","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPrimaryPrice","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"bool","name":"","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getSecondaryPrice","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_referencePrice","internalType":"uint256"},{"type":"bool","name":"_maximise","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gov","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isAdjustmentAdditive","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isSecondaryPriceEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastAdjustmentTimings","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxStrictPriceDeviation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"priceDecimals","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"priceFeedProxies","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"secondaryPriceFeed","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAdjustment","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"bool","name":"_isAdditive","internalType":"bool"},{"type":"uint256","name":"_adjustmentBps","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setExpireTimeForPriceFeed","inputs":[{"type":"uint256","name":"_expireTimeForPriceFeed","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFavorPrimaryPrice","inputs":[{"type":"bool","name":"_favorPrimaryPrice","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGov","inputs":[{"type":"address","name":"_gov","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIsSecondaryPriceEnabled","inputs":[{"type":"bool","name":"_isEnabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxStrictPriceDeviation","inputs":[{"type":"uint256","name":"_maxStrictPriceDeviation","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSecondaryPriceFeed","inputs":[{"type":"address","name":"_secondaryPriceFeed","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSpreadBasisPoints","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_spreadBasisPoints","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSpreadThresholdBasisPoints","inputs":[{"type":"uint256","name":"_spreadThresholdBasisPoints","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTokenConfig","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_priceFeedProxy","internalType":"address"},{"type":"uint256","name":"_priceDecimals","internalType":"uint256"},{"type":"bool","name":"_isStrictStable","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"spreadBasisPoints","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"spreadThresholdBasisPoints","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"strictStableTokens","inputs":[{"type":"address","name":"","internalType":"address"}]}]
              

Contract Creation Code

0x60806040526000805460ff60a01b1916600160a01b179055601e6003556201518060045534801561002f57600080fd5b50600080546001600160a01b031916331790556112cc806100516000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c8063717cfe7a11610125578063a39c73a3116100ad578063cefe0f211161007c578063cefe0f2114610491578063cfad57a2146104b1578063d694376c146104c4578063eb1c92a9146104d7578063ff59f163146104ea57600080fd5b8063a39c73a314610429578063afafed8814610432578063b731dd871461045b578063b8f611051461046e57600080fd5b806395082d25116100f457806395082d25146103555780639a0a6635146103da5780639b18dc47146103ed5780639b889380146103f6578063a27ea3861461040957600080fd5b8063717cfe7a1461038b5780637cdddae6146103ab5780638b86616c146103be57806390a5d2cb146103d157600080fd5b806348cac277116101a857806356c8c2c11161017757806356c8c2c11461031b578063593d9e801461032e578063604f37e91461034257806367781c0e146103555780636ce8a44b1461036857600080fd5b806348cac277146102cd5780634a4b1f4f146102ed5780634b9ade47146102f557806356bf9de41461030857600080fd5b80632fc3a70a116101e45780632fc3a70a1461027a578063378e7bf71461028d5780633eba8d36146102965780633ebbc601146102a957600080fd5b80630957aed914610216578063126082cf1461023157806312d43a511461023a5780632fbfe3d314610265575b600080fd5b61021e603281565b6040519081526020015b60405180910390f35b61021e61271081565b60005461024d906001600160a01b031681565b6040516001600160a01b039091168152602001610228565b610278610273366004610eb2565b6104fd565b005b61021e610288366004610ef7565b610535565b61021e60015481565b61021e6102a4366004610f4b565b6105de565b6000546102bd90600160a01b900460ff1681565b6040519015158152602001610228565b61021e6102db366004610f87565b60096020526000908152604090205481565b61021e601481565b610278610303366004610fa2565b61067f565b61021e610316366004610f87565b6106fe565b61021e610329366004610fe4565b61070f565b6000546102bd90600160a81b900460ff1681565b610278610350366004611017565b61076b565b61021e68327cb2734119d3b7a9601e1b81565b6102bd610376366004610f87565b600a6020526000908152604090205460ff1681565b61021e610399366004610f87565b600b6020526000908152604090205481565b61021e6103b9366004610fe4565b6107b3565b60025461024d906001600160a01b031681565b61021e60045481565b6102786103e8366004610f87565b61092c565b61021e611c2081565b610278610404366004611032565b610978565b61021e610417366004610f87565b60076020526000908152604090205481565b61021e60035481565b61024d610440366004610f87565b6005602052600090815260409020546001600160a01b031681565b610278610469366004610eb2565b610a22565b6102bd61047c366004610f87565b60086020526000908152604090205460ff1681565b61021e61049f366004610f87565b60066020526000908152604090205481565b6102786104bf366004610f87565b610a51565b6102786104d236600461105c565b610af3565b6102786104e5366004611017565b610c36565b6102786104f8366004610eb2565b610c7e565b6000546001600160a01b031633146105305760405162461bcd60e51b815260040161052790611098565b60405180910390fd5b600155565b60008061054286866107b3565b6001600160a01b03871660009081526009602052604090205490915080156105d4576001600160a01b0387166000908152600a602052604090205460ff1680156105ae5761271061059383826110e5565b61059d90856110f8565b6105a7919061110f565b92506105d2565b6127106105bb8382611131565b6105c590856110f8565b6105cf919061110f565b92505b505b5095945050505050565b6002546000906001600160a01b03166105f8575081610678565b600254604051630ffd9c6d60e31b81526001600160a01b03868116600483015260248201869052841515604483015290911690637fece36890606401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106759190611144565b90505b9392505050565b6000546001600160a01b031633146106a95760405162461bcd60e51b815260040161052790611098565b6001600160a01b03938416600090815260056020908152604080832080546001600160a01b03191696909716959095179095556006855283812092909255600890935220805460ff1916911515919091179055565b600061070982610cfe565b92915050565b60008061071b84610cfe565b6001600160a01b03851660009081526006602052604090205490915061074281600a611241565b61075868327cb2734119d3b7a9601e1b846110f8565b610762919061110f565b95945050505050565b6000546001600160a01b031633146107955760405162461bcd60e51b815260040161052790611098565b60008054911515600160a81b0260ff60a81b19909216919091179055565b6000806107c0848461070f565b600054909150600160a01b900460ff16156107e3576107e08482856105de565b90505b6001600160a01b03841660009081526008602052604090205460ff16156108cc57600068327cb2734119d3b7a9601e1b82116108345761082f8268327cb2734119d3b7a9601e1b611131565b61084a565b61084a68327cb2734119d3b7a9601e1b83611131565b9050600154811161086b5768327cb2734119d3b7a9601e1b92505050610709565b838015610883575068327cb2734119d3b7a9601e1b82115b1561089057509050610709565b831580156108a9575068327cb2734119d3b7a9601e1b82105b156108b657509050610709565b68327cb2734119d3b7a9601e1b92505050610709565b6001600160a01b0384166000908152600760205260409020548315610915576127106108f882826110e5565b61090290846110f8565b61090c919061110f565b92505050610709565b6127106109228282611131565b61075890846110f8565b6000546001600160a01b031633146109565760405162461bcd60e51b815260040161052790611098565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146109a25760405162461bcd60e51b815260040161052790611098565b6032811115610a065760405162461bcd60e51b815260206004820152602a60248201527f5661756c745072696365466565643a20696e76616c6964205f7370726561644260448201526961736973506f696e747360b01b6064820152608401610527565b6001600160a01b03909116600090815260076020526040902055565b6000546001600160a01b03163314610a4c5760405162461bcd60e51b815260040161052790611098565b600355565b6000546001600160a01b03163314610a7b5760405162461bcd60e51b815260040161052790611098565b6001600160a01b038116610ad15760405162461bcd60e51b815260206004820152601a60248201527f5661756c745072696365466565643a20616464726573732830290000000000006044820152606401610527565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610b1d5760405162461bcd60e51b815260040161052790611098565b6001600160a01b0383166000908152600b60205260409020544290610b4590611c20906110e5565b10610ba85760405162461bcd60e51b815260206004820152602d60248201527f5661756c745072696365466565643a2061646a7573746d656e7420667265717560448201526c195b98de48195e18d959591959609a1b6064820152608401610527565b6014811115610bf25760405162461bcd60e51b8152602060048201526016602482015275696e76616c6964205f61646a7573746d656e7442707360501b6044820152606401610527565b6001600160a01b03929092166000908152600a60209081526040808320805460ff1916941515949094179093556009815282822093909355600b9092529020429055565b6000546001600160a01b03163314610c605760405162461bcd60e51b815260040161052790611098565b60008054911515600160a01b0260ff60a01b19909216919091179055565b6000546001600160a01b03163314610ca85760405162461bcd60e51b815260040161052790611098565b603c811015610cf95760405162461bcd60e51b815260206004820152601f60248201527f696e76616c6964205f65787069726554696d65466f72507269636546656564006044820152606401610527565b600455565b6001600160a01b0380821660009081526005602052604081205490911680610d795760405162461bcd60e51b815260206004820152602860248201527f5661756c745072696365466565643a20696e76616c696420707269636520666560448201526765642070726f787960c01b6064820152608401610527565b600080826001600160a01b03166357de26a46040518163ffffffff1660e01b81526004016040805180830381865afa158015610db9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ddd919061124d565b63ffffffff1691509150600082601b0b13610e455760405162461bcd60e51b815260206004820152602260248201527f5661756c745072696365466565643a207072696365206e6f7420706f73697469604482015261766560f01b6064820152608401610527565b4260045482610e5491906110e5565b11610ea15760405162461bcd60e51b815260206004820152601760248201527f5661756c745072696365466565643a20657870697265640000000000000000006044820152606401610527565b506001600160e01b03169392505050565b600060208284031215610ec457600080fd5b5035919050565b80356001600160a01b0381168114610ee257600080fd5b919050565b80358015158114610ee257600080fd5b60008060008060808587031215610f0d57600080fd5b610f1685610ecb565b9350610f2460208601610ee7565b9250610f3260408601610ee7565b9150610f4060608601610ee7565b905092959194509250565b600080600060608486031215610f6057600080fd5b610f6984610ecb565b925060208401359150610f7e60408501610ee7565b90509250925092565b600060208284031215610f9957600080fd5b61067882610ecb565b60008060008060808587031215610fb857600080fd5b610fc185610ecb565b9350610fcf60208601610ecb565b925060408501359150610f4060608601610ee7565b60008060408385031215610ff757600080fd5b61100083610ecb565b915061100e60208401610ee7565b90509250929050565b60006020828403121561102957600080fd5b61067882610ee7565b6000806040838503121561104557600080fd5b61104e83610ecb565b946020939093013593505050565b60008060006060848603121561107157600080fd5b61107a84610ecb565b925061108860208501610ee7565b9150604084013590509250925092565b60208082526019908201527f5661756c745072696365466565643a20666f7262696464656e00000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610709576107096110cf565b8082028115828204841417610709576107096110cf565b60008261112c57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610709576107096110cf565b60006020828403121561115657600080fd5b5051919050565b600181815b8085111561119857816000190482111561117e5761117e6110cf565b8085161561118b57918102915b93841c9390800290611162565b509250929050565b6000826111af57506001610709565b816111bc57506000610709565b81600181146111d257600281146111dc576111f8565b6001915050610709565b60ff8411156111ed576111ed6110cf565b50506001821b610709565b5060208310610133831016604e8410600b841016171561121b575081810a610709565b611225838361115d565b8060001904821115611239576112396110cf565b029392505050565b600061067883836111a0565b6000806040838503121561126057600080fd5b825180601b0b811461127157600080fd5b602084015190925063ffffffff8116811461128b57600080fd5b80915050925092905056fea2646970667358221220d85a8940421f56a7581b40b0923f596c1db11592c745421698180a50ed86d8eb64736f6c63430008120033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063717cfe7a11610125578063a39c73a3116100ad578063cefe0f211161007c578063cefe0f2114610491578063cfad57a2146104b1578063d694376c146104c4578063eb1c92a9146104d7578063ff59f163146104ea57600080fd5b8063a39c73a314610429578063afafed8814610432578063b731dd871461045b578063b8f611051461046e57600080fd5b806395082d25116100f457806395082d25146103555780639a0a6635146103da5780639b18dc47146103ed5780639b889380146103f6578063a27ea3861461040957600080fd5b8063717cfe7a1461038b5780637cdddae6146103ab5780638b86616c146103be57806390a5d2cb146103d157600080fd5b806348cac277116101a857806356c8c2c11161017757806356c8c2c11461031b578063593d9e801461032e578063604f37e91461034257806367781c0e146103555780636ce8a44b1461036857600080fd5b806348cac277146102cd5780634a4b1f4f146102ed5780634b9ade47146102f557806356bf9de41461030857600080fd5b80632fc3a70a116101e45780632fc3a70a1461027a578063378e7bf71461028d5780633eba8d36146102965780633ebbc601146102a957600080fd5b80630957aed914610216578063126082cf1461023157806312d43a511461023a5780632fbfe3d314610265575b600080fd5b61021e603281565b6040519081526020015b60405180910390f35b61021e61271081565b60005461024d906001600160a01b031681565b6040516001600160a01b039091168152602001610228565b610278610273366004610eb2565b6104fd565b005b61021e610288366004610ef7565b610535565b61021e60015481565b61021e6102a4366004610f4b565b6105de565b6000546102bd90600160a01b900460ff1681565b6040519015158152602001610228565b61021e6102db366004610f87565b60096020526000908152604090205481565b61021e601481565b610278610303366004610fa2565b61067f565b61021e610316366004610f87565b6106fe565b61021e610329366004610fe4565b61070f565b6000546102bd90600160a81b900460ff1681565b610278610350366004611017565b61076b565b61021e68327cb2734119d3b7a9601e1b81565b6102bd610376366004610f87565b600a6020526000908152604090205460ff1681565b61021e610399366004610f87565b600b6020526000908152604090205481565b61021e6103b9366004610fe4565b6107b3565b60025461024d906001600160a01b031681565b61021e60045481565b6102786103e8366004610f87565b61092c565b61021e611c2081565b610278610404366004611032565b610978565b61021e610417366004610f87565b60076020526000908152604090205481565b61021e60035481565b61024d610440366004610f87565b6005602052600090815260409020546001600160a01b031681565b610278610469366004610eb2565b610a22565b6102bd61047c366004610f87565b60086020526000908152604090205460ff1681565b61021e61049f366004610f87565b60066020526000908152604090205481565b6102786104bf366004610f87565b610a51565b6102786104d236600461105c565b610af3565b6102786104e5366004611017565b610c36565b6102786104f8366004610eb2565b610c7e565b6000546001600160a01b031633146105305760405162461bcd60e51b815260040161052790611098565b60405180910390fd5b600155565b60008061054286866107b3565b6001600160a01b03871660009081526009602052604090205490915080156105d4576001600160a01b0387166000908152600a602052604090205460ff1680156105ae5761271061059383826110e5565b61059d90856110f8565b6105a7919061110f565b92506105d2565b6127106105bb8382611131565b6105c590856110f8565b6105cf919061110f565b92505b505b5095945050505050565b6002546000906001600160a01b03166105f8575081610678565b600254604051630ffd9c6d60e31b81526001600160a01b03868116600483015260248201869052841515604483015290911690637fece36890606401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106759190611144565b90505b9392505050565b6000546001600160a01b031633146106a95760405162461bcd60e51b815260040161052790611098565b6001600160a01b03938416600090815260056020908152604080832080546001600160a01b03191696909716959095179095556006855283812092909255600890935220805460ff1916911515919091179055565b600061070982610cfe565b92915050565b60008061071b84610cfe565b6001600160a01b03851660009081526006602052604090205490915061074281600a611241565b61075868327cb2734119d3b7a9601e1b846110f8565b610762919061110f565b95945050505050565b6000546001600160a01b031633146107955760405162461bcd60e51b815260040161052790611098565b60008054911515600160a81b0260ff60a81b19909216919091179055565b6000806107c0848461070f565b600054909150600160a01b900460ff16156107e3576107e08482856105de565b90505b6001600160a01b03841660009081526008602052604090205460ff16156108cc57600068327cb2734119d3b7a9601e1b82116108345761082f8268327cb2734119d3b7a9601e1b611131565b61084a565b61084a68327cb2734119d3b7a9601e1b83611131565b9050600154811161086b5768327cb2734119d3b7a9601e1b92505050610709565b838015610883575068327cb2734119d3b7a9601e1b82115b1561089057509050610709565b831580156108a9575068327cb2734119d3b7a9601e1b82105b156108b657509050610709565b68327cb2734119d3b7a9601e1b92505050610709565b6001600160a01b0384166000908152600760205260409020548315610915576127106108f882826110e5565b61090290846110f8565b61090c919061110f565b92505050610709565b6127106109228282611131565b61075890846110f8565b6000546001600160a01b031633146109565760405162461bcd60e51b815260040161052790611098565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146109a25760405162461bcd60e51b815260040161052790611098565b6032811115610a065760405162461bcd60e51b815260206004820152602a60248201527f5661756c745072696365466565643a20696e76616c6964205f7370726561644260448201526961736973506f696e747360b01b6064820152608401610527565b6001600160a01b03909116600090815260076020526040902055565b6000546001600160a01b03163314610a4c5760405162461bcd60e51b815260040161052790611098565b600355565b6000546001600160a01b03163314610a7b5760405162461bcd60e51b815260040161052790611098565b6001600160a01b038116610ad15760405162461bcd60e51b815260206004820152601a60248201527f5661756c745072696365466565643a20616464726573732830290000000000006044820152606401610527565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610b1d5760405162461bcd60e51b815260040161052790611098565b6001600160a01b0383166000908152600b60205260409020544290610b4590611c20906110e5565b10610ba85760405162461bcd60e51b815260206004820152602d60248201527f5661756c745072696365466565643a2061646a7573746d656e7420667265717560448201526c195b98de48195e18d959591959609a1b6064820152608401610527565b6014811115610bf25760405162461bcd60e51b8152602060048201526016602482015275696e76616c6964205f61646a7573746d656e7442707360501b6044820152606401610527565b6001600160a01b03929092166000908152600a60209081526040808320805460ff1916941515949094179093556009815282822093909355600b9092529020429055565b6000546001600160a01b03163314610c605760405162461bcd60e51b815260040161052790611098565b60008054911515600160a01b0260ff60a01b19909216919091179055565b6000546001600160a01b03163314610ca85760405162461bcd60e51b815260040161052790611098565b603c811015610cf95760405162461bcd60e51b815260206004820152601f60248201527f696e76616c6964205f65787069726554696d65466f72507269636546656564006044820152606401610527565b600455565b6001600160a01b0380821660009081526005602052604081205490911680610d795760405162461bcd60e51b815260206004820152602860248201527f5661756c745072696365466565643a20696e76616c696420707269636520666560448201526765642070726f787960c01b6064820152608401610527565b600080826001600160a01b03166357de26a46040518163ffffffff1660e01b81526004016040805180830381865afa158015610db9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ddd919061124d565b63ffffffff1691509150600082601b0b13610e455760405162461bcd60e51b815260206004820152602260248201527f5661756c745072696365466565643a207072696365206e6f7420706f73697469604482015261766560f01b6064820152608401610527565b4260045482610e5491906110e5565b11610ea15760405162461bcd60e51b815260206004820152601760248201527f5661756c745072696365466565643a20657870697265640000000000000000006044820152606401610527565b506001600160e01b03169392505050565b600060208284031215610ec457600080fd5b5035919050565b80356001600160a01b0381168114610ee257600080fd5b919050565b80358015158114610ee257600080fd5b60008060008060808587031215610f0d57600080fd5b610f1685610ecb565b9350610f2460208601610ee7565b9250610f3260408601610ee7565b9150610f4060608601610ee7565b905092959194509250565b600080600060608486031215610f6057600080fd5b610f6984610ecb565b925060208401359150610f7e60408501610ee7565b90509250925092565b600060208284031215610f9957600080fd5b61067882610ecb565b60008060008060808587031215610fb857600080fd5b610fc185610ecb565b9350610fcf60208601610ecb565b925060408501359150610f4060608601610ee7565b60008060408385031215610ff757600080fd5b61100083610ecb565b915061100e60208401610ee7565b90509250929050565b60006020828403121561102957600080fd5b61067882610ee7565b6000806040838503121561104557600080fd5b61104e83610ecb565b946020939093013593505050565b60008060006060848603121561107157600080fd5b61107a84610ecb565b925061108860208501610ee7565b9150604084013590509250925092565b60208082526019908201527f5661756c745072696365466565643a20666f7262696464656e00000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610709576107096110cf565b8082028115828204841417610709576107096110cf565b60008261112c57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610709576107096110cf565b60006020828403121561115657600080fd5b5051919050565b600181815b8085111561119857816000190482111561117e5761117e6110cf565b8085161561118b57918102915b93841c9390800290611162565b509250929050565b6000826111af57506001610709565b816111bc57506000610709565b81600181146111d257600281146111dc576111f8565b6001915050610709565b60ff8411156111ed576111ed6110cf565b50506001821b610709565b5060208310610133831016604e8410600b841016171561121b575081810a610709565b611225838361115d565b8060001904821115611239576112396110cf565b029392505050565b600061067883836111a0565b6000806040838503121561126057600080fd5b825180601b0b811461127157600080fd5b602084015190925063ffffffff8116811461128b57600080fd5b80915050925092905056fea2646970667358221220d85a8940421f56a7581b40b0923f596c1db11592c745421698180a50ed86d8eb64736f6c63430008120033