Contract

0xDA5079fd098a41100E30Ac6cF9c484296a541b85

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

-

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Prices With ...14702292024-12-24 14:31:161 min ago1735050676IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14700382024-12-24 14:28:563 mins ago1735050536IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14694952024-12-24 14:22:369 mins ago1735050156IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14692782024-12-24 14:20:1612 mins ago1735050016IN
0xDA5079fd...96a541b85
0 S0.000298791.221
Set Prices With ...14690682024-12-24 14:17:5614 mins ago1735049876IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14688602024-12-24 14:15:1617 mins ago1735049716IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14686372024-12-24 14:12:3619 mins ago1735049556IN
0xDA5079fd...96a541b85
0 S0.000296111.221
Set Prices With ...14681032024-12-24 14:06:1626 mins ago1735049176IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14678152024-12-24 14:02:3629 mins ago1735048956IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14676752024-12-24 14:00:3631 mins ago1735048836IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14674912024-12-24 13:57:3634 mins ago1735048656IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14673592024-12-24 13:55:1637 mins ago1735048516IN
0xDA5079fd...96a541b85
0 S0.000296111.221
Set Prices With ...14672212024-12-24 13:52:5639 mins ago1735048376IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14670732024-12-24 13:50:1642 mins ago1735048216IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14669282024-12-24 13:47:5644 mins ago1735048076IN
0xDA5079fd...96a541b85
0 S0.000298621.221
Set Prices With ...14665372024-12-24 13:41:3650 mins ago1735047696IN
0xDA5079fd...96a541b85
0 S0.000298791.221
Set Prices With ...14664002024-12-24 13:39:1653 mins ago1735047556IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14660202024-12-24 13:33:161 hrs ago1735047196IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14658792024-12-24 13:30:561 hr ago1735047056IN
0xDA5079fd...96a541b85
0 S0.000296091.221
Set Prices With ...14654942024-12-24 13:24:361 hr ago1735046676IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14652452024-12-24 13:20:561 hr ago1735046456IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14649772024-12-24 13:17:161 hr ago1735046236IN
0xDA5079fd...96a541b85
0 S0.00029881.221
Set Prices With ...14644842024-12-24 13:10:561 hr ago1735045856IN
0xDA5079fd...96a541b85
0 S0.000298631.221
Set Prices With ...14641692024-12-24 13:06:361 hr ago1735045596IN
0xDA5079fd...96a541b85
0 S0.000298791.221
Set Prices With ...14637642024-12-24 13:00:161 hr ago1735045216IN
0xDA5079fd...96a541b85
0 S0.000298631.221
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FastPriceFeed

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 250 runs

Other Settings:
london EvmVersion, MIT license
File 1 of 11 : FastPriceFeed.sol
// SPDX-License-Identifier: MIT

import "../libraries/math/SafeMath.sol";

import "./interfaces/ISecondaryPriceFeed.sol";
import "./interfaces/IFastPriceFeed.sol";
import "./interfaces/IFastPriceEvents.sol";
import "../core/interfaces/IVaultPriceFeed.sol";
import "../core/interfaces/IPositionRouter.sol";
import "../access/Governable.sol";
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
pragma solidity 0.8.16;

