Compatible with solidity ~0.8
Modified from uniswap v3 OracleLibrary.sol
Opinion: Uniswap has the propensity to make things pretty complicated and pushes much of that ambiguity off to the end devs, who want simple and quick solutions. When they approach the uniswap codebase, it makes it very difficult to adapt simple tasks into their project.
For instance, consider looking up the "last traded price" of a pool. It should be a trivial task but not for v3.
This contract is deployed on mainnet at 0xF3E834BE475Ad2ac1c4C7842073c9b62c9d91358, and it serves to allow a simple price lookup for this exact use case, nothing more.
To get started:
- complete .env by changing things in .env.example
- npm install
- review code in scripts/oracle.js
NOTE: In the oracle.js file, set deployed variable to true once you deploy the contract on a active network to save time/gas, or just use the contract already deployed on mainnet. (link above)
commands:
npx hardhat compile
npx hardhat run --network mainnet scripts/oracle.js
npx hardhat run --network hardhat scripts/oracle.js
npx hardhat run --network ropsten scripts/oracle.js
Remaining issues:
In other places, the underlying uniswap code identifies pools by using the "pool fee" as an index. In the case of the "OracleLibrary.sol", (this code directly copies) the pool fee isnt used at all to identify the pool.
In the enclosed javascript, the first contract call identifies a specific v3 pool by "pool address". In the second contract call, the exact pool is vaguely assumed by only supplying "token symbols".
function getQuoteAtTick() {
...
if (sqrtRatioX96 <= type(uint128).max) {
...
// this appears to be wrong.
quoteAmount = baseToken < quoteToken
? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192)
: FullMath.mulDiv(1 << 192, baseAmount, ratioX192);
} else {
...
}
}
My intention here was to make an easy method of looking up a price on a v3 pool, but there may be some issues regarding which pool the price is reading from when there are multiple pools of the same currency pair. Comments, critique, observations, bugs, complaints are all welcome.
To contribute something for my efforts, send ERC20's/NFTs/ETH to 0xEBE40BB6FAa9AC01B2eda5c3917Bc3Bb8Bb76437
A user friendly explanation of the oracle and how time based vwap is achieved Uniswap v3 TWAP Oracle Tooling and Deep Dive Pt. 1
About Ticks: Math nerds only. Not so user friendly. Uniswap v3 Features Explained in Depth