S Price: $0.467463 (-8.09%)

Contract

0xcE4aB22d33B7F13c541e638acA27df1841eb6B6E

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
V3TwapUtilities

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 10 : V3TwapUtilities.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v3-core/contracts/libraries/FixedPoint96.sol";
import "../interfaces/IERC20Metadata.sol";
import "../interfaces/IUniswapV3Pool.sol";
import "../interfaces/IV3TwapUtilities.sol";
import "../libraries/FullMath.sol";
import "../libraries/PoolAddress.sol";
import "../libraries/TickMath.sol";

contract V3TwapUtilities is IV3TwapUtilities, Ownable {
    uint32 constant INTERVAL = 10 minutes;

    constructor() Ownable(_msgSender()) {}

    function getV3Pool(address _v3Factory, address _t0, address _t1, uint24 _poolFee)
        external
        pure
        override
        returns (address)
    {
        (address _token0, address _token1) = _t0 < _t1 ? (_t0, _t1) : (_t1, _t0);
        PoolAddress.PoolKey memory _key = PoolAddress.PoolKey({token0: _token0, token1: _token1, fee: _poolFee});
        return PoolAddress.computeAddress(_v3Factory, _key);
    }

    function getV3Pool(address, address, address, int24) external pure override returns (address) {
        require(false, "I0");
        return address(0);
    }

    function getV3Pool(address, address, address) external pure override returns (address) {
        require(false, "I1");
        return address(0);
    }

    function getPoolPriceUSDX96(address _pricePool, address _nativeStablePool, address _WETH9)
        public
        view
        override
        returns (uint256)
    {
        address _token0 = IUniswapV3Pool(_nativeStablePool).token0();
        uint256 _priceStableWETH9X96 = _adjustedPriceX96(
            IUniswapV3Pool(_nativeStablePool), _token0 == _WETH9 ? IUniswapV3Pool(_nativeStablePool).token1() : _token0
        );
        if (_pricePool == _nativeStablePool) {
            return _priceStableWETH9X96;
        }
        uint256 _priceMainX96 = _adjustedPriceX96(IUniswapV3Pool(_pricePool), _WETH9);
        return (_priceStableWETH9X96 * _priceMainX96) / FixedPoint96.Q96;
    }

    function sqrtPriceX96FromPoolAndInterval(address _poolAddress)
        public
        view
        override
        returns (uint160 sqrtPriceX96)
    {
        sqrtPriceX96 = _sqrtPriceX96FromPoolAndInterval(_poolAddress, INTERVAL);
    }

    function sqrtPriceX96FromPoolAndPassedInterval(address _poolAddress, uint32 _interval)
        external
        view
        override
        returns (uint160 sqrtPriceX96)
    {
        sqrtPriceX96 = _sqrtPriceX96FromPoolAndInterval(_poolAddress, _interval);
    }

    function _sqrtPriceX96FromPoolAndInterval(address _poolAddress, uint32 _interval)
        internal
        view
        returns (uint160 _sqrtPriceX96)
    {
        IUniswapV3Pool _pool = IUniswapV3Pool(_poolAddress);
        if (_interval == 0) {
            (_sqrtPriceX96,,,,,,) = _pool.slot0();
        } else {
            uint32[] memory secondsAgo = new uint32[](2);
            secondsAgo[0] = _interval;
            secondsAgo[1] = 0;
            (int56[] memory tickCumulatives,) = _pool.observe(secondsAgo);
            int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];
            int24 arithmeticMeanTick = int24(tickCumulativesDelta / int32(_interval));
            // Always round to negative infinity
            if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int32(_interval) != 0)) arithmeticMeanTick--;
            _sqrtPriceX96 = TickMath.getSqrtRatioAtTick(arithmeticMeanTick);
        }
    }

    function priceX96FromSqrtPriceX96(uint160 sqrtPriceX96) public pure override returns (uint256 priceX96) {
        return FullMath.mulDiv(sqrtPriceX96, sqrtPriceX96, FixedPoint96.Q96);
    }

    function _adjustedPriceX96(IUniswapV3Pool _pool, address _numeratorToken) internal view returns (uint256) {
        address _token1 = _pool.token1();
        uint8 _decimals0 = IERC20Metadata(_pool.token0()).decimals();
        uint8 _decimals1 = IERC20Metadata(_token1).decimals();
        uint160 _sqrtPriceX96 = sqrtPriceX96FromPoolAndInterval(address(_pool));
        uint256 _priceX96 = priceX96FromSqrtPriceX96(_sqrtPriceX96);
        uint256 _ratioPriceX96 = _token1 == _numeratorToken ? _priceX96 : FixedPoint96.Q96 ** 2 / _priceX96;
        return _token1 == _numeratorToken
            ? (_ratioPriceX96 * 10 ** _decimals0) / 10 ** _decimals1
            : (_ratioPriceX96 * 10 ** _decimals1) / 10 ** _decimals0;
    }
}

