ETH Price: $2,507.53 (+0.29%)

Contract

0x5165B17e4e0513356e91975E5A67F32e2470CFA5
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x61018060193535542024-03-03 8:49:35243 days ago1709455775IN
 Create: ERC4626OracleAdapter
0 ETH0.0321909444.72113689

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC4626OracleAdapter

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
istanbul EvmVersion, None license
File 1 of 10 : ERC4626OracleAdapter.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity =0.7.6;

import "../../../interfaces/IERC4626.sol";
import "../../../interfaces/IERC20.sol";
import "../../math/SafeUint256.sol";
import "./ChainlinkAdapter.sol";

contract ERC4626OracleAdapter is ChainlinkAdapter {
    int256 immutable ASSET_PRECISION;
    using SafeInt256 for int256;
    using SafeUint256 for uint256;

    constructor (
        AggregatorV2V3Interface baseToUSDOracle_,
        AggregatorV2V3Interface quoteToUSDOracle_,
        bool invertBase_,
        bool invertQuote_,
        string memory description_,
        AggregatorV2V3Interface sequencerUptimeOracle_
    ) ChainlinkAdapter(
        baseToUSDOracle_, quoteToUSDOracle_, invertBase_, invertQuote_, description_, sequencerUptimeOracle_
    ) {
        uint256 assetDecimals = IERC20(IERC4626(address(quoteToUSDOracle_)).asset()).decimals();
        require(assetDecimals <= 18);
        ASSET_PRECISION = int256(10 ** assetDecimals);
    }
    
    function _getQuoteRate() internal view override returns (int256 quoteRate) {
        // quoteToUSDDecimals will be equal to 1 share of the ERC4626 token.
        // ASSET_PRECISION is equal to 1 asset token. This is returned as: ASSET/SHARE
        IERC4626 oracle = IERC4626(address(quoteToUSDOracle));
        quoteRate = invertQuote ? 
            oracle.convertToShares(uint256(ASSET_PRECISION)).toInt()
                .mul(ASSET_PRECISION).div(quoteToUSDDecimals) :
            oracle.convertToAssets(uint256(quoteToUSDDecimals)).toInt()
                .mul(quoteToUSDDecimals).div(ASSET_PRECISION);
    }
}

File 2 of 10 : IERC4626.sol
pragma solidity >=0.7.6;

interface IERC4626 {
    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
    );

    /**
     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
     *
     * - MUST be an ERC-20 token contract.
     * - MUST NOT revert.
     */
    function asset() external view returns (address assetTokenAddress);

    /**
     * @dev Returns the total amount of the underlying asset that is "managed" by Vault.
     *
     * - SHOULD include any compounding that occurs from yield.
     * - MUST be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT revert.
     */
    function totalAssets() external view returns (uint256 totalManagedAssets);

    /**
     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
     * scenario where all the conditions are met.
     *
     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT show any variations depending on the caller.
     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
     * - MUST NOT revert.
     *
     * NOTE: This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the
     * "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and
     * from.
     */
    function convertToShares(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
     * scenario where all the conditions are met.
     *
     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
     * - MUST NOT show any variations depending on the caller.
     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
     * - MUST NOT revert.
     *
     * NOTE: This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the
     * "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and
     * from.
     */
    function convertToAssets(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
     * through a deposit call.
     *
     * - MUST return a limited value if receiver is subject to some deposit limit.
     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
     * - MUST NOT revert.
     */
    function maxDeposit(address receiver) external view returns (uint256 maxAssets);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
     * current on-chain conditions.
     *
     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
     *   in the same transaction.
     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.
     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by depositing.
     */
    function previewDeposit(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
     *
     * - MUST emit the Deposit event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   deposit execution, and are accounted for during deposit.
     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
     *   approving enough underlying tokens to the Vault contract, etc).
     *
     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
     */
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    /**
     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
     * - MUST return a limited value if receiver is subject to some mint limit.
     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
     * - MUST NOT revert.
     */
    function maxMint(address receiver) external view returns (uint256 maxShares);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
     * current on-chain conditions.
     *
     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
     *   same transaction.
     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
     *   would be accepted, regardless if the user has enough tokens approved, etc.
     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by minting.
     */
    function previewMint(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
     *
     * - MUST emit the Deposit event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
     *   execution, and are accounted for during mint.
     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
     *   approving enough underlying tokens to the Vault contract, etc).
     *
     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
     */
    function mint(uint256 shares, address receiver) external returns (uint256 assets);

    /**
     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
     * Vault, through a withdraw call.
     *
     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
     * - MUST NOT revert.
     */
    function maxWithdraw(address owner) external view returns (uint256 maxAssets);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
     * given current on-chain conditions.
     *
     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
     *   called
     *   in the same transaction.
     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.
     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by depositing.
     */
    function previewWithdraw(uint256 assets) external view returns (uint256 shares);

    /**
     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
     *
     * - MUST emit the Withdraw event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   withdraw execution, and are accounted for during withdraw.
     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
     *   not having enough shares, etc).
     *
     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
     * Those methods should be performed separately.
     */
    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) external returns (uint256 shares);

    /**
     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
     * through a redeem call.
     *
     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
     * - MUST NOT revert.
     */
    function maxRedeem(address owner) external view returns (uint256 maxShares);

    /**
     * @dev Allows an on-chain or off-chain user to simulate the effects of their redemption at the current block,
     * given current on-chain conditions.
     *
     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
     *   same transaction.
     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
     *   redemption would be accepted, regardless if the user has enough shares, etc.
     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
     * - MUST NOT revert.
     *
     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.
     */
    function previewRedeem(uint256 shares) external view returns (uint256 assets);

    /**
     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
     *
     * - MUST emit the Withdraw event.
     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
     *   redeem execution, and are accounted for during redeem.
     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
     *   not having enough shares, etc).
     *
     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
     * Those methods should be performed separately.
     */
    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) external returns (uint256 assets);
}

File 3 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    function decimals() external view returns (uint8);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 4 of 10 : SafeUint256.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity =0.7.6;

import {Constants} from "../global/Constants.sol";

