Contract 0xeA3Fe12d8CC2E87f99e985EE271971C808006531

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xe8e0e56ec0b13705adab7e38357e92be45ac2c181a09bf4dd3063ea4118c4baeTransfer Ownersh...282210702022-10-03 20:43:18241 days 22 hrs ago0x4427040bbbc8084acf86ff409e84a83b3fad9e85 IN  0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH0.000027920.1
0xae57b9b21c5e6933b6c4f3d9b8e2bffd0a368a64eca0a92729a268a35ac7aeaf0x60806040282209712022-10-03 20:42:26241 days 22 hrs ago0x4427040bbbc8084acf86ff409e84a83b3fad9e85 IN  Create: ChainlinkPriceOracleV10 ETH0.000864430.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x50834f3163758fcc1df9973b6e91f0f0f0434ad30 ETH
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x639fe6ab55c921f74e7fac1ee960c0b6293ba6120 ETH
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0xe644043f710b99c2b8af4b34e0fdc0121690f4ee2a4232a235badb30316c13ad720786082023-03-21 9:45:3473 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x50834f3163758fcc1df9973b6e91f0f0f0434ad30 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x639fe6ab55c921f74e7fac1ee960c0b6293ba6120 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0xd7052732182fda673b516998eb7d618bc2c346211506def0aed073f23c544a03720781232023-03-21 9:43:3373 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x50834f3163758fcc1df9973b6e91f0f0f0434ad30 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x639fe6ab55c921f74e7fac1ee960c0b6293ba6120 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0x60b7c7ef10541d8dd30ff0ec5547909b16245331ae6fbefd33dd1f9adc40f918720779072023-03-21 9:42:3973 days 9 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x50834f3163758fcc1df9973b6e91f0f0f0434ad30 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x639fe6ab55c921f74e7fac1ee960c0b6293ba6120 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x3c14e07edd0dc67442fa96f1ec6999c57e810a830 ETH
0x7d2642c61b8d095a9a24e7cc7095f2cf9afcde4f076daeb88f88565a088bb5b2720413722023-03-21 7:12:5073 days 12 hrs ago Dolomite: Margin 0xea3fe12d8cc2e87f99e985ee271971c8080065310 ETH
0xad6757c1f3f6eff8c2584134af69ff26194a5e193641210f4ff4f28563e727cc720402532023-03-21 7:08:1573 days 12 hrs ago 0xea3fe12d8cc2e87f99e985ee271971c808006531 0x50834f3163758fcc1df9973b6e91f0f0f0434ad30 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainlinkPriceOracleV1

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
File 1 of 9 : ChainlinkPriceOracleV1.sol
/*

    Copyright 2020 Dolomite.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/ownership/Ownable.sol";

import "../../protocol/interfaces/IPriceOracle.sol";
import "../../protocol/lib/Monetary.sol";
import "../../protocol/lib/Require.sol";

import "../interfaces/IChainlinkAggregator.sol";

import "./IChainlinkFlags.sol";


/**
 * @title ChainlinkPriceOracleV1
 * @author Dolomite
 *
 * An implementation of the IPriceOracle interface that makes Chainlink prices compatible with the protocol.
 */
