/ src / PriceOracle.sol
PriceOracle.sol
 1  // SPDX-License-Identifier: MIT
 2  pragma solidity ^0.7.6;
 3  
 4  import "@uniswap/v3-periphery/contracts/libraries/OracleLibrary.sol";
 5  import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
 6  
 7  contract PriceOracle {
 8      uint32 public constant TWAP_PERIOD = 180;
 9      address public constant WETH = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270;//0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
10      IUniswapV3Factory immutable factory = IUniswapV3Factory(0x1F98431c8aD98523631AE4a59f267346ea31F984);
11  
12      function getPriceInEth(address token, uint amount) external view returns (uint256) {
13          return getOracleQuote(token, _toUint128(amount), TWAP_PERIOD);
14      }
15  
16      function getOracleQuote(address token, uint128 amount, uint32 twapPeriod) private view returns (uint256) {
17          address uniswapV3Pool = getPool(token);
18  
19          (int24 arithmeticMeanTick,) = OracleLibrary.consult(uniswapV3Pool, twapPeriod);
20          return OracleLibrary.getQuoteAtTick(
21              arithmeticMeanTick,
22              amount, 
23              token,
24              WETH
25          );
26      }
27  
28      function _toUint128(uint256 amount) private pure returns (uint128 n) {
29          require(amount == (n = uint128(amount)));
30      }
31  
32      function getPool(address token) private view returns (address) {
33          address pool = factory.getPool(token, WETH, 500);
34          if (pool != address(0)) {
35              return pool;
36          }
37          pool = factory.getPool(token, WETH, 1000);
38          if (pool != address(0)) {
39              return pool;
40          }
41          pool = factory.getPool(token, WETH, 10000);
42          if (pool != address(0)) {
43              return pool;
44          }
45          revert("Pool is not found in Uniswap V3");
46      }
47  }