Contract 0xb088ef2c9f01c4310be9b93a355313385a9bc27a

Contract Overview

Balance:
0 BNB
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x8ad5fb577205bd68b25e289bfc28e4887f768138da7150501cb73f9327247bf00x6080604080223612021-04-16 7:14:15161 days 7 mins ago0x20000b9b01e93a39db9d286e9264eff7f2af16e9 IN  Contract Creation0 BNB0.01156941
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xa6fd82dba78d20855184428b953ea15eb9d9ade5f53a2975b6de564196a964de87443282021-05-11 9:01:15135 days 22 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x1b97a6caf60a208e6e71478ec7392e55dbdc728ad7646dbaf302b87b0111161287443252021-05-11 9:01:06135 days 22 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xb65741503525896f2b62c1b01cf865217faa8416e8d57e5bbd828c8b81192ddf87443222021-05-11 9:00:57135 days 22 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x9df8ad9bb655eeee3d62931051dd142142d0d297c4129456c17ac417bd3d808187443202021-05-11 9:00:51135 days 22 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x86ba3919c88d0f819875f270f9e7af175c82dcf95834c93ae7cdbb3a3dd1d3a287443182021-05-11 9:00:45135 days 22 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x671344d12be9f7d0e697d38371a7f5d69b76c105c31769f1c0511bbedb3c43e787431272021-05-11 8:01:12135 days 23 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xa7f2f9f517395aa8bfa70fe8cbd5aceabf8f5a124f81e56ad12ed3fee6ef477487431252021-05-11 8:01:06135 days 23 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x69cc9593839768967273b3c2263263d3388668534060313a3aa9ffc6ab605fee87431232021-05-11 8:01:00135 days 23 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x8f5a45617c815807c8ba52af481b5a9ef98c0de873f7af54556535276d0613c887431202021-05-11 8:00:51135 days 23 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x5818dc86c5f2571c62b599aa6ccb967b933e099f88dc83e8edc84f64bbffa0ba87431182021-05-11 8:00:45135 days 23 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x84b168aa416de198817d4706c180e2fde6c47389b8a73f3f22bd546960fa694487419322021-05-11 7:01:27136 days 20 mins ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x34453f31456585ad038a09c37319b93c61aceec42dd08315ed2ab8574e9d480a87419302021-05-11 7:01:21136 days 20 mins ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xb5952ab9082d9f723e848580473c97e8c6b07af4655ff396fe06d5d8500414d987419262021-05-11 7:01:09136 days 20 mins ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x3fc1f62ec950248a2abb274af37ff65a285b8a57f6028dff7767e8f21a5a902387419222021-05-11 7:00:57136 days 20 mins ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xc9acb905539cf17a2869d2174b71d1a0a5554c69a44bcc6c0ff7cdcf7217718a87419192021-05-11 7:00:48136 days 20 mins ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xfd77835ae3e91c5e0faf6e67b4ac3d106a1c8eafa8d503e9c7b7306d3eb6f60a87407272021-05-11 6:01:12136 days 1 hr ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x0368897db12c3414b51f7bef33f41878f18c8c52758746d512e13c499b0b6fd187407252021-05-11 6:01:06136 days 1 hr ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x4fa7861a0dbbb42cf5f51970f92d2c38b2314ef2be116b231cba2d8dd933f6de87407222021-05-11 6:00:57136 days 1 hr ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x8e9ca324835f9b4dd69ddebad54a95a8dca9d69f8687063343c0edc6d416d01887407202021-05-11 6:00:51136 days 1 hr ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x2d7145e9191672d3e34c15f3585c292d9dfe488486393bc278f439945f39434d87407182021-05-11 6:00:45136 days 1 hr ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x611f45bd905f39ad1ecbfde3488048a1f203a394f3cee3bfadba2681f591d4f687395322021-05-11 5:01:27136 days 2 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0xdc9df1efd541f4b3cae38b923a07ca709521f3669cf0777fbed1482acc53169287395282021-05-11 5:01:15136 days 2 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x4652c9d256fe188e724b0e11060e299d234a151bf321d4569082fcc321f1e45d87395242021-05-11 5:01:03136 days 2 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x373741e101a64dc255b5897d2cc75f407b8e589709bdd8ef88a5a8f31c7a88b387395212021-05-11 5:00:54136 days 2 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
0x3f92f0766ded0fb91d1d3e70c340f1c07fb77a66be22eb997173363ccac50c8187395182021-05-11 5:00:45136 days 2 hrs ago 0xa5aeaeeedbe82e800b1ed8d02c10013b204a6f4c 0xb088ef2c9f01c4310be9b93a355313385a9bc27a0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BSCPriceFeed

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 9 : BSCPriceFeed.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.12;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "./interface/IBSCPriceFeed.sol";
import "./utils/Decimal.sol";

