Skip to content

Instantly share code, notes, and snippets.

@l3wi
Last active November 17, 2020 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save l3wi/0871d6f3b2f9a60845a5bcdaf179ba88 to your computer and use it in GitHub Desktop.
Save l3wi/0871d6f3b2f9a60845a5bcdaf179ba88 to your computer and use it in GitHub Desktop.
Off-chain Uniswap V2 TWAP calculator in Javascript
import { ethers } from 'ethers'
// To use this you need to read the Uniswap v2 contract for a pair/
// PRICE pulled from priceXCumulativeLast
// TIMESTAMPS pulled from _blockTimestampLast in getReserves()
// Mock Data
// In a real scenario you would fetch and store price & timestamp at an interval
// to mirror the contract calculating the TWAP on chain
const price0 = '529527205677379158060966860839'
const timestamp = '1603273219'
const oldPrice0 = '529504297305243109940199126701'
const oldTimestamp = '1603269588'
const calculateTwap = async () => {
// Convert Prices to BN
const price0CumulativeLast = ethers.BigNumber.from(oldPrice0)
let price0Cumulative = ethers.BigNumber.from(price0)
// Convert timestamps to BN
const latest = ethers.BigNumber.from(timestamp) // Current Uniswap contract timestamp
const blockTimestamp = latest.mod(ethers.BigNumber.from(2).pow(32))
const blockTimestampLast = ethers.BigNumber.from(oldTimestamp) // Saved Uniswap timestamp
// Sub the timestamps to get distance
const timeElapsed = blockTimestamp.sub(blockTimestampLast)
// If subbing timestamps equals 0: no new trades have happened so use the Spot Price
// Returning 0 here so it can be handled else where
if (timeElapsed.toNumber() === 0) return 0
// Do the TWAP calc
const price0Average = price0Cumulative
.sub(price0CumulativeLast)
.div(timeElapsed)
// Shifting the base to match the right numbers
// Adjust the number of 0s as necessary.
const targetRate = ethers.utils.parseEther('1000000000000')
const exchangeRate0 = price0Average
.mul(targetRate)
.div(ethers.BigNumber.from(2).pow(112))
// Returnthe Float of the TWAP
return parseFloat(ethers.utils.formatEther(exchangeRate0))
}
const main = async () => {
const twap = await calculateTwap()
console.log(twap)
}
main()
@l3wi
Copy link
Author

l3wi commented Oct 21, 2020

This code works in Javascript and should be easy to modify for different pairs.

Big thanks to @thegostep on the Uniswap discord for helping me out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment