Created
October 21, 2020 09:50
-
-
Save l3wi/180fb770d57a9ca74d2a1a2f2f5b0044 to your computer and use it in GitHub Desktop.
🦄 Off-chain Uniswap V2 TWAP calculator.
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