FRAX Price: $0.83 (+1.63%)

Contract

0xDB1bb99c6Ea20EAB2F2082b16F209fEF2e74e171

Overview

FRAX Balance | FXTL Balance

0 FRAX | 2,138 FXTL

FRAX Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

> 10 Internal Transactions and > 10 Token Transfers found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138962592024-12-19 10:13:49402 days ago1734603229
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
138458632024-12-18 6:13:57404 days ago1734502437
0xDB1bb99c...F2e74e171
0 FRAX
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FraxswapOracle

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 1000 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// =========================== FraxswapOracle =========================
// ====================================================================
// Gets token0 and token1 prices from a Fraxswap pair

import { FixedPoint } from "./libraries/FixedPoint.sol";
import { UQ112x112 } from "./libraries/UQ112x112.sol";
import { IFraxswapPair } from "dev-fraxswap/src/contracts/core/interfaces/IFraxswapPair.sol";

contract FraxswapOracle {
    // TODO (@dennis): does this contract need to be tested?
    using UQ112x112 for uint224;
    using FixedPoint for *;

    /// @notice Gets the prices for token0 and token1 from a Fraxswap pool
    /// @param pool The LP contract
    /// @param period The minimum size of the period between observations, in seconds
    /// @param rounds 2 ^ rounds # of blocks to search
    /// @param maxDiffPerc Max price change from last value
    /// @return result0 The price for token0
    /// @return result1 The price for token1
    function getPrice(
        IFraxswapPair pool,
        uint256 period,
        uint256 rounds,
        uint256 maxDiffPerc
    ) public view returns (uint256 result0, uint256 result1) {
        uint256 lastObservationIndex = pool.getTWAPHistoryLength() - 1;
        IFraxswapPair.TWAPObservation memory lastObservation = pool.TWAPObservationHistory(lastObservationIndex);

        // Update last observation up to the current block
        if (lastObservation.timestamp < block.timestamp) {
            // Update the reserves
            (uint112 _reserve0, uint112 _reserve1, ) = pool.getReserves();

            // Get the latest observed prices
            uint256 timeElapsed = block.timestamp - lastObservation.timestamp;
            lastObservation.price0CumulativeLast += uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
            lastObservation.price1CumulativeLast += uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
            lastObservation.timestamp = block.timestamp;
        }

        // Search for an observation via binary search within the last 2^round number of observations
        IFraxswapPair.TWAPObservation memory foundObservation;
        uint256 step = 2 ** rounds;
        uint256 min = (lastObservationIndex + 2 > step) ? (lastObservationIndex + 2 - step) : 0;
        while (step > 1) {
            step = step >> 1; // divide by 2
            uint256 pos = min + step - 1;
            if (pos <= lastObservationIndex) {
                IFraxswapPair.TWAPObservation memory observation = pool.TWAPObservationHistory(pos);
                if (lastObservation.timestamp - observation.timestamp > period) {
                    foundObservation = observation;
                    min = pos + 1;
                }
            }
        }

        // Reverts when a matching period can not be found
        require(foundObservation.timestamp > 0, "Period too long");

        // Get the price results 1E34 based
        result0 = mulDecode(
            uint224(
                (lastObservation.price0CumulativeLast - foundObservation.price0CumulativeLast) /
                    (lastObservation.timestamp - foundObservation.timestamp)
            )
        );
        result1 = mulDecode(
            uint224(
                (lastObservation.price1CumulativeLast - foundObservation.price1CumulativeLast) /
                    (lastObservation.timestamp - foundObservation.timestamp)
            )
        );

        // Revert if the price changed too much
        uint256 checkResult0 = 1e68 / result1;
        uint256 diff = (checkResult0 > result0 ? checkResult0 - result0 : result0 - checkResult0);
        uint256 diffPerc = (diff * 10_000) / result0;
        if (diffPerc > maxDiffPerc) revert("Max diff");
    }

    /// @notice Gets the prices for token0 from a Fraxswap pool
    /// @param pool The LP contract
    /// @param period The minimum size of the period between observations, in seconds
    /// @param rounds 2 ^ rounds # of blocks to search
    /// @param maxDiffPerc Max price change from last value
    /// @return result0 The price for token0
    function getPrice0(
        IFraxswapPair pool,
        uint256 period,
        uint256 rounds,
        uint256 maxDiffPerc
    ) external view returns (uint256 result0) {
        (result0, ) = getPrice(pool, period, rounds, maxDiffPerc);
    }

    /// @notice Gets the price for token1 from a Fraxswap pool
    /// @param pool The LP contract
    /// @param period The minimum size of the period between observations, in seconds
    /// @param rounds 2 ^ rounds # of blocks to search
    /// @param maxDiffPerc Max price change from last value
    /// @return result1 The price for token1
    function getPrice1(
        IFraxswapPair pool,
        uint256 period,
        uint256 rounds,
        uint256 maxDiffPerc
    ) external view returns (uint256 result1) {
        (, result1) = getPrice(pool, period, rounds, maxDiffPerc);
    }

    // multiplies the uq112x112 with 1E34 without overflowing and then converting it to uint.
    function mulDecode(uint224 value) public pure returns (uint256 result) {
        if (value < type(uint224).max / 1e34) {
            result = FixedPoint.uq112x112(value).mul(1e34).decode144();
        } else if (value < type(uint224).max / 1e17) {
            result = uint256(FixedPoint.uq112x112(value).mul(1e17).decode144()) * 1e17;
        } else {
            result = uint256(FixedPoint.uq112x112(value).decode()) * 1e34;
        }
    }
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.0;

import { FullMath } from "./FullMath.sol";
import { BitMath } from "./BitMath.sol";
import { Math } from "dev-fraxswap/src/contracts/core/libraries/Math.sol";

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
library FixedPoint {
    // range: [0, 2**112 - 1]
    // resolution: 1 / 2**112
    struct uq112x112 {
        uint224 _x;
    }

    // range: [0, 2**144 - 1]
    // resolution: 1 / 2**112
    struct uq144x112 {
        uint256 _x;
    }

    uint8 public constant RESOLUTION = 112;
    uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112
    uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224
    uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)

    // encode a uint112 as a UQ112x112
    function encode(uint112 x) internal pure returns (uq112x112 memory) {
        return uq112x112(uint224(x) << RESOLUTION);
    }

    // encodes a uint144 as a UQ144x112
    function encode144(uint144 x) internal pure returns (uq144x112 memory) {
        return uq144x112(uint256(x) << RESOLUTION);
    }

    // decode a UQ112x112 into a uint112 by truncating after the radix point
    function decode(uq112x112 memory self) internal pure returns (uint112) {
        return uint112(self._x >> RESOLUTION);
    }

    // decode a UQ144x112 into a uint144 by truncating after the radix point
    function decode144(uq144x112 memory self) internal pure returns (uint144) {
        return uint144(self._x >> RESOLUTION);
    }

    // multiply a UQ112x112 by a uint, returning a UQ144x112
    // reverts on overflow
    function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) {
        uint256 z = 0;
        require(y == 0 || (z = self._x * y) / y == self._x, "FixedPoint::mul: overflow");
        return uq144x112(z);
    }

    // multiply a UQ112x112 by an int and decode, returning an int
    // reverts on overflow
    function muli(uq112x112 memory self, int256 y) internal pure returns (int256) {
        uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112);
        require(z < 2 ** 255, "FixedPoint::muli: overflow");
        return y < 0 ? -int256(z) : int256(z);
    }

    // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112
    // lossy
    function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        if (self._x == 0 || other._x == 0) {
            return uq112x112(0);
        }
        uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0
        uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112
        uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0
        uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112

        // partial products
        uint224 upper = uint224(upper_self) * upper_other; // * 2^0
        uint224 lower = uint224(lower_self) * lower_other; // * 2^-224
        uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112
        uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112

        // so the bit shift does not overflow
        require(upper <= type(uint112).max, "FixedPoint::muluq: upper overflow");

        // this cannot exceed 256 bits, all values are 224 bits
        uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION);

        // so the cast does not overflow
        require(sum <= type(uint224).max, "FixedPoint::muluq: sum overflow");

        return uq112x112(uint224(sum));
    }

    // divide a UQ112x112 by a UQ112x112, returning a UQ112x112
    function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        require(other._x > 0, "FixedPoint::divuq: division by zero");
        if (self._x == other._x) {
            return uq112x112(uint224(Q112));
        }
        if (self._x <= type(uint144).max) {
            uint256 value = (uint256(self._x) << RESOLUTION) / other._x;
            require(value <= type(uint224).max, "FixedPoint::divuq: overflow");
            return uq112x112(uint224(value));
        }

        uint256 result = FullMath.mulDiv(Q112, self._x, other._x);
        require(result <= type(uint224).max, "FixedPoint::divuq: overflow");
        return uq112x112(uint224(result));
    }

    // returns a UQ112x112 which represents the ratio of the numerator to the denominator
    // can be lossy
    function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, "FixedPoint::fraction: division by zero");
        if (numerator == 0) return FixedPoint.uq112x112(0);

        if (numerator <= type(uint144).max) {
            uint256 result = (numerator << RESOLUTION) / denominator;
            require(result <= type(uint224).max, "FixedPoint::fraction: overflow");
            return uq112x112(uint224(result));
        } else {
            uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
            require(result <= type(uint224).max, "FixedPoint::fraction: overflow");
            return uq112x112(uint224(result));
        }
    }

    // take the reciprocal of a UQ112x112
    // reverts on overflow
    // lossy
    function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        require(self._x != 0, "FixedPoint::reciprocal: reciprocal of zero");
        require(self._x != 1, "FixedPoint::reciprocal: overflow");
        return uq112x112(uint224(Q224 / self._x));
    }

    // square root of a UQ112x112
    // lossy between 0/1 and 40 bits
    function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        if (self._x <= type(uint144).max) {
            return uq112x112(uint224(Math.sqrt(uint256(self._x) << 112)));
        }

        uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
        safeShiftBits -= safeShiftBits % 2;
        return uq112x112(uint224(Math.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
    }
}