library SafeUint256 {
    /**
     * @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);
        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) {
        require(b <= a);
        return a - b;
    }

    /**
     * @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) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b);
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting 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) {
        require(b > 0);
        return a / b;
    }

    function max(uint256 x, uint256 y) internal pure returns (uint256) {
        return x > y ? x : y;
    }

    function min(uint256 x, uint256 y) internal pure returns (uint256) {
        return x < y ? x : y;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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) {
        require(b > 0);
        return a % b;
    }

    function divInRatePrecision(uint256 x, uint256 y) internal pure returns (uint256) {
        return div(mul(x, uint256(Constants.RATE_PRECISION)), y);
    }

    function mulInRatePrecision(uint256 x, uint256 y) internal pure returns (uint256) {
        return div(mul(x, y), uint256(Constants.RATE_PRECISION));
    }

    function divInScalarPrecision(uint256 x, uint256 y) internal pure returns (uint256) {
        return div(mul(x, Constants.SCALAR_PRECISION), y);
    }

    function mulInScalarPrecision(uint256 x, uint256 y) internal pure returns (uint256) {
        return div(mul(x, y), Constants.SCALAR_PRECISION);
    }

    function toUint8(uint256 x) internal pure returns (uint8) {
        require(x <= type(uint8).max);
        return uint8(x);
    }

    function toUint32(uint256 x) internal pure returns (uint32) {
        require(x <= type(uint32).max);
        return uint32(x);
    }

    function toUint40(uint256 x) internal pure returns (uint40) {
        require(x <= type(uint40).max);
        return uint40(x);
    }

    function toUint48(uint256 x) internal pure returns (uint48) {
        require(x <= type(uint48).max);
        return uint48(x);
    }

    function toUint56(uint256 x) internal pure returns (uint56) {
        require(x <= type(uint56).max);
        return uint56(x);
    }

    function toUint72(uint256 x) internal pure returns (uint72) {
        require(x <= type(uint72).max);
        return uint72(x);
    }
    
    function toUint80(uint256 x) internal pure returns (uint80) {
        require(x <= type(uint80).max);
        return uint80(x);
    }

    function toUint88(uint256 x) internal pure returns (uint88) {
        require(x <= type(uint88).max);
        return uint88(x);
    }

    function toUint104(uint256 x) internal pure returns (uint104) {
        require(x <= type(uint104).max);
        return uint104(x);
    }

    function toUint112(uint256 x) internal pure returns (uint112) {
        require(x <= type(uint112).max);
        return uint112(x);
    }

    function toUint128(uint256 x) internal pure returns (uint128) {
        require(x <= type(uint128).max);
        return uint128(x);
    }

    function toInt(uint256 x) internal pure returns (int256) {
        require (x <= uint256(type(int256).max)); // dev: toInt overflow
        return int256(x);
    }

}

File 5 of 10 : ChainlinkAdapter.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity =0.7.6;

import "../../math/SafeInt256.sol";
import "../../../interfaces/chainlink/AggregatorV2V3Interface.sol";

contract ChainlinkAdapter is AggregatorV2V3Interface {
    using SafeInt256 for int256;
    uint8 public override constant decimals = 18;
    uint256 public override constant version = 1;
    int256 public constant rateDecimals = 10**18;

    string public override description;
    // Grace period after a sequencer downtime has occurred
    uint256 public constant SEQUENCER_UPTIME_GRACE_PERIOD = 1 hours;

    AggregatorV2V3Interface public immutable baseToUSDOracle;
    int256 public immutable baseToUSDDecimals;
    AggregatorV2V3Interface public immutable quoteToUSDOracle;
    int256 public immutable quoteToUSDDecimals;
    bool public immutable invertBase;
    bool public immutable invertQuote;
    AggregatorV2V3Interface public immutable sequencerUptimeOracle;

    constructor (
        AggregatorV2V3Interface baseToUSDOracle_,
        AggregatorV2V3Interface quoteToUSDOracle_,
        bool invertBase_,
        bool invertQuote_,
        string memory description_,
        AggregatorV2V3Interface sequencerUptimeOracle_
    ) {
        description = description_;
        baseToUSDOracle = baseToUSDOracle_;
        quoteToUSDOracle = quoteToUSDOracle_;
        uint8 _baseDecimals = baseToUSDOracle_.decimals();
        uint8 _quoteDecimals = quoteToUSDOracle_.decimals();

        require(_baseDecimals <= 18);
        require(_quoteDecimals <= 18);

        baseToUSDDecimals = int256(10**_baseDecimals);
        quoteToUSDDecimals = int256(10**_quoteDecimals);
        invertBase = invertBase_;
        invertQuote = invertQuote_;
        sequencerUptimeOracle = sequencerUptimeOracle_;
    }

    function _checkSequencer() private view {
        // See: https://docs.chain.link/data-feeds/l2-sequencer-feeds/
        if (address(sequencerUptimeOracle) != address(0)) {
            (
                /*uint80 roundID*/,
                int256 answer,
                uint256 startedAt,
                /*uint256 updatedAt*/,
                /*uint80 answeredInRound*/
            ) = sequencerUptimeOracle.latestRoundData();
            require(answer == 0, "Sequencer Down");
            require(SEQUENCER_UPTIME_GRACE_PERIOD < block.timestamp - startedAt, "Sequencer Grace Period");
        }
    }

    function _getQuoteRate() internal view virtual returns (int256 quoteRate) {
        (
            /* roundId */,
            quoteRate,
            /* uint256 startedAt */,
            /* updatedAt */,
            /* answeredInRound */
        ) = quoteToUSDOracle.latestRoundData();
        require(quoteRate > 0, "Chainlink Rate Error");
        if (invertQuote) quoteRate = (quoteToUSDDecimals * quoteToUSDDecimals) / quoteRate;
    }

    function _calculateBaseToQuote() internal view returns (
        uint80 roundId,
        int256 answer,
        uint256 startedAt,
        uint256 updatedAt,
        uint80 answeredInRound
    ) {
        _checkSequencer();

        int256 baseToUSD;
        (
            roundId,
            baseToUSD,
            startedAt,
            updatedAt,
            answeredInRound
        ) = baseToUSDOracle.latestRoundData();
        require(baseToUSD > 0, "Chainlink Rate Error");
        // Overflow and div by zero not possible
        if (invertBase) baseToUSD = (baseToUSDDecimals * baseToUSDDecimals) / baseToUSD;

        int256 quoteToUSD = _getQuoteRate();

        // To convert from USDC/USD (base) and ETH/USD (quote) to USDC/ETH we do:
        // (USDC/USD * quoteDecimals * 1e18) / (ETH/USD * baseDecimals)
        answer = baseToUSD
            .mul(quoteToUSDDecimals)
            .mul(rateDecimals)
            .div(quoteToUSD)
            .div(baseToUSDDecimals);
    }

    function latestRoundData() external view override returns (
        uint80 roundId,
        int256 answer,
        uint256 startedAt,
        uint256 updatedAt,
        uint80 answeredInRound
    ) {
        return _calculateBaseToQuote();
    }

    function latestAnswer() external view override returns (int256 answer) {
        (/* */, answer, /* */, /* */, /* */) = _calculateBaseToQuote();
    }

    function latestTimestamp() external view override returns (uint256 updatedAt) {
        (/* */, /* */, /* */, updatedAt, /* */) = _calculateBaseToQuote();
    }

    function latestRound() external view override returns (uint256 roundId) {
        (roundId, /* */, /* */, /* */, /* */) = _calculateBaseToQuote();
    }

    function getRoundData(uint80 /* _roundId */) external view override returns (
        uint80 /* roundId */,
        int256 /* answer */,
        uint256 /* startedAt */,
        uint256 /* updatedAt */,
        uint80 /* answeredInRound */
    ) {
        revert();
    }

    function getAnswer(uint256 /* roundId */) external view override returns (int256) { revert(); }
    function getTimestamp(uint256 /* roundId */) external view override returns (uint256) { revert(); }
}

