S Price: $0.482156 (+3.45%)

Contract Diff Checker

Contract Name:
PoolOracle

Contract Source Code:

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// 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);

}

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// 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:

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// 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);

}

<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>

// 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):