File 2 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 10 : FixedPoint96.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.4.0;

/// @title FixedPoint96
/// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format)
/// @dev Used in SqrtPriceMath.sol
library FixedPoint96 {
    uint8 internal constant RESOLUTION = 96;
    uint256 internal constant Q96 = 0x1000000000000000000000000;
}

File 4 of 10 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface IERC20Metadata {
    function decimals() external view returns (uint8);
}

File 5 of 10 : IUniswapV3Pool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface IUniswapV3Pool {
    /// @notice The first of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token0() external view returns (address);

    /// @notice The second of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token1() external view returns (address);

    /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6
    /// @return The fee
    function fee() external view returns (uint24);

    /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp
    /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing
    /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,
    /// you must call it with secondsAgos = [3600, 0].
    /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in
    /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.
    /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned
    /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp
    /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block
    /// timestamp
    function observe(uint32[] calldata secondsAgos)
        external
        view
        returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);

    /// @notice The 0th storage slot in the pool stores many values, and is exposed as a single method to save gas
    /// when accessed externally.
    /// @return sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value
    /// tick The current tick of the pool, i.e. according to the last tick transition that was run.
    /// This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick
    /// boundary.
    /// observationIndex The index of the last oracle observation that was written,
    /// observationCardinality The current maximum number of observations stored in the pool,
    /// observationCardinalityNext The next maximum number of observations, to be updated when the observation.
    /// feeProtocol The protocol fee for both tokens of the pool.
    /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted 4 bits and the protocol fee of token0
    /// is the lower 4 bits. Used as the denominator of a fraction of the swap fee, e.g. 4 means 1/4th of the swap fee.
    /// unlocked Whether the pool is currently locked to reentrancy
    function slot0()
        external
        view
        returns (
            uint160 sqrtPriceX96,
            int24 tick,
            uint16 observationIndex,
            uint16 observationCardinality,
            uint16 observationCardinalityNext,
            uint8 feeProtocol,
            bool unlocked
        );
}

File 6 of 10 : IV3TwapUtilities.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface IV3TwapUtilities {
    function getV3Pool(address v3Factory, address token0, address token1) external view returns (address);

    function getV3Pool(address v3Factory, address token0, address token1, uint24 poolFee)
        external
        view
        returns (address);

    function getV3Pool(address v3Factory, address token0, address token1, int24 tickSpacing)
        external
        view
        returns (address);

    function getPoolPriceUSDX96(address pricePool, address nativeStablePool, address WETH9)
        external
        view
        returns (uint256);

    function sqrtPriceX96FromPoolAndInterval(address pool) external view returns (uint160);

    function sqrtPriceX96FromPoolAndPassedInterval(address pool, uint32 interval) external view returns (uint160);

    function priceX96FromSqrtPriceX96(uint160 sqrtPriceX96) external pure returns (uint256);
}

File 7 of 10 : FullMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// https://github.com/Uniswap/v3-core/blob/0.8/contracts/libraries/FullMath.sol

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @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 a 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 = (0 - 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
            // 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 a 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) {
        unchecked {
            result = mulDiv(a, b, denominator);
            if (mulmod(a, b, denominator) > 0) {
                require(result < type(uint256).max);
                result++;
            }
        }
    }
}

File 8 of 10 : PoolAddress.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee
library PoolAddress {
    bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;

    /// @notice The identifying key of the pool
    struct PoolKey {
        address token0;
        address token1;
        uint24 fee;
    }

    /// @notice Returns PoolKey: the ordered tokens with the matched fee levels
    /// @param tokenA The first token of a pool, unsorted
    /// @param tokenB The second token of a pool, unsorted
    /// @param fee The fee level of the pool
    /// @return Poolkey The pool details with ordered token0 and token1 assignments
    function getPoolKey(address tokenA, address tokenB, uint24 fee) internal pure returns (PoolKey memory) {
        if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
        return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
    }

    /// @notice Deterministically computes the pool address given the factory and PoolKey
    /// @param factory The Uniswap V3 factory contract address
    /// @param key The PoolKey
    /// @return pool The contract address of the V3 pool
    function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
        require(key.token0 < key.token1);
        pool = address(
            uint160(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            hex"ff",
                            factory,
                            keccak256(abi.encode(key.token0, key.token1, key.fee)),
                            POOL_INIT_CODE_HASH
                        )
                    )
                )
            )
        );
    }
}

File 9 of 10 : TickMath.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

// https://github.com/Uniswap/v3-core/blob/0.8/contracts/libraries/TickMath.sol