contract ChainlinkPriceOracleV1 is IPriceOracle, Ownable {
    using SafeMath for uint;

    bytes32 private constant FILE = "ChainlinkPriceOracleV1";
    // solium-disable-next-line max-len
    address constant private FLAG_ARBITRUM_SEQ_OFFLINE = address(bytes20(bytes32(uint256(keccak256("chainlink.flags.arbitrum-seq-offline")) - 1)));

    event TokenInsertedOrUpdated(
        address indexed token,
        address indexed aggregator,
        address indexed tokenPair
    );

    mapping(address => IChainlinkAggregator) public tokenToAggregatorMap;
    mapping(address => uint8) public tokenToDecimalsMap;

    /// Defaults to USD if the value is the ZERO address
    mapping(address => address) public tokenToPairingMap;

    /// Should defaults to CHAINLINK_USD_DECIMALS when value is empty
    mapping(address => uint8) public tokenToAggregatorDecimalsMap;

    IChainlinkFlags public chainlinkFlags;

    uint8 public CHAINLINK_USD_DECIMALS = 8;
    uint8 public CHAINLINK_ETH_DECIMALS = 18;

    /**
     * Note, these arrays are set up, such that each index corresponds with one-another.
     *
     * @param tokens                The tokens that are supported by this adapter.
     * @param chainlinkAggregators  The Chainlink aggregators that have on-chain prices.
     * @param tokenDecimals         The number of decimals that each token has.
     * @param tokenPairs            The token against which this token's value is compared using the aggregator. The
     *                              zero address means USD.
     * @param aggregatorDecimals    The number of decimals that the value has that comes back from the corresponding
     *                              Chainlink Aggregator.
     * @param chainlinkFlagsOrNull  The contract for layer-2 that denotes whether or not Chainlink oracles are currently
     *                              offline, meaning data is stale and any critical operations should *not* occur. If
     *                              not on layer 2, this value can be set to `address(0)`.
     */
    constructor(
        address[] memory tokens,
        address[] memory chainlinkAggregators,
        uint8[] memory tokenDecimals,
        address[] memory tokenPairs,
        uint8[] memory aggregatorDecimals,
        address chainlinkFlagsOrNull
    ) public {
        require( // coverage-disable-line
            tokens.length == chainlinkAggregators.length,
            "invalid aggregators"
        );
        require( // coverage-disable-line
            chainlinkAggregators.length == tokenDecimals.length,
            "invalid token decimals"
        );
        require( // coverage-disable-line
            tokenDecimals.length == tokenPairs.length,
            "invalid token pairs"
        );
        require( // coverage-disable-line
            tokenPairs.length == aggregatorDecimals.length,
            "invalid aggregator decimals"
        );

        for (uint i = 0; i < tokens.length; i++) {
            _insertOrUpdateOracleToken(
                tokens[i],
                tokenDecimals[i],
                chainlinkAggregators[i],
                aggregatorDecimals[i],
                tokenPairs[i]
            );
        }

        chainlinkFlags = IChainlinkFlags(chainlinkFlagsOrNull);
    }

    // ============ Admin Functions ============

    function insertOrUpdateOracleToken(
        address token,
        uint8 tokenDecimals,
        address chainlinkAggregator,
        uint8 aggregatorDecimals,
        address tokenPair
    ) public onlyOwner {
        _insertOrUpdateOracleToken(
            token,
            tokenDecimals,
            chainlinkAggregator,
            aggregatorDecimals,
            tokenPair
        );
    }

    // ============ Public Functions ============

    function getPrice(
        address token
    )
    public
    view
    returns (Monetary.Price memory) {
        Require.that(
            address(tokenToAggregatorMap[token]) != address(0),
            FILE,
            "invalid token",
            token
        );
        IChainlinkFlags _chainlinkFlags = chainlinkFlags;
        if (address(_chainlinkFlags) != address(0)) {
            // https://docs.chain.link/docs/l2-sequencer-flag/
            bool isFlagRaised = _chainlinkFlags.getFlag(FLAG_ARBITRUM_SEQ_OFFLINE);
            Require.that(
                !isFlagRaised,
                FILE,
                "Chainlink price oracles offline"
            );
        }

        uint rawChainlinkPrice = uint(tokenToAggregatorMap[token].latestAnswer());
        address tokenPair = tokenToPairingMap[token];

        // standardize the Chainlink price to be the proper number of decimals of (36 - tokenDecimals)
        uint standardizedPrice = standardizeNumberOfDecimals(
            tokenToDecimalsMap[token],
            rawChainlinkPrice,
            tokenPair == address(0) ? CHAINLINK_USD_DECIMALS : tokenToAggregatorDecimalsMap[token]
        );

        if (tokenPair == address(0)) {
            // The pair has a USD base, we are done.
            return Monetary.Price({value : standardizedPrice});
        } else {
            // The price we just got and converted is NOT against USD. So we need to get its pair's price against USD.
            // We can do so by recursively calling #getPrice using the `tokenPair` as the parameter instead of `token`.
            uint tokenPairStandardizedPrice = getPrice(tokenPair).value;
            // Standardize the price to use 36 decimals.
            uint tokenPairWith36Decimals = tokenPairStandardizedPrice.mul(10 ** uint(tokenToDecimalsMap[tokenPair]));
            // Now that the chained price uses 36 decimals (and thus is standardized), we can do easy math.
            return Monetary.Price({value : standardizedPrice.mul(tokenPairWith36Decimals).div(ONE_DOLLAR)});
        }
    }

    /**
     * Standardizes `value` to have `ONE_DOLLAR` - `tokenDecimals` number of decimals.
     */
    function standardizeNumberOfDecimals(
        uint8 tokenDecimals,
        uint value,
        uint8 valueDecimals
    ) public pure returns (uint) {
        uint tokenDecimalsFactor = 10 ** uint(tokenDecimals);
        uint priceFactor = IPriceOracle.ONE_DOLLAR.div(tokenDecimalsFactor);
        uint valueFactor = 10 ** uint(valueDecimals);
        return value.mul(priceFactor).div(valueFactor);
    }

    // ============ Internal Functions ============

    function _insertOrUpdateOracleToken(
        address token,
        uint8 tokenDecimals,
        address chainlinkAggregator,
        uint8 aggregatorDecimals,
        address tokenPair
    ) internal {
        tokenToAggregatorMap[token] = IChainlinkAggregator(chainlinkAggregator);
        tokenToDecimalsMap[token] = tokenDecimals;
        if (tokenPair != address(0)) {
            // The aggregator's price is NOT against USD. Therefore, we need to store what it's against as well as the
            // # of decimals the aggregator's price has.
            tokenToPairingMap[token] = tokenPair;
            tokenToAggregatorDecimalsMap[token] = aggregatorDecimals;
        }
        emit TokenInsertedOrUpdated(token, chainlinkAggregator, tokenPair);
    }
}

