Contract 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 1

Contract Overview

Balance:
0 HT

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f28Update93051692021-10-21 8:50:404 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0fUpdate93051672021-10-21 8:50:345 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x7267ac24c8089217ed1f0a32f862980a14f94f7b35201455f6375935ac088688Update93049962021-10-21 8:42:0113 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0000327211
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765aUpdate93049942021-10-21 8:41:5513 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc45Update93049922021-10-21 8:41:4913 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x948ee9c906340d9c3389859cd3e513a993fc992b6116dfe47706b1186bd0a6c8Update93049902021-10-21 8:41:4313 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xd54377099925ebaf38bdbcffa05f7706a49e8a6d8aa8db0ce6e63767042d5289Update93049882021-10-21 8:41:3713 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x4eef3d1e9b3cb8e0df161561d3e4346221f14e74d1e8fa150b1414847d6a6c1fUpdate93049862021-10-21 8:41:3114 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xfecd057462b656e7b09127b42343e641a3dd89df425044902bc7f97cead0c1baUpdate93049112021-10-21 8:37:4617 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xc1fee48a158a3439ac8e28d32aef7c5c8fe3e93614b31d86b4228c17b42082abUpdate93049092021-10-21 8:37:4017 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x62c06ea06f92f3125c054cc55d3b9b7f845b40597fb1ec9951adbfbf766fab88Update93048742021-10-21 8:35:5519 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xe2c50085c4b9d80c85dec513197aa77451cac161756456058a931782ff1865fbUpdate93048722021-10-21 8:35:4919 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x303381be02deabbaf4e404b3e097c7487fa864711199b844fa6c1897f5a0ab35Update93048702021-10-21 8:35:4319 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x3668f40b0d605c48edab793706129c6f766be4d19954fd19c2aa7c33b2c65da3Update93048682021-10-21 8:35:3719 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x2fd0a2371c6d26b0489ae3e7b7107dc89192da0c9ab2d562b3321bbe64b876e0Update93048662021-10-21 8:35:3120 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x83d64ebfd47333f253bcf0b003e92e95b23bd3c417128bafcb77ed3b47e49f44Update93046542021-10-21 8:24:5530 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x43f291531356125072506a53834ec52d8825b32d45902f4ea67c4b553ff2264dUpdate93046522021-10-21 8:24:4930 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x7418629de8a80e459f64c873e52e733f5c5c4e616f2523d429e81b60e793634cUpdate93046502021-10-21 8:24:4330 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x1d8576604b0c71c1c48090455ce35b477bae8e76b000b433b5905c20defd5320Update93046482021-10-21 8:24:3730 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x13c3921a1ea4e2cd496b35c9819be037bd535aa08075d56c027c48b1c32ea231Update93046462021-10-21 8:24:3131 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xab464c9be3ece06d9851ec1d289149e081699838cb4ed1e033b8dab0f0466989Update93045292021-10-21 8:18:4036 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x147d58279030003614b837aa07f3cf89632df07f6f2a59648aa2c377a4fb8976Update93045272021-10-21 8:18:3437 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xd1bdde4d0164d0da95c1f49aa13032a47b14c388c7dd5e10daf6997cb1ccc39cUpdate93043532021-10-21 8:09:5245 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0x9ee1a7e284aff8aeb174a66cff14f05e0a6fd7b4f2f6e73cefd3c4502597f2b5Update93043512021-10-21 8:09:4645 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
0xcc52ab0a17b7ad7d9a913d10bd7857c8206a1215439cdd81e68eee392ab93fa7Update93043502021-10-21 8:09:4345 mins ago0x4645fa30a44cdafe8720af826253e3ce2f80b2e1 IN  0x4e7ce9b08021fefe08be2a1b9c696d14492537aa0 HT0.0001174061
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f2893051692021-10-21 8:50:404 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xe65d4d4d74d5d7b65d3f80ba9bbfbc14223b88740 HT
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f2893051692021-10-21 8:50:404 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xe65d4d4d74d5d7b65d3f80ba9bbfbc14223b88740 HT
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f2893051692021-10-21 8:50:404 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xe65d4d4d74d5d7b65d3f80ba9bbfbc14223b88740 HT
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f2893051692021-10-21 8:50:404 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0x256d568fd09482c2cba33c365d9c9613d246479c351cb7a3c4a1f344ce691f2893051692021-10-21 8:50:404 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0f93051672021-10-21 8:50:345 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xd8f5e8d751eff7c35b2350b034f63164c9224fcd0 HT
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0f93051672021-10-21 8:50:345 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xd8f5e8d751eff7c35b2350b034f63164c9224fcd0 HT
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0f93051672021-10-21 8:50:345 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xd8f5e8d751eff7c35b2350b034f63164c9224fcd0 HT
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0f93051672021-10-21 8:50:345 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0xce7aaeb2dc497730efe2de0d12cedbf6375bdee0fd463399d15a553cdd4b2e0f93051672021-10-21 8:50:345 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0x7267ac24c8089217ed1f0a32f862980a14f94f7b35201455f6375935ac08868893049962021-10-21 8:42:0113 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765a93049942021-10-21 8:41:5513 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xb0ba2fbb13b416eaa89d3508588d4d9a1c58978b0 HT
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765a93049942021-10-21 8:41:5513 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xb0ba2fbb13b416eaa89d3508588d4d9a1c58978b0 HT
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765a93049942021-10-21 8:41:5513 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0xb0ba2fbb13b416eaa89d3508588d4d9a1c58978b0 HT
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765a93049942021-10-21 8:41:5513 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0x6b0e1bf8283999e9fcaaeb93968735afaf6263eb2e4236334189260a0024765a93049942021-10-21 8:41:5513 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc4593049922021-10-21 8:41:4913 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x6bed6dcaf41664baaf4b88b54eba21b018e7be530 HT
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc4593049922021-10-21 8:41:4913 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x6bed6dcaf41664baaf4b88b54eba21b018e7be530 HT
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc4593049922021-10-21 8:41:4913 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x6bed6dcaf41664baaf4b88b54eba21b018e7be530 HT
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc4593049922021-10-21 8:41:4913 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0xebfe8f0cbc06a2d79664bbf494da0a191c434fe02169991ded97c93e5b8adc4593049922021-10-21 8:41:4913 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
0x948ee9c906340d9c3389859cd3e513a993fc992b6116dfe47706b1186bd0a6c893049902021-10-21 8:41:4313 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x7e9eb0a9e9fb42d25d5eb66d010afefa9f1bfc2e0 HT
0x948ee9c906340d9c3389859cd3e513a993fc992b6116dfe47706b1186bd0a6c893049902021-10-21 8:41:4313 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x7e9eb0a9e9fb42d25d5eb66d010afefa9f1bfc2e0 HT
0x948ee9c906340d9c3389859cd3e513a993fc992b6116dfe47706b1186bd0a6c893049902021-10-21 8:41:4313 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x7e9eb0a9e9fb42d25d5eb66d010afefa9f1bfc2e0 HT
0x948ee9c906340d9c3389859cd3e513a993fc992b6116dfe47706b1186bd0a6c893049902021-10-21 8:41:4313 mins ago 0x4e7ce9b08021fefe08be2a1b9c696d14492537aa 0x05637380c0bcc83e7d54fcca6885b9fb58db10cd0 HT
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Oracle

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 3 : Oracle.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.6.6;

import "../interfaces/IHdexFactory.sol";
import "../interfaces/IHdexPair.sol";

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
}

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

library HdexOracleLibrary {
    using FixedPoint for *;

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

    // 排序token
    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        require(tokenA != tokenB, 'ORACLELIBRARY: IDENTICAL_ADDRESSES');
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), 'ORACLELIBRARY: ZERO_ADDRESS');
    }

    // 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 = IHdexPair(pair).price0CumulativeLast();
        price1Cumulative = IHdexPair(pair).price1CumulativeLast();

        // if time has elapsed since the last update on the pair, mock the accumulated price values
        // 获取当前交易对的reverse及timestamp
        (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IHdexPair(pair).getReserves();
        // 如果reverse发生过变化
        if (blockTimestampLast != blockTimestamp) {
            // subtraction overflow is desired
            // 时间间隔
            uint32 timeElapsed = blockTimestamp - blockTimestampLast;
            // addition overflow is desired
            // counterfactual
            // token0累计价格
            price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
            // counterfactual
            // token1累计价格
            price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
        }
    }
}

contract Oracle {
    using FixedPoint for *;
    using SafeMath for uint;

    event Update(address indexed pair, uint indexed timestamp, uint price0Cumulative, uint price1Cumulative);

    struct Observation {
        // 时间戳
        uint timestamp;
        // token0累计价格
        uint price0Cumulative;
        // token1累计价格
        uint price1Cumulative;
    }

    address public immutable factory;
    // 30分钟记录一次
    uint public constant CYCLE = 30 minutes;

    // mapping from pair address to a list of price observations of that pair
    // lp -> priceInfo
    mapping(address => Observation[]) public pairObservations;

    constructor(address factory_) public {
        factory = factory_;
    }

    
    // 更新累计价格
    function update(address tokenA, address tokenB) external {
        uint latestTimestamp = getLatestTimestamp(tokenA, tokenB);
        // 时间间隔
        uint timeElapsed = block.timestamp.sub(latestTimestamp);
        // 要求时间间隔大于30分钟
        require(timeElapsed >= CYCLE, 'ORACLE: PERIOD_NOT_ELAPSED');

        // 获取当前交易对累计价格
        address pair = IHdexFactory(factory).getPair(tokenA, tokenB);
        (uint price0Cumulative, uint price1Cumulative,) = HdexOracleLibrary.currentCumulativePrices(pair);
        // 获取价格信息
        Observation memory observation = Observation({
            timestamp: block.timestamp,
            price0Cumulative: price0Cumulative,
            price1Cumulative: price1Cumulative
        });
        pairObservations[pair].push(observation);
        emit Update(pair, block.timestamp, price0Cumulative, price1Cumulative);
    }

    
    // 获取最近一次记录的时间戳
    function getLatestTimestamp(address tokenA, address tokenB) public view returns (uint) {
        address pair = IHdexFactory(factory).getPair(tokenA, tokenB);
        require(pair != address(0), "ORACLE: PAIR_NOT_EXIST");
        uint256 len = getObservationLength(pair);
        if (len == 0) {
            return 0;
        }
        return pairObservations[pair][len - 1].timestamp;
    }

    
    // 获取记录长度
    function getObservationLength(address pair) public view returns (uint) {
        require(pair != address(0), "ORACLE: PAIR_CANT_BE_ZERO");
        return pairObservations[pair].length;
    }


    // 根据最近一次价格计算兑出量
    function computeAmountOut(
        uint priceCumulativeStart,
        uint priceCumulativeEnd,
        uint timeElapsed,
        uint amountIn
    ) private pure returns (uint amountOut) {
        // overflow is desired.
        // 获取平均价格
        FixedPoint.uq112x112 memory priceAverage = computeAveragePrice(priceCumulativeStart, priceCumulativeEnd, timeElapsed);
        // 兑出量 = 平均价格 * 兑入量
        amountOut = priceAverage.mul(amountIn).decode144();
    }

    
    // 计算平均价格
    function computeAveragePrice(
        uint priceCumulativeStart,
        uint priceCumulativeEnd,
        uint timeElapsed
    ) private pure returns (FixedPoint.uq112x112 memory priceAverage) {
        // 平均价格 =(结束累计价格 - 开始累计价格) / 时间间隔
        priceAverage = FixedPoint.uq112x112(
            uint224((priceCumulativeEnd - priceCumulativeStart) / timeElapsed)
        );
    }

    // 根据平均价计算兑换量
    function consultTwap(
        address tokenIn,
        uint amountIn,
        address tokenOut,
        uint interval
    ) public view returns (uint amountOut) {
        require(interval != 0, "ORACLE: INTERVAL_CANT_BE_ZERO");
        uint latestTimestamp = getLatestTimestamp(tokenIn, tokenOut);
        require(latestTimestamp > 0, "ORACLE: NOT_ENOUGH_OBSERVATION");

        // 最近一次记录价格
        address pair = IHdexFactory(factory).getPair(tokenIn, tokenOut);
        uint round = getObservationLength(pair).sub(1);

        if (latestTimestamp < block.timestamp.sub(interval) || round == 0) {
            return consult(tokenIn, amountIn, tokenOut);
        }

        // 当前价格
        (uint price0Cumulative, uint price1Cumulative,) = HdexOracleLibrary.currentCumulativePrices(pair);

        // 累计时间
        Observation memory observation;
        uint cumulativeTime;
        (address token0,) = HdexOracleLibrary.sortTokens(tokenIn, tokenOut);

        while(true) {
            round = round.sub(1);
            observation = pairObservations[pair][round];

            if (observation.timestamp <= block.timestamp.sub(interval) || round == 0) {
                cumulativeTime = block.timestamp.sub(observation.timestamp);
                break;
            }
        }

        if (token0 == tokenIn) {
            return computeAmountOut(observation.price0Cumulative, price0Cumulative, cumulativeTime, amountIn);
        } else {
            return computeAmountOut(observation.price1Cumulative, price1Cumulative, cumulativeTime, amountIn);
        }
    }

    
    // 计算兑换数量
    function consult(address tokenIn, uint amountIn, address tokenOut) public view returns (uint amountOut) {
        uint latestTimestamp = getLatestTimestamp(tokenIn, tokenOut);
        // 如果没有记录,则返回0
        if(latestTimestamp == uint(0)) {
            return uint(0);
        }
        // 计算当前时间戳与最近一次价格记录的时间差
        uint timeElapsed = block.timestamp.sub(latestTimestamp);
        address pair = IHdexFactory(factory).getPair(tokenIn, tokenOut);
        uint len = getObservationLength(pair);
        Observation memory observation = pairObservations[pair][len.sub(1)];
        (uint price0Cumulative, uint price1Cumulative,) = HdexOracleLibrary.currentCumulativePrices(pair);
        (address token0,) = HdexOracleLibrary.sortTokens(tokenIn, tokenOut);
        // 计算兑出量
        if (token0 == tokenIn) {
            return computeAmountOut(observation.price0Cumulative, price0Cumulative, timeElapsed, amountIn);
        } else {
            return computeAmountOut(observation.price1Cumulative, price1Cumulative, timeElapsed, amountIn);
        }
    }
}

