UniV3OracleImpl

Git Source

Inherits: OracleError

This contract is used to get the exchange rate from from a Uniswap V3 Pool, including logic to check against TWAP max deltas.

Uses 5 secondsAgos values and 3 TWAP maxDeltas: e.g. 240, 60, 15, 1, 0 -> price240to60, price60to15, price 15to1, currentPrice delta checks: price240to60 vs currentPrice, price60to15 vs currentPrice and 15to1 vs currentPrice.

State Variables

_POOL

Uniswap V3 Pool to check for the exchange rate

IUniswapV3Pool internal immutable _POOL;

_UNIV3_INVERT_RATE

Flag to invert the price or not (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)

bool internal immutable _UNIV3_INVERT_RATE;

_UNI_TWAP1_MAX_DELTA_PERCENT

Uniswap oracle delta for TWAP1 in 1e2 percent. If uniswap price TWAP1 is out of this delta, current price fetching reverts. E.g. for delta of TWAP 240 -> 60 vs current price

uint256 internal immutable _UNI_TWAP1_MAX_DELTA_PERCENT;

_UNI_TWAP2_MAX_DELTA_PERCENT

Uniswap oracle delta for TWAP2 in 1e2 percent. If uniswap price TWAP2 is out of this delta, current price fetching reverts. E.g. for delta of TWAP 60 -> 15 vs current price

uint256 internal immutable _UNI_TWAP2_MAX_DELTA_PERCENT;

_UNI_TWAP3_MAX_DELTA_PERCENT

Uniswap oracle delta for TWAP3 in 1e2 percent. If uniswap price TWAP3 is out of this delta, current price fetching reverts. E.g. for delta of TWAP 15 -> 1 vs current price

uint256 internal immutable _UNI_TWAP3_MAX_DELTA_PERCENT;

_UNI_SECONDS_AGO_1

Uniswap oracle seconds ago for twap, 1. value, e.g. 240

uint256 internal immutable _UNI_SECONDS_AGO_1;

_UNI_SECONDS_AGO_2

Uniswap oracle seconds ago for twap, 2. value, e.g. 60

uint256 internal immutable _UNI_SECONDS_AGO_2;

_UNI_SECONDS_AGO_3

Uniswap oracle seconds ago for twap, 3. value, e.g. 15

uint256 internal immutable _UNI_SECONDS_AGO_3;

_UNI_SECONDS_AGO_4

Uniswap oracle seconds ago for twap, 4. value, e.g. 1

uint256 internal immutable _UNI_SECONDS_AGO_4;

_UNI_SECONDS_AGO_5

Uniswap oracle seconds ago for twap, 5. value, e.g. 0

uint256 internal immutable _UNI_SECONDS_AGO_5;

_UNI_TWAP1_INTERVAL

Uniswap TWAP1 interval duration.

int256 internal immutable _UNI_TWAP1_INTERVAL;

_UNI_TWAP2_INTERVAL

Uniswap TWAP2 interval duration.

int256 internal immutable _UNI_TWAP2_INTERVAL;

_UNI_TWAP3_INTERVAL

Uniswap TWAP3 interval duration.

int256 internal immutable _UNI_TWAP3_INTERVAL;

_UNI_TWAP4_INTERVAL

Uniswap TWAP4 interval duration.

int256 internal immutable _UNI_TWAP4_INTERVAL;

_SECONDS_AGOS_LENGTH

stored array lengths to optimize gas

uint256 internal constant _SECONDS_AGOS_LENGTH = 5;

_TWAP_DELTAS_LENGTH

uint256 internal constant _TWAP_DELTAS_LENGTH = 3;

_UNIV3_PRICE_SCALER_MULTIPLIER

constant value for price scaling to reduce gas usage

uint256 internal immutable _UNIV3_PRICE_SCALER_MULTIPLIER;

_UNIV3_INVERT_PRICE_DIVIDEND

constant value for inverting price to reduce gas usage

uint256 internal immutable _UNIV3_INVERT_PRICE_DIVIDEND;

Functions

constructor

constructor sets the Uniswap V3 pool_ to check for the exchange rate and the invertRate_ flag. E.g. invertRate_ should be true if for the WETH/USDC pool it's expected that the oracle returns USDC per 1 WETH

constructor(UniV3ConstructorParams memory params_);

_getUniV3ExchangeRateUnsafe

Get the last exchange rate from the pool's last observed value without any checks

function _getUniV3ExchangeRateUnsafe() internal view returns (uint256 exchangeRateUnsafe_);

Returns

NameTypeDescription
exchangeRateUnsafe_uint256The exchange rate between the underlying asset and the peg asset in OracleUtils.RATE_OUTPUT_DECIMALS

_getUniV3ExchangeRate

Get the last exchange rate from the pool's last observed value, checked against TWAP deviations.

function _getUniV3ExchangeRate() internal view returns (uint256 exchangeRate_);

Returns

NameTypeDescription
exchangeRate_uint256The exchange rate between the underlying asset and the peg asset in OracleUtils.RATE_OUTPUT_DECIMALS If 0 then the fetching the price failed or a delta was invalid.

_isInvalidTWAPDelta

verifies that exchangeRate_ is within maxDelta_ for derived price from tickCumulativesDelta_ and interval_. returns true if delta is invalid

function _isInvalidTWAPDelta(uint256 exchangeRate_, int256 tickCumulativesDelta_, int256 interval_, uint256 maxDelta_)
    internal
    view
    returns (bool);

uniV3OracleData

returns all UniV3 oracle related data as utility for easy off-chain use / block explorer in a single view method

function uniV3OracleData()
    public
    view
    returns (
        IUniswapV3Pool uniV3Pool_,
        bool uniV3InvertRate_,
        uint32[] memory uniV3secondsAgos_,
        uint256[] memory uniV3TwapDeltas_,
        uint256 uniV3exchangeRateUnsafe_,
        uint256 uniV3exchangeRate_
    );

_getPriceFromSqrtPriceX96

Get the price from the sqrt price in OracleUtils.RATE_OUTPUT_DECIMALS (see https://blog.uniswap.org/uniswap-v3-math-primer)

function _getPriceFromSqrtPriceX96(uint160 sqrtPriceX96_) private view returns (uint256 priceX96_);

Parameters

NameTypeDescription
sqrtPriceX96_uint160The sqrt price to convert

_invertUniV3Price

Invert the price

function _invertUniV3Price(uint256 price_) private view returns (uint256 invertedPrice_);

Parameters

NameTypeDescription
price_uint256The price to invert

Returns

NameTypeDescription
invertedPrice_uint256The inverted price in OracleUtils.RATE_OUTPUT_DECIMALS

Structs

UniV3ConstructorParams

struct UniV3ConstructorParams {
    IUniswapV3Pool pool;
    bool invertRate;
    uint256[_TWAP_DELTAS_LENGTH] tWAPMaxDeltaPercents;
    uint32[_SECONDS_AGOS_LENGTH] secondsAgos;
}