contract FastPriceFeed is ISecondaryPriceFeed, IFastPriceFeed, Governable {
    using SafeMath for uint256;

    // fit data in a uint256 slot to save gas costs
    struct PriceDataItem {
        uint160 refPrice; // Chainlink price
        uint32 refTime; // last updated at time
        uint32 cumulativeRefDelta; // cumulative Chainlink price delta
        uint32 cumulativeFastDelta; // cumulative fast price delta
    }

    uint256 public constant PRICE_PRECISION = 10 ** 30;

    uint256 public constant CUMULATIVE_DELTA_PRECISION = 10 * 1000 * 1000;

    uint256 public constant MAX_REF_PRICE = type(uint160).max;
    uint256 public constant MAX_CUMULATIVE_REF_DELTA = type(uint32).max;
    uint256 public constant MAX_CUMULATIVE_FAST_DELTA = type(uint32).max;

    // uint256(~0) is 256 bits of 1s
    // shift the 1s by (256 - 32) to get (256 - 32) 0s followed by 32 1s
    uint256 constant public BITMASK_32 = type(uint256).max >> (256 - 32);

    uint256 public constant BASIS_POINTS_DIVISOR = 10000;

    uint256 public constant MAX_PRICE_DURATION = 30 minutes;

    bool public isInitialized;
    bool public isSpreadEnabled = false;

    address public vaultPriceFeed;
    address public fastPriceEvents;

    address public tokenManager;

    address public positionRouter;

    uint256 public override lastUpdatedAt;
    uint256 public override lastUpdatedBlock;

    uint256 public priceDuration;
    uint256 public maxPriceUpdateDelay;
    uint256 public spreadBasisPointsIfInactive;
    uint256 public spreadBasisPointsIfChainError;
    uint256 public minBlockInterval;
    uint256 public maxTimeDeviation;

    uint256 public priceDataInterval;

    // allowed deviation from primary price
    uint256 public maxDeviationBasisPoints;

    uint256 public minAuthorizations;
    uint256 public disableFastPriceVoteCount = 0;

    mapping(address => bool) public isUpdater;

    mapping(address => uint256) public prices;
    mapping(address => PriceDataItem) public priceData;
    mapping(address => uint256) public maxCumulativeDeltaDiffs;

    mapping(address => bool) public isSigner;
    mapping(address => bool) public disableFastPriceVotes;

    // array of tokens used in setCompactedPrices, saves L1 calldata gas costs
    address[] public tokens;
    // array of tokenPrecisions used in setCompactedPrices, saves L1 calldata gas costs
    // if the token price will be sent with 3 decimals, then tokenPrecision for that token
    // should be 10 ** 3
    uint256[] public tokenPrecisions;

    event DisableFastPrice(address signer);
    event EnableFastPrice(address signer);
    event PriceData(address token, uint256 refPrice, uint256 fastPrice, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta);
    event MaxCumulativeDeltaDiffExceeded(address token, uint256 refPrice, uint256 fastPrice, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta);

    modifier onlySigner() {
        require(isSigner[msg.sender], "FastPriceFeed: forbidden");
        _;
    }

    modifier onlyUpdater() {
        require(isUpdater[msg.sender], "FastPriceFeed: forbidden");
        _;
    }

    modifier onlyTokenManager() {
        require(msg.sender == tokenManager, "FastPriceFeed: forbidden");
        _;
    }

    constructor(
        uint256 _priceDuration,
        uint256 _maxPriceUpdateDelay,
        uint256 _minBlockInterval,
        uint256 _maxDeviationBasisPoints,
        address _fastPriceEvents,
        address _tokenManager,
        address _positionRouter
    ) public {
        require(_priceDuration <= MAX_PRICE_DURATION, "FastPriceFeed: invalid _priceDuration");
        priceDuration = _priceDuration;
        maxPriceUpdateDelay = _maxPriceUpdateDelay;
        minBlockInterval = _minBlockInterval;
        maxDeviationBasisPoints = _maxDeviationBasisPoints;
        fastPriceEvents = _fastPriceEvents;
        tokenManager = _tokenManager;
        positionRouter = _positionRouter;
    }

    function initialize(uint256 _minAuthorizations, address[] memory _signers, address[] memory _updaters) public onlyGov {
        require(!isInitialized, "FastPriceFeed: already initialized");
        isInitialized = true;

        minAuthorizations = _minAuthorizations;

        for (uint256 i = 0; i < _signers.length; i++) {
            address signer = _signers[i];
            isSigner[signer] = true;
        }

        for (uint256 i = 0; i < _updaters.length; i++) {
            address updater = _updaters[i];
            isUpdater[updater] = true;
        }
    }

    function setSigner(address _account, bool _isActive) external override onlyGov {
        isSigner[_account] = _isActive;
    }

    function setUpdater(address _account, bool _isActive) external override onlyGov {
        isUpdater[_account] = _isActive;
    }

    function setFastPriceEvents(address _fastPriceEvents) external onlyGov {
        fastPriceEvents = _fastPriceEvents;
    }

    function setVaultPriceFeed(address _vaultPriceFeed) external override onlyGov {
        vaultPriceFeed = _vaultPriceFeed;
    }

    function setMaxTimeDeviation(uint256 _maxTimeDeviation) external onlyGov {
        maxTimeDeviation = _maxTimeDeviation;
    }

    function setPriceDuration(uint256 _priceDuration) external override onlyGov {
        require(_priceDuration <= MAX_PRICE_DURATION, "FastPriceFeed: invalid _priceDuration");
        priceDuration = _priceDuration;
    }

    function setMaxPriceUpdateDelay(uint256 _maxPriceUpdateDelay) external override onlyGov {
        maxPriceUpdateDelay = _maxPriceUpdateDelay;
    }

    function setSpreadBasisPointsIfInactive(uint256 _spreadBasisPointsIfInactive) external override onlyGov {
        spreadBasisPointsIfInactive = _spreadBasisPointsIfInactive;
    }

    function setSpreadBasisPointsIfChainError(uint256 _spreadBasisPointsIfChainError) external override onlyGov {
        spreadBasisPointsIfChainError = _spreadBasisPointsIfChainError;
    }

    function setMinBlockInterval(uint256 _minBlockInterval) external override onlyGov {
        minBlockInterval = _minBlockInterval;
    }

    function setIsSpreadEnabled(bool _isSpreadEnabled) external override onlyGov {
        isSpreadEnabled = _isSpreadEnabled;
    }

    function setLastUpdatedAt(uint256 _lastUpdatedAt) external onlyGov {
        lastUpdatedAt = _lastUpdatedAt;
    }

    function setTokenManager(address _tokenManager) external onlyTokenManager {
        tokenManager = _tokenManager;
    }

    function setMaxDeviationBasisPoints(uint256 _maxDeviationBasisPoints) external override onlyTokenManager {
        maxDeviationBasisPoints = _maxDeviationBasisPoints;
    }

    function setMaxCumulativeDeltaDiffs(address[] memory _tokens, uint256[] memory _maxCumulativeDeltaDiffs) external override onlyTokenManager {
        for (uint256 i = 0; i < _tokens.length; i++) {
            address token = _tokens[i];
            maxCumulativeDeltaDiffs[token] = _maxCumulativeDeltaDiffs[i];
        }
    }

    function setPriceDataInterval(uint256 _priceDataInterval) external override onlyTokenManager {
        priceDataInterval = _priceDataInterval;
    }

    function setMinAuthorizations(uint256 _minAuthorizations) external onlyTokenManager {
        minAuthorizations = _minAuthorizations;
    }

    function setTokens(address[] memory _tokens, uint256[] memory _tokenPrecisions) external override onlyGov {
        require(_tokens.length == _tokenPrecisions.length, "FastPriceFeed: invalid lengths");
        tokens = _tokens;
        tokenPrecisions = _tokenPrecisions;
    }

    function setPrices(address[] memory _tokens, uint256[] memory _prices, uint256 _timestamp) external onlyUpdater {
        bool shouldUpdate = _setLastUpdatedValues(_timestamp);

        if (shouldUpdate) {
            address _fastPriceEvents = fastPriceEvents;
            address _vaultPriceFeed = vaultPriceFeed;

            for (uint256 i = 0; i < _tokens.length; i++) {
                address token = _tokens[i];
                _setPrice(token, _prices[i], _vaultPriceFeed, _fastPriceEvents);
            }
        }
    }

    function setCompactedPrices(uint256[] memory _priceBitArray, uint256 _timestamp) external onlyUpdater {
        bool shouldUpdate = _setLastUpdatedValues(_timestamp);

        if (shouldUpdate) {
            address _fastPriceEvents = fastPriceEvents;
            address _vaultPriceFeed = vaultPriceFeed;

            for (uint256 i = 0; i < _priceBitArray.length; i++) {
                uint256 priceBits = _priceBitArray[i];

                for (uint256 j = 0; j < 8; j++) {
                    uint256 index = i * 8 + j;
                    if (index >= tokens.length) {return;}

                    uint256 startBit = 32 * j;
                    uint256 price = (priceBits >> startBit) & BITMASK_32;

                    address token = tokens[i * 8 + j];
                    uint256 tokenPrecision = tokenPrecisions[i * 8 + j];
                    uint256 adjustedPrice = price.mul(PRICE_PRECISION).div(tokenPrecision);

                    _setPrice(token, adjustedPrice, _vaultPriceFeed, _fastPriceEvents);
                }
            }
        }
    }

    function setPricesWithBits(uint256 _priceBits, uint256 _timestamp) external onlyUpdater {
        _setPricesWithBits(_priceBits, _timestamp);
    }

    function setPricesWithBitsAndExecute(
        uint256 _priceBits,
        uint256 _timestamp,
        uint256 _endIndexForIncreasePositions,
        uint256 _endIndexForDecreasePositions,
        uint256 _maxIncreasePositions,
        uint256 _maxDecreasePositions
    ) external payable {
        setPricesWithBitsAndExecute(_priceBits, _timestamp, _endIndexForIncreasePositions, _endIndexForDecreasePositions, _maxIncreasePositions, _maxDecreasePositions, new bytes[](0));
    }
    function setPricesWithBitsAndExecute(
        uint256 _priceBits,
        uint256 _timestamp,
        uint256 _endIndexForIncreasePositions,
        uint256 _endIndexForDecreasePositions,
        uint256 _maxIncreasePositions,
        uint256 _maxDecreasePositions,
        bytes[] memory _updateData
    ) public payable onlyUpdater {
        if (_updateData.length > 0) {
            IPyth(IVaultPriceFeed(vaultPriceFeed).pythNetwork()).updatePriceFeeds{value: msg.value}(_updateData);
        }
        _setPricesWithBits(_priceBits, _timestamp);

        IPositionRouter _positionRouter = IPositionRouter(positionRouter);
        uint256 maxEndIndexForIncrease = _positionRouter.increasePositionRequestKeysStart().add(_maxIncreasePositions);
        uint256 maxEndIndexForDecrease = _positionRouter.decreasePositionRequestKeysStart().add(_maxDecreasePositions);

        if (_endIndexForIncreasePositions > maxEndIndexForIncrease) {
            _endIndexForIncreasePositions = maxEndIndexForIncrease;
        }

        if (_endIndexForDecreasePositions > maxEndIndexForDecrease) {
            _endIndexForDecreasePositions = maxEndIndexForDecrease;
        }

        _positionRouter.executeIncreasePositions(_endIndexForIncreasePositions, payable(msg.sender));
        _positionRouter.executeDecreasePositions(_endIndexForDecreasePositions, payable(msg.sender));
    }

    function disableFastPrice() external onlySigner {
        require(!disableFastPriceVotes[msg.sender], "FastPriceFeed: already voted");
        disableFastPriceVotes[msg.sender] = true;
        disableFastPriceVoteCount = disableFastPriceVoteCount.add(1);

        emit DisableFastPrice(msg.sender);
    }

    function enableFastPrice() external onlySigner {
        require(disableFastPriceVotes[msg.sender], "FastPriceFeed: already enabled");
        disableFastPriceVotes[msg.sender] = false;
        disableFastPriceVoteCount = disableFastPriceVoteCount.sub(1);

        emit EnableFastPrice(msg.sender);
    }

    // under regular operation, the fastPrice (prices[token]) is returned and there is no spread returned from this function,
    // though VaultPriceFeed might apply its own spread
    //
    // if the fastPrice has not been updated within priceDuration then it is ignored and only _refPrice with a spread is used (spread: spreadBasisPointsIfInactive)
    // in case the fastPrice has not been updated for maxPriceUpdateDelay then the _refPrice with a larger spread is used (spread: spreadBasisPointsIfChainError)
    //
    // there will be a spread from the _refPrice to the fastPrice in the following cases:
    // - in case isSpreadEnabled is set to true
    // - in case the maxDeviationBasisPoints between _refPrice and fastPrice is exceeded
    // - in case watchers flag an issue
    // - in case the cumulativeFastDelta exceeds the cumulativeRefDelta by the maxCumulativeDeltaDiff
    function getPrice(address _token, uint256 _refPrice, bool _maximise) external override view returns (uint256) {
        if (block.timestamp > lastUpdatedAt.add(maxPriceUpdateDelay)) {
            if (_maximise) {
                return _refPrice.mul(BASIS_POINTS_DIVISOR.add(spreadBasisPointsIfChainError)).div(BASIS_POINTS_DIVISOR);
            }

            return _refPrice.mul(BASIS_POINTS_DIVISOR.sub(spreadBasisPointsIfChainError)).div(BASIS_POINTS_DIVISOR);
        }

        if (block.timestamp > lastUpdatedAt.add(priceDuration)) {
            if (_maximise) {
                return _refPrice.mul(BASIS_POINTS_DIVISOR.add(spreadBasisPointsIfInactive)).div(BASIS_POINTS_DIVISOR);
            }

            return _refPrice.mul(BASIS_POINTS_DIVISOR.sub(spreadBasisPointsIfInactive)).div(BASIS_POINTS_DIVISOR);
        }
        uint256 fastPrice = prices[_token];
        if (fastPrice == 0) {return _refPrice;}


        uint256 diffBasisPoints = _refPrice > fastPrice ? _refPrice.sub(fastPrice) : fastPrice.sub(_refPrice);
        diffBasisPoints = diffBasisPoints.mul(BASIS_POINTS_DIVISOR).div(_refPrice);

        // create a spread between the _refPrice and the fastPrice if the maxDeviationBasisPoints is exceeded
        // or if watchers have flagged an issue with the fast price
        bool hasSpread = !favorFastPrice(_token) || diffBasisPoints > maxDeviationBasisPoints;

        if (hasSpread) {
            // return the higher of the two prices
            if (_maximise) {
                return _refPrice > fastPrice ? _refPrice : fastPrice;
            }

            // return the lower of the two prices
            return _refPrice < fastPrice ? _refPrice : fastPrice;
        }

        return fastPrice;
    }

    function favorFastPrice(address _token) public view returns (bool) {
        if (isSpreadEnabled) {
            return false;
        }

        if (disableFastPriceVoteCount >= minAuthorizations) {
            // force a spread if watchers have flagged an issue with the fast price
            return false;
        }

        (/* uint256 prevRefPrice */, /* uint256 refTime */, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta) = getPriceData(_token);
        if (cumulativeFastDelta > cumulativeRefDelta && cumulativeFastDelta.sub(cumulativeRefDelta) > maxCumulativeDeltaDiffs[_token]) {
            // force a spread if the cumulative delta for the fast price feed exceeds the cumulative delta
            // for the Chainlink price feed by the maxCumulativeDeltaDiff allowed
            return false;
        }

        return true;
    }

    function getPriceData(address _token) public view returns (uint256, uint256, uint256, uint256) {
        PriceDataItem memory data = priceData[_token];
        return (uint256(data.refPrice), uint256(data.refTime), uint256(data.cumulativeRefDelta), uint256(data.cumulativeFastDelta));
    }

    function _setPricesWithBits(uint256 _priceBits, uint256 _timestamp) private {
        bool shouldUpdate = _setLastUpdatedValues(_timestamp);

        if (shouldUpdate) {
            address _fastPriceEvents = fastPriceEvents;
            address _vaultPriceFeed = vaultPriceFeed;

            for (uint256 j = 0; j < 8; j++) {
                uint256 index = j;
                if (index >= tokens.length) {return;}

                uint256 startBit = 32 * j;
                uint256 price = (_priceBits >> startBit) & BITMASK_32;

                address token = tokens[j];
                uint256 tokenPrecision = tokenPrecisions[j];
                uint256 adjustedPrice = price.mul(PRICE_PRECISION).div(tokenPrecision);

                _setPrice(token, adjustedPrice, _vaultPriceFeed, _fastPriceEvents);
            }
        }
    }

    function _setPrice(address _token, uint256 _price, address _vaultPriceFeed, address _fastPriceEvents) private {
        if (_vaultPriceFeed != address(0)) {
            uint256 refPrice = IVaultPriceFeed(_vaultPriceFeed).getLatestPrimaryPrice(_token);
            uint256 fastPrice = prices[_token];

            (uint256 prevRefPrice, uint256 refTime, uint256 cumulativeRefDelta, uint256 cumulativeFastDelta) = getPriceData(_token);

            if (prevRefPrice > 0) {
                uint256 refDeltaAmount = refPrice > prevRefPrice ? refPrice.sub(prevRefPrice) : prevRefPrice.sub(refPrice);
                uint256 fastDeltaAmount = fastPrice > _price ? fastPrice.sub(_price) : _price.sub(fastPrice);

                // reset cumulative delta values if it is a new time window
                if (refTime.div(priceDataInterval) != block.timestamp.div(priceDataInterval)) {
                    cumulativeRefDelta = 0;
                    cumulativeFastDelta = 0;
                }

                cumulativeRefDelta = cumulativeRefDelta.add(refDeltaAmount.mul(CUMULATIVE_DELTA_PRECISION).div(prevRefPrice));
                cumulativeFastDelta = cumulativeFastDelta.add(fastDeltaAmount.mul(CUMULATIVE_DELTA_PRECISION).div(fastPrice));
            }

            if (cumulativeFastDelta > cumulativeRefDelta && cumulativeFastDelta.sub(cumulativeRefDelta) > maxCumulativeDeltaDiffs[_token]) {
                emit MaxCumulativeDeltaDiffExceeded(_token, refPrice, fastPrice, cumulativeRefDelta, cumulativeFastDelta);
            }

            _setPriceData(_token, refPrice, cumulativeRefDelta, cumulativeFastDelta);
            emit PriceData(_token, refPrice, fastPrice, cumulativeRefDelta, cumulativeFastDelta);
        }

        prices[_token] = _price;
        _emitPriceEvent(_fastPriceEvents, _token, _price);
    }

    function _setPriceData(address _token, uint256 _refPrice, uint256 _cumulativeRefDelta, uint256 _cumulativeFastDelta) private {
        require(_refPrice < MAX_REF_PRICE, "FastPriceFeed: invalid refPrice");
        // skip validation of block.timestamp, it should only be out of range after the year 2100
        require(_cumulativeRefDelta < MAX_CUMULATIVE_REF_DELTA, "FastPriceFeed: invalid cumulativeRefDelta");
        require(_cumulativeFastDelta < MAX_CUMULATIVE_FAST_DELTA, "FastPriceFeed: invalid cumulativeFastDelta");

        priceData[_token] = PriceDataItem(
            uint160(_refPrice),
            uint32(block.timestamp),
            uint32(_cumulativeRefDelta),
            uint32(_cumulativeFastDelta)
        );
    }

    function _emitPriceEvent(address _fastPriceEvents, address _token, uint256 _price) private {
        if (_fastPriceEvents == address(0)) {
            return;
        }

        IFastPriceEvents(_fastPriceEvents).emitPriceEvent(_token, _price);
    }

    function _setLastUpdatedValues(uint256 _timestamp) private returns (bool) {
        if (minBlockInterval > 0) {
            require(block.number.sub(lastUpdatedBlock) >= minBlockInterval, "FastPriceFeed: minBlockInterval not yet passed");
        }

        uint256 _maxTimeDeviation = maxTimeDeviation;
        require(_timestamp > block.timestamp.sub(_maxTimeDeviation), "FastPriceFeed: _timestamp below allowed range");
        require(_timestamp < block.timestamp.add(_maxTimeDeviation), "FastPriceFeed: _timestamp exceeds allowed range");

        // do not update prices if _timestamp is before the current lastUpdatedAt value
        if (_timestamp < lastUpdatedAt) {
            return false;
        }

        lastUpdatedAt = _timestamp;
        lastUpdatedBlock = block.number;

        return true;
    }

    function getUpdateFee(
        bytes[] calldata _updateData
    ) external view returns (uint feeAmount) {
        IPyth pyth = IPyth(IVaultPriceFeed(vaultPriceFeed).pythNetwork());
        return pyth.getUpdateFee(_updateData);
    }
}

