Last active
November 17, 2020 16:59
-
-
Save l3wi/0871d6f3b2f9a60845a5bcdaf179ba88 to your computer and use it in GitHub Desktop.
Off-chain Uniswap V2 TWAP calculator in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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!