contract BSCPriceFeed is IBSCPriceFeed, OwnableUpgradeable {
    using SafeMathUpgradeable for uint256;
    using Decimal for Decimal.decimal;

    uint256 private constant TOKEN_DIGIT = 10**18;

    event AggregatorAdded(bytes32 currencyKey, address aggregator);
    event AggregatorRemoved(bytes32 currencyKey, address aggregator);

    // key by currency symbol, eg ETH
    mapping(bytes32 => AggregatorV3Interface) public priceFeedMap;
    bytes32[] public priceFeedKeys;

    //**********************************************************//
    //    Can not change the order of above state variables     //
    //**********************************************************//

    //◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤ add state variables below ◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤//

    //◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣ add state variables above ◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣//
    uint256[50] private __gap;

    //
    // FUNCTIONS
    //
    function initialize() public initializer {
        __Ownable_init();
    }

    function addAggregator(bytes32 _priceFeedKey, address _aggregator) external onlyOwner {
        requireNonEmptyAddress(_aggregator);
        if (address(priceFeedMap[_priceFeedKey]) == address(0)) {
            priceFeedKeys.push(_priceFeedKey);
        }
        priceFeedMap[_priceFeedKey] = AggregatorV3Interface(_aggregator);
        emit AggregatorAdded(_priceFeedKey, address(_aggregator));
    }

    function removeAggregator(bytes32 _priceFeedKey) external onlyOwner {
        address aggregator = address(priceFeedMap[_priceFeedKey]);
        requireNonEmptyAddress(aggregator);
        delete priceFeedMap[_priceFeedKey];

        uint256 length = priceFeedKeys.length;
        for (uint256 i; i < length; i++) {
            if (priceFeedKeys[i] == _priceFeedKey) {
                // if the removal item is the last one, just `pop`
                if (i != length - 1) {
                    priceFeedKeys[i] = priceFeedKeys[length - 1];
                }
                priceFeedKeys.pop();
                emit AggregatorRemoved(_priceFeedKey, aggregator);
                break;
            }
        }
    }

    function getAggregator(bytes32 _priceFeedKey) public view returns (AggregatorV3Interface) {
        return priceFeedMap[_priceFeedKey];
    }

    function getPrice(bytes32 _priceFeedKey) external view override returns (uint256) {
        require(isExistedKey(_priceFeedKey), "key not existed");
        AggregatorV3Interface aggregator = getAggregator(_priceFeedKey);

        (, int256 _price, , , ) = aggregator.latestRoundData();
        require(_price >= 0, "negative answer");
        uint8 decimals = aggregator.decimals();

        Decimal.decimal memory decimalPrice = Decimal.decimal(formatDecimals(uint256(_price), decimals));

        return decimalPrice.toUint();
    }

    function getLatestTimestamp(bytes32 _priceFeedKey) public view returns (uint256) {
        AggregatorV3Interface aggregator = getAggregator(_priceFeedKey);
        requireNonEmptyAddress(address(aggregator));

        (, , , uint256 timestamp, ) = aggregator.latestRoundData();

        return timestamp;
    }

    function getTwapPrice(bytes32 _priceFeedKey, uint256 _interval) external view override returns (uint256) {
        require(isExistedKey(_priceFeedKey), "key not existed");
        require(_interval != 0, "interval can't be 0");

        // ** We assume L1 and L2 timestamp will be very similar here **
        // 3 different timestamps, `previous`, `current`, `target`
        // `base` = now - _interval
        // `current` = current round timestamp from aggregator
        // `previous` = previous round timestamp form aggregator
        // now >= previous > current > = < base
        //
        //  while loop i = 0
        //  --+------+-----+-----+-----+-----+-----+
        //         base                 current  now(previous)
        //
        //  while loop i = 1
        //  --+------+-----+-----+-----+-----+-----+
        //         base           current previous now

        AggregatorV3Interface aggregator = getAggregator(_priceFeedKey);
        (uint80 roundId, int256 _price, , uint256 timestamp, ) = aggregator.latestRoundData();
        require(_price >= 0, "negative answer");
        uint8 decimals = aggregator.decimals();

        Decimal.decimal memory decimalPrice = Decimal.decimal(formatDecimals(uint256(_price), decimals));
        uint256 latestPrice = decimalPrice.toUint();

        require(roundId >= 0, "Not enough history");
        uint256 latestTimestamp = timestamp;
        uint256 baseTimestamp = block.timestamp.sub(_interval);
        // if latest updated timestamp is earlier than target timestamp, return the latest price.
        if (latestTimestamp < baseTimestamp || roundId == 0) {
            return latestPrice;
        }

        // rounds are like snapshots, latestRound means the latest price snapshot. follow chainlink naming
        uint256 cumulativeTime = block.timestamp.sub(latestTimestamp);
        uint256 previousTimestamp = latestTimestamp;
        uint256 weightedPrice = latestPrice.mul(cumulativeTime);
        while (true) {
            if (roundId == 0) {
                // if cumulative time is less than requested interval, return current twap price
                return weightedPrice.div(cumulativeTime);
            }

            roundId = roundId - 1;
            // get current round timestamp and price
            (, int256 _priceTemp, , uint256 currentTimestamp, ) = aggregator.getRoundData(roundId);
            require(_priceTemp >= 0, "negative answer");

            Decimal.decimal memory decimalPriceTemp = Decimal.decimal(formatDecimals(uint256(_priceTemp), decimals));
            uint256 price = decimalPriceTemp.toUint();

            // check if current round timestamp is earlier than target timestamp
            if (currentTimestamp <= baseTimestamp) {
                // weighted time period will be (target timestamp - previous timestamp). For example,
                // now is 1000, _interval is 100, then target timestamp is 900. If timestamp of current round is 970,
                // and timestamp of NEXT round is 880, then the weighted time period will be (970 - 900) = 70,
                // instead of (970 - 880)
                weightedPrice = weightedPrice.add(price.mul(previousTimestamp.sub(baseTimestamp)));
                break;
            }

            uint256 timeFraction = previousTimestamp.sub(currentTimestamp);
            weightedPrice = weightedPrice.add(price.mul(timeFraction));
            cumulativeTime = cumulativeTime.add(timeFraction);
            previousTimestamp = currentTimestamp;
        }
        return weightedPrice.div(_interval);
    }

    function isExistedKey(bytes32 _priceFeedKey) private view returns (bool) {
        uint256 length = priceFeedKeys.length;
        for (uint256 i; i < length; i++) {
            if (priceFeedKeys[i] == _priceFeedKey) {
                return true;
            }
        }
        return false;
    }

    function requireKeyExisted(bytes32 _key, bool _existed) private view {
        if (_existed) {
            require(isExistedKey(_key), "key not existed");
        } else {
            require(!isExistedKey(_key), "key existed");
        }
    }

    function requireNonEmptyAddress(address _addr) internal pure {
        require(_addr != address(0), "empty address");
    }

    function formatDecimals(uint256 _price, uint8 _decimals) internal pure returns (uint256) {
        return _price.mul(TOKEN_DIGIT).div(10**uint256(_decimals));
    }

    function getPriceFeedLength() public view returns (uint256 length) {
        return priceFeedKeys.length;
    }
}

File 2 of 9 : IBSCPriceFeed.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.12;

interface IBSCPriceFeed {
    // get latest price
    function getPrice(bytes32 _priceFeedKey) external view returns (uint256);

    // get twap price depending on _period
    function getTwapPrice(bytes32 _priceFeedKey, uint256 _interval) external view returns (uint256);
}

File 3 of 9 : Decimal.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.12;

import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "./DecimalMath.sol";

library Decimal {
    using DecimalMath for uint256;
    using SafeMathUpgradeable for uint256;

    struct decimal {
        uint256 d;
    }

    function zero() internal pure returns (decimal memory) {
        return decimal(0);
    }

    function one() internal pure returns (decimal memory) {
        return decimal(DecimalMath.unit(18));
    }

    function toUint(decimal memory x) internal pure returns (uint256) {
        return x.d;
    }

    function modD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        return decimal(x.d.mul(DecimalMath.unit(18)) % y.d);
    }

    function cmp(decimal memory x, decimal memory y) internal pure returns (int8) {
        if (x.d > y.d) {
            return 1;
        } else if (x.d < y.d) {
            return -1;
        }
        return 0;
    }

    /// @dev add two decimals
    function addD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.add(y.d);
        return t;
    }

    /// @dev subtract two decimals
    function subD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.sub(y.d);
        return t;
    }

    /// @dev multiple two decimals
    function mulD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.muld(y.d);
        return t;
    }

    /// @dev multiple a decimal by a uint256
    function mulScalar(decimal memory x, uint256 y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.mul(y);
        return t;
    }

    /// @dev divide two decimals
    function divD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.divd(y.d);
        return t;
    }

    /// @dev divide a decimal by a uint256
    function divScalar(decimal memory x, uint256 y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.div(y);
        return t;
    }
}

File 4 of 9 : DecimalMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.12;

import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";

/// @dev Implements simple fixed point math add, sub, mul and div operations.
/// @author Alberto Cuesta Cañada
library DecimalMath {
    using SafeMathUpgradeable for uint256;

    /// @dev Returns 1 in the fixed point representation, with `decimals` decimals.
    function unit(uint8 decimals) internal pure returns (uint256) {
        return 10**uint256(decimals);
    }

    /// @dev Adds x and y, assuming they are both fixed point with 18 decimals.
    function addd(uint256 x, uint256 y) internal pure returns (uint256) {
        return x.add(y);
    }

    /// @dev Subtracts y from x, assuming they are both fixed point with 18 decimals.
    function subd(uint256 x, uint256 y) internal pure returns (uint256) {
        return x.sub(y);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with 18 digits.
    function muld(uint256 x, uint256 y) internal pure returns (uint256) {
        return muld(x, y, 18);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with `decimals` digits.
    function muld(
        uint256 x,
        uint256 y,
        uint8 decimals
    ) internal pure returns (uint256) {
        return x.mul(y).div(unit(decimals));
    }

    /// @dev Divides x between y, assuming they are both fixed point with 18 digits.
    function divd(uint256 x, uint256 y) internal pure returns (uint256) {
        return divd(x, y, 18);
    }

    /// @dev Divides x between y, assuming they are both fixed point with `decimals` digits.
    function divd(
        uint256 x,
        uint256 y,
        uint8 decimals
    ) internal pure returns (uint256) {
        return x.mul(unit(decimals)).div(y);
    }
}

File 5 of 9 : AggregatorV3Interface.sol
pragma solidity >=0.6.0;

interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

}

File 6 of 9 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";

/*
 * @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 GSN 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 ContextUpgradeable is Initializable {
    function __Context_init() internal initializer {
        __Context_init_unchained();
    }

    function __Context_init_unchained() internal initializer {
    }
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
    uint256[50] private __gap;
}

File 7 of 9 : OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../GSN/ContextUpgradeable.sol";
import "../proxy/Initializable.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.
 *
 * By default, the owner account will be the one that deploys the contract. 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal initializer {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
    uint256[49] private __gap;
}

File 8 of 9 : SafeMathUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMathUpgradeable {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 9 of 9 : Initializable.sol
// SPDX-License-Identifier: MIT

// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;


/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 * 
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
 * 
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {

    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /// @dev Returns true if and only if the function is running in the constructor
    function _isConstructor() private view returns (bool) {
        // extcodesize checks the size of the code stored in an address, and
        // address returns the current address. Since the code is still not
        // deployed when running a constructor, any checks on its code size will
        // yield zero, making it an effective way to detect if a contract is
        // under construction or not.
        address self = address(this);
        uint256 cs;
        // solhint-disable-next-line no-inline-assembly
        assembly { cs := extcodesize(self) }
        return cs == 0;
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"indexed":false,"internalType":"address","name":"aggregator","type":"address"}],"name":"AggregatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"currencyKey","type":"bytes32"},{"indexed":false,"internalType":"address","name":"aggregator","type":"address"}],"name":"AggregatorRemoved","type":"event"},{"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":"bytes32","name":"_priceFeedKey","type":"bytes32"},{"internalType":"address","name":"_aggregator","type":"address"}],"name":"addAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_priceFeedKey","type":"bytes32"}],"name":"getAggregator","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_priceFeedKey","type":"bytes32"}],"name":"getLatestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_priceFeedKey","type":"bytes32"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPriceFeedLength","outputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_priceFeedKey","type":"bytes32"},{"internalType":"uint256","name":"_interval","type":"uint256"}],"name":"getTwapPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"priceFeedKeys","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"priceFeedMap","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_priceFeedKey","type":"bytes32"}],"name":"removeAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506113f9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80634cea5ee81161008c5780638129fc1c116100665780638129fc1c146101ee5780638da5cb5b146101f6578063a2173df4146101fe578063f2fde38b14610221576100cf565b80634cea5ee8146101c1578063715018a6146101c95780637ad22632146101d1576100cf565b8063250742cc146100d45780632a0ab1dd1461010d5780632bed9e0c1461013c57806331d98b3f1461015b578063331b1816146101785780633f0e084f14610195575b600080fd5b6100f1600480360360208110156100ea57600080fd5b5035610247565b604080516001600160a01b039092168252519081900360200190f35b61012a6004803603602081101561012357600080fd5b5035610262565b60408051918252519081900360200190f35b6101596004803603602081101561015257600080fd5b5035610280565b005b61012a6004803603602081101561017157600080fd5b50356103fc565b6100f16004803603602081101561018e57600080fd5b50356105aa565b610159600480360360408110156101ab57600080fd5b50803590602001356001600160a01b03166105c5565b61012a6106e0565b6101596106e6565b61012a600480360360208110156101e757600080fd5b5035610788565b610159610811565b6100f16108bb565b61012a6004803603604081101561021457600080fd5b50803590602001356108ca565b6101596004803603602081101561023757600080fd5b50356001600160a01b0316610ce9565b6065602052600090815260409020546001600160a01b031681565b6066818154811061026f57fe5b600091825260209091200154905081565b610288610de2565b6033546001600160a01b039081169116146102d8576040805162461bcd60e51b815260206004820181905260248201526000805160206113a4833981519152604482015290519081900360640190fd5b6000818152606560205260409020546001600160a01b03166102f981610de6565b600082815260656020526040812080546001600160a01b0319169055606654905b818110156103f657836066828154811061033057fe5b906000526020600020015414156103ee57600182038114610380576066600183038154811061035b57fe5b90600052602060002001546066828154811061037357fe5b6000918252602090912001555b606680548061038b57fe5b600190038181906000526020600020016000905590557fec70e890fc7db7de4059b114c9093a1f41283d18ffcfbcac45566feea4d4f777848460405180838152602001826001600160a01b031681526020019250505060405180910390a16103f6565b60010161031a565b50505050565b600061040782610e31565b61044a576040805162461bcd60e51b815260206004820152600f60248201526e1ad95e481b9bdd08195e1a5cdd1959608a1b604482015290519081900360640190fd5b6000610455836105aa565b90506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561049257600080fd5b505afa1580156104a6573d6000803e3d6000fd5b505050506040513d60a08110156104bc57600080fd5b50602001519050600081121561050b576040805162461bcd60e51b815260206004820152600f60248201526e3732b3b0ba34bb329030b739bbb2b960891b604482015290519081900360640190fd5b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561054657600080fd5b505afa15801561055a573d6000803e3d6000fd5b505050506040513d602081101561057057600080fd5b5051905061057c61131b565b60405180602001604052806105918585610e7d565b9052905061059e81610ea8565b9450505050505b919050565b6000908152606560205260409020546001600160a01b031690565b6105cd610de2565b6033546001600160a01b0390811691161461061d576040805162461bcd60e51b815260206004820181905260248201526000805160206113a4833981519152604482015290519081900360640190fd5b61062681610de6565b6000828152606560205260409020546001600160a01b031661067857606680546001810182556000919091527f46501879b8ca8525e8c2fd519e2fbfcfa2ebea26501294aa02cbfcfb12e94354018290555b60008281526065602090815260409182902080546001600160a01b0319166001600160a01b03851690811790915582518581529182015281517f0bcae573430f69c5361e5d76534d3f61d2d803958778680cd74be9dc6299bc63929181900390910190a15050565b60665490565b6106ee610de2565b6033546001600160a01b0390811691161461073e576040805162461bcd60e51b815260206004820181905260248201526000805160206113a4833981519152604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600080610794836105aa565b905061079f81610de6565b6000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156107da57600080fd5b505afa1580156107ee573d6000803e3d6000fd5b505050506040513d60a081101561080457600080fd5b5060600151949350505050565b600054610100900460ff168061082a575061082a610eac565b80610838575060005460ff16155b6108735760405162461bcd60e51b815260040180806020018281038252602e815260200180611355602e913960400191505060405180910390fd5b600054610100900460ff1615801561089e576000805460ff1961ff0019909116610100171660011790555b6108a6610eb2565b80156108b8576000805461ff00191690555b50565b6033546001600160a01b031690565b60006108d583610e31565b610918576040805162461bcd60e51b815260206004820152600f60248201526e1ad95e481b9bdd08195e1a5cdd1959608a1b604482015290519081900360640190fd5b81610960576040805162461bcd60e51b81526020600482015260136024820152720696e74657276616c2063616e2774206265203606c1b604482015290519081900360640190fd5b600061096b846105aa565b90506000806000836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156109ab57600080fd5b505afa1580156109bf573d6000803e3d6000fd5b505050506040513d60a08110156109d557600080fd5b508051602082015160609092015190945090925090506000821215610a33576040805162461bcd60e51b815260206004820152600f60248201526e3732b3b0ba34bb329030b739bbb2b960891b604482015290519081900360640190fd5b6000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d6020811015610a9857600080fd5b50519050610aa461131b565b6040518060200160405280610ab98685610e7d565b905290506000610ac882610ea8565b9050836000610ad7428c610f4f565b905080821080610af1575069ffffffffffffffffffff8816155b15610b0757829950505050505050505050610ce3565b6000610b134284610f4f565b9050826000610b228684610f91565b90505b69ffffffffffffffffffff8b16610b5357610b408184610fea565b9c50505050505050505050505050610ce3565b60018b039a506000808d6001600160a01b0316639a6fc8f58e6040518263ffffffff1660e01b8152600401808269ffffffffffffffffffff16815260200191505060a06040518083038186803b158015610bac57600080fd5b505afa158015610bc0573d6000803e3d6000fd5b505050506040513d60a0811015610bd657600080fd5b50602081015160609091015190925090506000821215610c2f576040805162461bcd60e51b815260206004820152600f60248201526e3732b3b0ba34bb329030b739bbb2b960891b604482015290519081900360640190fd5b610c3761131b565b6040518060200160405280610c4c858e610e7d565b905290506000610c5b82610ea8565b9050878311610c8d57610c82610c7b610c74888b610f4f565b8390610f91565b869061102c565b945050505050610cca565b6000610c998785610f4f565b9050610caf610ca88383610f91565b879061102c565b9550610cbb888261102c565b97508396505050505050610b25565b610cd4818f610fea565b9c505050505050505050505050505b92915050565b610cf1610de2565b6033546001600160a01b03908116911614610d41576040805162461bcd60e51b815260206004820181905260248201526000805160206113a4833981519152604482015290519081900360640190fd5b6001600160a01b038116610d865760405162461bcd60e51b815260040180806020018281038252602681526020018061132f6026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0381166108b8576040805162461bcd60e51b815260206004820152600d60248201526c656d707479206164647265737360981b604482015290519081900360640190fd5b606654600090815b81811015610e73578360668281548110610e4f57fe5b90600052602060002001541415610e6b576001925050506105a5565b600101610e39565b5060009392505050565b6000610ea160ff8316600a0a610e9b85670de0b6b3a7640000610f91565b90610fea565b9392505050565b5190565b303b1590565b600054610100900460ff1680610ecb5750610ecb610eac565b80610ed9575060005460ff16155b610f145760405162461bcd60e51b815260040180806020018281038252602e815260200180611355602e913960400191505060405180910390fd5b600054610100900460ff16158015610f3f576000805460ff1961ff0019909116610100171660011790555b610f47611086565b6108a6611126565b6000610ea183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061121f565b600082610fa057506000610ce3565b82820282848281610fad57fe5b0414610ea15760405162461bcd60e51b81526004018080602001828103825260218152602001806113836021913960400191505060405180910390fd5b6000610ea183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506112b6565b600082820183811015610ea1576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600054610100900460ff168061109f575061109f610eac565b806110ad575060005460ff16155b6110e85760405162461bcd60e51b815260040180806020018281038252602e815260200180611355602e913960400191505060405180910390fd5b600054610100900460ff161580156108a6576000805460ff1961ff00199091166101001716600117905580156108b8576000805461ff001916905550565b600054610100900460ff168061113f575061113f610eac565b8061114d575060005460ff16155b6111885760405162461bcd60e51b815260040180806020018281038252602e815260200180611355602e913960400191505060405180910390fd5b600054610100900460ff161580156111b3576000805460ff1961ff0019909116610100171660011790555b60006111bd610de2565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156108b8576000805461ff001916905550565b600081848411156112ae5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561127357818101518382015260200161125b565b50505050905090810190601f1680156112a05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836113055760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561127357818101518382015260200161125b565b50600083858161131157fe5b0495945050505050565b604051806020016040528060008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212209b3a3ca2ba4583cba604dc16bf1aba2b6c49d891188dad862c34b71f16d4e93464736f6c634300060c0033

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