/// @title Math library for computing sqrt prices from ticks and vice versa
/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports
/// prices between 2**-128 and 2**128
library TickMath {
    error T();
    error R();

    /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128
    int24 internal constant MIN_TICK = -887272;
    /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128
    int24 internal constant MAX_TICK = -MIN_TICK;

    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)
    uint160 internal constant MIN_SQRT_RATIO = 4295128739;
    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)
    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;

    /// @notice Calculates sqrt(1.0001^tick) * 2^96
    /// @dev Throws if |tick| > max tick
    /// @param tick The input tick for the above formula
    /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)
    /// at the given tick
    function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
        unchecked {
            uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
            if (absTick > uint256(int256(MAX_TICK))) revert T();

            uint256 ratio =
                absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
            if (absTick & 0x2 != 0) {
                ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
            }
            if (absTick & 0x4 != 0) {
                ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
            }
            if (absTick & 0x8 != 0) {
                ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
            }
            if (absTick & 0x10 != 0) {
                ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
            }
            if (absTick & 0x20 != 0) {
                ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
            }
            if (absTick & 0x40 != 0) {
                ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
            }
            if (absTick & 0x80 != 0) {
                ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
            }
            if (absTick & 0x100 != 0) {
                ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
            }
            if (absTick & 0x200 != 0) {
                ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
            }
            if (absTick & 0x400 != 0) {
                ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
            }
            if (absTick & 0x800 != 0) {
                ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
            }
            if (absTick & 0x1000 != 0) {
                ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
            }
            if (absTick & 0x2000 != 0) {
                ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
            }
            if (absTick & 0x4000 != 0) {
                ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
            }
            if (absTick & 0x8000 != 0) {
                ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
            }
            if (absTick & 0x10000 != 0) {
                ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
            }
            if (absTick & 0x20000 != 0) {
                ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
            }
            if (absTick & 0x40000 != 0) {
                ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
            }
            if (absTick & 0x80000 != 0) {
                ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;
            }

            if (tick > 0) ratio = type(uint256).max / ratio;

            // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.
            // we then downcast because we know the result always fits within 160 bits due to our tick input constraint
            // we round up in the division so getTickAtSqrtRatio of the output price is always consistent
            sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
        }
    }

    /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio
    /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may
    /// ever return.
    /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96
    /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio
    function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {
        unchecked {
            // second inequality must be < because the price can never reach the price at the max tick
            if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) {
                revert R();
            }
            uint256 ratio = uint256(sqrtPriceX96) << 32;

            uint256 r = ratio;
            uint256 msb = 0;

            assembly {
                let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(5, gt(r, 0xFFFFFFFF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(4, gt(r, 0xFFFF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(3, gt(r, 0xFF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(2, gt(r, 0xF))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := shl(1, gt(r, 0x3))
                msb := or(msb, f)
                r := shr(f, r)
            }
            assembly {
                let f := gt(r, 0x1)
                msb := or(msb, f)
            }

            if (msb >= 128) r = ratio >> (msb - 127);
            else r = ratio << (127 - msb);

            int256 log_2 = (int256(msb) - 128) << 64;

            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(63, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(62, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(61, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(60, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(59, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(58, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(57, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(56, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(55, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(54, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(53, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(52, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(51, f))
                r := shr(f, r)
            }
            assembly {
                r := shr(127, mul(r, r))
                let f := shr(128, r)
                log_2 := or(log_2, shl(50, f))
            }

            int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number

            int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);
            int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);

            tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
        }
    }
}

File 10 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

Settings
{
  "remappings": [
    "@chainlink/=node_modules/@chainlink/",
    "@fraxlend/=test/invariant/modules/fraxlend/",
    "fuzzlib/=lib/fuzzlib/src/",
    "swap-router/=test/invariant/modules/v3-periphery/swapRouter/",
    "v3-core/=test/invariant/modules/v3-core/",
    "v3-periphery/=test/invariant/modules/v3-periphery/",
    "v2-core/=test/invariant/modules/uniswap-v2/v2-core/contracts/",
    "v2-periphery/=test/invariant/modules/uniswap-v2/v2-periphery/contracts/",
    "uniswap-v2/=test/invariant/modules/uniswap-v2/",
    "solidity-bytes-utils/contracts/=test/invariant/modules/fraxlend/libraries/",
    "@rari-capital/solmate/=node_modules/solmate/",
    "@arbitrum/=node_modules/@arbitrum/",
    "@ensdomains/=node_modules/@ensdomains/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "@ethereum-waffle/=node_modules/@ethereum-waffle/",
    "@mean-finance/=node_modules/@mean-finance/",
    "@offchainlabs/=node_modules/@offchainlabs/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@scroll-tech/=node_modules/@scroll-tech/",
    "@uniswap/=node_modules/@uniswap/",
    "@zksync/=node_modules/@zksync/",
    "base64-sol/=node_modules/base64-sol/",
    "ds-test/=lib/fuzzlib/lib/forge-std/lib/ds-test/src/",
    "erc721a/=node_modules/erc721a/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/forge-std/src/",
    "hardhat/=node_modules/hardhat/",
    "solidity-code-metrics/=node_modules/solidity-code-metrics/",
    "solmate/=node_modules/solmate/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"T","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"_pricePool","type":"address"},{"internalType":"address","name":"_nativeStablePool","type":"address"},{"internalType":"address","name":"_WETH9","type":"address"}],"name":"getPoolPriceUSDX96","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"int24","name":"","type":"int24"}],"name":"getV3Pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_v3Factory","type":"address"},{"internalType":"address","name":"_t0","type":"address"},{"internalType":"address","name":"_t1","type":"address"},{"internalType":"uint24","name":"_poolFee","type":"uint24"}],"name":"getV3Pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"getV3Pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"name":"priceX96FromSqrtPriceX96","outputs":[{"internalType":"uint256","name":"priceX96","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_poolAddress","type":"address"}],"name":"sqrtPriceX96FromPoolAndInterval","outputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_poolAddress","type":"address"},{"internalType":"uint32","name":"_interval","type":"uint32"}],"name":"sqrtPriceX96FromPoolAndPassedInterval","outputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052348015600f57600080fd5b503380603557604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b603c816041565b506091565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6114b0806100a06000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80638da5cb5b116100665780638da5cb5b14610116578063b5ed446314610127578063d4bf133414610148578063ddca45b01461015b578063f2fde38b1461016e57600080fd5b80630bbf9b68146100a35780632e33f332146100d35780634556bd20146100e6578063715018a6146100f95780637fb4f79d14610103575b600080fd5b6100b66100b1366004610e08565b610181565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b66100e1366004610e59565b610194565b6100b66100f4366004610eb5565b6101c9565b610101610241565b005b6100b6610111366004610f0e565b610255565b6000546001600160a01b03166100b6565b61013a610135366004610f2b565b610269565b6040519081526020016100ca565b61013a610156366004610f0e565b6103b2565b6100b6610169366004610f2b565b6103cc565b61010161017c366004610f0e565b6103fc565b600061018d838361043a565b9392505050565b60405162461bcd60e51b8152602060048201526002602482015261049360f41b60448201526000906064015b60405180910390fd5b6000806000846001600160a01b0316866001600160a01b0316106101ee5784866101f1565b85855b9150915060006040518060600160405280846001600160a01b03168152602001836001600160a01b031681526020018662ffffff168152509050610235888261064d565b98975050505050505050565b610249610736565b6102536000610763565b565b60006102638261025861043a565b92915050565b600080836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ce9190610f76565b9050600061035c85856001600160a01b0316846001600160a01b0316146102f557836107b3565b866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103579190610f76565b6107b3565b9050846001600160a01b0316866001600160a01b03160361038057915061018d9050565b600061038c87866107b3565b9050600160601b61039d8284610fa9565b6103a79190610fd6565b979650505050505050565b60006102636001600160a01b03831680600160601b610a1e565b60405162461bcd60e51b8152602060048201526002602482015261493160f01b60448201526000906064016101c0565b610404610736565b6001600160a01b03811661042e57604051631e4fbdf760e01b8152600060048201526024016101c0565b61043781610763565b50565b60008263ffffffff831682036104bb57806001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015610488573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ac9190611012565b50949650610646945050505050565b60408051600280825260608201835260009260208301908036833701905050905083816000815181106104f0576104f06110bc565b602002602001019063ffffffff16908163ffffffff168152505060008160018151811061051f5761051f6110bc565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b0384169063883bdbfd906105639085906004016110d2565b600060405180830381865afa158015610580573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a891908101906111e6565b5090506000816000815181106105c0576105c06110bc565b6020026020010151826001815181106105db576105db6110bc565b60200260200101516105ed91906112b9565b905060006105ff600388900b836112e6565b905060008260060b128015610623575061061d600388900b83611324565b60060b15155b15610636578061063281611346565b9150505b61063f81610ad0565b9550505050505b5092915050565b600081602001516001600160a01b031682600001516001600160a01b03161061067557600080fd5b815160208084015160408086015181516001600160a01b0395861681860152949092168482015262ffffff90911660608085019190915281518085038201815260808501909252815191909201206001600160f81b031960a08401529085901b6bffffffffffffffffffffffff191660a183015260b58201527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d582015260f50160408051601f1981840301815291905280516020909101209392505050565b6000546001600160a01b031633146102535760405163118cdaa760e01b81523360048201526024016101c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108189190610f76565b90506000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e9190610f76565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108df9190611369565b90506000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610921573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109459190611369565b9050600061095287610255565b9050600061095f826103b2565b90506000876001600160a01b0316866001600160a01b03161461099b578161098c6002600160601b61146b565b6109969190610fd6565b61099d565b815b9050876001600160a01b0316866001600160a01b0316146109e7576109c385600a61146b565b6109ce85600a61146b565b6109d89083610fa9565b6109e29190610fd6565b610a11565b6109f284600a61146b565b6109fd86600a61146b565b610a079083610fa9565b610a119190610fd6565b9998505050505050505050565b6000808060001985870985870292508281108382030391505080600003610a575760008411610a4c57600080fd5b50829004905061018d565b808411610a6357600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60008060008360020b12610ae7578260020b610aef565b8260020b6000035b9050620d89e8811115610b15576040516315e4079d60e11b815260040160405180910390fd5b600081600116600003610b2c57600160801b610b3e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610b72576ffff97272373d413259a46990580e213a0260801c5b6004821615610b91576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610bb0576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615610bcf576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615610bee576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615610c0d576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610c2c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610c4c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610c6c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610c8c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610cac576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610ccc576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610cec576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610d0c576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610d2c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610d4d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610d6d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610d8c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610da9576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610dca578060001981610dc657610dc6610fc0565b0490505b640100000000810615610dde576001610de1565b60005b60ff16602082901c0192505050919050565b6001600160a01b038116811461043757600080fd5b60008060408385031215610e1b57600080fd5b8235610e2681610df3565b9150602083013563ffffffff81168114610e3f57600080fd5b809150509250929050565b8060020b811461043757600080fd5b60008060008060808587031215610e6f57600080fd5b8435610e7a81610df3565b93506020850135610e8a81610df3565b92506040850135610e9a81610df3565b91506060850135610eaa81610e4a565b939692955090935050565b60008060008060808587031215610ecb57600080fd5b8435610ed681610df3565b93506020850135610ee681610df3565b92506040850135610ef681610df3565b9150606085013562ffffff81168114610eaa57600080fd5b600060208284031215610f2057600080fd5b813561018d81610df3565b600080600060608486031215610f4057600080fd5b8335610f4b81610df3565b92506020840135610f5b81610df3565b91506040840135610f6b81610df3565b809150509250925092565b600060208284031215610f8857600080fd5b815161018d81610df3565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761026357610263610f93565b634e487b7160e01b600052601260045260246000fd5b600082610fe557610fe5610fc0565b500490565b805161ffff81168114610ffc57600080fd5b919050565b805160ff81168114610ffc57600080fd5b600080600080600080600060e0888a03121561102d57600080fd5b875161103881610df3565b602089015190975061104981610e4a565b955061105760408901610fea565b945061106560608901610fea565b935061107360808901610fea565b925061108160a08901611001565b915060c0880151801515811461109657600080fd5b8091505092959891949750929550565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000918401906040840190835b8181101561111057835163ffffffff168352602093840193909201916001016110ec565b509095945050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611144576111446110a6565b604052919050565b600067ffffffffffffffff821115611166576111666110a6565b5060051b60200190565b600082601f83011261118157600080fd5b815161119461118f8261114c565b61111b565b8082825260208201915060208360051b8601019250858311156111b657600080fd5b602085015b838110156111dc5780516111ce81610df3565b8352602092830192016111bb565b5095945050505050565b600080604083850312156111f957600080fd5b825167ffffffffffffffff81111561121057600080fd5b8301601f8101851361122157600080fd5b805161122f61118f8261114c565b8082825260208201915060208360051b85010192508783111561125157600080fd5b6020840193505b828410156112825783518060060b811461127157600080fd5b825260209384019390910190611258565b80955050505050602083015167ffffffffffffffff8111156112a357600080fd5b6112af85828601611170565b9150509250929050565b600682810b9082900b03667fffffffffffff198112667fffffffffffff8213171561026357610263610f93565b60008160060b8360060b806112fd576112fd610fc0565b667fffffffffffff1982146000198214161561131b5761131b610f93565b90059392505050565b60008260060b8061133757611337610fc0565b808360060b0791505092915050565b60008160020b627fffff19810361135f5761135f610f93565b6000190192915050565b60006020828403121561137b57600080fd5b61018d82611001565b6001815b60018411156113bf578085048111156113a3576113a3610f93565b60018416156113b157908102905b60019390931c928002611388565b935093915050565b6000826113d657506001610263565b816113e357506000610263565b81600181146113f957600281146114035761141f565b6001915050610263565b60ff84111561141457611414610f93565b50506001821b610263565b5060208310610133831016604e8410600b8410161715611442575081810a610263565b61144f6000198484611384565b806000190482111561146357611463610f93565b029392505050565b600061018d60ff8416836113c756fea264697066735822122057eb3628fc425e80661974765cbc84b30b38bd454e8c61dc593d57adcbd66b4964736f6c634300081c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80638da5cb5b116100665780638da5cb5b14610116578063b5ed446314610127578063d4bf133414610148578063ddca45b01461015b578063f2fde38b1461016e57600080fd5b80630bbf9b68146100a35780632e33f332146100d35780634556bd20146100e6578063715018a6146100f95780637fb4f79d14610103575b600080fd5b6100b66100b1366004610e08565b610181565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b66100e1366004610e59565b610194565b6100b66100f4366004610eb5565b6101c9565b610101610241565b005b6100b6610111366004610f0e565b610255565b6000546001600160a01b03166100b6565b61013a610135366004610f2b565b610269565b6040519081526020016100ca565b61013a610156366004610f0e565b6103b2565b6100b6610169366004610f2b565b6103cc565b61010161017c366004610f0e565b6103fc565b600061018d838361043a565b9392505050565b60405162461bcd60e51b8152602060048201526002602482015261049360f41b60448201526000906064015b60405180910390fd5b6000806000846001600160a01b0316866001600160a01b0316106101ee5784866101f1565b85855b9150915060006040518060600160405280846001600160a01b03168152602001836001600160a01b031681526020018662ffffff168152509050610235888261064d565b98975050505050505050565b610249610736565b6102536000610763565b565b60006102638261025861043a565b92915050565b600080836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ce9190610f76565b9050600061035c85856001600160a01b0316846001600160a01b0316146102f557836107b3565b866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103579190610f76565b6107b3565b9050846001600160a01b0316866001600160a01b03160361038057915061018d9050565b600061038c87866107b3565b9050600160601b61039d8284610fa9565b6103a79190610fd6565b979650505050505050565b60006102636001600160a01b03831680600160601b610a1e565b60405162461bcd60e51b8152602060048201526002602482015261493160f01b60448201526000906064016101c0565b610404610736565b6001600160a01b03811661042e57604051631e4fbdf760e01b8152600060048201526024016101c0565b61043781610763565b50565b60008263ffffffff831682036104bb57806001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015610488573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ac9190611012565b50949650610646945050505050565b60408051600280825260608201835260009260208301908036833701905050905083816000815181106104f0576104f06110bc565b602002602001019063ffffffff16908163ffffffff168152505060008160018151811061051f5761051f6110bc565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b0384169063883bdbfd906105639085906004016110d2565b600060405180830381865afa158015610580573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a891908101906111e6565b5090506000816000815181106105c0576105c06110bc565b6020026020010151826001815181106105db576105db6110bc565b60200260200101516105ed91906112b9565b905060006105ff600388900b836112e6565b905060008260060b128015610623575061061d600388900b83611324565b60060b15155b15610636578061063281611346565b9150505b61063f81610ad0565b9550505050505b5092915050565b600081602001516001600160a01b031682600001516001600160a01b03161061067557600080fd5b815160208084015160408086015181516001600160a01b0395861681860152949092168482015262ffffff90911660608085019190915281518085038201815260808501909252815191909201206001600160f81b031960a08401529085901b6bffffffffffffffffffffffff191660a183015260b58201527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d582015260f50160408051601f1981840301815291905280516020909101209392505050565b6000546001600160a01b031633146102535760405163118cdaa760e01b81523360048201526024016101c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108189190610f76565b90506000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561085a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087e9190610f76565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108df9190611369565b90506000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610921573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109459190611369565b9050600061095287610255565b9050600061095f826103b2565b90506000876001600160a01b0316866001600160a01b03161461099b578161098c6002600160601b61146b565b6109969190610fd6565b61099d565b815b9050876001600160a01b0316866001600160a01b0316146109e7576109c385600a61146b565b6109ce85600a61146b565b6109d89083610fa9565b6109e29190610fd6565b610a11565b6109f284600a61146b565b6109fd86600a61146b565b610a079083610fa9565b610a119190610fd6565b9998505050505050505050565b6000808060001985870985870292508281108382030391505080600003610a575760008411610a4c57600080fd5b50829004905061018d565b808411610a6357600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60008060008360020b12610ae7578260020b610aef565b8260020b6000035b9050620d89e8811115610b15576040516315e4079d60e11b815260040160405180910390fd5b600081600116600003610b2c57600160801b610b3e565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615610b72576ffff97272373d413259a46990580e213a0260801c5b6004821615610b91576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615610bb0576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615610bcf576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615610bee576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615610c0d576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615610c2c576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615610c4c576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615610c6c576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615610c8c576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615610cac576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615610ccc576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615610cec576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615610d0c576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615610d2c576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615610d4d576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62020000821615610d6d576e5d6af8dedb81196699c329225ee6040260801c5b62040000821615610d8c576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615610da9576b048a170391f7dc42444e8fa20260801c5b60008460020b1315610dca578060001981610dc657610dc6610fc0565b0490505b640100000000810615610dde576001610de1565b60005b60ff16602082901c0192505050919050565b6001600160a01b038116811461043757600080fd5b60008060408385031215610e1b57600080fd5b8235610e2681610df3565b9150602083013563ffffffff81168114610e3f57600080fd5b809150509250929050565b8060020b811461043757600080fd5b60008060008060808587031215610e6f57600080fd5b8435610e7a81610df3565b93506020850135610e8a81610df3565b92506040850135610e9a81610df3565b91506060850135610eaa81610e4a565b939692955090935050565b60008060008060808587031215610ecb57600080fd5b8435610ed681610df3565b93506020850135610ee681610df3565b92506040850135610ef681610df3565b9150606085013562ffffff81168114610eaa57600080fd5b600060208284031215610f2057600080fd5b813561018d81610df3565b600080600060608486031215610f4057600080fd5b8335610f4b81610df3565b92506020840135610f5b81610df3565b91506040840135610f6b81610df3565b809150509250925092565b600060208284031215610f8857600080fd5b815161018d81610df3565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761026357610263610f93565b634e487b7160e01b600052601260045260246000fd5b600082610fe557610fe5610fc0565b500490565b805161ffff81168114610ffc57600080fd5b919050565b805160ff81168114610ffc57600080fd5b600080600080600080600060e0888a03121561102d57600080fd5b875161103881610df3565b602089015190975061104981610e4a565b955061105760408901610fea565b945061106560608901610fea565b935061107360808901610fea565b925061108160a08901611001565b915060c0880151801515811461109657600080fd5b8091505092959891949750929550565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000918401906040840190835b8181101561111057835163ffffffff168352602093840193909201916001016110ec565b509095945050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611144576111446110a6565b604052919050565b600067ffffffffffffffff821115611166576111666110a6565b5060051b60200190565b600082601f83011261118157600080fd5b815161119461118f8261114c565b61111b565b8082825260208201915060208360051b8601019250858311156111b657600080fd5b602085015b838110156111dc5780516111ce81610df3565b8352602092830192016111bb565b5095945050505050565b600080604083850312156111f957600080fd5b825167ffffffffffffffff81111561121057600080fd5b8301601f8101851361122157600080fd5b805161122f61118f8261114c565b8082825260208201915060208360051b85010192508783111561125157600080fd5b6020840193505b828410156112825783518060060b811461127157600080fd5b825260209384019390910190611258565b80955050505050602083015167ffffffffffffffff8111156112a357600080fd5b6112af85828601611170565b9150509250929050565b600682810b9082900b03667fffffffffffff198112667fffffffffffff8213171561026357610263610f93565b60008160060b8360060b806112fd576112fd610fc0565b667fffffffffffff1982146000198214161561131b5761131b610f93565b90059392505050565b60008260060b8061133757611337610fc0565b808360060b0791505092915050565b60008160020b627fffff19810361135f5761135f610f93565b6000190192915050565b60006020828403121561137b57600080fd5b61018d82611001565b6001815b60018411156113bf578085048111156113a3576113a3610f93565b60018416156113b157908102905b60019390931c928002611388565b935093915050565b6000826113d657506001610263565b816113e357506000610263565b81600181146113f957600281146114035761141f565b6001915050610263565b60ff84111561141457611414610f93565b50506001821b610263565b5060208310610133831016604e8410600b8410161715611442575081810a610263565b61144f6000198484611384565b806000190482111561146357611463610f93565b029392505050565b600061018d60ff8416836113c756fea264697066735822122057eb3628fc425e80661974765cbc84b30b38bd454e8c61dc593d57adcbd66b4964736f6c634300081c0033

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.