S Price: $0.450771 (-0.06%)
    /

    Contract Diff Checker

    Contract Name:
    PoolOracle

    Contract Source Code:

    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.26;
    
    interface IPool {
        error NOT_AUTHORIZED();
        error UNSTABLE_RATIO();
        /// @dev safe transfer failed
        error STF();
        error OVERFLOW();
        /// @dev skim disabled
        error SD();
        /// @dev insufficient liquidity minted
        error ILM();
        /// @dev insufficient liquidity burned
        error ILB();
        /// @dev insufficient output amount
        error IOA();
        /// @dev insufficient input amount
        error IIA();
        error IL();
        error IT();
        error K();
    
        event Mint(address indexed sender, uint256 amount0, uint256 amount1);
        event Burn(
            address indexed sender,
            uint256 amount0,
            uint256 amount1,
            address indexed to
        );
        event Swap(
            address indexed sender,
            uint256 amount0In,
            uint256 amount1In,
            uint256 amount0Out,
            uint256 amount1Out,
            address indexed to
        );
        event Sync(uint112 reserve0, uint112 reserve1);
    
        /// @notice Same as prices with with an additional window argument.
        ///         Window = 2 means 2 * 30min (or 1 hr) between observations
        /// @param tokenIn .
        /// @param amountIn .
        /// @param points .
        /// @param window .
        /// @return Array of TWAP prices
        function sample(
            address tokenIn,
            uint256 amountIn,
            uint256 points,
            uint256 window
        ) external view returns (uint256[] memory);
    
        function observations(uint256 index) external view returns (uint256 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative);
    
        function current(address tokenIn, uint256 amountIn) external view returns (uint256 amountOut);
    
        /// @notice Provides twap price with user configured granularity, up to the full window size
        /// @param tokenIn .
        /// @param amountIn .
        /// @param granularity .
        /// @return amountOut .
        function quote(address tokenIn, uint256 amountIn, uint256 granularity) external view returns (uint256 amountOut);
    
        /// @notice Get the number of observations recorded
        function observationLength() external view returns (uint256);
    
        /// @notice Address of token in the pool with the lower address value
        function token0() external view returns (address);
    
        /// @notice Address of token in the poool with the higher address value
        function token1() external view returns (address);
    
        /// @notice initialize the pool, called only once programatically
        function initialize(
            address _token0,
            address _token1,
            bool _stable
        ) external;
    
        /// @notice calculate the current reserves of the pool and their last 'seen' timestamp
        /// @return _reserve0 amount of token0 in reserves
        /// @return _reserve1 amount of token1 in reserves
        /// @return _blockTimestampLast the timestamp when the pool was last updated
        function getReserves()
        external
        view
        returns (
            uint112 _reserve0,
            uint112 _reserve1,
            uint32 _blockTimestampLast
        );
    
        /// @notice mint the pair tokens (LPs)
        /// @param to where to mint the LP tokens to
        /// @return liquidity amount of LP tokens to mint
        function mint(address to) external returns (uint256 liquidity);
    
        /// @notice burn the pair tokens (LPs)
        /// @param to where to send the underlying
        /// @return amount0 amount of amount0
        /// @return amount1 amount of amount1
        function burn(
            address to
        ) external returns (uint256 amount0, uint256 amount1);
    
        /// @notice direct swap through the pool
        function swap(
            uint256 amount0Out,
            uint256 amount1Out,
            address to,
            bytes calldata data
        ) external;
    
        /// @notice force balances to match reserves, can be used to harvest rebases from rebasing tokens or other external factors
        /// @param to where to send the excess tokens to
        function skim(address to) external;
    
        /// @notice force reserves to match balances, prevents skim excess if skim is enabled
        function sync() external;
    
        /// @notice set the pair fees contract address
        function setFeeRecipient(address _pairFees) external;
    
        /// @notice set the feesplit variable
        function setFeeSplit(uint256 _feeSplit) external;
    
        /// @notice sets the swap fee of the pair
        /// @dev max of 10_000 (10%)
        /// @param _fee the fee
        function setFee(uint256 _fee) external;
    
        /// @notice 'mint' the fees as LP tokens
        /// @dev this is used for protocol/voter fees
        function mintFee() external;
    
        /// @notice calculates the amount of tokens to receive post swap
        /// @param amountIn the token amount
        /// @param tokenIn the address of the token
        function getAmountOut(
            uint256 amountIn,
            address tokenIn
        ) external view returns (uint256 amountOut);
    
        /// @notice returns various metadata about the pair
        function metadata()
        external
        view
        returns (
            uint256 _decimals0,
            uint256 _decimals1,
            uint256 _reserve0,
            uint256 _reserve1,
            bool _stable,
            address _token0,
            address _token1
        );
    
        /// @notice returns the feeSplit of the pair
        function feeSplit() external view returns (uint256);
    
        /// @notice returns the fee of the pair
        function fee() external view returns (uint256);
    
        /// @notice returns the feeRecipient of the pair
        function feeRecipient() external view returns (address);
    
    }

    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.28;
    
    import "../interfaces/IPool.sol";
    
    /**
     * @title PoolOracle
     * @notice Provides TWAP price consultations for a liquidity pool (pair) using a new Pair implementation.
     * @dev This contract reads observations from the pool to compute a time-weighted average price (TWAP).
     * It also allows updating the pool state by calling sync.
     */
    contract PoolOracle {
        // The two tokens in the pair.
        address public token0;
        address public token1;
    
        // The liquidity pool (pair) from which the oracle reads price data.
        IPool public pair;
    
        /**
         * @notice Initializes the PoolOracle with the given pair.
         * @param _pair The liquidity pool contract.
         */
        constructor(IPool _pair) {
            pair = _pair;
            token0 = pair.token0();
            token1 = pair.token1();
    
            // Check that the pair has non-zero reserves.
            (uint256 reserve0, uint256 reserve1,) = pair.getReserves();
            require(reserve0 != 0 && reserve1 != 0, "PoolOracle: No reserves");
        }
    
        /**
         * @notice Updates the pool's internal state by calling sync.
         */
        function update() external {
            pair.sync();
        }
    
        /**
         * @notice Consults the oracle for a quote based on historical data.
         * @param _token The token address for which to get the quote (must be token0 or token1).
         * @param _amountIn The amount of input token.
         * @return amountOut The quoted output amount.
         * @dev Uses a granularity of 12 observations (e.g. 6 hours if each observation is 30min).
         */
        function consult(
            address _token,
            uint256 _amountIn
        ) external view returns (uint256 amountOut) {
            if (_token == token0 || _token == token1) {
                amountOut = _quote(_token, _amountIn, 12);
            } else {
                revert("PoolOracle: Invalid token");
            }
        }
    
        /**
         * @notice Returns the time-weighted average price (TWAP) for a given token.
         * @param _token The token address for which to get the TWAP (must be token0 or token1).
         * @param _amountIn The amount of input token.
         * @return amountOut The TWAP quoted output amount.
         * @dev Uses a granularity of 2 observations (e.g. 1 hour if each observation is 30min).
         */
        function twap(
            address _token,
            uint256 _amountIn
        ) external view returns (uint256 amountOut) {
            if (_token == token0 || _token == token1) {
                amountOut = _quote(_token, _amountIn, 2);
            } else {
                revert("PoolOracle: Invalid token");
            }
        }
    
        /**
         * @dev Internal function to obtain a price quote from the pool.
         * @param tokenIn The input token address.
         * @param amountIn The input token amount.
         * @param granularity The number of historical observations to use.
         * @return amountOut The quoted output amount.
         * @notice The granularity parameter effectively sets the time window for TWAP calculations.
         * For example, if each observation represents 30 minutes, a granularity of 12 gives a 6-hour window.
         */
        function _quote(
            address tokenIn,
            uint256 amountIn,
            uint256 granularity
        ) internal view returns (uint256 amountOut) {
            uint256 observationLength = pair.observationLength();
            require(granularity <= observationLength, "PoolOracle: Not enough observations");
    
            amountOut = pair.quote(tokenIn, amountIn, granularity);
        }
    }

    Contract Name:
    PoolOracle

    Contract Source Code:

    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.26;
    
    interface IPool {
        error NOT_AUTHORIZED();
        error UNSTABLE_RATIO();
        /// @dev safe transfer failed
        error STF();
        error OVERFLOW();
        /// @dev skim disabled
        error SD();
        /// @dev insufficient liquidity minted
        error ILM();
        /// @dev insufficient liquidity burned
        error ILB();
        /// @dev insufficient output amount
        error IOA();
        /// @dev insufficient input amount
        error IIA();
        error IL();
        error IT();
        error K();
    
        event Mint(address indexed sender, uint256 amount0, uint256 amount1);
        event Burn(
            address indexed sender,
            uint256 amount0,
            uint256 amount1,
            address indexed to
        );
        event Swap(
            address indexed sender,
            uint256 amount0In,
            uint256 amount1In,
            uint256 amount0Out,
            uint256 amount1Out,
            address indexed to
        );
        event Sync(uint112 reserve0, uint112 reserve1);
    
        /// @notice Same as prices with with an additional window argument.
        ///         Window = 2 means 2 * 30min (or 1 hr) between observations
        /// @param tokenIn .
        /// @param amountIn .
        /// @param points .
        /// @param window .
        /// @return Array of TWAP prices
        function sample(
            address tokenIn,
            uint256 amountIn,
            uint256 points,
            uint256 window
        ) external view returns (uint256[] memory);
    
        function observations(uint256 index) external view returns (uint256 timestamp, uint256 reserve0Cumulative, uint256 reserve1Cumulative);
    
        function current(address tokenIn, uint256 amountIn) external view returns (uint256 amountOut);
    
        /// @notice Provides twap price with user configured granularity, up to the full window size
        /// @param tokenIn .
        /// @param amountIn .
        /// @param granularity .
        /// @return amountOut .
        function quote(address tokenIn, uint256 amountIn, uint256 granularity) external view returns (uint256 amountOut);
    
        /// @notice Get the number of observations recorded
        function observationLength() external view returns (uint256);
    
        /// @notice Address of token in the pool with the lower address value
        function token0() external view returns (address);
    
        /// @notice Address of token in the poool with the higher address value
        function token1() external view returns (address);
    
        /// @notice initialize the pool, called only once programatically
        function initialize(
            address _token0,
            address _token1,
            bool _stable
        ) external;
    
        /// @notice calculate the current reserves of the pool and their last 'seen' timestamp
        /// @return _reserve0 amount of token0 in reserves
        /// @return _reserve1 amount of token1 in reserves
        /// @return _blockTimestampLast the timestamp when the pool was last updated
        function getReserves()
        external
        view
        returns (
            uint112 _reserve0,
            uint112 _reserve1,
            uint32 _blockTimestampLast
        );
    
        /// @notice mint the pair tokens (LPs)
        /// @param to where to mint the LP tokens to
        /// @return liquidity amount of LP tokens to mint
        function mint(address to) external returns (uint256 liquidity);
    
        /// @notice burn the pair tokens (LPs)
        /// @param to where to send the underlying
        /// @return amount0 amount of amount0
        /// @return amount1 amount of amount1
        function burn(
            address to
        ) external returns (uint256 amount0, uint256 amount1);
    
        /// @notice direct swap through the pool
        function swap(
            uint256 amount0Out,
            uint256 amount1Out,
            address to,
            bytes calldata data
        ) external;
    
        /// @notice force balances to match reserves, can be used to harvest rebases from rebasing tokens or other external factors
        /// @param to where to send the excess tokens to
        function skim(address to) external;
    
        /// @notice force reserves to match balances, prevents skim excess if skim is enabled
        function sync() external;
    
        /// @notice set the pair fees contract address
        function setFeeRecipient(address _pairFees) external;
    
        /// @notice set the feesplit variable
        function setFeeSplit(uint256 _feeSplit) external;
    
        /// @notice sets the swap fee of the pair
        /// @dev max of 10_000 (10%)
        /// @param _fee the fee
        function setFee(uint256 _fee) external;
    
        /// @notice 'mint' the fees as LP tokens
        /// @dev this is used for protocol/voter fees
        function mintFee() external;
    
        /// @notice calculates the amount of tokens to receive post swap
        /// @param amountIn the token amount
        /// @param tokenIn the address of the token
        function getAmountOut(
            uint256 amountIn,
            address tokenIn
        ) external view returns (uint256 amountOut);
    
        /// @notice returns various metadata about the pair
        function metadata()
        external
        view
        returns (
            uint256 _decimals0,
            uint256 _decimals1,
            uint256 _reserve0,
            uint256 _reserve1,
            bool _stable,
            address _token0,
            address _token1
        );
    
        /// @notice returns the feeSplit of the pair
        function feeSplit() external view returns (uint256);
    
        /// @notice returns the fee of the pair
        function fee() external view returns (uint256);
    
        /// @notice returns the feeRecipient of the pair
        function feeRecipient() external view returns (address);
    
    }

    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.28;
    
    import "../interfaces/IPool.sol";
    
    /**
     * @title PoolOracle
     * @notice Provides TWAP price consultations for a liquidity pool (pair) using a new Pair implementation.
     * @dev This contract reads observations from the pool to compute a time-weighted average price (TWAP).
     * It also allows updating the pool state by calling sync.
     */
    contract PoolOracle {
        // The two tokens in the pair.
        address public token0;
        address public token1;
    
        // The liquidity pool (pair) from which the oracle reads price data.
        IPool public pair;
    
        /**
         * @notice Initializes the PoolOracle with the given pair.
         * @param _pair The liquidity pool contract.
         */
        constructor(IPool _pair) {
            pair = _pair;
            token0 = pair.token0();
            token1 = pair.token1();
    
            // Check that the pair has non-zero reserves.
            (uint256 reserve0, uint256 reserve1,) = pair.getReserves();
            require(reserve0 != 0 && reserve1 != 0, "PoolOracle: No reserves");
        }
    
        /**
         * @notice Updates the pool's internal state by calling sync.
         */
        function update() external {
            pair.sync();
        }
    
        /**
         * @notice Consults the oracle for a quote based on historical data.
         * @param _token The token address for which to get the quote (must be token0 or token1).
         * @param _amountIn The amount of input token.
         * @return amountOut The quoted output amount.
         * @dev Uses a granularity of 12 observations (e.g. 6 hours if each observation is 30min).
         */
        function consult(
            address _token,
            uint256 _amountIn
        ) external view returns (uint256 amountOut) {
            if (_token == token0 || _token == token1) {
                amountOut = _quote(_token, _amountIn, 12);
            } else {
                revert("PoolOracle: Invalid token");
            }
        }
    
        /**
         * @notice Returns the time-weighted average price (TWAP) for a given token.
         * @param _token The token address for which to get the TWAP (must be token0 or token1).
         * @param _amountIn The amount of input token.
         * @return amountOut The TWAP quoted output amount.
         * @dev Uses a granularity of 2 observations (e.g. 1 hour if each observation is 30min).
         */
        function twap(
            address _token,
            uint256 _amountIn
        ) external view returns (uint256 amountOut) {
            if (_token == token0 || _token == token1) {
                amountOut = _quote(_token, _amountIn, 2);
            } else {
                revert("PoolOracle: Invalid token");
            }
        }
    
        /**
         * @dev Internal function to obtain a price quote from the pool.
         * @param tokenIn The input token address.
         * @param amountIn The input token amount.
         * @param granularity The number of historical observations to use.
         * @return amountOut The quoted output amount.
         * @notice The granularity parameter effectively sets the time window for TWAP calculations.
         * For example, if each observation represents 30 minutes, a granularity of 12 gives a 6-hour window.
         */
        function _quote(
            address tokenIn,
            uint256 amountIn,
            uint256 granularity
        ) internal view returns (uint256 amountOut) {
            uint256 observationLength = pair.observationLength();
            require(granularity <= observationLength, "PoolOracle: Not enough observations");
    
            amountOut = pair.quote(tokenIn, amountIn, granularity);
        }
    }

    Context size (optional):