File 2 of 11 : IPyth.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import "./PythStructs.sol";
import "./IPythEvents.sol";

/// @title Consume prices from the Pyth Network (https://pyth.network/).
/// @dev Please refer to the guidance at https://docs.pyth.network/consumers/best-practices for how to consume prices safely.
/// @author Pyth Data Association
interface IPyth is IPythEvents {
    /// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time
    function getValidTimePeriod() external view returns (uint validTimePeriod);

    /// @notice Returns the price and confidence interval.
    /// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds.
    /// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getPrice(
        bytes32 id
    ) external view returns (PythStructs.Price memory price);

    /// @notice Returns the exponentially-weighted moving average price and confidence interval.
    /// @dev Reverts if the EMA price is not available.
    /// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getEmaPrice(
        bytes32 id
    ) external view returns (PythStructs.Price memory price);

    /// @notice Returns the price of a price feed without any sanity checks.
    /// @dev This function returns the most recent price update in this contract without any recency checks.
    /// This function is unsafe as the returned price update may be arbitrarily far in the past.
    ///
    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is
    /// sufficiently recent for their application. If you are considering using this function, it may be
    /// safer / easier to use either `getPrice` or `getPriceNoOlderThan`.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getPriceUnsafe(
        bytes32 id
    ) external view returns (PythStructs.Price memory price);

    /// @notice Returns the price that is no older than `age` seconds of the current time.
    /// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in
    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
    /// recently.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getPriceNoOlderThan(
        bytes32 id,
        uint age
    ) external view returns (PythStructs.Price memory price);

    /// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.
    /// @dev This function returns the same price as `getEmaPrice` in the case where the price is available.
    /// However, if the price is not recent this function returns the latest available price.
    ///
    /// The returned price can be from arbitrarily far in the past; this function makes no guarantees that
    /// the returned price is recent or useful for any particular application.
    ///
    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is
    /// sufficiently recent for their application. If you are considering using this function, it may be
    /// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getEmaPriceUnsafe(
        bytes32 id
    ) external view returns (PythStructs.Price memory price);

    /// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds
    /// of the current time.
    /// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in
    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
    /// recently.
    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
    function getEmaPriceNoOlderThan(
        bytes32 id,
        uint age
    ) external view returns (PythStructs.Price memory price);

    /// @notice Update price feeds with given update messages.
    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
    /// `getUpdateFee` with the length of the `updateData` array.
    /// Prices will be updated if they are more recent than the current stored prices.
    /// The call will succeed even if the update is not the most recent.
    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid.
    /// @param updateData Array of price update data.
    function updatePriceFeeds(bytes[] calldata updateData) external payable;

    /// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is
    /// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the
    /// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`.
    ///
    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
    /// `getUpdateFee` with the length of the `updateData` array.
    ///
    /// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime
    /// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have
    /// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.
    /// Otherwise, it calls updatePriceFeeds method to update the prices.
    ///
    /// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.
    /// @param updateData Array of price update data.
    /// @param priceIds Array of price ids.
    /// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`
    function updatePriceFeedsIfNecessary(
        bytes[] calldata updateData,
        bytes32[] calldata priceIds,
        uint64[] calldata publishTimes
    ) external payable;

    /// @notice Returns the required fee to update an array of price updates.
    /// @param updateData Array of price update data.
    /// @return feeAmount The required fee in Wei.
    function getUpdateFee(
        bytes[] calldata updateData
    ) external view returns (uint feeAmount);

    /// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published
    /// within `minPublishTime` and `maxPublishTime`.
    ///
    /// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price;
    /// otherwise, please consider using `updatePriceFeeds`. This method does not store the price updates on-chain.
    ///
    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
    /// `getUpdateFee` with the length of the `updateData` array.
    ///
    ///
    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is
    /// no update for any of the given `priceIds` within the given time range.
    /// @param updateData Array of price update data.
    /// @param priceIds Array of price ids.
    /// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.
    /// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.
    /// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order).
    function parsePriceFeedUpdates(
        bytes[] calldata updateData,
        bytes32[] calldata priceIds,
        uint64 minPublishTime,
        uint64 maxPublishTime
    ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds);
}

File 3 of 11 : IPythEvents.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @title IPythEvents contains the events that Pyth contract emits.
/// @dev This interface can be used for listening to the updates for off-chain and testing purposes.
interface IPythEvents {
    /// @dev Emitted when the price feed with `id` has received a fresh update.
    /// @param id The Pyth Price Feed ID.
    /// @param publishTime Publish time of the given price update.
    /// @param price Price of the given price update.
    /// @param conf Confidence interval of the given price update.
    event PriceFeedUpdate(
        bytes32 indexed id,
        uint64 publishTime,
        int64 price,
        uint64 conf
    );

    /// @dev Emitted when a batch price update is processed successfully.
    /// @param chainId ID of the source chain that the batch price update comes from.
    /// @param sequenceNumber Sequence number of the batch price update.
    event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber);
}

File 4 of 11 : PythStructs.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

contract PythStructs {
    // A price with a degree of uncertainty, represented as a price +- a confidence interval.
    //
    // The confidence interval roughly corresponds to the standard error of a normal distribution.
    // Both the price and confidence are stored in a fixed-point numeric representation,
    // `x * (10^expo)`, where `expo` is the exponent.
    //
    // Please refer to the documentation at https://docs.pyth.network/consumers/best-practices for how
    // to how this price safely.
    struct Price {
        // Price
        int64 price;
        // Confidence interval around the price
        uint64 conf;
        // Price exponent
        int32 expo;
        // Unix timestamp describing when the price was published
        uint publishTime;
    }

    // PriceFeed represents a current aggregate price from pyth publisher feeds.
    struct PriceFeed {
        // The price ID.
        bytes32 id;
        // Latest available price
        Price price;
        // Latest available exponentially-weighted moving average price
        Price emaPrice;
    }
}

File 5 of 11 : Governable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

contract Governable {
    address public gov;

    constructor() public {
        gov = msg.sender;
    }

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

    function setGov(address _gov) external onlyGov {
        gov = _gov;
    }
}

File 6 of 11 : IPositionRouter.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IPositionRouter {
    function increasePositionRequestKeysStart() external returns (uint256);
    function decreasePositionRequestKeysStart() external returns (uint256);
    function executeIncreasePositions(uint256 _count, address payable _executionFeeReceiver) external;
    function executeDecreasePositions(uint256 _count, address payable _executionFeeReceiver) external;
}

File 7 of 11 : IVaultPriceFeed.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IVaultPriceFeed {
    function adjustmentBasisPoints(address _token) external view returns (uint256);
    function isAdjustmentAdditive(address _token) external view returns (bool);
    function pythNetwork() external view returns (address);
    function setAdjustment(address _token, bool _isAdditive, uint256 _adjustmentBps) external;
    function setIsSecondaryPriceEnabled(bool _isEnabled) 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 getLatestPrimaryPrice(address _token) external view returns (uint256);
    function getPrimaryPrice(address _token, bool _maximise) external view returns (uint256);
    function setPythNetwork(address _pythNetwork) external;
    function setTokenConfig(
        address _token,
        bytes32 _priceFeed,
        uint256 _allowedStaleness,
        bool _isStrictStable
    ) external;
    function setSecondaryPriceFeed(address _secondaryPriceFeed) external;

}

File 8 of 11 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 9 of 11 : IFastPriceEvents.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IFastPriceEvents {
    function emitPriceEvent(address _token, uint256 _price) external;
    function setIsPriceFeed(address _priceFeed, bool _isPriceFeed) external;
}

File 10 of 11 : IFastPriceFeed.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

interface IFastPriceFeed {
    function lastUpdatedAt() external view returns (uint256);
    function lastUpdatedBlock() external view returns (uint256);
    function setSigner(address _account, bool _isActive) external;
    function setUpdater(address _account, bool _isActive) external;
    function setPriceDuration(uint256 _priceDuration) external;
    function setMaxPriceUpdateDelay(uint256 _maxPriceUpdateDelay) external;
    function setSpreadBasisPointsIfInactive(uint256 _spreadBasisPointsIfInactive) external;
    function setSpreadBasisPointsIfChainError(uint256 _spreadBasisPointsIfChainError) external;
    function setMinBlockInterval(uint256 _minBlockInterval) external;
    function setIsSpreadEnabled(bool _isSpreadEnabled) external;
    function setMaxDeviationBasisPoints(uint256 _maxDeviationBasisPoints) external;
    function setMaxCumulativeDeltaDiffs(address[] memory _tokens,  uint256[] memory _maxCumulativeDeltaDiffs) external;
    function setPriceDataInterval(uint256 _priceDataInterval) external;
    function setVaultPriceFeed(address _vaultPriceFeed) external;
    function setTokens(address[] memory _tokens, uint256[] memory _tokenPrecisions) external;
}

File 11 of 11 : ISecondaryPriceFeed.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

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

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 250
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_priceDuration","type":"uint256"},{"internalType":"uint256","name":"_maxPriceUpdateDelay","type":"uint256"},{"internalType":"uint256","name":"_minBlockInterval","type":"uint256"},{"internalType":"uint256","name":"_maxDeviationBasisPoints","type":"uint256"},{"internalType":"address","name":"_fastPriceEvents","type":"address"},{"internalType":"address","name":"_tokenManager","type":"address"},{"internalType":"address","name":"_positionRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"DisableFastPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"EnableFastPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"refPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fastPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cumulativeRefDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cumulativeFastDelta","type":"uint256"}],"name":"MaxCumulativeDeltaDiffExceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"refPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fastPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cumulativeRefDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cumulativeFastDelta","type":"uint256"}],"name":"PriceData","type":"event"},{"inputs":[],"name":"BASIS_POINTS_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BITMASK_32","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CUMULATIVE_DELTA_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CUMULATIVE_FAST_DELTA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CUMULATIVE_REF_DELTA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRICE_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REF_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableFastPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableFastPriceVoteCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"disableFastPriceVotes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableFastPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fastPriceEvents","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"favorFastPrice","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_refPrice","type":"uint256"},{"internalType":"bool","name":"_maximise","type":"bool"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getPriceData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_updateData","type":"bytes[]"}],"name":"getUpdateFee","outputs":[{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minAuthorizations","type":"uint256"},{"internalType":"address[]","name":"_signers","type":"address[]"},{"internalType":"address[]","name":"_updaters","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSpreadEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isUpdater","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdatedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdatedBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxCumulativeDeltaDiffs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDeviationBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPriceUpdateDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTimeDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAuthorizations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBlockInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"priceData","outputs":[{"internalType":"uint160","name":"refPrice","type":"uint160"},{"internalType":"uint32","name":"refTime","type":"uint32"},{"internalType":"uint32","name":"cumulativeRefDelta","type":"uint32"},{"internalType":"uint32","name":"cumulativeFastDelta","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceDataInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"prices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_priceBitArray","type":"uint256[]"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setCompactedPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fastPriceEvents","type":"address"}],"name":"setFastPriceEvents","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isSpreadEnabled","type":"bool"}],"name":"setIsSpreadEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastUpdatedAt","type":"uint256"}],"name":"setLastUpdatedAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_maxCumulativeDeltaDiffs","type":"uint256[]"}],"name":"setMaxCumulativeDeltaDiffs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDeviationBasisPoints","type":"uint256"}],"name":"setMaxDeviationBasisPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPriceUpdateDelay","type":"uint256"}],"name":"setMaxPriceUpdateDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTimeDeviation","type":"uint256"}],"name":"setMaxTimeDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minAuthorizations","type":"uint256"}],"name":"setMinAuthorizations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBlockInterval","type":"uint256"}],"name":"setMinBlockInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceDataInterval","type":"uint256"}],"name":"setPriceDataInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceDuration","type":"uint256"}],"name":"setPriceDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceBits","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"setPricesWithBits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceBits","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_endIndexForIncreasePositions","type":"uint256"},{"internalType":"uint256","name":"_endIndexForDecreasePositions","type":"uint256"},{"internalType":"uint256","name":"_maxIncreasePositions","type":"uint256"},{"internalType":"uint256","name":"_maxDecreasePositions","type":"uint256"}],"name":"setPricesWithBitsAndExecute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceBits","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_endIndexForIncreasePositions","type":"uint256"},{"internalType":"uint256","name":"_endIndexForDecreasePositions","type":"uint256"},{"internalType":"uint256","name":"_maxIncreasePositions","type":"uint256"},{"internalType":"uint256","name":"_maxDecreasePositions","type":"uint256"},{"internalType":"bytes[]","name":"_updateData","type":"bytes[]"}],"name":"setPricesWithBitsAndExecute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_isActive","type":"bool"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_spreadBasisPointsIfChainError","type":"uint256"}],"name":"setSpreadBasisPointsIfChainError","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_spreadBasisPointsIfInactive","type":"uint256"}],"name":"setSpreadBasisPointsIfInactive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenManager","type":"address"}],"name":"setTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_tokenPrecisions","type":"uint256[]"}],"name":"setTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_isActive","type":"bool"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultPriceFeed","type":"address"}],"name":"setVaultPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spreadBasisPointsIfChainError","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spreadBasisPointsIfInactive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenPrecisions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultPriceFeed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040526000805460ff60a81b191681556010553480156200002157600080fd5b50604051620032b8380380620032b8833981016040819052620000449162000130565b600080546001600160a01b03191633179055610708871115620000bb5760405162461bcd60e51b815260206004820152602560248201527f466173745072696365466565643a20696e76616c6964205f707269636544757260448201526430ba34b7b760d91b606482015260840160405180910390fd5b600796909655600894909455600b92909255600e55600280546001600160a01b039283166001600160a01b031991821617909155600380549383169382169390931790925560048054919093169116179055620001a1565b80516001600160a01b03811681146200012b57600080fd5b919050565b600080600080600080600060e0888a0312156200014c57600080fd5b87519650602088015195506040880151945060608801519350620001736080890162000113565b92506200018360a0890162000113565b91506200019360c0890162000113565b905092959891949750929550565b61310780620001b16000396000f3fe6080604052600436106103d95760003560e01c806374bfed89116101fd578063b70c7b7011610118578063d47eed45116100ab578063dfb481c91161007a578063dfb481c914610ba9578063e64559ad14610bbf578063e68a22c014610bd5578063eeaa783a14610bf0578063f90ce5ba14610c1057600080fd5b8063d47eed4514610b29578063d6a153f114610b49578063d925351a14610b69578063de0d1b9414610b8957600080fd5b8063cab44b76116100e7578063cab44b7614610a2c578063ce98dfa814610abc578063cfad57a214610adc578063cfed246b14610afc57600080fd5b8063b70c7b70146109c4578063c7475b32146109e4578063c8390a48146109f7578063c84a912414610a1757600080fd5b806382553aad11610190578063a37424251161015f578063a374242514610955578063a6eca89614610982578063b0a2566614610998578063b3606b56146109ae57600080fd5b806382553aad146108dd5780638b7677f4146108fd57806395082d251461091d578063a2b47c161461093e57600080fd5b80637df73e27116101cc5780637df73e271461086d5780637fbc79c61461089d5780637fece368146108bd578063807c97821461046957600080fd5b806374bfed89146107f7578063776d16c11461080d578063782661bc1461082d5780637cb2b79c1461084d57600080fd5b8063392e53cd116102f857806354aea1271161028b578063695d41841161025a578063695d41841461074b5780636c56fd051461076c5780636ccd47c41461078c578063715c7536146107a157806372279ba1146107b757600080fd5b806354aea127146106ec578063574ec1be1461070257806361ef161f14610715578063668d3d651461073557600080fd5b80634c0e31c8116102c75780634c0e31c81461065c5780634d11fb4a1461067c5780634f64b2be1461069c5780634fdfb086146106bc57600080fd5b8063392e53cd146106055780633aa08f861461062657806344c231931461063c5780634bd66c1c1461046957600080fd5b8063162ac4e011610370578063287800c91161033f578063287800c91461058f5780632a709b14146105a55780632e9cd94b146105c557806331cb6105146105e557600080fd5b8063162ac4e01461050f57806317835d1c1461052f5780631a1533911461054f578063238aafb71461056f57600080fd5b80630e9272ea116103ac5780630e9272ea14610481578063126082cf146104b957806312d43a51146104cf57806314dd2dce146104ef57600080fd5b806303b04936146103de57806303cd25711461042357806303f4d7dc146104475780630604ddea14610469575b600080fd5b3480156103ea57600080fd5b5061040e6103f936600461283c565b60166020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b34801561042f57600080fd5b5061043960075481565b60405190815260200161041a565b34801561045357600080fd5b5061046761046236600461292f565b610c26565b005b34801561047557600080fd5b5061043963ffffffff81565b34801561048d57600080fd5b506002546104a1906001600160a01b031681565b6040516001600160a01b03909116815260200161041a565b3480156104c557600080fd5b5061043961271081565b3480156104db57600080fd5b506000546104a1906001600160a01b031681565b3480156104fb57600080fd5b5061046761050a366004612974565b610ddd565b34801561051b57600080fd5b5061046761052a36600461283c565b610e0c565b34801561053b57600080fd5b5061046761054a36600461298d565b610e58565b34801561055b57600080fd5b5061046761056a3660046129c4565b610e91565b34801561057b57600080fd5b5061046761058a36600461283c565b610ee6565b34801561059b57600080fd5b50610439600f5481565b3480156105b157600080fd5b506003546104a1906001600160a01b031681565b3480156105d157600080fd5b506104676105e0366004612974565b610f32565b3480156105f157600080fd5b506104676106003660046129c4565b610f61565b34801561061157600080fd5b5060005461040e90600160a01b900460ff1681565b34801561063257600080fd5b50610439600c5481565b34801561064857600080fd5b50610467610657366004612974565b610fb6565b34801561066857600080fd5b50610467610677366004612a5d565b611045565b34801561068857600080fd5b50610439610697366004612974565b6110e3565b3480156106a857600080fd5b506104a16106b7366004612974565b611104565b3480156106c857600080fd5b5061040e6106d736600461283c565b60116020526000908152604090205460ff1681565b3480156106f857600080fd5b5061043960055481565b610467610710366004612ac1565b61112e565b34801561072157600080fd5b506004546104a1906001600160a01b031681565b34801561074157600080fd5b5061043961070881565b34801561075757600080fd5b5060005461040e90600160a81b900460ff1681565b34801561077857600080fd5b5061040e61078736600461283c565b611172565b34801561079857600080fd5b506104676111fa565b3480156107ad57600080fd5b50610439600e5481565b3480156107c357600080fd5b506107d76107d236600461283c565b6112e6565b60408051948552602085019390935291830152606082015260800161041a565b34801561080357600080fd5b5061043960095481565b34801561081957600080fd5b50610467610828366004612974565b611350565b34801561083957600080fd5b50610467610848366004612b04565b61137f565b34801561085957600080fd5b5061046761086836600461283c565b611440565b34801561087957600080fd5b5061040e61088836600461283c565b60156020526000908152604090205460ff1681565b3480156108a957600080fd5b506104676108b8366004612b71565b61148c565b3480156108c957600080fd5b506104396108d8366004612bde565b6115f4565b3480156108e957600080fd5b506104676108f8366004612974565b61177d565b34801561090957600080fd5b50610467610918366004612974565b6117ac565b34801561092957600080fd5b506104396c0c9f2c9cd04674edea4000000081565b34801561094a57600080fd5b506104396298968081565b34801561096157600080fd5b5061043961097036600461283c565b60146020526000908152604090205481565b34801561098e57600080fd5b50610439600a5481565b3480156109a457600080fd5b5061043960105481565b3480156109ba57600080fd5b50610439600b5481565b3480156109d057600080fd5b506104676109df366004612974565b6117db565b6104676109f2366004612c1c565b61180a565b348015610a0357600080fd5b50610467610a12366004612a5d565b611aca565b348015610a2357600080fd5b50610467611b6c565b348015610a3857600080fd5b50610a86610a4736600461283c565b6013602052600090815260409020546001600160a01b0381169063ffffffff600160a01b8204811691600160c01b8104821691600160e01b9091041684565b604080516001600160a01b03909516855263ffffffff93841660208601529183169184019190915216606082015260800161041a565b348015610ac857600080fd5b50610467610ad7366004612d79565b611c57565b348015610ae857600080fd5b50610467610af736600461283c565b611c9f565b348015610b0857600080fd5b50610439610b1736600461283c565b60126020526000908152604090205481565b348015610b3557600080fd5b50610439610b44366004612d94565b611ceb565b348015610b5557600080fd5b50610467610b64366004612974565b611de1565b348015610b7557600080fd5b50610467610b84366004612974565b611e10565b348015610b9557600080fd5b50610467610ba4366004612974565b611e3f565b348015610bb557600080fd5b50610439600d5481565b348015610bcb57600080fd5b5061043960085481565b348015610be157600080fd5b506104396001600160a01b0381565b348015610bfc57600080fd5b506001546104a1906001600160a01b031681565b348015610c1c57600080fd5b5061043960065481565b3360009081526011602052604090205460ff16610c5e5760405162461bcd60e51b8152600401610c5590612e09565b60405180910390fd5b6000610c6982611e6e565b90508015610dd7576002546001546001600160a01b03918216911660005b8551811015610dd3576000868281518110610ca457610ca4612e40565b6020026020010151905060005b6008811015610dbe57600081610cc8856008612e6c565b610cd29190612e8b565b6017549091508110610ce957505050505050505050565b6000610cf6836020612e6c565b905083811c63ffffffff166000601785610d11896008612e6c565b610d1b9190612e8b565b81548110610d2b57610d2b612e40565b60009182526020822001546001600160a01b03169150601886610d4f8a6008612e6c565b610d599190612e8b565b81548110610d6957610d69612e40565b60009182526020822001549150610d9782610d91866c0c9f2c9cd04674edea40000000611ff1565b90612073565b9050610da583828c8e6120b5565b5050505050508080610db690612e9e565b915050610cb1565b50508080610dcb90612e9e565b915050610c87565b5050505b505b5050565b6000546001600160a01b03163314610e075760405162461bcd60e51b8152600401610c5590612eb7565b600555565b6000546001600160a01b03163314610e365760405162461bcd60e51b8152600401610c5590612eb7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526011602052604090205460ff16610e875760405162461bcd60e51b8152600401610c5590612e09565b610dd9828261233f565b6000546001600160a01b03163314610ebb5760405162461bcd60e51b8152600401610c5590612eb7565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314610f105760405162461bcd60e51b8152600401610c5590612eb7565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b03163314610f5c5760405162461bcd60e51b8152600401610c5590612e09565b600d55565b6000546001600160a01b03163314610f8b5760405162461bcd60e51b8152600401610c5590612eb7565b6001600160a01b03919091166000908152601560205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314610fe05760405162461bcd60e51b8152600401610c5590612eb7565b6107088111156110405760405162461bcd60e51b815260206004820152602560248201527f466173745072696365466565643a20696e76616c6964205f707269636544757260448201526430ba34b7b760d91b6064820152608401610c55565b600755565b6003546001600160a01b0316331461106f5760405162461bcd60e51b8152600401610c5590612e09565b60005b8251811015610dd757600083828151811061108f5761108f612e40565b602002602001015190508282815181106110ab576110ab612e40565b6020908102919091018101516001600160a01b03909216600090815260149091526040902055806110db81612e9e565b915050611072565b601881815481106110f357600080fd5b600091825260209091200154905081565b6017818154811061111457600080fd5b6000918252602090912001546001600160a01b0316905081565b610dd3868686868686600060405190808252806020026020018201604052801561116c57816020015b60608152602001906001900390816111575790505b5061180a565b60008054600160a81b900460ff161561118d57506000919050565b600f54601054106111a057506000919050565b6000806111ac846112e6565b93509350505081811180156111e157506001600160a01b0384166000908152601460205260409020546111df8284612433565b115b156111f0575060009392505050565b5060019392505050565b3360009081526015602052604090205460ff166112295760405162461bcd60e51b8152600401610c5590612e09565b3360009081526016602052604090205460ff166112885760405162461bcd60e51b815260206004820152601e60248201527f466173745072696365466565643a20616c726561647920656e61626c656400006044820152606401610c55565b336000908152601660205260409020805460ff191690556010546112ad906001612433565b6010556040513381527f9fe0c305c33aa92757a537936872a60be0d91549a4303cc99fd8b7fce8a00275906020015b60405180910390a1565b6001600160a01b039081166000908152601360209081526040918290208251608081018452905493841680825263ffffffff600160a01b86048116938301849052600160c01b86048116948301859052600160e01b90950490941660609091018190529293909290565b6000546001600160a01b0316331461137a5760405162461bcd60e51b8152600401610c5590612eb7565b600c55565b3360009081526011602052604090205460ff166113ae5760405162461bcd60e51b8152600401610c5590612e09565b60006113b982611e6e565b9050801561143a576002546001546001600160a01b03918216911660005b86518110156114365760008782815181106113f4576113f4612e40565b602002602001015190506114238188848151811061141457611414612e40565b602002602001015185876120b5565b508061142e81612e9e565b9150506113d7565b5050505b50505050565b6003546001600160a01b0316331461146a5760405162461bcd60e51b8152600401610c5590612e09565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146114b65760405162461bcd60e51b8152600401610c5590612eb7565b600054600160a01b900460ff161561151b5760405162461bcd60e51b815260206004820152602260248201527f466173745072696365466565643a20616c726561647920696e697469616c697a604482015261195960f21b6064820152608401610c55565b6000805460ff60a01b1916600160a01b178155600f8490555b825181101561159257600083828151811061155157611551612e40565b6020908102919091018101516001600160a01b03166000908152601590915260409020805460ff19166001179055508061158a81612e9e565b915050611534565b5060005b815181101561143a5760008282815181106115b3576115b3612e40565b6020908102919091018101516001600160a01b03166000908152601190915260409020805460ff1916600117905550806115ec81612e9e565b915050611596565b600061160d60085460055461247590919063ffffffff16565b42111561166857811561164857611641612710610d9161163a600a5461271061247590919063ffffffff16565b8690611ff1565b9050611776565b611641612710610d9161163a600a5461271061243390919063ffffffff16565b60075460055461167791612475565b4211156116c45781156116a457611641612710610d9161163a60095461271061247590919063ffffffff16565b611641612710610d9161163a60095461271061243390919063ffffffff16565b6001600160a01b038416600090815260126020526040812054908190036116ee5783915050611776565b6000818511611706576117018286612433565b611710565b6117108583612433565b905061172285610d9183612710611ff1565b9050600061172f87611172565b158061173c5750600e5482115b90508015611770578415611763578286116117575782611759565b855b9350505050611776565b8286106117575782611759565b50909150505b9392505050565b6003546001600160a01b031633146117a75760405162461bcd60e51b8152600401610c5590612e09565b600e55565b6000546001600160a01b031633146117d65760405162461bcd60e51b8152600401610c5590612eb7565b600855565b6000546001600160a01b031633146118055760405162461bcd60e51b8152600401610c5590612eb7565b600955565b3360009081526011602052604090205460ff166118395760405162461bcd60e51b8152600401610c5590612e09565b80511561191657600160009054906101000a90046001600160a01b03166001600160a01b031663553dcbbd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190612ee6565b6001600160a01b031663ef9e5e2834836040518363ffffffff1660e01b81526004016118e39190612f49565b6000604051808303818588803b1580156118fc57600080fd5b505af1158015611910573d6000803e3d6000fd5b50505050505b611920878761233f565b60048054604080516304dabc3160e51b815290516001600160a01b039092169260009261199d9288928692639b578620928083019260209291829003018189875af1158015611973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119979190612fab565b90612475565b905060006119e585846001600160a01b0316631bca8cf06040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611973573d6000803e3d6000fd5b9050818811156119f3578197505b808711156119ff578096505b604051629a208160e81b8152600481018990523360248201526001600160a01b03841690639a20810090604401600060405180830381600087803b158015611a4657600080fd5b505af1158015611a5a573d6000803e3d6000fd5b505060405163f3883d8b60e01b8152600481018a90523360248201526001600160a01b038616925063f3883d8b9150604401600060405180830381600087803b158015611aa657600080fd5b505af1158015611aba573d6000803e3d6000fd5b5050505050505050505050505050565b6000546001600160a01b03163314611af45760405162461bcd60e51b8152600401610c5590612eb7565b8051825114611b455760405162461bcd60e51b815260206004820152601e60248201527f466173745072696365466565643a20696e76616c6964206c656e6774687300006044820152606401610c55565b8151611b5890601790602085019061276f565b508051610dd79060189060208401906127d4565b3360009081526015602052604090205460ff16611b9b5760405162461bcd60e51b8152600401610c5590612e09565b3360009081526016602052604090205460ff1615611bfb5760405162461bcd60e51b815260206004820152601c60248201527f466173745072696365466565643a20616c726561647920766f746564000000006044820152606401610c55565b336000908152601660205260409020805460ff19166001908117909155601054611c2491612475565b6010556040513381527f4c0c5fabf50e808e3bc8d19577d305e3a7163eea7e8a74a50caa8896694cd44b906020016112dc565b6000546001600160a01b03163314611c815760405162461bcd60e51b8152600401610c5590612eb7565b60008054911515600160a81b0260ff60a81b19909216919091179055565b6000546001600160a01b03163314611cc95760405162461bcd60e51b8152600401610c5590612eb7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663553dcbbd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d659190612ee6565b60405163d47eed4560e01b81529091506001600160a01b0382169063d47eed4590611d969087908790600401612fed565b602060405180830381865afa158015611db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd79190612fab565b9150505b92915050565b6000546001600160a01b03163314611e0b5760405162461bcd60e51b8152600401610c5590612eb7565b600b55565b6003546001600160a01b03163314611e3a5760405162461bcd60e51b8152600401610c5590612e09565b600f55565b6000546001600160a01b03163314611e695760405162461bcd60e51b8152600401610c5590612eb7565b600a55565b600b5460009015611eef57600b54600654611e8a904390612433565b1015611eef5760405162461bcd60e51b815260206004820152602e60248201527f466173745072696365466565643a206d696e426c6f636b496e74657276616c2060448201526d1b9bdd081e595d081c185cdcd95960921b6064820152608401610c55565b600c54611efc4282612433565b8311611f605760405162461bcd60e51b815260206004820152602d60248201527f466173745072696365466565643a205f74696d657374616d702062656c6f772060448201526c616c6c6f7765642072616e676560981b6064820152608401610c55565b611f6a4282612475565b8310611fd05760405162461bcd60e51b815260206004820152602f60248201527f466173745072696365466565643a205f74696d657374616d702065786365656460448201526e7320616c6c6f7765642072616e676560881b6064820152608401610c55565b600554831015611fe35750600092915050565b505060055543600655600190565b60008260000361200357506000611ddb565b600061200f8385612e6c565b90508261201c8583613089565b146117765760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c55565b600061177683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506124d4565b6001600160a01b03821615612319576040516315afe77960e21b81526001600160a01b038581166004830152600091908416906356bf9de490602401602060405180830381865afa15801561210e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121329190612fab565b6001600160a01b03861660009081526012602052604081205491925080808061215a8a6112e6565b935093509350935060008411156122215760008487116121835761217e8588612433565b61218d565b61218d8786612433565b905060008a87116121a7576121a28b88612433565b6121b1565b6121b1878c612433565b90506121c8600d544261207390919063ffffffff16565b600d546121d6908790612073565b146121e45760009350600092505b6121ff6121f887610d918562989680611ff1565b8590612475565b935061221c61221588610d918462989680611ff1565b8490612475565b925050505b818111801561225057506001600160a01b038a1660009081526014602052604090205461224e8284612433565b115b156122ae57604080516001600160a01b038c1681526020810188905290810186905260608101839052608081018290527fe582322b389ad06b2bbf619cd6da3f16a288ec873ea0fa6df4d72f3d9480b4479060a00160405180910390a15b6122ba8a87848461250b565b604080516001600160a01b038c1681526020810188905290810186905260608101839052608081018290527f23b9387f81fca646aac1dc4487ede045c65f5f7445482906565f01e05afdb3a89060a00160405180910390a15050505050505b6001600160a01b038416600090815260126020526040902083905561143a8185856126cd565b600061234a82611e6e565b90508015610dd7576002546001546001600160a01b03918216911660005b6008811015610dd357601754819081106123855750505050505050565b6000612392836020612e6c565b6017805491925089831c63ffffffff169160009190869081106123b7576123b7612e40565b6000918252602082200154601880546001600160a01b03909216935090879081106123e4576123e4612e40565b6000918252602082200154915061240c82610d91866c0c9f2c9cd04674edea40000000611ff1565b905061241a83828a8c6120b5565b505050505050808061242b90612e9e565b915050612368565b600061177683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061273e565b6000806124828385612e8b565b9050838110156117765760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c55565b600081836124f55760405162461bcd60e51b8152600401610c5591906130ab565b5060006125028486613089565b95945050505050565b6001600160a01b0383106125615760405162461bcd60e51b815260206004820152601f60248201527f466173745072696365466565643a20696e76616c6964207265665072696365006044820152606401610c55565b63ffffffff82106125c65760405162461bcd60e51b815260206004820152602960248201527f466173745072696365466565643a20696e76616c69642063756d756c617469766044820152686552656644656c746160b81b6064820152608401610c55565b63ffffffff811061262c5760405162461bcd60e51b815260206004820152602a60248201527f466173745072696365466565643a20696e76616c69642063756d756c61746976604482015269654661737444656c746160b01b6064820152608401610c55565b604080516080810182526001600160a01b03948516815263ffffffff4281166020808401918252958216838501908152948216606084019081529787166000908152601390965292909420905181549251935196518516600160e01b026001600160e01b03978616600160c01b02979097166001600160c01b0394909516600160a01b026001600160c01b0319909316951694909417171617919091179055565b6001600160a01b0383166126e057505050565b60405163e0409c7160e01b81526001600160a01b0383811660048301526024820183905284169063e0409c7190604401600060405180830381600087803b15801561272a57600080fd5b505af1158015611436573d6000803e3d6000fd5b600081848411156127625760405162461bcd60e51b8152600401610c5591906130ab565b50600061250284866130be565b8280548282559060005260206000209081019282156127c4579160200282015b828111156127c457825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061278f565b506127d092915061280f565b5090565b8280548282559060005260206000209081019282156127c4579160200282015b828111156127c45782518255916020019190600101906127f4565b5b808211156127d05760008155600101612810565b6001600160a01b038116811461283957600080fd5b50565b60006020828403121561284e57600080fd5b813561177681612824565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561289857612898612859565b604052919050565b600067ffffffffffffffff8211156128ba576128ba612859565b5060051b60200190565b600082601f8301126128d557600080fd5b813560206128ea6128e5836128a0565b61286f565b82815260059290921b8401810191818101908684111561290957600080fd5b8286015b84811015612924578035835291830191830161290d565b509695505050505050565b6000806040838503121561294257600080fd5b823567ffffffffffffffff81111561295957600080fd5b612965858286016128c4565b95602094909401359450505050565b60006020828403121561298657600080fd5b5035919050565b600080604083850312156129a057600080fd5b50508035926020909101359150565b803580151581146129bf57600080fd5b919050565b600080604083850312156129d757600080fd5b82356129e281612824565b91506129f0602084016129af565b90509250929050565b600082601f830112612a0a57600080fd5b81356020612a1a6128e5836128a0565b82815260059290921b84018101918181019086841115612a3957600080fd5b8286015b84811015612924578035612a5081612824565b8352918301918301612a3d565b60008060408385031215612a7057600080fd5b823567ffffffffffffffff80821115612a8857600080fd5b612a94868387016129f9565b93506020850135915080821115612aaa57600080fd5b50612ab7858286016128c4565b9150509250929050565b60008060008060008060c08789031215612ada57600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b600080600060608486031215612b1957600080fd5b833567ffffffffffffffff80821115612b3157600080fd5b612b3d878388016129f9565b94506020860135915080821115612b5357600080fd5b50612b60868287016128c4565b925050604084013590509250925092565b600080600060608486031215612b8657600080fd5b83359250602084013567ffffffffffffffff80821115612ba557600080fd5b612bb1878388016129f9565b93506040860135915080821115612bc757600080fd5b50612bd4868287016129f9565b9150509250925092565b600080600060608486031215612bf357600080fd5b8335612bfe81612824565b925060208401359150612c13604085016129af565b90509250925092565b600080600080600080600060e0888a031215612c3757600080fd5b873596506020880135955060408801359450606088013593506080880135925060a0880135915067ffffffffffffffff60c08901351115612c7757600080fd5b60c0880135880189601f820112612c8d57600080fd5b612c9a6128e582356128a0565b81358082526020808301929160051b8401018c1015612cb857600080fd5b602083015b6020843560051b850101811015612d665767ffffffffffffffff81351115612ce457600080fd5b803584018d603f820112612cf757600080fd5b602081013567ffffffffffffffff811115612d1457612d14612859565b612d27601f8201601f191660200161286f565b8181528f6040838501011115612d3c57600080fd5b81604084016020830137600060208383010152808652505050602083019250602081019050612cbd565b5080935050505092959891949750929550565b600060208284031215612d8b57600080fd5b611776826129af565b60008060208385031215612da757600080fd5b823567ffffffffffffffff80821115612dbf57600080fd5b818501915085601f830112612dd357600080fd5b813581811115612de257600080fd5b8660208260051b8501011115612df757600080fd5b60209290920196919550909350505050565b60208082526018908201527f466173745072696365466565643a20666f7262696464656e0000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612e8657612e86612e56565b500290565b80820180821115611ddb57611ddb612e56565b600060018201612eb057612eb0612e56565b5060010190565b60208082526015908201527423b7bb32b93730b136329d103337b93134b23232b760591b604082015260600190565b600060208284031215612ef857600080fd5b815161177681612824565b6000815180845260005b81811015612f2957602081850181015186830182015201612f0d565b506000602082860101526020601f19601f83011685010191505092915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612f9e57603f19888603018452612f8c858351612f03565b94509285019290850190600101612f70565b5092979650505050505050565b600060208284031215612fbd57600080fd5b5051919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208082528181018390526000906040600585901b8401810190840186845b8781101561307c57868403603f190183528135368a9003601e1901811261303257600080fd5b8901858101903567ffffffffffffffff81111561304e57600080fd5b80360382131561305d57600080fd5b613068868284612fc4565b95505050918401919084019060010161300c565b5091979650505050505050565b6000826130a657634e487b7160e01b600052601260045260246000fd5b500490565b6020815260006117766020830184612f03565b81810381811115611ddb57611ddb612e5656fea264697066735822122011e38d54f945d4f9d9ba819ca188c2ba8eb218a29ba30dc1f863d047e5650f3464736f6c6343000810003300000000000000000000000000000000000000000000000000000000000002580000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000004236907b95d07e56a70f21707e6105b1dccebfc000000000000000000000000030b12942912cee5a719edec2dd147224fcc373a000000000000000000000000091c62ae93ccffdbe0b1be841433e46e033514c8d

Deployed Bytecode

0x6080604052600436106103d95760003560e01c806374bfed89116101fd578063b70c7b7011610118578063d47eed45116100ab578063dfb481c91161007a578063dfb481c914610ba9578063e64559ad14610bbf578063e68a22c014610bd5578063eeaa783a14610bf0578063f90ce5ba14610c1057600080fd5b8063d47eed4514610b29578063d6a153f114610b49578063d925351a14610b69578063de0d1b9414610b8957600080fd5b8063cab44b76116100e7578063cab44b7614610a2c578063ce98dfa814610abc578063cfad57a214610adc578063cfed246b14610afc57600080fd5b8063b70c7b70146109c4578063c7475b32146109e4578063c8390a48146109f7578063c84a912414610a1757600080fd5b806382553aad11610190578063a37424251161015f578063a374242514610955578063a6eca89614610982578063b0a2566614610998578063b3606b56146109ae57600080fd5b806382553aad146108dd5780638b7677f4146108fd57806395082d251461091d578063a2b47c161461093e57600080fd5b80637df73e27116101cc5780637df73e271461086d5780637fbc79c61461089d5780637fece368146108bd578063807c97821461046957600080fd5b806374bfed89146107f7578063776d16c11461080d578063782661bc1461082d5780637cb2b79c1461084d57600080fd5b8063392e53cd116102f857806354aea1271161028b578063695d41841161025a578063695d41841461074b5780636c56fd051461076c5780636ccd47c41461078c578063715c7536146107a157806372279ba1146107b757600080fd5b806354aea127146106ec578063574ec1be1461070257806361ef161f14610715578063668d3d651461073557600080fd5b80634c0e31c8116102c75780634c0e31c81461065c5780634d11fb4a1461067c5780634f64b2be1461069c5780634fdfb086146106bc57600080fd5b8063392e53cd146106055780633aa08f861461062657806344c231931461063c5780634bd66c1c1461046957600080fd5b8063162ac4e011610370578063287800c91161033f578063287800c91461058f5780632a709b14146105a55780632e9cd94b146105c557806331cb6105146105e557600080fd5b8063162ac4e01461050f57806317835d1c1461052f5780631a1533911461054f578063238aafb71461056f57600080fd5b80630e9272ea116103ac5780630e9272ea14610481578063126082cf146104b957806312d43a51146104cf57806314dd2dce146104ef57600080fd5b806303b04936146103de57806303cd25711461042357806303f4d7dc146104475780630604ddea14610469575b600080fd5b3480156103ea57600080fd5b5061040e6103f936600461283c565b60166020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b34801561042f57600080fd5b5061043960075481565b60405190815260200161041a565b34801561045357600080fd5b5061046761046236600461292f565b610c26565b005b34801561047557600080fd5b5061043963ffffffff81565b34801561048d57600080fd5b506002546104a1906001600160a01b031681565b6040516001600160a01b03909116815260200161041a565b3480156104c557600080fd5b5061043961271081565b3480156104db57600080fd5b506000546104a1906001600160a01b031681565b3480156104fb57600080fd5b5061046761050a366004612974565b610ddd565b34801561051b57600080fd5b5061046761052a36600461283c565b610e0c565b34801561053b57600080fd5b5061046761054a36600461298d565b610e58565b34801561055b57600080fd5b5061046761056a3660046129c4565b610e91565b34801561057b57600080fd5b5061046761058a36600461283c565b610ee6565b34801561059b57600080fd5b50610439600f5481565b3480156105b157600080fd5b506003546104a1906001600160a01b031681565b3480156105d157600080fd5b506104676105e0366004612974565b610f32565b3480156105f157600080fd5b506104676106003660046129c4565b610f61565b34801561061157600080fd5b5060005461040e90600160a01b900460ff1681565b34801561063257600080fd5b50610439600c5481565b34801561064857600080fd5b50610467610657366004612974565b610fb6565b34801561066857600080fd5b50610467610677366004612a5d565b611045565b34801561068857600080fd5b50610439610697366004612974565b6110e3565b3480156106a857600080fd5b506104a16106b7366004612974565b611104565b3480156106c857600080fd5b5061040e6106d736600461283c565b60116020526000908152604090205460ff1681565b3480156106f857600080fd5b5061043960055481565b610467610710366004612ac1565b61112e565b34801561072157600080fd5b506004546104a1906001600160a01b031681565b34801561074157600080fd5b5061043961070881565b34801561075757600080fd5b5060005461040e90600160a81b900460ff1681565b34801561077857600080fd5b5061040e61078736600461283c565b611172565b34801561079857600080fd5b506104676111fa565b3480156107ad57600080fd5b50610439600e5481565b3480156107c357600080fd5b506107d76107d236600461283c565b6112e6565b60408051948552602085019390935291830152606082015260800161041a565b34801561080357600080fd5b5061043960095481565b34801561081957600080fd5b50610467610828366004612974565b611350565b34801561083957600080fd5b50610467610848366004612b04565b61137f565b34801561085957600080fd5b5061046761086836600461283c565b611440565b34801561087957600080fd5b5061040e61088836600461283c565b60156020526000908152604090205460ff1681565b3480156108a957600080fd5b506104676108b8366004612b71565b61148c565b3480156108c957600080fd5b506104396108d8366004612bde565b6115f4565b3480156108e957600080fd5b506104676108f8366004612974565b61177d565b34801561090957600080fd5b50610467610918366004612974565b6117ac565b34801561092957600080fd5b506104396c0c9f2c9cd04674edea4000000081565b34801561094a57600080fd5b506104396298968081565b34801561096157600080fd5b5061043961097036600461283c565b60146020526000908152604090205481565b34801561098e57600080fd5b50610439600a5481565b3480156109a457600080fd5b5061043960105481565b3480156109ba57600080fd5b50610439600b5481565b3480156109d057600080fd5b506104676109df366004612974565b6117db565b6104676109f2366004612c1c565b61180a565b348015610a0357600080fd5b50610467610a12366004612a5d565b611aca565b348015610a2357600080fd5b50610467611b6c565b348015610a3857600080fd5b50610a86610a4736600461283c565b6013602052600090815260409020546001600160a01b0381169063ffffffff600160a01b8204811691600160c01b8104821691600160e01b9091041684565b604080516001600160a01b03909516855263ffffffff93841660208601529183169184019190915216606082015260800161041a565b348015610ac857600080fd5b50610467610ad7366004612d79565b611c57565b348015610ae857600080fd5b50610467610af736600461283c565b611c9f565b348015610b0857600080fd5b50610439610b1736600461283c565b60126020526000908152604090205481565b348015610b3557600080fd5b50610439610b44366004612d94565b611ceb565b348015610b5557600080fd5b50610467610b64366004612974565b611de1565b348015610b7557600080fd5b50610467610b84366004612974565b611e10565b348015610b9557600080fd5b50610467610ba4366004612974565b611e3f565b348015610bb557600080fd5b50610439600d5481565b348015610bcb57600080fd5b5061043960085481565b348015610be157600080fd5b506104396001600160a01b0381565b348015610bfc57600080fd5b506001546104a1906001600160a01b031681565b348015610c1c57600080fd5b5061043960065481565b3360009081526011602052604090205460ff16610c5e5760405162461bcd60e51b8152600401610c5590612e09565b60405180910390fd5b6000610c6982611e6e565b90508015610dd7576002546001546001600160a01b03918216911660005b8551811015610dd3576000868281518110610ca457610ca4612e40565b6020026020010151905060005b6008811015610dbe57600081610cc8856008612e6c565b610cd29190612e8b565b6017549091508110610ce957505050505050505050565b6000610cf6836020612e6c565b905083811c63ffffffff166000601785610d11896008612e6c565b610d1b9190612e8b565b81548110610d2b57610d2b612e40565b60009182526020822001546001600160a01b03169150601886610d4f8a6008612e6c565b610d599190612e8b565b81548110610d6957610d69612e40565b60009182526020822001549150610d9782610d91866c0c9f2c9cd04674edea40000000611ff1565b90612073565b9050610da583828c8e6120b5565b5050505050508080610db690612e9e565b915050610cb1565b50508080610dcb90612e9e565b915050610c87565b5050505b505b5050565b6000546001600160a01b03163314610e075760405162461bcd60e51b8152600401610c5590612eb7565b600555565b6000546001600160a01b03163314610e365760405162461bcd60e51b8152600401610c5590612eb7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526011602052604090205460ff16610e875760405162461bcd60e51b8152600401610c5590612e09565b610dd9828261233f565b6000546001600160a01b03163314610ebb5760405162461bcd60e51b8152600401610c5590612eb7565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314610f105760405162461bcd60e51b8152600401610c5590612eb7565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b03163314610f5c5760405162461bcd60e51b8152600401610c5590612e09565b600d55565b6000546001600160a01b03163314610f8b5760405162461bcd60e51b8152600401610c5590612eb7565b6001600160a01b03919091166000908152601560205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314610fe05760405162461bcd60e51b8152600401610c5590612eb7565b6107088111156110405760405162461bcd60e51b815260206004820152602560248201527f466173745072696365466565643a20696e76616c6964205f707269636544757260448201526430ba34b7b760d91b6064820152608401610c55565b600755565b6003546001600160a01b0316331461106f5760405162461bcd60e51b8152600401610c5590612e09565b60005b8251811015610dd757600083828151811061108f5761108f612e40565b602002602001015190508282815181106110ab576110ab612e40565b6020908102919091018101516001600160a01b03909216600090815260149091526040902055806110db81612e9e565b915050611072565b601881815481106110f357600080fd5b600091825260209091200154905081565b6017818154811061111457600080fd5b6000918252602090912001546001600160a01b0316905081565b610dd3868686868686600060405190808252806020026020018201604052801561116c57816020015b60608152602001906001900390816111575790505b5061180a565b60008054600160a81b900460ff161561118d57506000919050565b600f54601054106111a057506000919050565b6000806111ac846112e6565b93509350505081811180156111e157506001600160a01b0384166000908152601460205260409020546111df8284612433565b115b156111f0575060009392505050565b5060019392505050565b3360009081526015602052604090205460ff166112295760405162461bcd60e51b8152600401610c5590612e09565b3360009081526016602052604090205460ff166112885760405162461bcd60e51b815260206004820152601e60248201527f466173745072696365466565643a20616c726561647920656e61626c656400006044820152606401610c55565b336000908152601660205260409020805460ff191690556010546112ad906001612433565b6010556040513381527f9fe0c305c33aa92757a537936872a60be0d91549a4303cc99fd8b7fce8a00275906020015b60405180910390a1565b6001600160a01b039081166000908152601360209081526040918290208251608081018452905493841680825263ffffffff600160a01b86048116938301849052600160c01b86048116948301859052600160e01b90950490941660609091018190529293909290565b6000546001600160a01b0316331461137a5760405162461bcd60e51b8152600401610c5590612eb7565b600c55565b3360009081526011602052604090205460ff166113ae5760405162461bcd60e51b8152600401610c5590612e09565b60006113b982611e6e565b9050801561143a576002546001546001600160a01b03918216911660005b86518110156114365760008782815181106113f4576113f4612e40565b602002602001015190506114238188848151811061141457611414612e40565b602002602001015185876120b5565b508061142e81612e9e565b9150506113d7565b5050505b50505050565b6003546001600160a01b0316331461146a5760405162461bcd60e51b8152600401610c5590612e09565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146114b65760405162461bcd60e51b8152600401610c5590612eb7565b600054600160a01b900460ff161561151b5760405162461bcd60e51b815260206004820152602260248201527f466173745072696365466565643a20616c726561647920696e697469616c697a604482015261195960f21b6064820152608401610c55565b6000805460ff60a01b1916600160a01b178155600f8490555b825181101561159257600083828151811061155157611551612e40565b6020908102919091018101516001600160a01b03166000908152601590915260409020805460ff19166001179055508061158a81612e9e565b915050611534565b5060005b815181101561143a5760008282815181106115b3576115b3612e40565b6020908102919091018101516001600160a01b03166000908152601190915260409020805460ff1916600117905550806115ec81612e9e565b915050611596565b600061160d60085460055461247590919063ffffffff16565b42111561166857811561164857611641612710610d9161163a600a5461271061247590919063ffffffff16565b8690611ff1565b9050611776565b611641612710610d9161163a600a5461271061243390919063ffffffff16565b60075460055461167791612475565b4211156116c45781156116a457611641612710610d9161163a60095461271061247590919063ffffffff16565b611641612710610d9161163a60095461271061243390919063ffffffff16565b6001600160a01b038416600090815260126020526040812054908190036116ee5783915050611776565b6000818511611706576117018286612433565b611710565b6117108583612433565b905061172285610d9183612710611ff1565b9050600061172f87611172565b158061173c5750600e5482115b90508015611770578415611763578286116117575782611759565b855b9350505050611776565b8286106117575782611759565b50909150505b9392505050565b6003546001600160a01b031633146117a75760405162461bcd60e51b8152600401610c5590612e09565b600e55565b6000546001600160a01b031633146117d65760405162461bcd60e51b8152600401610c5590612eb7565b600855565b6000546001600160a01b031633146118055760405162461bcd60e51b8152600401610c5590612eb7565b600955565b3360009081526011602052604090205460ff166118395760405162461bcd60e51b8152600401610c5590612e09565b80511561191657600160009054906101000a90046001600160a01b03166001600160a01b031663553dcbbd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b79190612ee6565b6001600160a01b031663ef9e5e2834836040518363ffffffff1660e01b81526004016118e39190612f49565b6000604051808303818588803b1580156118fc57600080fd5b505af1158015611910573d6000803e3d6000fd5b50505050505b611920878761233f565b60048054604080516304dabc3160e51b815290516001600160a01b039092169260009261199d9288928692639b578620928083019260209291829003018189875af1158015611973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119979190612fab565b90612475565b905060006119e585846001600160a01b0316631bca8cf06040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611973573d6000803e3d6000fd5b9050818811156119f3578197505b808711156119ff578096505b604051629a208160e81b8152600481018990523360248201526001600160a01b03841690639a20810090604401600060405180830381600087803b158015611a4657600080fd5b505af1158015611a5a573d6000803e3d6000fd5b505060405163f3883d8b60e01b8152600481018a90523360248201526001600160a01b038616925063f3883d8b9150604401600060405180830381600087803b158015611aa657600080fd5b505af1158015611aba573d6000803e3d6000fd5b5050505050505050505050505050565b6000546001600160a01b03163314611af45760405162461bcd60e51b8152600401610c5590612eb7565b8051825114611b455760405162461bcd60e51b815260206004820152601e60248201527f466173745072696365466565643a20696e76616c6964206c656e6774687300006044820152606401610c55565b8151611b5890601790602085019061276f565b508051610dd79060189060208401906127d4565b3360009081526015602052604090205460ff16611b9b5760405162461bcd60e51b8152600401610c5590612e09565b3360009081526016602052604090205460ff1615611bfb5760405162461bcd60e51b815260206004820152601c60248201527f466173745072696365466565643a20616c726561647920766f746564000000006044820152606401610c55565b336000908152601660205260409020805460ff19166001908117909155601054611c2491612475565b6010556040513381527f4c0c5fabf50e808e3bc8d19577d305e3a7163eea7e8a74a50caa8896694cd44b906020016112dc565b6000546001600160a01b03163314611c815760405162461bcd60e51b8152600401610c5590612eb7565b60008054911515600160a81b0260ff60a81b19909216919091179055565b6000546001600160a01b03163314611cc95760405162461bcd60e51b8152600401610c5590612eb7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080600160009054906101000a90046001600160a01b03166001600160a01b031663553dcbbd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d659190612ee6565b60405163d47eed4560e01b81529091506001600160a01b0382169063d47eed4590611d969087908790600401612fed565b602060405180830381865afa158015611db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd79190612fab565b9150505b92915050565b6000546001600160a01b03163314611e0b5760405162461bcd60e51b8152600401610c5590612eb7565b600b55565b6003546001600160a01b03163314611e3a5760405162461bcd60e51b8152600401610c5590612e09565b600f55565b6000546001600160a01b03163314611e695760405162461bcd60e51b8152600401610c5590612eb7565b600a55565b600b5460009015611eef57600b54600654611e8a904390612433565b1015611eef5760405162461bcd60e51b815260206004820152602e60248201527f466173745072696365466565643a206d696e426c6f636b496e74657276616c2060448201526d1b9bdd081e595d081c185cdcd95960921b6064820152608401610c55565b600c54611efc4282612433565b8311611f605760405162461bcd60e51b815260206004820152602d60248201527f466173745072696365466565643a205f74696d657374616d702062656c6f772060448201526c616c6c6f7765642072616e676560981b6064820152608401610c55565b611f6a4282612475565b8310611fd05760405162461bcd60e51b815260206004820152602f60248201527f466173745072696365466565643a205f74696d657374616d702065786365656460448201526e7320616c6c6f7765642072616e676560881b6064820152608401610c55565b600554831015611fe35750600092915050565b505060055543600655600190565b60008260000361200357506000611ddb565b600061200f8385612e6c565b90508261201c8583613089565b146117765760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c55565b600061177683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506124d4565b6001600160a01b03821615612319576040516315afe77960e21b81526001600160a01b038581166004830152600091908416906356bf9de490602401602060405180830381865afa15801561210e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121329190612fab565b6001600160a01b03861660009081526012602052604081205491925080808061215a8a6112e6565b935093509350935060008411156122215760008487116121835761217e8588612433565b61218d565b61218d8786612433565b905060008a87116121a7576121a28b88612433565b6121b1565b6121b1878c612433565b90506121c8600d544261207390919063ffffffff16565b600d546121d6908790612073565b146121e45760009350600092505b6121ff6121f887610d918562989680611ff1565b8590612475565b935061221c61221588610d918462989680611ff1565b8490612475565b925050505b818111801561225057506001600160a01b038a1660009081526014602052604090205461224e8284612433565b115b156122ae57604080516001600160a01b038c1681526020810188905290810186905260608101839052608081018290527fe582322b389ad06b2bbf619cd6da3f16a288ec873ea0fa6df4d72f3d9480b4479060a00160405180910390a15b6122ba8a87848461250b565b604080516001600160a01b038c1681526020810188905290810186905260608101839052608081018290527f23b9387f81fca646aac1dc4487ede045c65f5f7445482906565f01e05afdb3a89060a00160405180910390a15050505050505b6001600160a01b038416600090815260126020526040902083905561143a8185856126cd565b600061234a82611e6e565b90508015610dd7576002546001546001600160a01b03918216911660005b6008811015610dd357601754819081106123855750505050505050565b6000612392836020612e6c565b6017805491925089831c63ffffffff169160009190869081106123b7576123b7612e40565b6000918252602082200154601880546001600160a01b03909216935090879081106123e4576123e4612e40565b6000918252602082200154915061240c82610d91866c0c9f2c9cd04674edea40000000611ff1565b905061241a83828a8c6120b5565b505050505050808061242b90612e9e565b915050612368565b600061177683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061273e565b6000806124828385612e8b565b9050838110156117765760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c55565b600081836124f55760405162461bcd60e51b8152600401610c5591906130ab565b5060006125028486613089565b95945050505050565b6001600160a01b0383106125615760405162461bcd60e51b815260206004820152601f60248201527f466173745072696365466565643a20696e76616c6964207265665072696365006044820152606401610c55565b63ffffffff82106125c65760405162461bcd60e51b815260206004820152602960248201527f466173745072696365466565643a20696e76616c69642063756d756c617469766044820152686552656644656c746160b81b6064820152608401610c55565b63ffffffff811061262c5760405162461bcd60e51b815260206004820152602a60248201527f466173745072696365466565643a20696e76616c69642063756d756c61746976604482015269654661737444656c746160b01b6064820152608401610c55565b604080516080810182526001600160a01b03948516815263ffffffff4281166020808401918252958216838501908152948216606084019081529787166000908152601390965292909420905181549251935196518516600160e01b026001600160e01b03978616600160c01b02979097166001600160c01b0394909516600160a01b026001600160c01b0319909316951694909417171617919091179055565b6001600160a01b0383166126e057505050565b60405163e0409c7160e01b81526001600160a01b0383811660048301526024820183905284169063e0409c7190604401600060405180830381600087803b15801561272a57600080fd5b505af1158015611436573d6000803e3d6000fd5b600081848411156127625760405162461bcd60e51b8152600401610c5591906130ab565b50600061250284866130be565b8280548282559060005260206000209081019282156127c4579160200282015b828111156127c457825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061278f565b506127d092915061280f565b5090565b8280548282559060005260206000209081019282156127c4579160200282015b828111156127c45782518255916020019190600101906127f4565b5b808211156127d05760008155600101612810565b6001600160a01b038116811461283957600080fd5b50565b60006020828403121561284e57600080fd5b813561177681612824565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561289857612898612859565b604052919050565b600067ffffffffffffffff8211156128ba576128ba612859565b5060051b60200190565b600082601f8301126128d557600080fd5b813560206128ea6128e5836128a0565b61286f565b82815260059290921b8401810191818101908684111561290957600080fd5b8286015b84811015612924578035835291830191830161290d565b509695505050505050565b6000806040838503121561294257600080fd5b823567ffffffffffffffff81111561295957600080fd5b612965858286016128c4565b95602094909401359450505050565b60006020828403121561298657600080fd5b5035919050565b600080604083850312156129a057600080fd5b50508035926020909101359150565b803580151581146129bf57600080fd5b919050565b600080604083850312156129d757600080fd5b82356129e281612824565b91506129f0602084016129af565b90509250929050565b600082601f830112612a0a57600080fd5b81356020612a1a6128e5836128a0565b82815260059290921b84018101918181019086841115612a3957600080fd5b8286015b84811015612924578035612a5081612824565b8352918301918301612a3d565b60008060408385031215612a7057600080fd5b823567ffffffffffffffff80821115612a8857600080fd5b612a94868387016129f9565b93506020850135915080821115612aaa57600080fd5b50612ab7858286016128c4565b9150509250929050565b60008060008060008060c08789031215612ada57600080fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b600080600060608486031215612b1957600080fd5b833567ffffffffffffffff80821115612b3157600080fd5b612b3d878388016129f9565b94506020860135915080821115612b5357600080fd5b50612b60868287016128c4565b925050604084013590509250925092565b600080600060608486031215612b8657600080fd5b83359250602084013567ffffffffffffffff80821115612ba557600080fd5b612bb1878388016129f9565b93506040860135915080821115612bc757600080fd5b50612bd4868287016129f9565b9150509250925092565b600080600060608486031215612bf357600080fd5b8335612bfe81612824565b925060208401359150612c13604085016129af565b90509250925092565b600080600080600080600060e0888a031215612c3757600080fd5b873596506020880135955060408801359450606088013593506080880135925060a0880135915067ffffffffffffffff60c08901351115612c7757600080fd5b60c0880135880189601f820112612c8d57600080fd5b612c9a6128e582356128a0565b81358082526020808301929160051b8401018c1015612cb857600080fd5b602083015b6020843560051b850101811015612d665767ffffffffffffffff81351115612ce457600080fd5b803584018d603f820112612cf757600080fd5b602081013567ffffffffffffffff811115612d1457612d14612859565b612d27601f8201601f191660200161286f565b8181528f6040838501011115612d3c57600080fd5b81604084016020830137600060208383010152808652505050602083019250602081019050612cbd565b5080935050505092959891949750929550565b600060208284031215612d8b57600080fd5b611776826129af565b60008060208385031215612da757600080fd5b823567ffffffffffffffff80821115612dbf57600080fd5b818501915085601f830112612dd357600080fd5b813581811115612de257600080fd5b8660208260051b8501011115612df757600080fd5b60209290920196919550909350505050565b60208082526018908201527f466173745072696365466565643a20666f7262696464656e0000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615612e8657612e86612e56565b500290565b80820180821115611ddb57611ddb612e56565b600060018201612eb057612eb0612e56565b5060010190565b60208082526015908201527423b7bb32b93730b136329d103337b93134b23232b760591b604082015260600190565b600060208284031215612ef857600080fd5b815161177681612824565b6000815180845260005b81811015612f2957602081850181015186830182015201612f0d565b506000602082860101526020601f19601f83011685010191505092915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612f9e57603f19888603018452612f8c858351612f03565b94509285019290850190600101612f70565b5092979650505050505050565b600060208284031215612fbd57600080fd5b5051919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208082528181018390526000906040600585901b8401810190840186845b8781101561307c57868403603f190183528135368a9003601e1901811261303257600080fd5b8901858101903567ffffffffffffffff81111561304e57600080fd5b80360382131561305d57600080fd5b613068868284612fc4565b95505050918401919084019060010161300c565b5091979650505050505050565b6000826130a657634e487b7160e01b600052601260045260246000fd5b500490565b6020815260006117766020830184612f03565b81810381811115611ddb57611ddb612e5656fea264697066735822122011e38d54f945d4f9d9ba819ca188c2ba8eb218a29ba30dc1f863d047e5650f3464736f6c63430008100033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000002580000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000004236907b95d07e56a70f21707e6105b1dccebfc000000000000000000000000030b12942912cee5a719edec2dd147224fcc373a000000000000000000000000091c62ae93ccffdbe0b1be841433e46e033514c8d

-----Decoded View---------------
Arg [0] : _priceDuration (uint256): 600
Arg [1] : _maxPriceUpdateDelay (uint256): 3600
Arg [2] : _minBlockInterval (uint256): 1
Arg [3] : _maxDeviationBasisPoints (uint256): 250
Arg [4] : _fastPriceEvents (address): 0x4236907B95d07E56A70f21707e6105B1dCcebfC0
Arg [5] : _tokenManager (address): 0x30B12942912Cee5A719edec2dD147224fCC373A0
Arg [6] : _positionRouter (address): 0x91c62ae93ccfFdBE0B1Be841433E46E033514C8D

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000258
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000e10
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000fa
Arg [4] : 0000000000000000000000004236907b95d07e56a70f21707e6105b1dccebfc0
Arg [5] : 00000000000000000000000030b12942912cee5a719edec2dd147224fcc373a0
Arg [6] : 00000000000000000000000091c62ae93ccffdbe0b1be841433e46e033514c8d


Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.