File 6 of 10 : Constants.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity >=0.7.6;

/// @title All shared constants for the Notional system should be declared here.
library Constants {
    uint8 internal constant CETH_DECIMAL_PLACES = 8;

    // Token precision used for all internal balances, TokenHandler library ensures that we
    // limit the dust amount caused by precision mismatches
    int256 internal constant INTERNAL_TOKEN_PRECISION = 1e8;
    uint256 internal constant INCENTIVE_ACCUMULATION_PRECISION = 1e18;

    // ETH will be initialized as the first currency
    uint256 internal constant ETH_CURRENCY_ID = 1;
    uint8 internal constant ETH_DECIMAL_PLACES = 18;
    int256 internal constant ETH_DECIMALS = 1e18;
    address internal constant ETH_ADDRESS = address(0);
    // Used to prevent overflow when converting decimal places to decimal precision values via
    // 10**decimalPlaces. This is a safe value for int256 and uint256 variables. We apply this
    // constraint when storing decimal places in governance.
    uint256 internal constant MAX_DECIMAL_PLACES = 36;

    // Address of the account where fees are collected
    address internal constant FEE_RESERVE = 0x0000000000000000000000000000000000000FEE;
    // Address of the account where settlement funds are collected, this is only
    // used for off chain event tracking.
    address internal constant SETTLEMENT_RESERVE = 0x00000000000000000000000000000000000005e7;

    // Most significant bit
    bytes32 internal constant MSB =
        0x8000000000000000000000000000000000000000000000000000000000000000;

    // Each bit set in this mask marks where an active market should be in the bitmap
    // if the first bit refers to the reference time. Used to detect idiosyncratic
    // fcash in the nToken accounts
    bytes32 internal constant ACTIVE_MARKETS_MASK = (
        MSB >> ( 90 - 1) | // 3 month
        MSB >> (105 - 1) | // 6 month
        MSB >> (135 - 1) | // 1 year
        MSB >> (147 - 1) | // 2 year
        MSB >> (183 - 1) | // 5 year
        MSB >> (211 - 1) | // 10 year
        MSB >> (251 - 1)   // 20 year
    );

    // Basis for percentages
    int256 internal constant PERCENTAGE_DECIMALS = 100;
    // Min Buffer Scale and Buffer Scale are used in ExchangeRate to increase the maximum
    // possible buffer values at the higher end of the uint8 range.
    int256 internal constant MIN_BUFFER_SCALE = 150;
    int256 internal constant BUFFER_SCALE = 10;
    // Max number of traded markets, also used as the maximum number of assets in a portfolio array
    uint256 internal constant MAX_TRADED_MARKET_INDEX = 7;
    // Max number of fCash assets in a bitmap, this is based on the gas costs of calculating free collateral
    // for a bitmap portfolio
    uint256 internal constant MAX_BITMAP_ASSETS = 20;
    uint256 internal constant FIVE_MINUTES = 300;

    // Internal date representations, note we use a 6/30/360 week/month/year convention here
    uint256 internal constant DAY = 86400;
    // We use six day weeks to ensure that all time references divide evenly
    uint256 internal constant WEEK = DAY * 6;
    uint256 internal constant MONTH = WEEK * 5;
    uint256 internal constant QUARTER = MONTH * 3;
    uint256 internal constant YEAR = QUARTER * 4;
    
    // These constants are used in DateTime.sol
    uint256 internal constant DAYS_IN_WEEK = 6;
    uint256 internal constant DAYS_IN_MONTH = 30;
    uint256 internal constant DAYS_IN_QUARTER = 90;

    // Offsets for each time chunk denominated in days
    uint256 internal constant MAX_DAY_OFFSET = 90;
    uint256 internal constant MAX_WEEK_OFFSET = 360;
    uint256 internal constant MAX_MONTH_OFFSET = 2160;
    uint256 internal constant MAX_QUARTER_OFFSET = 7650;

    // Offsets for each time chunk denominated in bits
    uint256 internal constant WEEK_BIT_OFFSET = 90;
    uint256 internal constant MONTH_BIT_OFFSET = 135;
    uint256 internal constant QUARTER_BIT_OFFSET = 195;

    // Number of decimal places that rates are stored in, equals 100%
    int256 internal constant RATE_PRECISION = 1e9;
    // Used for prime cash scalars
    uint256 internal constant SCALAR_PRECISION = 1e18;
    // Used in prime rate lib
    int256 internal constant DOUBLE_SCALAR_PRECISION = 1e36;
    // One basis point in RATE_PRECISION terms
    uint256 internal constant BASIS_POINT = uint256(RATE_PRECISION / 10000);
    // Used to when calculating the amount to deleverage of a market when minting nTokens
    uint256 internal constant DELEVERAGE_BUFFER = 300 * BASIS_POINT;
    // Used for scaling cash group factors
    uint256 internal constant FIVE_BASIS_POINTS = 5 * BASIS_POINT;
    // Used for residual purchase incentive and cash withholding buffer
    uint256 internal constant TEN_BASIS_POINTS = 10 * BASIS_POINT;
    // Used for max oracle rate
    uint256 internal constant FIFTEEN_BASIS_POINTS = 15 * BASIS_POINT;
    // Used in max rate calculations
    uint256 internal constant MAX_LOWER_INCREMENT = 150;
    uint256 internal constant MAX_LOWER_INCREMENT_VALUE = 150 * 25 * BASIS_POINT;
    uint256 internal constant TWENTY_FIVE_BASIS_POINTS = 25 * BASIS_POINT;
    uint256 internal constant ONE_HUNDRED_FIFTY_BASIS_POINTS = 150 * BASIS_POINT;

    // This is the ABDK64x64 representation of RATE_PRECISION
    // RATE_PRECISION_64x64 = ABDKMath64x64.fromUint(RATE_PRECISION)
    int128 internal constant RATE_PRECISION_64x64 = 0x3b9aca000000000000000000;

    uint8 internal constant FCASH_ASSET_TYPE          = 1;
    // Liquidity token asset types are 1 + marketIndex (where marketIndex is 1-indexed)
    uint8 internal constant MIN_LIQUIDITY_TOKEN_INDEX = 2;
    uint8 internal constant MAX_LIQUIDITY_TOKEN_INDEX = 8;
    uint8 internal constant VAULT_SHARE_ASSET_TYPE    = 9;
    uint8 internal constant VAULT_DEBT_ASSET_TYPE     = 10;
    uint8 internal constant VAULT_CASH_ASSET_TYPE     = 11;
    // Used for tracking legacy nToken assets
    uint8 internal constant LEGACY_NTOKEN_ASSET_TYPE  = 12;

    // Account context flags
    bytes1 internal constant HAS_ASSET_DEBT           = 0x01;
    bytes1 internal constant HAS_CASH_DEBT            = 0x02;
    bytes2 internal constant ACTIVE_IN_PORTFOLIO      = 0x8000;
    bytes2 internal constant ACTIVE_IN_BALANCES       = 0x4000;
    bytes2 internal constant UNMASK_FLAGS             = 0x3FFF;
    uint16 internal constant MAX_CURRENCIES           = uint16(UNMASK_FLAGS);

    // Equal to 100% of all deposit amounts for nToken liquidity across fCash markets.
    int256 internal constant DEPOSIT_PERCENT_BASIS    = 1e8;

    // nToken Parameters: there are offsets in the nTokenParameters bytes6 variable returned
    // in nTokenHandler. Each constant represents a position in the byte array.
    uint8 internal constant LIQUIDATION_HAIRCUT_PERCENTAGE = 0;
    uint8 internal constant CASH_WITHHOLDING_BUFFER = 1;
    uint8 internal constant RESIDUAL_PURCHASE_TIME_BUFFER = 2;
    uint8 internal constant PV_HAIRCUT_PERCENTAGE = 3;
    uint8 internal constant RESIDUAL_PURCHASE_INCENTIVE = 4;
    uint8 internal constant MAX_MINT_DEVIATION_LIMIT = 5;

    // Liquidation parameters
    // Default percentage of collateral that a liquidator is allowed to liquidate, will be higher if the account
    // requires more collateral to be liquidated
    int256 internal constant DEFAULT_LIQUIDATION_PORTION = 40;
    // Percentage of local liquidity token cash claim delivered to the liquidator for liquidating liquidity tokens
    int256 internal constant TOKEN_REPO_INCENTIVE_PERCENT = 30;

    // Pause Router liquidation enabled states
    bytes1 internal constant LOCAL_CURRENCY_ENABLED = 0x01;
    bytes1 internal constant COLLATERAL_CURRENCY_ENABLED = 0x02;
    bytes1 internal constant LOCAL_FCASH_ENABLED = 0x04;
    bytes1 internal constant CROSS_CURRENCY_FCASH_ENABLED = 0x08;

    // Requires vault accounts to enter a position for a minimum of 1 min
    // to mitigate strange behavior where accounts may enter and exit using
    // flash loans or other MEV type behavior.
    uint256 internal constant VAULT_ACCOUNT_MIN_TIME = 1 minutes;

    // Placeholder constant to mark the variable rate prime cash maturity
    uint40 internal constant PRIME_CASH_VAULT_MATURITY = type(uint40).max;

    // This represents the maximum percent change allowed before and after 
    // a rebalancing. 100_000 represents a 0.01% change
    // as a result of rebalancing. We should expect to never lose value as
    // a result of rebalancing, but some rounding errors may exist as a result
    // of redemption and deposit.
    int256 internal constant REBALANCING_UNDERLYING_DELTA_PERCENT = 100_000;

    // Ensures that the minimum total underlying held by the contract continues
    // to accrue interest so that money market oracle rates are properly updated
    // between rebalancing. With a minimum rebalancing cool down time of 6 hours
    // we would be able to detect at least 1 unit of accrual at 8 decimal precision
    // at an interest rate of 2.8 basis points (0.0288%) with 0.05e8 minimum balance
    // held in a given token.
    //
    //                          MIN_ACCRUAL * (86400 / REBALANCING_COOL_DOWN_HOURS)
    // MINIMUM_INTEREST_RATE =  ---------------------------------------------------
    //                                     MINIMUM_UNDERLYING_BALANCE
    int256 internal constant MIN_TOTAL_UNDERLYING_VALUE = 0.05e8;
}