pragma solidity >=0.8.0;

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))

// range: [0, 2**112 - 1]
// resolution: 1 / 2**112

library UQ112x112 {
    uint224 constant Q112 = 2 ** 112;

    // encode a uint112 as a UQ112x112
    function encode(uint112 y) internal pure returns (uint224 z) {
        z = uint224(y) * Q112; // never overflows
    }

    // divide a UQ112x112 by a uint112, returning a UQ112x112
    function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
        z = x / uint224(y);
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import { IUniswapV2Pair } from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";

/// @dev Fraxswap LP Pair Interface
interface IFraxswapPair is IUniswapV2Pair {
    // TWAMM
    struct TWAPObservation {
        uint256 timestamp;
        uint256 price0CumulativeLast;
        uint256 price1CumulativeLast;
    }

    function TWAPObservationHistory(uint256 index) external view returns (TWAPObservation memory);

    event LongTermSwap0To1(address indexed addr, uint256 orderId, uint256 amount0In, uint256 numberOfTimeIntervals);
    event LongTermSwap1To0(address indexed addr, uint256 orderId, uint256 amount1In, uint256 numberOfTimeIntervals);
    event CancelLongTermOrder(
        address indexed addr,
        uint256 orderId,
        address sellToken,
        uint256 unsoldAmount,
        address buyToken,
        uint256 purchasedAmount
    );
    event WithdrawProceedsFromLongTermOrder(
        address indexed addr,
        uint256 orderId,
        address indexed proceedToken,
        uint256 proceeds,
        bool orderExpired
    );

    function fee() external view returns (uint256);

    function longTermSwapFrom0To1(uint256 amount0In, uint256 numberOfTimeIntervals) external returns (uint256 orderId);
    function longTermSwapFrom1To0(uint256 amount1In, uint256 numberOfTimeIntervals) external returns (uint256 orderId);
    function cancelLongTermSwap(uint256 orderId) external;
    function withdrawProceedsFromLongTermSwap(
        uint256 orderId
    ) external returns (bool is_expired, address rewardTkn, uint256 totalReward);
    function executeVirtualOrders(uint256 blockTimestamp) external;

    function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256);
    function getAmountIn(uint256 amountOut, address tokenOut) external view returns (uint256);

    function orderTimeInterval() external returns (uint256);
    function getTWAPHistoryLength() external view returns (uint256);
    function getTwammReserves()
        external
        view
        returns (
            uint112 _reserve0,
            uint112 _reserve1,
            uint32 _blockTimestampLast,
            uint112 _twammReserve0,
            uint112 _twammReserve1,
            uint256 _fee
        );
    function getReserveAfterTwamm(
        uint256 blockTimestamp
    )
        external
        view
        returns (
            uint112 _reserve0,
            uint112 _reserve1,
            uint256 lastVirtualOrderTimestamp,
            uint112 _twammReserve0,
            uint112 _twammReserve1
        );
    function getNextOrderID() external view returns (uint256);
    function getOrderIDsForUser(address user) external view returns (uint256[] memory);
    function getOrderIDsForUserLength(address user) external view returns (uint256);
    function twammUpToDate() external view returns (bool);
    function getTwammState()
        external
        view
        returns (
            uint256 token0Rate,
            uint256 token1Rate,
            uint256 lastVirtualOrderTimestamp,
            uint256 orderTimeInterval_rtn,
            uint256 rewardFactorPool0,
            uint256 rewardFactorPool1
        );
    function getTwammSalesRateEnding(
        uint256 _blockTimestamp
    ) external view returns (uint256 orderPool0SalesRateEnding, uint256 orderPool1SalesRateEnding);
    function getTwammRewardFactor(
        uint256 _blockTimestamp
    ) external view returns (uint256 rewardFactorPool0AtTimestamp, uint256 rewardFactorPool1AtTimestamp);
    function getTwammOrder(
        uint256 orderId
    )
        external
        view
        returns (
            uint256 id,
            uint256 creationTimestamp,
            uint256 expirationTimestamp,
            uint256 saleRate,
            address owner,
            address sellTokenAddr,
            address buyTokenAddr
        );
    function getTwammOrderProceedsView(
        uint256 orderId,
        uint256 blockTimestamp
    ) external view returns (bool orderExpired, uint256 totalReward);
    function getTwammOrderProceeds(uint256 orderId) external returns (bool orderExpired, uint256 totalReward);

    function togglePauseNewSwaps() external;
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Math library that facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision.
/// @author Adapted from https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/FullMath.sol.
/// @dev Handles "phantom overflow", i.e., allows multiplication and division where an intermediate value overflows 256 bits.
library FullMath {
    /// @notice Calculates floor(a×b÷denominator) with full precision - throws if result overflows an uint256 or denominator == 0.
    /// @param a The multiplicand.
    /// @param b The multiplier.
    /// @param denominator The divisor.
    /// @return result The 256-bit result.
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.
    function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = a * b.
            // Compute the product mod 2**256 and mod 2**256 - 1,
            // then use the Chinese Remainder Theorem to reconstruct
            // the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2**256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product.
            uint256 prod1; // Most significant 256 bits of the product.
            assembly {
                let mm := mulmod(a, b, not(0))
                prod0 := mul(a, b)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }
            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                require(denominator > 0);
                assembly {
                    result := div(prod0, denominator)
                }
                return result;
            }
            // Make sure the result is less than 2**256 -
            // also prevents denominator == 0.
            require(denominator > prod1);
            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////
            // Make division exact by subtracting the remainder from [prod1 prod0] -
            // compute remainder using mulmod.
            uint256 remainder;
            assembly {
                remainder := mulmod(a, b, denominator)
            }
            // Subtract 256 bit number from 512 bit number.
            assembly {
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }
            // Factor powers of two out of denominator -
            // compute largest power of two divisor of denominator
            // (always >= 1).
            uint256 twos = uint256(-int256(denominator)) & denominator;
            // Divide denominator by power of two.
            assembly {
                denominator := div(denominator, twos)
            }
            // Divide [prod1 prod0] by the factors of two.
            assembly {
                prod0 := div(prod0, twos)
            }
            // Shift in bits from prod1 into prod0. For this we need
            // to flip `twos` such that it is 2**256 / twos -
            // if twos is zero, then it becomes one.
            assembly {
                twos := add(div(sub(0, twos), twos), 1)
            }
            prod0 |= prod1 * twos;
            // Invert denominator mod 2**256 -
            // now that denominator is an odd number, it has an inverse
            // modulo 2**256 such that denominator * inv = 1 mod 2**256.
            // Compute the inverse by starting with a seed that is correct
            // for four bits. That is, denominator * inv = 1 mod 2**4.
            uint256 inv = (3 * denominator) ^ 2;
            // Now use Newton-Raphson iteration to improve the precision.
            // Thanks to Hensel's lifting lemma, this also works in modular
            // arithmetic, doubling the correct bits in each step.
            inv *= 2 - denominator * inv; // Inverse mod 2**8.
            inv *= 2 - denominator * inv; // Inverse mod 2**16.
            inv *= 2 - denominator * inv; // Inverse mod 2**32.
            inv *= 2 - denominator * inv; // Inverse mod 2**64.
            inv *= 2 - denominator * inv; // Inverse mod 2**128.
            inv *= 2 - denominator * inv; // Inverse mod 2**256.
            // Because the division is now exact we can divide by multiplying
            // with the modular inverse of denominator. This will give us the
            // correct result modulo 2**256. Since the precoditions guarantee
            // that the outcome is less than 2**256, this is the final result.
            // We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inv;
            return result;
        }
    }

    /// @notice Calculates ceil(a×b÷denominator) with full precision - throws if result overflows an uint256 or denominator == 0.
    /// @param a The multiplicand.
    /// @param b The multiplier.
    /// @param denominator The divisor.
    /// @return result The 256-bit result.
    function mulDivRoundingUp(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {
        result = mulDiv(a, b, denominator);
        unchecked {
            if (mulmod(a, b, denominator) != 0) {
                require(result < type(uint256).max);
                result++;
            }
        }
    }
}

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.0;

library BitMath {
    // returns the 0 indexed position of the most significant bit of the input x
    // s.t. x >= 2**msb and x < 2**(msb+1)
    function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::mostSignificantBit: zero");

        if (x >= 0x100000000000000000000000000000000) {
            x >>= 128;
            r += 128;
        }
        if (x >= 0x10000000000000000) {
            x >>= 64;
            r += 64;
        }
        if (x >= 0x100000000) {
            x >>= 32;
            r += 32;
        }
        if (x >= 0x10000) {
            x >>= 16;
            r += 16;
        }
        if (x >= 0x100) {
            x >>= 8;
            r += 8;
        }
        if (x >= 0x10) {
            x >>= 4;
            r += 4;
        }
        if (x >= 0x4) {
            x >>= 2;
            r += 2;
        }
        if (x >= 0x2) r += 1;
    }

    // returns the 0 indexed position of the least significant bit of the input x
    // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0)
    // i.e. the bit at the index is set and the mask of all lower bits is 0
    function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::leastSignificantBit: zero");

        r = 255;
        if (x & type(uint128).max > 0) {
            r -= 128;
        } else {
            x >>= 128;
        }
        if (x & type(uint64).max > 0) {
            r -= 64;
        } else {
            x >>= 64;
        }
        if (x & type(uint32).max > 0) {
            r -= 32;
        } else {
            x >>= 32;
        }
        if (x & type(uint16).max > 0) {
            r -= 16;
        } else {
            x >>= 16;
        }
        if (x & type(uint8).max > 0) {
            r -= 8;
        } else {
            x >>= 8;
        }
        if (x & 0xf > 0) {
            r -= 4;
        } else {
            x >>= 4;
        }
        if (x & 0x3 > 0) {
            r -= 2;
        } else {
            x >>= 2;
        }
        if (x & 0x1 > 0) r -= 1;
    }
}

// SPDX-Licence-Identifier: MIT
pragma solidity ^0.8.0;

// a library for performing various math operations

library Math {
    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x < y ? x : y;
    }

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
}

pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

Settings
{
  "remappings": [
    "frax-std/=node_modules/frax-standard-solidity/src/",
    "@prb/test/=node_modules/@prb/test/",
    "forge-std/=node_modules/forge-std/src/",
    "ds-test/=node_modules/ds-test/src/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@rari-capital/=node_modules/@rari-capital/",
    "@uniswap/=node_modules/@uniswap/",
    "dev-fraxswap/=node_modules/dev-fraxswap/",
    "frax-standard-solidity/=node_modules/frax-standard-solidity/",
    "solidity-bytes-utils/=node_modules/solidity-bytes-utils/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IFraxswapPair","name":"pool","type":"address"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"rounds","type":"uint256"},{"internalType":"uint256","name":"maxDiffPerc","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"result0","type":"uint256"},{"internalType":"uint256","name":"result1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IFraxswapPair","name":"pool","type":"address"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"rounds","type":"uint256"},{"internalType":"uint256","name":"maxDiffPerc","type":"uint256"}],"name":"getPrice0","outputs":[{"internalType":"uint256","name":"result0","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IFraxswapPair","name":"pool","type":"address"},{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"rounds","type":"uint256"},{"internalType":"uint256","name":"maxDiffPerc","type":"uint256"}],"name":"getPrice1","outputs":[{"internalType":"uint256","name":"result1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint224","name":"value","type":"uint224"}],"name":"mulDecode","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"pure","type":"function"}]

