From 221480114301744c99d86f9cc8f7e55ff4b24342 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Tue, 25 Aug 2026 17:12:00 +0200 Subject: [PATCH] feat(libraries): add oracle helper for twap consumers --- src/libraries/OracleLibrary.sol | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/libraries/OracleLibrary.sol diff --git a/src/libraries/OracleLibrary.sol b/src/libraries/OracleLibrary.sol new file mode 100644 index 0000000..c9bf526 --- /dev/null +++ b/src/libraries/OracleLibrary.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.36; + +import {IFluxClPool} from "../interfaces/IFluxClPool.sol"; +import {TickMath} from "./TickMath.sol"; +import {FullMath} from "./FullMath.sol"; + +/// @title Time weighted average tick and price quotes derived from pool observations. +library OracleLibrary { + function consult(address pool, uint32 secondsAgo) internal view returns (int24 arithmeticMeanTick) { + require(secondsAgo != 0, "OracleLibrary: PERIOD"); + + uint32[] memory secondsAgos = new uint32[](2); + secondsAgos[0] = secondsAgo; + secondsAgos[1] = 0; + + (int56[] memory tickCumulatives,) = IFluxClPool(pool).observe(secondsAgos); + int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; + + arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(secondsAgo))); + if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int56(uint56(secondsAgo)) != 0)) { + arithmeticMeanTick--; + } + } + + function getQuoteAtTick(int24 tick, uint128 baseAmount, address baseToken, address quoteToken) + internal + pure + returns (uint256 quoteAmount) + { + uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); + + if (sqrtRatioX96 <= type(uint128).max) { + uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96; + quoteAmount = baseToken < quoteToken + ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192) + : FullMath.mulDiv(1 << 192, baseAmount, ratioX192); + } else { + uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64); + quoteAmount = baseToken < quoteToken + ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128) + : FullMath.mulDiv(1 << 128, baseAmount, ratioX128); + } + } +}