File 7 of 10 : SafeInt256.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity =0.7.6;

import {Constants} from "../global/Constants.sol";

library SafeInt256 {
    int256 private constant _INT256_MIN = type(int256).min;

    /// @dev Returns the multiplication of two signed integers, reverting on
    /// overflow.

    /// Counterpart to Solidity's `*` operator.

    /// Requirements:

    /// - Multiplication cannot overflow.

    function mul(int256 a, int256 b) internal pure returns (int256 c) {
        c = a * b;
        if (a == -1) require (b == 0 || c / b == a);
        else require (a == 0 || c / a == b);
    }

    /// @dev Returns the integer division of two signed 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(int256 a, int256 b) internal pure returns (int256 c) {
        require(!(b == -1 && a == _INT256_MIN)); // dev: int256 div overflow
        // NOTE: solidity will automatically revert on divide by zero
        c = a / b;
    }

    function sub(int256 x, int256 y) internal pure returns (int256 z) {
        //  taken from uniswap v3
        require((z = x - y) <= x == (y >= 0));
    }

    function add(int256 x, int256 y) internal pure returns (int256 z) {
        require((z = x + y) >= x == (y >= 0));
    }

    function neg(int256 x) internal pure returns (int256 y) {
        return mul(-1, x);
    }

    function abs(int256 x) internal pure returns (int256) {
        if (x < 0) return neg(x);
        else return x;
    }

    function subNoNeg(int256 x, int256 y) internal pure returns (int256 z) {
        z = sub(x, y);
        require(z >= 0); // dev: int256 sub to negative

        return z;
    }

    /// @dev Calculates x * RATE_PRECISION / y while checking overflows
    function divInRatePrecision(int256 x, int256 y) internal pure returns (int256) {
        return div(mul(x, Constants.RATE_PRECISION), y);
    }

    /// @dev Calculates x * y / RATE_PRECISION while checking overflows
    function mulInRatePrecision(int256 x, int256 y) internal pure returns (int256) {
        return div(mul(x, y), Constants.RATE_PRECISION);
    }

    function toUint(int256 x) internal pure returns (uint256) {
        require(x >= 0);
        return uint256(x);
    }

    function toInt(uint256 x) internal pure returns (int256) {
        require (x <= uint256(type(int256).max)); // dev: toInt overflow
        return int256(x);
    }

    function toInt80(int256 x) internal pure returns (int80) {
        require (int256(type(int80).min) <= x && x <= int256(type(int80).max)); // dev: toInt overflow
        return int80(x);
    }

    function toInt88(int256 x) internal pure returns (int88) {
        require (int256(type(int88).min) <= x && x <= int256(type(int88).max)); // dev: toInt overflow
        return int88(x);
    }

    function toInt128(int256 x) internal pure returns (int128) {
        require (int256(type(int128).min) <= x && x <= int256(type(int128).max)); // dev: toInt overflow
        return int128(x);
    }

    function max(int256 x, int256 y) internal pure returns (int256) {
        return x > y ? x : y;
    }

    function min(int256 x, int256 y) internal pure returns (int256) {
        return x < y ? x : y;
    }

    /// @notice Returns the net change in negative signed values, used for
    /// determining the (positive) amount of debt change
    function negChange(int256 start, int256 end) internal pure returns (int256) {
        // No change in these two scenarios
        if (start == end || (start >= 0 && end >= 0)) return 0;
        if (start <= 0 && 0 < end) {
            // Negative portion has been eliminated so the net change on the
            // negative side is start (i.e. a reduction in the negative balance)
            return start;
        } else if (end <= 0 && 0 < start) {
            // Entire negative portion has been created so the net change on the
            // negative side is -end (i.e. an increase in the negative balance)
            return neg(end);
        } else if (start <= 0 && end <= 0) {
            // There is some net change in the negative amounts.
            // If start < end then this is negative, debt has been reduced
            // If end < start then this is positive, debt has been increased
            return sub(start, end);
        }

        // Should never get to this point
        revert();
    }
}

File 8 of 10 : AggregatorV2V3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

import "./AggregatorInterface.sol";
import "./AggregatorV3Interface.sol";

interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
{
}

File 9 of 10 : AggregatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

interface AggregatorInterface {
  function latestAnswer() external view returns (int256);
  function latestTimestamp() external view returns (uint256);
  function latestRound() external view returns (uint256);
  function getAnswer(uint256 roundId) external view returns (int256);
  function getTimestamp(uint256 roundId) external view returns (uint256);

  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);
  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
}

File 10 of 10 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
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
    );

}

Settings
{
  "remappings": [
    "@openzeppelin-4.6/=node_modules/@openzeppelin-4.6/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "hardhat/=node_modules/hardhat/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "murky/=lib/murky/",
    "openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "istanbul",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract AggregatorV2V3Interface","name":"baseToUSDOracle_","type":"address"},{"internalType":"contract AggregatorV2V3Interface","name":"quoteToUSDOracle_","type":"address"},{"internalType":"bool","name":"invertBase_","type":"bool"},{"internalType":"bool","name":"invertQuote_","type":"bool"},{"internalType":"string","name":"description_","type":"string"},{"internalType":"contract AggregatorV2V3Interface","name":"sequencerUptimeOracle_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"current","type":"int256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"updatedAt","type":"uint256"}],"name":"AnswerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":true,"internalType":"address","name":"startedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"NewRound","type":"event"},{"inputs":[],"name":"SEQUENCER_UPTIME_GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseToUSDDecimals","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseToUSDOracle","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"","type":"uint80"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invertBase","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invertQuote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"answer","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"roundId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToUSDDecimals","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToUSDOracle","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateDecimals","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sequencerUptimeOracle","outputs":[{"internalType":"contract AggregatorV2V3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6101806040523480156200001257600080fd5b506040516200103c3803806200103c833981810160405260c08110156200003857600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007457600080fd5b9083019060208201858111156200008a57600080fd5b8251640100000000811182820188101715620000a557600080fd5b82525081516020918201929091019080838360005b83811015620000d4578181015183820152602001620000ba565b50505050905090810190601f168015620001025780820380516001836020036101000a031916815260200191505b506040526020908101518451909350889250879187918791879187916200012f91600091850190620003a2565b506001600160601b0319606087811b821660805286901b1660c0526040805163313ce56760e01b815290516000916001600160a01b0389169163313ce56791600480820192602092909190829003018186803b1580156200018f57600080fd5b505afa158015620001a4573d6000803e3d6000fd5b505050506040513d6020811015620001bb57600080fd5b50516040805163313ce56760e01b815290519192506000916001600160a01b0389169163313ce567916004808301926020929190829003018186803b1580156200020457600080fd5b505afa15801562000219573d6000803e3d6000fd5b505050506040513d60208110156200023057600080fd5b50519050601260ff831611156200024657600080fd5b60128160ff1611156200025857600080fd5b60ff918216600a90810a60a0529116900a60e05292151560f890811b6101005291151590911b610120525060601b6001600160601b031916610140525050604080516338d52e0f60e01b815290516000916001600160a01b038816916338d52e0f91600480820192602092909190829003018186803b158015620002db57600080fd5b505afa158015620002f0573d6000803e3d6000fd5b505050506040513d60208110156200030757600080fd5b50516040805163313ce56760e01b815290516001600160a01b039092169163313ce56791600480820192602092909190829003018186803b1580156200034c57600080fd5b505afa15801562000361573d6000803e3d6000fd5b505050506040513d60208110156200037857600080fd5b505160ff16905060128111156200038e57600080fd5b600a0a61016052506200044e945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620003da576000855562000425565b82601f10620003f557805160ff191683800117855562000425565b8280016001018555821562000425579182015b828111156200042557825182559160200191906001019062000408565b506200043392915062000437565b5090565b5b8082111562000433576000815560010162000438565b60805160601c60a05160c05160601c60e0516101005160f81c6101205160f81c6101405160601c61016051610b3662000506600039806108cc52806109d55280610a085250806104b95280610721528061075352508061048e52806108a452508061033a528061062d52508061035e52806106e452806108f0528061092352806109b152508061039b52806108835250806104dd5280610654528061067552806106b1525080610311528061053a5250610b366000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c80637284e416116100ad578063b633620c11610071578063b633620c146102c6578063c15ef47a146102e3578063d836d4ae146102eb578063dc60eac9146102f3578063feaf968c146102fb57610121565b80637284e416146101c65780638205bf6a146102435780639a6fc8f51461024b578063a8ecc66d146102be578063b5ab58dc146102c657610121565b806344f8f24d116100f457806344f8f24d1461019e57806350d25bcd146101a657806354fd4d50146101ae578063653ea66f146101b6578063668a0f02146101be57610121565b80631a3480b5146101265780631aafcce314610140578063313ce567146101645780633e374e1614610182575b600080fd5b61012e610303565b60408051918252519081900360200190f35b61014861030f565b604080516001600160a01b039092168252519081900360200190f35b61016c610333565b6040805160ff9092168252519081900360200190f35b61018a610338565b604080519115158252519081900360200190f35b61012e61035c565b61012e610380565b61012e610394565b610148610399565b61012e6103bd565b6101ce6103de565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102085781810151838201526020016101f0565b50505050905090810190601f1680156102355780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61012e61046c565b6102746004803603602081101561026157600080fd5b503569ffffffffffffffffffff1661047f565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b61018a61048c565b61012e600480360360208110156102dc57600080fd5b50356104b0565b6101486104b7565b61012e6104db565b61012e6104ff565b610274610505565b670de0b6b3a764000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b601281565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061038a610526565b5091949350505050565b600181565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006103c7610526565b505069ffffffffffffffffffff9092169392505050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104645780601f1061043957610100808354040283529160200191610464565b820191906000526020600020905b81548152906001019060200180831161044757829003601f168201915b505050505081565b6000610476610526565b50949350505050565b6000806000806000806000fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b610e1081565b6000806000806000610515610526565b945094509450945094509091929394565b600080600080600061053661071f565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561059157600080fd5b505afa1580156105a5573d6000803e3d6000fd5b505050506040513d60a08110156105bb57600080fd5b5080516020820151604083015160608401516080909401519299509650919450925090506000811361062b576040805162461bcd60e51b815260206004820152601460248201527321b430b4b73634b735902930ba329022b93937b960611b604482015290519081900360640190fd5b7f0000000000000000000000000000000000000000000000000000000000000000156106a057807f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000028161069c57fe5b0590505b60006106aa61087f565b90506107147f000000000000000000000000000000000000000000000000000000000000000061070e8381670de0b6b3a7640000610708887f0000000000000000000000000000000000000000000000000000000000000000610a61565b90610a61565b90610ab5565b955050509091929394565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161561087d576000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156107aa57600080fd5b505afa1580156107be573d6000803e3d6000fd5b505050506040513d60a08110156107d457600080fd5b50602081015160409091015190925090508115610829576040805162461bcd60e51b815260206004820152600e60248201526d29b2b8bab2b731b2b9102237bbb760911b604482015290519081900360640190fd5b804203610e101061087a576040805162461bcd60e51b815260206004820152601660248201527514d95c5d595b98d95c8811dc9858d94814195c9a5bd960521b604482015290519081900360640190fd5b50505b565b60007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006109ac576109a77f000000000000000000000000000000000000000000000000000000000000000061070e7f0000000000000000000000000000000000000000000000000000000000000000610708856001600160a01b03166307a2d13a7f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561097657600080fd5b505afa15801561098a573d6000803e3d6000fd5b505050506040513d60208110156109a057600080fd5b5051610ae6565b610a5b565b610a5b7f000000000000000000000000000000000000000000000000000000000000000061070e7f0000000000000000000000000000000000000000000000000000000000000000610708856001600160a01b031663c6e6f5927f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561097657600080fd5b91505090565b818102600019831415610a9157811580610a83575082828281610a8057fe5b05145b610a8c57600080fd5b610aaf565b821580610aa6575081838281610aa357fe5b05145b610aaf57600080fd5b92915050565b600081600019148015610acb5750600160ff1b83145b15610ad557600080fd5b818381610ade57fe5b059392505050565b60006001600160ff1b03821115610afc57600080fd5b509056fea26469706673582212201a9bbf76d421f112fc03d5a4d39ae738644656a1c876b3530719f12c8cd57be064736f6c634300070600330000000000000000000000006085b0a8f4c7ffa2e8ca578037792d6535d1e29b00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4e6f74696f6e616c207344414920436861696e6c696e6b204164617074657200

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101215760003560e01c80637284e416116100ad578063b633620c11610071578063b633620c146102c6578063c15ef47a146102e3578063d836d4ae146102eb578063dc60eac9146102f3578063feaf968c146102fb57610121565b80637284e416146101c65780638205bf6a146102435780639a6fc8f51461024b578063a8ecc66d146102be578063b5ab58dc146102c657610121565b806344f8f24d116100f457806344f8f24d1461019e57806350d25bcd146101a657806354fd4d50146101ae578063653ea66f146101b6578063668a0f02146101be57610121565b80631a3480b5146101265780631aafcce314610140578063313ce567146101645780633e374e1614610182575b600080fd5b61012e610303565b60408051918252519081900360200190f35b61014861030f565b604080516001600160a01b039092168252519081900360200190f35b61016c610333565b6040805160ff9092168252519081900360200190f35b61018a610338565b604080519115158252519081900360200190f35b61012e61035c565b61012e610380565b61012e610394565b610148610399565b61012e6103bd565b6101ce6103de565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102085781810151838201526020016101f0565b50505050905090810190601f1680156102355780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61012e61046c565b6102746004803603602081101561026157600080fd5b503569ffffffffffffffffffff1661047f565b604051808669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1681526020019550505050505060405180910390f35b61018a61048c565b61012e600480360360208110156102dc57600080fd5b50356104b0565b6101486104b7565b61012e6104db565b61012e6104ff565b610274610505565b670de0b6b3a764000081565b7f0000000000000000000000006085b0a8f4c7ffa2e8ca578037792d6535d1e29b81565b601281565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b600061038a610526565b5091949350505050565b600181565b7f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea81565b60006103c7610526565b505069ffffffffffffffffffff9092169392505050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104645780601f1061043957610100808354040283529160200191610464565b820191906000526020600020905b81548152906001019060200180831161044757829003601f168201915b505050505081565b6000610476610526565b50949350505050565b6000806000806000806000fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b610e1081565b6000806000806000610515610526565b945094509450945094509091929394565b600080600080600061053661071f565b60007f0000000000000000000000006085b0a8f4c7ffa2e8ca578037792d6535d1e29b6001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561059157600080fd5b505afa1580156105a5573d6000803e3d6000fd5b505050506040513d60a08110156105bb57600080fd5b5080516020820151604083015160608401516080909401519299509650919450925090506000811361062b576040805162461bcd60e51b815260206004820152601460248201527321b430b4b73634b735902930ba329022b93937b960611b604482015290519081900360640190fd5b7f0000000000000000000000000000000000000000000000000000000000000000156106a057807f0000000000000000000000000000000000000000000000000de0b6b3a76400007f0000000000000000000000000000000000000000000000000de0b6b3a7640000028161069c57fe5b0590505b60006106aa61087f565b90506107147f0000000000000000000000000000000000000000000000000de0b6b3a764000061070e8381670de0b6b3a7640000610708887f0000000000000000000000000000000000000000000000000de0b6b3a7640000610a61565b90610a61565b90610ab5565b955050509091929394565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161561087d576000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156107aa57600080fd5b505afa1580156107be573d6000803e3d6000fd5b505050506040513d60a08110156107d457600080fd5b50602081015160409091015190925090508115610829576040805162461bcd60e51b815260206004820152600e60248201526d29b2b8bab2b731b2b9102237bbb760911b604482015290519081900360640190fd5b804203610e101061087a576040805162461bcd60e51b815260206004820152601660248201527514d95c5d595b98d95c8811dc9858d94814195c9a5bd960521b604482015290519081900360640190fd5b50505b565b60007f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea7f00000000000000000000000000000000000000000000000000000000000000006109ac576109a77f0000000000000000000000000000000000000000000000000de0b6b3a764000061070e7f0000000000000000000000000000000000000000000000000de0b6b3a7640000610708856001600160a01b03166307a2d13a7f0000000000000000000000000000000000000000000000000de0b6b3a76400006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561097657600080fd5b505afa15801561098a573d6000803e3d6000fd5b505050506040513d60208110156109a057600080fd5b5051610ae6565b610a5b565b610a5b7f0000000000000000000000000000000000000000000000000de0b6b3a764000061070e7f0000000000000000000000000000000000000000000000000de0b6b3a7640000610708856001600160a01b031663c6e6f5927f0000000000000000000000000000000000000000000000000de0b6b3a76400006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561097657600080fd5b91505090565b818102600019831415610a9157811580610a83575082828281610a8057fe5b05145b610a8c57600080fd5b610aaf565b821580610aa6575081838281610aa357fe5b05145b610aaf57600080fd5b92915050565b600081600019148015610acb5750600160ff1b83145b15610ad557600080fd5b818381610ade57fe5b059392505050565b60006001600160ff1b03821115610afc57600080fd5b509056fea26469706673582212201a9bbf76d421f112fc03d5a4d39ae738644656a1c876b3530719f12c8cd57be064736f6c63430007060033

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

