This contract's source code is verified! Compiler
0.8.17+commit.8df45f5f
File 1 of 8: FastPriceFeed.sol
import "./interfaces/ISecondaryPriceFeed.sol" ;
import "./interfaces/IFastPriceFeed.sol" ;
import "./interfaces/IFastPriceEvents.sol" ;
import "../core/interfaces/IRouter.sol" ;
import "../core/interfaces/IVaultPriceFeed.sol" ;
import "../access/Governable.sol" ;
import "../library/utils/math/SafeMath.sol" ;
pragma solidity ^0.8.17;
contract FastPriceFeed is ISecondaryPriceFeed , IFastPriceFeed , Governable {
using SafeMath for uint256 ;
struct PriceDataItem {
uint160 refPrice;
uint32 refTime;
uint32 cumulativeRefDelta;
uint32 cumulativeFastDelta;
}
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 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;
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;
address [] public tokens;
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
) {
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 setPositionRouter (address _positionRouter ) external onlyGov {
positionRouter = _positionRouter;
}
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 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 onlyUpdater {
_setPricesWithBits(_priceBits, _timestamp);
IRouter _positionRouter = IRouter(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 );
}
function getPrice (address _token, uint256 _refPrice, bool _maximise ) external override view returns (uint256 ) {
if (_refPrice = = 0 ){
return prices[_token];
}
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);
bool hasSpread = ! favorFastPrice(_token) | | diffBasisPoints > maxDeviationBasisPoints;
if (hasSpread) {
if (_maximise) {
return _refPrice > fastPrice ? _refPrice : fastPrice;
}
return _refPrice < fastPrice ? _refPrice : fastPrice;
}
return fastPrice;
}
function favorFastPrice (address _token ) public view returns (bool ) {
if (isSpreadEnabled) {
return false ;
}
if (disableFastPriceVoteCount > = minAuthorizations) {
return false ;
}
(, , uint256 cumulativeRefDelta, uint256 cumulativeFastDelta) = getPriceData(_token);
if (cumulativeFastDelta > cumulativeRefDelta & & cumulativeFastDelta.sub(cumulativeRefDelta) > maxCumulativeDeltaDiffs[_token]) {
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);
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" );
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" );
if (_timestamp < lastUpdatedAt) {
return false ;
}
lastUpdatedAt = _timestamp;
lastUpdatedBlock = block .number ;
return true ;
}
function getCurrBlockTime ( ) view public returns (uint ) {
return block .timestamp ;
}
}
File 2 of 8: Governable.sol
pragma solidity ^0.8.17;
contract Governable {
address public gov;
constructor ( ) {
gov = msg .sender ;
}
modifier onlyGov ( ) {
require (msg .sender = = gov, "Governable: forbidden" );
_ ;
}
function setGov (address _gov ) external onlyGov {
gov = _gov;
}
}
File 3 of 8: IFastPriceEvents.sol
pragma solidity ^0.8.17;
interface IFastPriceEvents {
function emitPriceEvent (address _token, uint256 _price ) external ;
}
File 4 of 8: IFastPriceFeed.sol
pragma solidity ^0.8.17;
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 ;
}
File 5 of 8: IRouter.sol
pragma solidity ^0.8.17;
interface IRouter {
function createIncreasePosition (
address _inToken,
address _indexToken,
uint256 _collateralDelta,
uint256 _sizeDelta,
bool _isLong,
uint256 _acceptablePrice,
uint256 _insuranceLevel,
uint256 _executionFee,
bytes32 _referralCode
) external payable returns (bytes32 ) ;
function createDecreasePosition (
address _inToken,
address _indexToken,
uint256 _collateralDelta,
uint256 _sizeDelta,
bool _isLong,
uint256 _acceptablePrice,
uint256 _insuranceLevel,
uint256 _minOut,
uint256 _executionFee
) external payable returns (bytes32 ) ;
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 ;
function referral ( ) external view returns (address ) ;
}
File 6 of 8: ISecondaryPriceFeed.sol
pragma solidity ^0.8.17;
interface ISecondaryPriceFeed {
function getPrice (address _token, uint256 _referencePrice, bool _maximise ) external view returns (uint256 ) ;
}
File 7 of 8: IVaultPriceFeed.sol
pragma solidity ^0.8.17;
interface IVaultPriceFeed {
function adjustmentBasisPoints (address _token ) external view returns (uint256 ) ;
function isAdjustmentAdditive (address _token ) external view returns (bool ) ;
function setAdjustment (address _token, bool _isAdditive, uint256 _adjustmentBps ) external ;
function setUseV2Pricing (bool _useV2Pricing ) external ;
function setIsAmmEnabled (bool _isEnabled ) external ;
function setIsSecondaryPriceEnabled (bool _isEnabled ) external ;
function setSpreadBasisPoints (address _token, uint256 _spreadBasisPoints ) external ;
function setSpreadThresholdBasisPoints (uint256 _spreadThresholdBasisPoints ) external ;
function setFavorPrimaryPrice (bool _favorPrimaryPrice ) external ;
function setPriceSampleSpace (uint256 _priceSampleSpace ) external ;
function setMaxStrictPriceDeviation (uint256 _maxStrictPriceDeviation ) external ;
function getPrice (address _token, bool _maximise ) external view returns (uint256 ) ;
function getAmmPrice (address _token ) external view returns (uint256 ) ;
function getLatestPrimaryPrice (address _token ) external view returns (uint256 ) ;
function getPrimaryPrice (address _token, bool _maximise ) external view returns (uint256 ) ;
function setTokenConfig (
address _token,
address _priceFeed,
uint256 _priceDecimals,
bool _isStrictStable
) external ;
}
File 8 of 8: SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd (uint256 a, uint256 b ) internal pure returns (bool , uint256 ) {
unchecked {
uint256 c = a + b;
if (c < a) return (false , 0 );
return (true , c);
}
}
function trySub (uint256 a, uint256 b ) internal pure returns (bool , uint256 ) {
unchecked {
if (b > a) return (false , 0 );
return (true , a - b);
}
}
function tryMul (uint256 a, uint256 b ) internal pure returns (bool , uint256 ) {
unchecked {
if (a = = 0 ) return (true , 0 );
uint256 c = a * b;
if (c / a ! = b) return (false , 0 );
return (true , c);
}
}
function tryDiv (uint256 a, uint256 b ) internal pure returns (bool , uint256 ) {
unchecked {
if (b = = 0 ) return (false , 0 );
return (true , a / b);
}
}
function tryMod (uint256 a, uint256 b ) internal pure returns (bool , uint256 ) {
unchecked {
if (b = = 0 ) return (false , 0 );
return (true , a % b);
}
}
function add (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return a + b;
}
function sub (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return a - b;
}
function mul (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return a * b;
}
function div (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return a / b;
}
function mod (uint256 a, uint256 b ) internal pure returns (uint256 ) {
return a % b;
}
function sub (
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256 ) {
unchecked {
require (b < = a, errorMessage);
return a - b;
}
}
function div (
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256 ) {
unchecked {
require (b > 0 , errorMessage);
return a / b;
}
}
function mod (
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256 ) {
unchecked {
require (b > 0 , errorMessage);
return a % b;
}
}
}
{
"compilationTarget" : {
"contracts/oracle/FastPriceFeed.sol" : "FastPriceFeed"
} ,
"evmVersion" : "london" ,
"libraries" : { } ,
"metadata" : {
"bytecodeHash" : "ipfs"
} ,
"optimizer" : {
"enabled" : true ,
"runs" : 200
} ,
"remappings" : [ ]
} [{"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":[],"name":"getCurrBlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"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":"address","name":"_positionRouter","type":"address"}],"name":"setPositionRouter","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":"nonpayable","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"}]