当前位置: 首页 > 工具软件 > Sol > 使用案例 >

UniswapV2OracleLirary.sol

锺离穆冉
2023-12-01
//规定版本
pragma solidity >=0.5.0;

//导入Pair接口
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
//导入浮点库,什么作用?
import '@uniswap/lib/contracts/libraries/FixedPoint.sol';

//一个记录着对计算平均价格的预言机提供了一些有帮助的方法的库
// library with helper methods for oracles that are concerned with computing average prices
library UniswapV2OracleLibrary {
    using FixedPoint for *;

    //辅助函数,返回当前区块时间,在uint32的范围内
    // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1]
    function currentBlockTimestamp() internal view returns (uint32) {
        return uint32(block.timestamp % 2 ** 32);
    }

    //产生一个积累的价格,使用(反事实的)去节省gas以及避免同时的呼叫
    // produces the cumulative price using counterfactuals to save gas and avoid a call to sync.
    //提交一个交易对,返回两个代币的累计价格、当前区块时间戳
    function currentCumulativePrices(
        address pair
    ) internal view returns (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) {
        //获取当前区块链时间戳
        blockTimestamp = currentBlockTimestamp();
        //获取交易对中代币的累计价格
        price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
        price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();

        //自pair最新一次更新之后,如果时间已经流过,仿制累计的价格数值
        // if time has elapsed since the last update on the pair, mock the accumulated price values
        //获取交易对的储备量、最新时间戳
        (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves();
        //若记录的最新时间戳与当前时间戳不一致
        if (blockTimestampLast != blockTimestamp) {
            //基础溢出已被考虑
            // subtraction overflow is desired
            //经过的时间 = 当前时间 - 上次更新时间
            uint32 timeElapsed = blockTimestamp - blockTimestampLast;
            //加法溢出已被考虑
            // addition overflow is desired
            //对价格进行累计,依旧不明白为什么要累计此值
            //fraction()用于提升除法精度,函数调用后返回的是一个结构体,
            //需要通过._x的方式获取其存储的值,在本合约下面附上FixedPoint.sol
            // counterfactual
            price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
            // counterfactual
            price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
        }
    }
}

//以下是FixedPoint.sol
pragma solidity >=0.4.0;

// 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 {
        uint _x;
    }

    uint8 private constant RESOLUTION = 112;

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

    // divide a UQ112x112 by a uint112, returning a UQ112x112
    function div(uq112x112 memory self, uint112 x) internal pure returns (uq112x112 memory) {
        require(x != 0, 'FixedPoint: DIV_BY_ZERO');
        return uq112x112(self._x / uint224(x));
    }

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

    // returns a UQ112x112 which represents the ratio of the numerator to the denominator
    // equivalent to encode(numerator).div(denominator)
    function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, "FixedPoint: DIV_BY_ZERO");
        return uq112x112((uint224(numerator) << RESOLUTION) / denominator);
    }

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

 

 类似资料:

相关阅读

相关文章

相关问答