File 2 of 9 : Ownable.sol
pragma solidity ^0.5.0;

import "../GSN/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.
 *
 * 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.
 */
contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        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(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _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 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 3 of 9 : SafeMath.sol
pragma solidity ^0.5.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 SafeMath {
    /**
     * @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.
     *
     * _Available since v2.4.0._
     */
    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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 4 of 9 : Context.sol
pragma solidity ^0.5.0;

/*
 * @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.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

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

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

File 5 of 9 : Require.sol
/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;
pragma experimental ABIEncoderV2;


/**
 * @title Require
 * @author dYdX
 *
 * Stringifies parameters to pretty-print revert messages. Costs more gas than regular require()
 */
library Require {

    // ============ Constants ============

    uint256 constant ASCII_ZERO = 48; // '0'
    uint256 constant ASCII_RELATIVE_ZERO = 87; // 'a' - 10
    uint256 constant ASCII_LOWER_EX = 120; // 'x'
    bytes2 constant COLON = 0x3a20; // ': '
    bytes2 constant COMMA = 0x2c20; // ', '
    bytes2 constant LPAREN = 0x203c; // ' <'
    byte constant RPAREN = 0x3e; // '>'
    uint256 constant FOUR_BIT_MASK = 0xf;

    // ============ Library Functions ============

    function that(
        bool must,
        bytes32 file,
        bytes32 reason
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason)
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        uint256 payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        address payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        RPAREN
                    )
                )
            );
        }
    }

    function that(
        bool must,
        bytes32 file,
        bytes32 reason,
        bytes32 payloadA,
        uint256 payloadB,
        uint256 payloadC
    )
        internal
        pure
    {
        if (!must) {
            revert(
                string(
                    abi.encodePacked(
                        stringifyTruncated(file),
                        COLON,
                        stringifyTruncated(reason),
                        LPAREN,
                        stringify(payloadA),
                        COMMA,
                        stringify(payloadB),
                        COMMA,
                        stringify(payloadC),
                        RPAREN
                    )
                )
            );
        }
    }

    // ============ Private Functions ============

    function stringifyTruncated(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        // put the input bytes into the result
        bytes memory result = abi.encodePacked(input);

        // determine the length of the input by finding the location of the last non-zero byte
        for (uint256 i = 32; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // find the last non-zero byte in order to determine the length
            if (result[i] != 0) {
                uint256 length = i + 1;

                /* solium-disable-next-line security/no-inline-assembly */
                assembly {
                    mstore(result, length) // r.length = length;
                }

                return result;
            }
        }

        // all bytes are zero
        return new bytes(0);
    }

    function stringify(
        uint256 input
    )
        private
        pure
        returns (bytes memory)
    {
        if (input == 0) {
            return "0";
        }

        // get the final string length
        uint256 j = input;
        uint256 length;
        while (j != 0) {
            length++;
            j /= 10;
        }

        // allocate the string
        bytes memory bstr = new bytes(length);

        // populate the string starting with the least-significant character
        j = input;
        for (uint256 i = length; i > 0; ) {
            // reverse-for-loops with unsigned integer
            /* solium-disable-next-line security/no-modify-for-iter-var */
            i--;

            // take last decimal digit
            bstr[i] = byte(uint8(ASCII_ZERO + (j % 10)));

            // remove the last decimal digit
            j /= 10;
        }

        return bstr;
    }

    function stringify(
        address input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // addresses are "0x" followed by 20 bytes of data which take up 2 characters each
        bytes memory result = new bytes(42);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 20; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[41 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[40 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function stringify(
        bytes32 input
    )
        private
        pure
        returns (bytes memory)
    {
        uint256 z = uint256(input);

        // bytes32 are "0x" followed by 32 bytes of data which take up 2 characters each
        bytes memory result = new bytes(66);

        // populate the result with "0x"
        result[0] = byte(uint8(ASCII_ZERO));
        result[1] = byte(uint8(ASCII_LOWER_EX));

        // for each byte (starting from the lowest byte), populate the result with two characters
        for (uint256 i = 0; i < 32; i++) {
            // each byte takes two characters
            uint256 shift = i * 2;

            // populate the least-significant character
            result[65 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;

            // populate the most-significant character
            result[64 - shift] = char(z & FOUR_BIT_MASK);
            z = z >> 4;
        }

        return result;
    }

    function char(
        uint256 input
    )
        private
        pure
        returns (byte)
    {
        // return ASCII digit (0-9)
        if (input < 10) {
            return byte(uint8(input + ASCII_ZERO));
        }

        // return ASCII letter (a-f)
        return byte(uint8(input + ASCII_RELATIVE_ZERO));
    }
}

File 6 of 9 : Monetary.sol
/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;
pragma experimental ABIEncoderV2;


/**
 * @title Monetary
 * @author dYdX
 *
 * Library for types involving money
 */
library Monetary {

    /*
     * The price of a base-unit of an asset. Has `36 - token.decimals` decimals
     */
    struct Price {
        uint256 value;
    }

    /*
     * Total value of an some amount of an asset. Equal to (price * amount). Has 36 decimals.
     */
    struct Value {
        uint256 value;
    }
}

File 7 of 9 : IPriceOracle.sol
/*

    Copyright 2019 dYdX Trading Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;
pragma experimental ABIEncoderV2;

import { Monetary } from "../lib/Monetary.sol";


/**
 * @title IPriceOracle
 * @author dYdX
 *
 * Interface that Price Oracles for DolomiteMargin must implement in order to report prices.
 */
contract IPriceOracle {

    // ============ Constants ============

    uint256 public constant ONE_DOLLAR = 10 ** 36;

    // ============ Public Functions ============

    /**
     * Get the price of a token
     *
     * @param  token  The ERC20 token address of the market
     * @return        The USD price of a base unit of the token, then multiplied by 10^36.
     *                So a USD-stable coin with 18 decimal places would return 10^18.
     *                This is the price of the base unit rather than the price of a "human-readable"
     *                token amount. Every ERC20 may have a different number of decimals.
     */
    function getPrice(
        address token
    )
        public
        view
        returns (Monetary.Price memory);
}

File 8 of 9 : IChainlinkFlags.sol
/*

    Copyright 2022 Dolomite.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;


/**
 * @title IChainlinkFlags
 * @author Dolomite
 */
interface IChainlinkFlags {

    function getFlag(address subject) external view returns (bool);
}

File 9 of 9 : IChainlinkAggregator.sol
/*

    Copyright 2020 Dolomite.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

*/

pragma solidity ^0.5.7;
pragma experimental ABIEncoderV2;


/**
 * @title IChainlinkAggregator
 * @author Dolomite
 *
 * Gets the latest price from the Chainlink Oracle Network. Amount of decimals depends on the base.
 */
contract IChainlinkAggregator {

    function latestAnswer() public view returns (int256);

}

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

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address[]","name":"chainlinkAggregators","type":"address[]"},{"internalType":"uint8[]","name":"tokenDecimals","type":"uint8[]"},{"internalType":"address[]","name":"tokenPairs","type":"address[]"},{"internalType":"uint8[]","name":"aggregatorDecimals","type":"uint8[]"},{"internalType":"address","name":"chainlinkFlagsOrNull","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"aggregator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenPair","type":"address"}],"name":"TokenInsertedOrUpdated","type":"event"},{"constant":true,"inputs":[],"name":"CHAINLINK_ETH_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAINLINK_USD_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ONE_DOLLAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"chainlinkFlags","outputs":[{"internalType":"contract IChainlinkFlags","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getPrice","outputs":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Monetary.Price","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"internalType":"address","name":"chainlinkAggregator","type":"address"},{"internalType":"uint8","name":"aggregatorDecimals","type":"uint8"},{"internalType":"address","name":"tokenPair","type":"address"}],"name":"insertOrUpdateOracleToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint8","name":"valueDecimals","type":"uint8"}],"name":"standardizeNumberOfDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToAggregatorDecimalsMap","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToAggregatorMap","outputs":[{"internalType":"contract IChainlinkAggregator","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToDecimalsMap","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToPairingMap","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040526005805460ff60a01b1916600160a31b1760ff60a81b1916600960a91b1790553480156200003157600080fd5b5060405162001d0738038062001d0783398101604081905262000054916200040e565b6000620000696001600160e01b036200020816565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508451865114620000e05760405162461bcd60e51b8152600401620000d79062000617565b60405180910390fd5b8351855114620001045760405162461bcd60e51b8152600401620000d79062000629565b8251845114620001285760405162461bcd60e51b8152600401620000d79062000605565b81518351146200014c5760405162461bcd60e51b8152600401620000d7906200063b565b60005b8651811015620001db57620001d28782815181106200016a57fe5b60200260200101518683815181106200017f57fe5b60200260200101518884815181106200019457fe5b6020026020010151868581518110620001a957fe5b6020026020010151888681518110620001be57fe5b60200260200101516200020c60201b60201c565b6001016200014f565b50600580546001600160a01b0319166001600160a01b039290921691909117905550620006db9350505050565b3390565b6001600160a01b03858116600090815260016020908152604080832080546001600160a01b03191688861617905560029091529020805460ff191660ff87161790558116156200029b576001600160a01b03858116600090815260036020908152604080832080546001600160a01b031916948616949094179093556004905220805460ff191660ff84161790555b806001600160a01b0316836001600160a01b0316866001600160a01b03167ff6dcff57d435662a867049d43b76e51e72ffba006347ec701ce100b59ee6da3760405160405180910390a45050505050565b8051620002f981620006b6565b92915050565b600082601f8301126200031157600080fd5b815162000328620003228262000674565b6200064d565b915081818352602084019350602081019050838560208402820111156200034e57600080fd5b60005b838110156200037e5781620003678882620002ec565b845250602092830192919091019060010162000351565b5050505092915050565b600082601f8301126200039a57600080fd5b8151620003ab620003228262000674565b91508181835260208401935060208101905083856020840282011115620003d157600080fd5b60005b838110156200037e5781620003ea888262000401565b8452506020928301929190910190600101620003d4565b8051620002f981620006d0565b60008060008060008060c087890312156200042857600080fd5b86516001600160401b038111156200043f57600080fd5b6200044d89828a01620002ff565b96505060208701516001600160401b038111156200046a57600080fd5b6200047889828a01620002ff565b95505060408701516001600160401b038111156200049557600080fd5b620004a389828a0162000388565b94505060608701516001600160401b03811115620004c057600080fd5b620004ce89828a01620002ff565b93505060808701516001600160401b03811115620004eb57600080fd5b620004f989828a0162000388565b92505060a06200050c89828a01620002ec565b9150509295509295509295565b60006200052860138362000695565b7f696e76616c696420746f6b656e20706169727300000000000000000000000000815260200192915050565b60006200056360138362000695565b7f696e76616c69642061676772656761746f727300000000000000000000000000815260200192915050565b60006200059e60168362000695565b7f696e76616c696420746f6b656e20646563696d616c7300000000000000000000815260200192915050565b6000620005d9601b8362000695565b7f696e76616c69642061676772656761746f7220646563696d616c730000000000815260200192915050565b60208082528101620002f98162000519565b60208082528101620002f98162000554565b60208082528101620002f9816200058f565b60208082528101620002f981620005ca565b6040518181016001600160401b03811182821017156200066c57600080fd5b604052919050565b60006001600160401b038211156200068b57600080fd5b5060209081020190565b90815260200190565b60006001600160a01b038216620002f9565b60ff1690565b620006c1816200069e565b8114620006cd57600080fd5b50565b620006c181620006b0565b61161c80620006eb6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806378f875b411610097578063d08f994211610066578063d08f9942146101e0578063e4440e0214610200578063f042c09414610208578063f2fde38b14610210576100f5565b806378f875b41461019d5780638da5cb5b146101b05780638f32d59b146101b8578063a9c12c84146101cd576100f5565b80632f4abe92116100d35780632f4abe921461014057806341976e0914610160578063572ca9e714610180578063715018a614610195576100f5565b806309359d02146100fa57806321fff1c31461012357806323c77b9e14610138575b600080fd5b61010d610108366004611034565b610223565b60405161011a91906114b4565b60405180910390f35b61013661013136600461105a565b610238565b005b61010d610293565b61015361014e366004611034565b6102b4565b60405161011a919061142d565b61017361016e366004611034565b6102dc565b60405161011a9190611498565b6101886106a4565b60405161011a91906114a6565b6101366106b7565b6101886101ab36600461110b565b610764565b6101536107b5565b6101c06107d1565b60405161011a919061143b565b61010d6101db366004611034565b61080f565b6101f36101ee366004611034565b610824565b60405161011a9190611449565b6101f361084c565b61010d610868565b61013661021e366004611034565b61088a565b60046020526000908152604090205460ff1681565b6102406107d1565b61027f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690611488565b60405180910390fd5b61028c85858585856108d4565b5050505050565b60055474010000000000000000000000000000000000000000900460ff1681565b60036020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6102e4610fea565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526001602052604090205461035a911615157f436861696e6c696e6b50726963654f7261636c655631000000000000000000007f696e76616c696420746f6b656e0000000000000000000000000000000000000085610a60565b60055473ffffffffffffffffffffffffffffffffffffffff1680156104895760008173ffffffffffffffffffffffffffffffffffffffff1663357e47fe60016040516103a590611422565b6040519081900381207fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1682526103e992900360601c9060040161142d565b60206040518083038186803b15801561040157600080fd5b505afa158015610415573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061043991908101906110cf565b905061048781157f436861696e6c696e6b50726963654f7261636c655631000000000000000000007f436861696e6c696e6b207072696365206f7261636c6573206f66666c696e6500610b5c565b505b73ffffffffffffffffffffffffffffffffffffffff80841660009081526001602090815260408083205481517f50d25bcd0000000000000000000000000000000000000000000000000000000081529151939416926350d25bcd92600480840193919291829003018186803b15801561050157600080fd5b505afa158015610515573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061053991908101906110ed565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600360209081526040808320546002909252822054939450909116916105d19060ff168484156105ae5773ffffffffffffffffffffffffffffffffffffffff891660009081526004602052604090205460ff166101ab565b60055474010000000000000000000000000000000000000000900460ff16610764565b905073ffffffffffffffffffffffffffffffffffffffff82166106085760405180602001604052808281525094505050505061069f565b6000610613836102dc565b5173ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260408120549192509061065590839060ff16600a0a63ffffffff610bab16565b905060405180602001604052806106946ec097ce7bc90715b34b9f10000000006106888588610bab90919063ffffffff16565b9063ffffffff610c0816565b905296505050505050505b919050565b6ec097ce7bc90715b34b9f100000000081565b6106bf6107d1565b6106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690611488565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600060ff8416600a0a8161078d6ec097ce7bc90715b34b9f10000000008363ffffffff610c0816565b905060ff8416600a0a6107aa81610688888563ffffffff610bab16565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6000805473ffffffffffffffffffffffffffffffffffffffff166107f3610c4a565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b60026020526000908152604090205460ff1681565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b6005547501000000000000000000000000000000000000000000900460ff1681565b6108926107d1565b6108c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690611488565b6108d181610c4e565b50565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260016020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168886161790556002909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790558116156109e85773ffffffffffffffffffffffffffffffffffffffff858116600090815260036020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694861694909417909355600490522080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff84161790555b8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff6dcff57d435662a867049d43b76e51e72ffba006347ec701ce100b59ee6da3760405160405180910390a45050505050565b83610b5657610a6e83610d28565b7f3a20000000000000000000000000000000000000000000000000000000000000610a9884610d28565b7f203c000000000000000000000000000000000000000000000000000000000000610ac285610e00565b604051610af89594939291907f3e00000000000000000000000000000000000000000000000000000000000000906020016113c4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261027691600401611457565b50505050565b82610ba657610b6a82610d28565b7f3a20000000000000000000000000000000000000000000000000000000000000610b9483610d28565b604051602001610af893929190611393565b505050565b600082610bba57506000610c02565b82820282848281610bc757fe5b0414610bff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690611478565b90505b92915050565b6000610bff83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610f77565b3390565b73ffffffffffffffffffffffffffffffffffffffff8116610c9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027690611468565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60608082604051602001610d3c919061137e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060205b8015610de55781517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190829082908110610da857fe5b01602001517fff000000000000000000000000000000000000000000000000000000000000001615610de0576001018152905061069f565b610d6f565b5060408051600080825260208201909252905b509392505050565b60408051602a808252606082810190935273ffffffffffffffffffffffffffffffffffffffff8416918391602082018180388339019050509050603060f81b81600081518110610e4c57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350607860f81b81600181518110610e8d57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b6014811015610df85760028102610ed8600f8516610fc8565b838260290381518110610ee757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600484901c9350610f29600f8516610fc8565b838260280381518110610f3857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505060049290921c91600101610ebf565b60008183610fb2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102769190611457565b506000838581610fbe57fe5b0495945050505050565b6000600a821015610fe057506030810160f81b61069f565b5060570160f81b90565b6040518060200160405280600081525090565b8035610c02816115aa565b8051610c02816115be565b8051610c02816115c7565b8035610c02816115c7565b8035610c02816115d0565b60006020828403121561104657600080fd5b60006110528484610ffd565b949350505050565b600080600080600060a0868803121561107257600080fd5b600061107e8888610ffd565b955050602061108f88828901611029565b94505060406110a088828901610ffd565b93505060606110b188828901611029565b92505060806110c288828901610ffd565b9150509295509295909350565b6000602082840312156110e157600080fd5b60006110528484611008565b6000602082840312156110ff57600080fd5b60006110528484611013565b60008060006060848603121561112057600080fd5b600061112c8686611029565b935050602061113d8682870161101e565b925050604061114e86828701611029565b9150509250925092565b611161816114cf565b82525050565b611161816114da565b61116161117c826114df565b611529565b61116161117c82611504565b61116161117c82611529565b60006111a4826114c2565b6111ae818561069f565b93506111be818560208601611556565b9290920192915050565b6111618161154b565b60006111dc826114c2565b6111e681856114c6565b93506111f6818560208601611556565b6111ff81611582565b9093019392505050565b60006112166026836114c6565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181527f6464726573730000000000000000000000000000000000000000000000000000602082015260400192915050565b60006112756021836114c6565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f81527f7700000000000000000000000000000000000000000000000000000000000000602082015260400192915050565b60006112d46020836114c6565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b600061130d60248361069f565b7f636861696e6c696e6b2e666c6167732e617262697472756d2d7365712d6f666681527f6c696e6500000000000000000000000000000000000000000000000000000000602082015260240192915050565b80516020830190610b5684825b61116181611529565b61116181611545565b600061138a828461118d565b50602001919050565b600061139f8286611199565b91506113ab8285611181565b6002820191506113bb8284611199565b95945050505050565b60006113d08289611199565b91506113dc8288611181565b6002820191506113ec8287611199565b91506113f88286611181565b6002820191506114088285611199565b91506114148284611170565b506001019695505050505050565b6000610c0282611300565b60208101610c028284611158565b60208101610c028284611167565b60208101610c0282846111c8565b60208082528101610bff81846111d1565b60208082528101610c0281611209565b60208082528101610c0281611268565b60208082528101610c02816112c7565b60208101610c02828461135f565b60208101610c02828461136c565b60208101610c028284611375565b5190565b90815260200190565b6000610c028261152c565b151590565b7fff000000000000000000000000000000000000000000000000000000000000001690565b7fffff0000000000000000000000000000000000000000000000000000000000001690565b90565b73ffffffffffffffffffffffffffffffffffffffff1690565b60ff1690565b6000610c02826114cf565b60005b83811015611571578181015183820152602001611559565b83811115610b565750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b6115b3816114cf565b81146108d157600080fd5b6115b3816114da565b6115b381611529565b6115b38161154556fea365627a7a72315820596cb7dc5f180f7bcebdbd9f3ed54a278856de11a28941b2a1d7f77f94e8412d6c6578706572696d656e74616cf564736f6c6343000510004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000004400000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a830000000000000000000000000000000000000000000000000000000000000006000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0f000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb90000000000000000000000000000000000000000000000000000000000000006000000000000000000000000c5c8e77b397e531b8ec06bfb0048328b30e9ecfb00000000000000000000000086e53cf1b870786351da77a57575e79cb55812cb00000000000000000000000050834f3163758fcc1df9973b6e91f0f0f0434ad3000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba6120000000000000000000000006ce185860a4963106506c203335a2910413708e90000000000000000000000003f3f5df88dc9f13eac63df89ec16ef6e7e25dde7000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008

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

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000004400000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a830000000000000000000000000000000000000000000000000000000000000006000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0f000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb90000000000000000000000000000000000000000000000000000000000000006000000000000000000000000c5c8e77b397e531b8ec06bfb0048328b30e9ecfb00000000000000000000000086e53cf1b870786351da77a57575e79cb55812cb00000000000000000000000050834f3163758fcc1df9973b6e91f0f0f0434ad3000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba6120000000000000000000000006ce185860a4963106506c203335a2910413708e90000000000000000000000003f3f5df88dc9f13eac63df89ec16ef6e7e25dde7000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008

-----Decoded View---------------
Arg [0] : tokens (address[]): 0xda10009cbd5d07dd0cecc66161fc93d7c9000da1,0xf97f4df75117a78c1a5a0dbb814af92458539fb4,0xff970a61a04b1ca14834a43f5de4533ebddb5cc8,0x82af49447d8a07e3bd95bd0d56f35241523fbab1,0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f,0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9
Arg [1] : chainlinkAggregators (address[]): 0xc5c8e77b397e531b8ec06bfb0048328b30e9ecfb,0x86e53cf1b870786351da77a57575e79cb55812cb,0x50834f3163758fcc1df9973b6e91f0f0f0434ad3,0x639fe6ab55c921f74e7fac1ee960c0b6293ba612,0x6ce185860a4963106506c203335a2910413708e9,0x3f3f5df88dc9f13eac63df89ec16ef6e7e25dde7
Arg [2] : tokenDecimals (uint8[]): 18,18,6,18,8,6
Arg [3] : tokenPairs (address[]): 0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000,0x0000000000000000000000000000000000000000
Arg [4] : aggregatorDecimals (uint8[]): 8,8,8,8,8,8
Arg [5] : chainlinkFlagsOrNull (address): 0x3c14e07edd0dc67442fa96f1ec6999c57e810a83

-----Encoded View---------------
41 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000280
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000360
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000440
Arg [5] : 0000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a83
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [7] : 000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1
Arg [8] : 000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4
Arg [9] : 000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc8
Arg [10] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [11] : 0000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0f
Arg [12] : 000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [14] : 000000000000000000000000c5c8e77b397e531b8ec06bfb0048328b30e9ecfb
Arg [15] : 00000000000000000000000086e53cf1b870786351da77a57575e79cb55812cb
Arg [16] : 00000000000000000000000050834f3163758fcc1df9973b6e91f0f0f0434ad3
Arg [17] : 000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba612
Arg [18] : 0000000000000000000000006ce185860a4963106506c203335a2910413708e9
Arg [19] : 0000000000000000000000003f3f5df88dc9f13eac63df89ec16ef6e7e25dde7
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [24] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [26] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [28] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [29] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [30] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [31] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [32] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [33] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [34] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [35] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [36] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [37] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [38] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [39] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [40] : 0000000000000000000000000000000000000000000000000000000000000008


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.