File 2 of 3 : IHdexFactory.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

interface IHdexFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToRate() external view returns (uint256);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function recommendedPairs(uint) external view returns (address pair);
    function allRecommendedPairLength() external view returns(uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);
    function addRecommendedPair(address tokenA, address tokenB) external;
    function removeRecommendedPair(address tokenA, address tokenB) external;

    function setFeeTo(address) external;
    function setFeeToRate(uint256) external;
}

File 3 of 3 : IHdexPair.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

interface IHdexPair {
    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
{
  "evmVersion": "istanbul",
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"factory_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price0Cumulative","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price1Cumulative","type":"uint256"}],"name":"Update","type":"event"},{"inputs":[],"name":"CYCLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"consult","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"interval","type":"uint256"}],"name":"consultTwap","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getLatestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getObservationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"pairObservations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"price0Cumulative","type":"uint256"},{"internalType":"uint256","name":"price1Cumulative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405234801561001057600080fd5b5060405161114d38038061114d8339818101604052602081101561003357600080fd5b5051606081901b6001600160601b0319166080526001600160a01b03166110d261007b600039806102ed52806104ea5280610699528061090652806109ce52506110d26000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b68a5cf81161005b578063b68a5cf814610145578063bfcc8e421461016b578063c45a0155146101b5578063c640752d146101d957610088565b806339d8402b1461008d5780638820e2d1146100d95780638c86f1e4146101075780639e8d48d01461013d575b600080fd5b6100c7600480360360808110156100a357600080fd5b506001600160a01b0381358116916020810135916040820135169060600135610209565b60408051918252519081900360200190f35b6100c7600480360360408110156100ef57600080fd5b506001600160a01b03813581169160200135166104e5565b6100c76004803603606081101561011d57600080fd5b506001600160a01b03813581169160208101359160409091013516610663565b6100c7610846565b6100c76004803603602081101561015b57600080fd5b50356001600160a01b031661084c565b6101976004803603604081101561018157600080fd5b506001600160a01b0381351690602001356108c5565b60408051938452602084019290925282820152519081900360600190f35b6101bd610904565b604080516001600160a01b039092168252519081900360200190f35b610207600480360360408110156101ef57600080fd5b506001600160a01b0381358116916020013516610928565b005b60008161025d576040805162461bcd60e51b815260206004820152601d60248201527f4f5241434c453a20494e54455256414c5f43414e545f42455f5a45524f000000604482015290519081900360640190fd5b600061026986856104e5565b9050600081116102c0576040805162461bcd60e51b815260206004820152601e60248201527f4f5241434c453a204e4f545f454e4f5547485f4f42534552564154494f4e0000604482015290519081900360640190fd5b6040805163e6a4390560e01b81526001600160a01b038881166004830152868116602483015291516000927f0000000000000000000000000000000000000000000000000000000000000000169163e6a43905916044808301926020929190829003018186803b15801561033357600080fd5b505afa158015610347573d6000803e3d6000fd5b505050506040513d602081101561035d57600080fd5b50519050600061037d60016103718461084c565b9063ffffffff610b0116565b905061038f428663ffffffff610b0116565b83108061039a575080155b156103b4576103aa888888610663565b93505050506104dd565b6000806103c084610b59565b50915091506103cd611011565b6000806103da8d8c610d5a565b5090505b6103ef86600163ffffffff610b0116565b6001600160a01b03881660009081526020819052604090208054919750908790811061041757fe5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505092506104638a42610b0190919063ffffffff16565b8351111580610470575085155b1561048f57825161048890429063ffffffff610b0116565b9150610494565b6103de565b8c6001600160a01b0316816001600160a01b031614156104cd576104be836020015186848f610e38565b985050505050505050506104dd565b6104be836040015185848f610e38565b949350505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561057857600080fd5b505afa15801561058c573d6000803e3d6000fd5b505050506040513d60208110156105a257600080fd5b505190506001600160a01b038116610601576040805162461bcd60e51b815260206004820152601660248201527f4f5241434c453a20504149525f4e4f545f455849535400000000000000000000604482015290519081900360640190fd5b600061060c8261084c565b90508061061e5760009250505061065d565b6001600160a01b03821660009081526020819052604090208054600019830190811061064657fe5b906000526020600020906003020160000154925050505b92915050565b60008061067085846104e5565b90508061068157600091505061083f565b6000610693428363ffffffff610b0116565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390588876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561072757600080fd5b505afa15801561073b573d6000803e3d6000fd5b505050506040513d602081101561075157600080fd5b5051905060006107608261084c565b905061076a611011565b6001600160a01b038316600090815260208190526040902061079383600163ffffffff610b0116565b8154811061079d57fe5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505090506000806107e285610b59565b509150915060006107f38c8b610d5a565b5090508b6001600160a01b0316816001600160a01b0316141561082f57610820846020015184898e610e38565b9850505050505050505061083f565b610820846040015183898e610e38565b9392505050565b61070881565b60006001600160a01b0382166108a9576040805162461bcd60e51b815260206004820152601960248201527f4f5241434c453a20504149525f43414e545f42455f5a45524f00000000000000604482015290519081900360640190fd5b506001600160a01b031660009081526020819052604090205490565b600060205281600052604060002081815481106108de57fe5b600091825260209091206003909102018054600182015460029092015490935090915083565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061093483836104e5565b90506000610948428363ffffffff610b0116565b90506107088110156109a1576040805162461bcd60e51b815260206004820152601a60248201527f4f5241434c453a20504552494f445f4e4f545f454c4150534544000000000000604482015290519081900360640190fd5b6040805163e6a4390560e01b81526001600160a01b038681166004830152858116602483015291516000927f0000000000000000000000000000000000000000000000000000000000000000169163e6a43905916044808301926020929190829003018186803b158015610a1457600080fd5b505afa158015610a28573d6000803e3d6000fd5b505050506040513d6020811015610a3e57600080fd5b50519050600080610a4e83610b59565b5091509150610a5b611011565b50604080516060810182524280825260208083018681528385018681526001600160a01b03891660008181528085528781208054600181810183559183529186902088516003909302019182559351938101939093559051600290920191909155845187815291820186905284519394929390927f96ca5813fd6a7ce6930a4f31eb077b2cb8e92e497a52cc5d763773e80b6ec703928290030190a35050505050505050565b8082038281111561065d576040805162461bcd60e51b815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6000806000610b66610e85565b9050836001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b158015610ba157600080fd5b505afa158015610bb5573d6000803e3d6000fd5b505050506040513d6020811015610bcb57600080fd5b5051604080517f5a3d549300000000000000000000000000000000000000000000000000000000815290519194506001600160a01b03861691635a3d549391600480820192602092909190829003018186803b158015610c2a57600080fd5b505afa158015610c3e573d6000803e3d6000fd5b505050506040513d6020811015610c5457600080fd5b5051604080517f0902f1ac0000000000000000000000000000000000000000000000000000000081529051919350600091829182916001600160a01b03891691630902f1ac916004808301926060929190829003018186803b158015610cb957600080fd5b505afa158015610ccd573d6000803e3d6000fd5b505050506040513d6060811015610ce357600080fd5b5080516020820151604090920151909450909250905063ffffffff80821690851614610d505780840363ffffffff8116610d1d8486610e8f565b516001600160e01b031602969096019563ffffffff8116610d3e8585610e8f565b516001600160e01b0316029590950194505b5050509193909250565b600080826001600160a01b0316846001600160a01b03161415610dae5760405162461bcd60e51b81526004018080602001828103825260228152602001806110586022913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610610dce578284610dd1565b83835b90925090506001600160a01b038216610e31576040805162461bcd60e51b815260206004820152601b60248201527f4f5241434c454c4942524152593a205a45524f5f414444524553530000000000604482015290519081900360640190fd5b9250929050565b6000610e42611032565b610e4d868686610f58565b9050610e67610e62828563ffffffff610f8c16565b61100a565b71ffffffffffffffffffffffffffffffffffff169695505050505050565b63ffffffff421690565b610e97611032565b6000826dffffffffffffffffffffffffffff1611610efc576040805162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f000000000000000000604482015290519081900360640190fd5b6040805160208101909152806dffffffffffffffffffffffffffff84167bffffffffffffffffffffffffffff0000000000000000000000000000607087901b1681610f4357fe5b046001600160e01b0316815250905092915050565b610f60611032565b60405180602001604052808386860381610f7657fe5b046001600160e01b031681525090509392505050565b610f94611044565b6000821580610fba57505082516001600160e01b031682810290838281610fb757fe5b04145b610ff55760405162461bcd60e51b815260040180806020018281038252602381526020018061107a6023913960400191505060405180910390fd5b60408051602081019091529081529392505050565b5160701c90565b60405180606001604052806000815260200160008152602001600081525090565b60408051602081019091526000815290565b604051806020016040528060008152509056fe4f5241434c454c4942524152593a204944454e544943414c5f4144445245535345534669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552464c4f57a264697066735822122048c392eafb7d23cab6062b4909743ca8635bb2fbef29966b6d4f7b5ff6da67fe64736f6c6343000606003300000000000000000000000005637380c0bcc83e7d54fcca6885b9fb58db10cd

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000005637380c0bcc83e7d54fcca6885b9fb58db10cd
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000005637380c0bcc83e7d54fcca6885b9fb58db10cd


Block Transaction Gas Used Reward
Age Block Fee Address Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading