Uniswap V2 Median
A medianizer using the Uniswap V2 TWAP oracle implementation
1. Summary
The UniswapConsecutiveSlotsPriceFeedMedianizer is integrated with Uniswap V2 in order to provide a price feed for one of the tokens in a pool. It is also connected to a converterFeed in order to get the fiat value of the price quoted by the pool.
2. Contract Variables & Functions
Variables
- defaultAmountIn- default amount of- targetTokenused when calculating the- denominationTokenoutput
- targetToken- the token which the contract calculates the- medianPricefor
- denominationToken- pair token for- targetToken
- uniswapPair- the address of the Uniswap V2 pair
- uniswapFactory- the address of the Uniswap V2 factory
- uniswapObservations[observation: UniswapObservation]- array of prices taken from the Uniswap pool and the timestamps associated with each of them
- converterPriceCumulative- the snapshot of the latest sum of prices fetched from the- converterFeedsince the contract has been deployed
- converterFeed- address of the contract that offers fiat price feeds for the- denominationToken
- converterFeedObservations[observation: ConverterFeedObservation]- array of fiat price feeds for the- denominationToken
- symbol- the symbol of the price feed offered by the contract
- granularity- how many price observations are stored for the- windowSize.As granularity increases from 1, more frequent updates are needed, but moving averages become more precise.
- lastUpdateTime- when the price feed was last updated
- updates- total number of updates up until now
- windowSize- the desired amount of time over which the moving average should be computed, e.g. 24 hours
- maxWindowSize- max window over which the moving average can be computed
- periodSize- this is redundant with- granularityand- windowSize, but stored for gas savings & informational purposes. It is the minimum amount of time that must pass between two updates.
- converterFeedScalingFactor- this is the denominator that correctly scales the- medianPriceaccording to how many decimals the- denominationTokenhas
- medianPrice- the latest- targetTokenmedian price
- validityFlag- flag that indicates whether the median is valid or not
- relayer- address of the contract that rewards others for updating the median
Modifiers
- isAuthorized**** - checks whether an address is part of- authorizedAddresses(and thus can call authed functions).
Functions
- modifyParameters- allows governance to modify parameters.
- timeElapsedSinceFirstObservation() public view returns (uint256)- returns the time passed since the first observation in the window.
- earliestObservationIndex() public view returns (uint256)- returns the index of the earliest observation in the window.
- getObservationListLength() public view returns (uint256, uint256)- get the observation list length
- uniswapComputeAmountOut(priceCumulativeStart: uint256,- priceCumulativeEnd: uint256,- timeElapsed: uint256,- amountIn: uint256) public pure returns (amountOut: uint256)- given the Uniswap V2 cumulative prices of the start and end of a period, and the length of the period, compute the average price in terms of how much amount out is received for the amount in.
- converterComputeAmountOut(amountIn: uint256) public view returns (amountOut: uint256)- calculate the price of an amount of tokens using the converter price feed. Used internally after the contract determines the amount of denomination tokens for- defaultAmountIntarget tokens.
- updateResult(feeReceiver: address)- update the- medianPriceand pay the- feeReceiverafterwards.
- read- gets a non-zero price or fails
- getResultWithValidity- gets the price and its validity
Events
- AddAuthorization- emitted when a new address becomes authorized. Contains:- account- the new authorized account
 
- RemoveAuthorization- emitted when an address is de-authorized. Contains:- account- the address that was de-authorized
 
- ModifyParameters**** - emitted when a parameter is updated
- UpdateResult- emitted when- updateResultis called. Contains:- medianPrice- the latest median price for- targetToken
- lastUpdateTime- the current timestamp
 
- FailedConverterFeedUpdate- emitted when the contract fails to pull a price from the- converterFeed. Contains:- reason- the failure reason
 
- FailedUniswapPairSync- emitted when the contract fails to sync the Uniswap V2 pool that it's connected to. Contains:- reason- the reason why the sync failed
 
3. Walkthrough
updateResult first tries to update the converterFeed and the Uniswap pool before it stores new observations and computes the latest median.
read will only return a result if the median is non-null, if updateResult has been successfully called at least granularity times, if the validityFlag is 1 and if timeElapsedSinceFirstObservation() <= maxWindowSize. getResultWithValidity will return the median price and its validity (determined using the same checks as read).
4. Gotchas
This oracle depends on a pinger call within a defined frequency. THe calls should be properly incentivised.
5. Failure Modes (Bounds on Operating Conditions & External Risk Factors)
Uniswap V2 is vulnerable to oracle manipulation attacks. A motivated attacker could push the price in the wrong direction and update the oracle. For TWAPs that is less of an issue (it would require multiple successful calls from an attacker).
Last updated
Was this helpful?