6080604052348015600f57600080fd5b50610b028061001f6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806336968ca4146100515780638f4bb32a1461007757806393e2ae7c1461009f5780639c59bc53146100b2575b600080fd5b61006461005f3660046107dc565b6100c5565b6040519081526020015b60405180910390f35b61008a6100853660046107dc565b6100dd565b6040805192835260208301919091520161006e565b6100646100ad3660046107dc565b610574565b6100646100c0366004610823565b61058c565b60006100d3858585856100dd565b9695505050505050565b60008060006001876001600160a01b0316637fa2ee6e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610122573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610146919061084c565b610150919061087b565b6040516313f39c1b60e11b8152600481018290529091506000906001600160a01b038916906327e7383690602401606060405180830381865afa15801561019b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101bf919061088e565b905042816000015110156102c957600080896001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561020e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610916565b5084519193509150600090610247904261087b565b90508061026684610257856106f0565b6001600160e01b03169061071b565b6001600160e01b03166102799190610966565b8460200181815161028a919061097d565b9052508061029b83610257866106f0565b6001600160e01b03166102ae9190610966565b846040018181516102bf919061097d565b9052505042835250505b6102ed60405180606001604052806000815260200160008152602001600081525090565b60006102fa886002610a74565b905060008161030a86600261097d565b1161031657600061032c565b8161032286600261097d565b61032c919061087b565b90505b60018211156103fc57600191821c9160009061034b848461097d565b610355919061087b565b90508581116103f6576040516313f39c1b60e11b8152600481018290526000906001600160a01b038e16906327e7383690602401606060405180830381865afa1580156103a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ca919061088e565b805187519192508d916103dd919061087b565b11156103f4579350836103f182600161097d565b92505b505b5061032f565b825161044f5760405162461bcd60e51b815260206004820152600f60248201527f506572696f6420746f6f206c6f6e67000000000000000000000000000000000060448201526064015b60405180910390fd5b8251845161047e916104609161087b565b84602001518660200151610474919061087b565b6100c09190610a96565b835185519198506104a791610493919061087b565b84604001518660400151610474919061087b565b955060006104d2877c03b58e88c75313ec9d329eaaa18fb92f75215b17100000000000000000610a96565b905060008882116104ec576104e7828a61087b565b6104f6565b6104f6898361087b565b905060008961050783612710610966565b6105119190610a96565b90508a8111156105635760405162461bcd60e51b815260206004820152600860248201527f4d617820646966660000000000000000000000000000000000000000000000006044820152606401610446565b505050505050505094509492505050565b6000610582858585856100dd565b5095945050505050565b60006105ae6e01ed09bead87c0378d8e64000000006001600160e01b03610aaa565b6001600160e01b0316826001600160e01b0316101561061c5760408051602081019091526001600160e01b0383168152610602906105fb906e01ed09bead87c0378d8e640000000061073e565b5160701c90565b71ffffffffffffffffffffffffffffffffffff1692915050565b61063567016345785d8a00006001600160e01b03610aaa565b6001600160e01b0316826001600160e01b031610156106a75760408051602081019091526001600160e01b038316815261067b906105fb9067016345785d8a000061073e565b6106a19071ffffffffffffffffffffffffffffffffffff1667016345785d8a0000610966565b92915050565b60408051602081019091526001600160e01b03831690526106a16dffffffffffffffffffffffffffff607084901c166e01ed09bead87c0378d8e6400000000610966565b919050565b60006106a16e0100000000000000000000000000006dffffffffffffffffffffffffffff8416610ad0565b60006107376dffffffffffffffffffffffffffff831684610aaa565b9392505050565b604080516020810190915260008152600082158061077b575083516001600160e01b03168361076d8183610966565b92506107799083610a96565b145b6107c75760405162461bcd60e51b815260206004820152601960248201527f4669786564506f696e743a3a6d756c3a206f766572666c6f77000000000000006044820152606401610446565b60408051602081019091529081529392505050565b600080600080608085870312156107f257600080fd5b84356001600160a01b038116811461080957600080fd5b966020860135965060408601359560600135945092505050565b60006020828403121561083557600080fd5b81356001600160e01b038116811461073757600080fd5b60006020828403121561085e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106a1576106a1610865565b6000606082840312156108a057600080fd5b6040516060810181811067ffffffffffffffff821117156108d157634e487b7160e01b600052604160045260246000fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b80516dffffffffffffffffffffffffffff811681146106eb57600080fd5b60008060006060848603121561092b57600080fd5b610934846108f8565b9250610942602085016108f8565b9150604084015163ffffffff8116811461095b57600080fd5b809150509250925092565b80820281158282048414176106a1576106a1610865565b808201808211156106a1576106a1610865565b600181815b808511156109cb5781600019048211156109b1576109b1610865565b808516156109be57918102915b93841c9390800290610995565b509250929050565b6000826109e2575060016106a1565b816109ef575060006106a1565b8160018114610a055760028114610a0f57610a2b565b60019150506106a1565b60ff841115610a2057610a20610865565b50506001821b6106a1565b5060208310610133831016604e8410600b8410161715610a4e575081810a6106a1565b610a588383610990565b8060001904821115610a6c57610a6c610865565b029392505050565b600061073783836109d3565b634e487b7160e01b600052601260045260246000fd5b600082610aa557610aa5610a80565b500490565b60006001600160e01b0380841680610ac457610ac4610a80565b92169190910492915050565b6001600160e01b03828116828216818102831692918115828504821417610af957610af9610865565b5050509291505056

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806336968ca4146100515780638f4bb32a1461007757806393e2ae7c1461009f5780639c59bc53146100b2575b600080fd5b61006461005f3660046107dc565b6100c5565b6040519081526020015b60405180910390f35b61008a6100853660046107dc565b6100dd565b6040805192835260208301919091520161006e565b6100646100ad3660046107dc565b610574565b6100646100c0366004610823565b61058c565b60006100d3858585856100dd565b9695505050505050565b60008060006001876001600160a01b0316637fa2ee6e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610122573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610146919061084c565b610150919061087b565b6040516313f39c1b60e11b8152600481018290529091506000906001600160a01b038916906327e7383690602401606060405180830381865afa15801561019b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101bf919061088e565b905042816000015110156102c957600080896001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561020e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610916565b5084519193509150600090610247904261087b565b90508061026684610257856106f0565b6001600160e01b03169061071b565b6001600160e01b03166102799190610966565b8460200181815161028a919061097d565b9052508061029b83610257866106f0565b6001600160e01b03166102ae9190610966565b846040018181516102bf919061097d565b9052505042835250505b6102ed60405180606001604052806000815260200160008152602001600081525090565b60006102fa886002610a74565b905060008161030a86600261097d565b1161031657600061032c565b8161032286600261097d565b61032c919061087b565b90505b60018211156103fc57600191821c9160009061034b848461097d565b610355919061087b565b90508581116103f6576040516313f39c1b60e11b8152600481018290526000906001600160a01b038e16906327e7383690602401606060405180830381865afa1580156103a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ca919061088e565b805187519192508d916103dd919061087b565b11156103f4579350836103f182600161097d565b92505b505b5061032f565b825161044f5760405162461bcd60e51b815260206004820152600f60248201527f506572696f6420746f6f206c6f6e67000000000000000000000000000000000060448201526064015b60405180910390fd5b8251845161047e916104609161087b565b84602001518660200151610474919061087b565b6100c09190610a96565b835185519198506104a791610493919061087b565b84604001518660400151610474919061087b565b955060006104d2877c03b58e88c75313ec9d329eaaa18fb92f75215b17100000000000000000610a96565b905060008882116104ec576104e7828a61087b565b6104f6565b6104f6898361087b565b905060008961050783612710610966565b6105119190610a96565b90508a8111156105635760405162461bcd60e51b815260206004820152600860248201527f4d617820646966660000000000000000000000000000000000000000000000006044820152606401610446565b505050505050505094509492505050565b6000610582858585856100dd565b5095945050505050565b60006105ae6e01ed09bead87c0378d8e64000000006001600160e01b03610aaa565b6001600160e01b0316826001600160e01b0316101561061c5760408051602081019091526001600160e01b0383168152610602906105fb906e01ed09bead87c0378d8e640000000061073e565b5160701c90565b71ffffffffffffffffffffffffffffffffffff1692915050565b61063567016345785d8a00006001600160e01b03610aaa565b6001600160e01b0316826001600160e01b031610156106a75760408051602081019091526001600160e01b038316815261067b906105fb9067016345785d8a000061073e565b6106a19071ffffffffffffffffffffffffffffffffffff1667016345785d8a0000610966565b92915050565b60408051602081019091526001600160e01b03831690526106a16dffffffffffffffffffffffffffff607084901c166e01ed09bead87c0378d8e6400000000610966565b919050565b60006106a16e0100000000000000000000000000006dffffffffffffffffffffffffffff8416610ad0565b60006107376dffffffffffffffffffffffffffff831684610aaa565b9392505050565b604080516020810190915260008152600082158061077b575083516001600160e01b03168361076d8183610966565b92506107799083610a96565b145b6107c75760405162461bcd60e51b815260206004820152601960248201527f4669786564506f696e743a3a6d756c3a206f766572666c6f77000000000000006044820152606401610446565b60408051602081019091529081529392505050565b600080600080608085870312156107f257600080fd5b84356001600160a01b038116811461080957600080fd5b966020860135965060408601359560600135945092505050565b60006020828403121561083557600080fd5b81356001600160e01b038116811461073757600080fd5b60006020828403121561085e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106a1576106a1610865565b6000606082840312156108a057600080fd5b6040516060810181811067ffffffffffffffff821117156108d157634e487b7160e01b600052604160045260246000fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b80516dffffffffffffffffffffffffffff811681146106eb57600080fd5b60008060006060848603121561092b57600080fd5b610934846108f8565b9250610942602085016108f8565b9150604084015163ffffffff8116811461095b57600080fd5b809150509250925092565b80820281158282048414176106a1576106a1610865565b808201808211156106a1576106a1610865565b600181815b808511156109cb5781600019048211156109b1576109b1610865565b808516156109be57918102915b93841c9390800290610995565b509250929050565b6000826109e2575060016106a1565b816109ef575060006106a1565b8160018114610a055760028114610a0f57610a2b565b60019150506106a1565b60ff841115610a2057610a20610865565b50506001821b6106a1565b5060208310610133831016604e8410600b8410161715610a4e575081810a6106a1565b610a588383610990565b8060001904821115610a6c57610a6c610865565b029392505050565b600061073783836109d3565b634e487b7160e01b600052601260045260246000fd5b600082610aa557610aa5610a80565b500490565b60006001600160e01b0380841680610ac457610ac4610a80565b92169190910492915050565b6001600160e01b03828116828216818102831692918115828504821417610af957610af9610865565b5050509291505056

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.