0000000000000000000000006085b0a8f4c7ffa2e8ca578037792d6535d1e29b00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f4e6f74696f6e616c207344414920436861696e6c696e6b204164617074657200

-----Decoded View---------------
Arg [0] : baseToUSDOracle_ (address): 0x6085B0a8f4c7ffA2E8CA578037792D6535d1E29B
Arg [1] : quoteToUSDOracle_ (address): 0x83F20F44975D03b1b09e64809B757c47f942BEeA
Arg [2] : invertBase_ (bool): False
Arg [3] : invertQuote_ (bool): False
Arg [4] : description_ (string): Notional sDAI Chainlink Adapter
Arg [5] : sequencerUptimeOracle_ (address): 0x0000000000000000000000000000000000000000

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000006085b0a8f4c7ffa2e8ca578037792d6535d1e29b
Arg [1] : 00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 000000000000000000000000000000000000000000000000000000000000001f
Arg [7] : 4e6f74696f6e616c207344414920436861696e6c696e6b204164617074657200


Deployed Bytecode Sourcemap

217:1382:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;359:44:0;;;:::i;:::-;;;;;;;;;;;;;;;;580:56;;;:::i;:::-;;;;-1:-1:-1;;;;;580:56:0;;;;;;;;;;;;;;259:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;800:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;752:42;;;:::i;4083:150::-;;;:::i;309:44::-;;;:::i;689:57::-;;;:::i;4405:152::-;;;:::i;410:34::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4239:160;;;:::i;4563:271::-;;;;;;;;;;;;;;;;-1:-1:-1;4563:271:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;838:33;;;:::i;4840:95::-;;;;;;;;;;;;;;;;-1:-1:-1;4840:95:0;;:::i;877:62::-;;;:::i;642:41::-;;;:::i;510:63::-;;;:::i;3832:245::-;;;:::i;359:44::-;397:6;359:44;:::o;580:56::-;;;:::o;259:44::-;301:2;259:44;:::o;800:32::-;;;:::o;752:42::-;;;:::o;4083:150::-;4139:13;4203:23;:21;:23::i;:::-;-1:-1:-1;4164:62:0;;4083:150;-1:-1:-1;;;;4083:150:0:o;309:44::-;352:1;309:44;:::o;689:57::-;;;:::o;4405:152::-;4460:15;4527:23;:21;:23::i;:::-;-1:-1:-1;;4487:63:0;;;;;4405:152;-1:-1:-1;;;4405:152:0:o;410:34::-;;;;;;;;;;;;;;;-1:-1:-1;;410:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4239:160::-;4298:17;4369:23;:21;:23::i;:::-;-1:-1:-1;4327:65:0;4239:160;-1:-1:-1;;;;4239:160:0:o;4563:271::-;4649:6;4679;4708:7;4741;4774:6;4819:8;;;838:33;;;:::o;4840:95::-;4914:6;4924:8;;;877:62;;;:::o;642:41::-;;;:::o;510:63::-;566:7;510:63;:::o;3832:245::-;3900:14;3924:13;3947:17;3974;4001:22;4047:23;:21;:23::i;:::-;4040:30;;;;;;;;;;3832:245;;;;;:::o;2839:987::-;2904:14;2928:13;2951:17;2978;3005:22;3044:17;:15;:17::i;:::-;3072:16;3230:15;-1:-1:-1;;;;;3230:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3230:33:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3230:33:0;-1:-1:-1;3230:33:0;;-1:-1:-1;3230:33:0;-1:-1:-1;3230:33:0;-1:-1:-1;3293:1:0;3281:13;;3273:46;;;;;-1:-1:-1;;;3273:46:0;;;;;;;;;;;;-1:-1:-1;;;3273:46:0;;;;;;;;;;;;;;;3382:10;3378:79;;;3448:9;3427:17;3407;:37;3406:51;;;;;;3394:63;;3378:79;3468:17;3488:15;:13;:15::i;:::-;3468:35;-1:-1:-1;3677:142:0;3801:17;3677:106;3468:35;3677:106;397:6;3677:46;:9;3704:18;3677:26;:46::i;:::-;:63;;:77::i;:::-;:94;;:106::i;:142::-;3668:151;;2839:987;;;;;;;:::o;1787:603::-;1920:21;-1:-1:-1;;;;;1912:44:0;;1908:476;;2026:13;2057:17;2174:21;-1:-1:-1;;;;;2174:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2174:39:0;;;;;;;;;;;-1:-1:-1;2174:39:0;-1:-1:-1;2235:11:0;;2227:38;;;;;-1:-1:-1;;;2227:38:0;;;;;;;;;;;;-1:-1:-1;;;2227:38:0;;;;;;;;;;;;;;;2337:9;2319:15;:27;566:7;2287:59;2279:94;;;;;-1:-1:-1;;;2279:94:0;;;;;;;;;;;;-1:-1:-1;;;2279:94:0;;;;;;;;;;;;;;;1908:476;;;1787:603::o;985:612:1:-;1042:16;1269;1309:11;:281;;1469:121;1574:15;1469:100;1550:18;1469:59;:6;-1:-1:-1;;;;;1469:22:1;;1500:18;1469:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1469:51:1;:57;:59::i;:121::-;1309:281;;;1336:118;1435:18;1336:94;1414:15;1336:56;:6;-1:-1:-1;;;;;1336:22:1;;1367:15;1336:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:118;1297:293;;985:612;;:::o;411:190:3:-;491:5;;;-1:-1:-1;;510:7:3;;506:88;;;528:6;;;:20;;;547:1;542;538;:5;;;;;;:10;528:20;519:30;;;;;;506:88;;;573:6;;;:20;;;592:1;587;583;:5;;;;;;:10;573:20;564:30;;;;;;411:190;;;;:::o;1035:239::-;1091:8;1121:1;-1:-1:-1;;1121:7:3;:27;;;;;-1:-1:-1;;;1132:1:3;:16;1121:27;1119:30;1111:39;;;;;;1266:1;1262;:5;;;;;;;1035:239;-1:-1:-1;;;1035:239:3:o;4888:163:4:-;4937:6;-1:-1:-1;;;;;4964:1:4;:30;;4955:40;;;;;;-1:-1:-1;5042:1:4;4888:163::o

Swarm Source

ipfs://1a9bbf76d421f112fc03d5a4d39ae738644656a1c876b3530719f12c8cd57be0

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.