creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/external/adapters/ChainlinkAdapter.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\n\nimport \"../../math/SafeInt256.sol\";\nimport \"../../../interfaces/chainlink/AggregatorV2V3Interface.sol\";\n\ncontract ChainlinkAdapter is AggregatorV2V3Interface {\n    using SafeInt256 for int256;\n    uint8 public override constant decimals = 18;\n    uint256 public override constant version = 1;\n    int256 public constant rateDecimals = 10**18;\n\n    string public override description;\n    // Grace period after a sequencer downtime has occurred\n    uint256 public constant SEQUENCER_UPTIME_GRACE_PERIOD = 1 hours;\n\n    AggregatorV2V3Interface public immutable baseToUSDOracle;\n    int256 public immutable baseToUSDDecimals;\n    AggregatorV2V3Interface public immutable quoteToUSDOracle;\n    int256 public immutable quoteToUSDDecimals;\n    bool public immutable invertBase;\n    bool public immutable invertQuote;\n    AggregatorV2V3Interface public immutable sequencerUptimeOracle;\n\n    constructor (\n        AggregatorV2V3Interface baseToUSDOracle_,\n        AggregatorV2V3Interface quoteToUSDOracle_,\n        bool invertBase_,\n        bool invertQuote_,\n        string memory description_,\n        AggregatorV2V3Interface sequencerUptimeOracle_\n    ) {\n        description = description_;\n        baseToUSDOracle = baseToUSDOracle_;\n        quoteToUSDOracle = quoteToUSDOracle_;\n        uint8 _baseDecimals = baseToUSDOracle_.decimals();\n        uint8 _quoteDecimals = quoteToUSDOracle_.decimals();\n\n        require(_baseDecimals <= 18);\n        require(_quoteDecimals <= 18);\n\n        baseToUSDDecimals = int256(10**_baseDecimals);\n        quoteToUSDDecimals = int256(10**_quoteDecimals);\n        invertBase = invertBase_;\n        invertQuote = invertQuote_;\n        sequencerUptimeOracle = sequencerUptimeOracle_;\n    }\n\n    function _checkSequencer() private view {\n        // See: https://docs.chain.link/data-feeds/l2-sequencer-feeds/\n        if (address(sequencerUptimeOracle) != address(0)) {\n            (\n                /*uint80 roundID*/,\n                int256 answer,\n                uint256 startedAt,\n                /*uint256 updatedAt*/,\n                /*uint80 answeredInRound*/\n            ) = sequencerUptimeOracle.latestRoundData();\n            require(answer == 0, \"Sequencer Down\");\n            require(SEQUENCER_UPTIME_GRACE_PERIOD < block.timestamp - startedAt, \"Sequencer Grace Period\");\n        }\n    }\n\n    function _getQuoteRate() internal view virtual returns (int256 quoteRate) {\n        (\n            /* roundId */,\n            quoteRate,\n            /* uint256 startedAt */,\n            /* updatedAt */,\n            /* answeredInRound */\n        ) = quoteToUSDOracle.latestRoundData();\n        require(quoteRate > 0, \"Chainlink Rate Error\");\n        if (invertQuote) quoteRate = (quoteToUSDDecimals * quoteToUSDDecimals) / quoteRate;\n    }\n\n    function _calculateBaseToQuote() internal view returns (\n        uint80 roundId,\n        int256 answer,\n        uint256 startedAt,\n        uint256 updatedAt,\n        uint80 answeredInRound\n    ) {\n        _checkSequencer();\n\n        int256 baseToUSD;\n        (\n            roundId,\n            baseToUSD,\n            startedAt,\n            updatedAt,\n            answeredInRound\n        ) = baseToUSDOracle.latestRoundData();\n        require(baseToUSD > 0, \"Chainlink Rate Error\");\n        // Overflow and div by zero not possible\n        if (invertBase) baseToUSD = (baseToUSDDecimals * baseToUSDDecimals) / baseToUSD;\n\n        int256 quoteToUSD = _getQuoteRate();\n\n        // To convert from USDC/USD (base) and ETH/USD (quote) to USDC/ETH we do:\n        // (USDC/USD * quoteDecimals * 1e18) / (ETH/USD * baseDecimals)\n        answer = baseToUSD\n            .mul(quoteToUSDDecimals)\n            .mul(rateDecimals)\n            .div(quoteToUSD)\n            .div(baseToUSDDecimals);\n    }\n\n    function latestRoundData() external view override returns (\n        uint80 roundId,\n        int256 answer,\n        uint256 startedAt,\n        uint256 updatedAt,\n        uint80 answeredInRound\n    ) {\n        return _calculateBaseToQuote();\n    }\n\n    function latestAnswer() external view override returns (int256 answer) {\n        (/* */, answer, /* */, /* */, /* */) = _calculateBaseToQuote();\n    }\n\n    function latestTimestamp() external view override returns (uint256 updatedAt) {\n        (/* */, /* */, /* */, updatedAt, /* */) = _calculateBaseToQuote();\n    }\n\n    function latestRound() external view override returns (uint256 roundId) {\n        (roundId, /* */, /* */, /* */, /* */) = _calculateBaseToQuote();\n    }\n\n    function getRoundData(uint80 /* _roundId */) external view override returns (\n        uint80 /* roundId */,\n        int256 /* answer */,\n        uint256 /* startedAt */,\n        uint256 /* updatedAt */,\n        uint80 /* answeredInRound */\n    ) {\n        revert();\n    }\n\n    function getAnswer(uint256 /* roundId */) external view override returns (int256) { revert(); }\n    function getTimestamp(uint256 /* roundId */) external view override returns (uint256) { revert(); }\n}\n"
      },
      "contracts/global/Constants.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\n\n/// @title All shared constants for the Notional system should be declared here.\nlibrary Constants {\n    uint8 internal constant CETH_DECIMAL_PLACES = 8;\n\n    // Token precision used for all internal balances, TokenHandler library ensures that we\n    // limit the dust amount caused by precision mismatches\n    int256 internal constant INTERNAL_TOKEN_PRECISION = 1e8;\n    uint256 internal constant INCENTIVE_ACCUMULATION_PRECISION = 1e18;\n\n    // ETH will be initialized as the first currency\n    uint256 internal constant ETH_CURRENCY_ID = 1;\n    uint8 internal constant ETH_DECIMAL_PLACES = 18;\n    int256 internal constant ETH_DECIMALS = 1e18;\n    address internal constant ETH_ADDRESS = address(0);\n    // Used to prevent overflow when converting decimal places to decimal precision values via\n    // 10**decimalPlaces. This is a safe value for int256 and uint256 variables. We apply this\n    // constraint when storing decimal places in governance.\n    uint256 internal constant MAX_DECIMAL_PLACES = 36;\n\n    // Address of the account where fees are collected\n    address internal constant FEE_RESERVE = 0x0000000000000000000000000000000000000FEE;\n    // Address of the account where settlement funds are collected, this is only\n    // used for off chain event tracking.\n    address internal constant SETTLEMENT_RESERVE = 0x00000000000000000000000000000000000005e7;\n\n    // Most significant bit\n    bytes32 internal constant MSB =\n        0x8000000000000000000000000000000000000000000000000000000000000000;\n\n    // Each bit set in this mask marks where an active market should be in the bitmap\n    // if the first bit refers to the reference time. Used to detect idiosyncratic\n    // fcash in the nToken accounts\n    bytes32 internal constant ACTIVE_MARKETS_MASK = (\n        MSB >> ( 90 - 1) | // 3 month\n        MSB >> (105 - 1) | // 6 month\n        MSB >> (135 - 1) | // 1 year\n        MSB >> (147 - 1) | // 2 year\n        MSB >> (183 - 1) | // 5 year\n        MSB >> (211 - 1) | // 10 year\n        MSB >> (251 - 1)   // 20 year\n    );\n\n    // Basis for percentages\n    int256 internal constant PERCENTAGE_DECIMALS = 100;\n    // Min Buffer Scale and Buffer Scale are used in ExchangeRate to increase the maximum\n    // possible buffer values at the higher end of the uint8 range.\n    int256 internal constant MIN_BUFFER_SCALE = 150;\n    int256 internal constant BUFFER_SCALE = 10;\n    // Max number of traded markets, also used as the maximum number of assets in a portfolio array\n    uint256 internal constant MAX_TRADED_MARKET_INDEX = 7;\n    // Max number of fCash assets in a bitmap, this is based on the gas costs of calculating free collateral\n    // for a bitmap portfolio\n    uint256 internal constant MAX_BITMAP_ASSETS = 20;\n    uint256 internal constant FIVE_MINUTES = 300;\n\n    // Internal date representations, note we use a 6/30/360 week/month/year convention here\n    uint256 internal constant DAY = 86400;\n    // We use six day weeks to ensure that all time references divide evenly\n    uint256 internal constant WEEK = DAY * 6;\n    uint256 internal constant MONTH = WEEK * 5;\n    uint256 internal constant QUARTER = MONTH * 3;\n    uint256 internal constant YEAR = QUARTER * 4;\n    \n    // These constants are used in DateTime.sol\n    uint256 internal constant DAYS_IN_WEEK = 6;\n    uint256 internal constant DAYS_IN_MONTH = 30;\n    uint256 internal constant DAYS_IN_QUARTER = 90;\n\n    // Offsets for each time chunk denominated in days\n    uint256 internal constant MAX_DAY_OFFSET = 90;\n    uint256 internal constant MAX_WEEK_OFFSET = 360;\n    uint256 internal constant MAX_MONTH_OFFSET = 2160;\n    uint256 internal constant MAX_QUARTER_OFFSET = 7650;\n\n    // Offsets for each time chunk denominated in bits\n    uint256 internal constant WEEK_BIT_OFFSET = 90;\n    uint256 internal constant MONTH_BIT_OFFSET = 135;\n    uint256 internal constant QUARTER_BIT_OFFSET = 195;\n\n    // Number of decimal places that rates are stored in, equals 100%\n    int256 internal constant RATE_PRECISION = 1e9;\n    // Used for prime cash scalars\n    uint256 internal constant SCALAR_PRECISION = 1e18;\n    // Used in prime rate lib\n    int256 internal constant DOUBLE_SCALAR_PRECISION = 1e36;\n    // One basis point in RATE_PRECISION terms\n    uint256 internal constant BASIS_POINT = uint256(RATE_PRECISION / 10000);\n    // Used to when calculating the amount to deleverage of a market when minting nTokens\n    uint256 internal constant DELEVERAGE_BUFFER = 300 * BASIS_POINT;\n    // Used for scaling cash group factors\n    uint256 internal constant FIVE_BASIS_POINTS = 5 * BASIS_POINT;\n    // Used for residual purchase incentive and cash withholding buffer\n    uint256 internal constant TEN_BASIS_POINTS = 10 * BASIS_POINT;\n    // Used for max oracle rate\n    uint256 internal constant FIFTEEN_BASIS_POINTS = 15 * BASIS_POINT;\n    // Used in max rate calculations\n    uint256 internal constant MAX_LOWER_INCREMENT = 150;\n    uint256 internal constant MAX_LOWER_INCREMENT_VALUE = 150 * 25 * BASIS_POINT;\n    uint256 internal constant TWENTY_FIVE_BASIS_POINTS = 25 * BASIS_POINT;\n    uint256 internal constant ONE_HUNDRED_FIFTY_BASIS_POINTS = 150 * BASIS_POINT;\n\n    // This is the ABDK64x64 representation of RATE_PRECISION\n    // RATE_PRECISION_64x64 = ABDKMath64x64.fromUint(RATE_PRECISION)\n    int128 internal constant RATE_PRECISION_64x64 = 0x3b9aca000000000000000000;\n\n    uint8 internal constant FCASH_ASSET_TYPE          = 1;\n    // Liquidity token asset types are 1 + marketIndex (where marketIndex is 1-indexed)\n    uint8 internal constant MIN_LIQUIDITY_TOKEN_INDEX = 2;\n    uint8 internal constant MAX_LIQUIDITY_TOKEN_INDEX = 8;\n    uint8 internal constant VAULT_SHARE_ASSET_TYPE    = 9;\n    uint8 internal constant VAULT_DEBT_ASSET_TYPE     = 10;\n    uint8 internal constant VAULT_CASH_ASSET_TYPE     = 11;\n    // Used for tracking legacy nToken assets\n    uint8 internal constant LEGACY_NTOKEN_ASSET_TYPE  = 12;\n\n    // Account context flags\n    bytes1 internal constant HAS_ASSET_DEBT           = 0x01;\n    bytes1 internal constant HAS_CASH_DEBT            = 0x02;\n    bytes2 internal constant ACTIVE_IN_PORTFOLIO      = 0x8000;\n    bytes2 internal constant ACTIVE_IN_BALANCES       = 0x4000;\n    bytes2 internal constant UNMASK_FLAGS             = 0x3FFF;\n    uint16 internal constant MAX_CURRENCIES           = uint16(UNMASK_FLAGS);\n\n    // Equal to 100% of all deposit amounts for nToken liquidity across fCash markets.\n    int256 internal constant DEPOSIT_PERCENT_BASIS    = 1e8;\n\n    // nToken Parameters: there are offsets in the nTokenParameters bytes6 variable returned\n    // in nTokenHandler. Each constant represents a position in the byte array.\n    uint8 internal constant LIQUIDATION_HAIRCUT_PERCENTAGE = 0;\n    uint8 internal constant CASH_WITHHOLDING_BUFFER = 1;\n    uint8 internal constant RESIDUAL_PURCHASE_TIME_BUFFER = 2;\n    uint8 internal constant PV_HAIRCUT_PERCENTAGE = 3;\n    uint8 internal constant RESIDUAL_PURCHASE_INCENTIVE = 4;\n    uint8 internal constant MAX_MINT_DEVIATION_LIMIT = 5;\n\n    // Liquidation parameters\n    // Default percentage of collateral that a liquidator is allowed to liquidate, will be higher if the account\n    // requires more collateral to be liquidated\n    int256 internal constant DEFAULT_LIQUIDATION_PORTION = 40;\n    // Percentage of local liquidity token cash claim delivered to the liquidator for liquidating liquidity tokens\n    int256 internal constant TOKEN_REPO_INCENTIVE_PERCENT = 30;\n\n    // Pause Router liquidation enabled states\n    bytes1 internal constant LOCAL_CURRENCY_ENABLED = 0x01;\n    bytes1 internal constant COLLATERAL_CURRENCY_ENABLED = 0x02;\n    bytes1 internal constant LOCAL_FCASH_ENABLED = 0x04;\n    bytes1 internal constant CROSS_CURRENCY_FCASH_ENABLED = 0x08;\n\n    // Requires vault accounts to enter a position for a minimum of 1 min\n    // to mitigate strange behavior where accounts may enter and exit using\n    // flash loans or other MEV type behavior.\n    uint256 internal constant VAULT_ACCOUNT_MIN_TIME = 1 minutes;\n\n    // Placeholder constant to mark the variable rate prime cash maturity\n    uint40 internal constant PRIME_CASH_VAULT_MATURITY = type(uint40).max;\n\n    // This represents the maximum percent change allowed before and after \n    // a rebalancing. 100_000 represents a 0.01% change\n    // as a result of rebalancing. We should expect to never lose value as\n    // a result of rebalancing, but some rounding errors may exist as a result\n    // of redemption and deposit.\n    int256 internal constant REBALANCING_UNDERLYING_DELTA_PERCENT = 100_000;\n\n    // Ensures that the minimum total underlying held by the contract continues\n    // to accrue interest so that money market oracle rates are properly updated\n    // between rebalancing. With a minimum rebalancing cool down time of 6 hours\n    // we would be able to detect at least 1 unit of accrual at 8 decimal precision\n    // at an interest rate of 2.8 basis points (0.0288%) with 0.05e8 minimum balance\n    // held in a given token.\n    //\n    //                          MIN_ACCRUAL * (86400 / REBALANCING_COOL_DOWN_HOURS)\n    // MINIMUM_INTEREST_RATE =  ---------------------------------------------------\n    //                                     MINIMUM_UNDERLYING_BALANCE\n    int256 internal constant MIN_TOTAL_UNDERLYING_VALUE = 0.05e8;\n}\n"
      },
      "contracts/math/SafeInt256.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\n\nimport {Constants} from \"../global/Constants.sol\";\n\nlibrary SafeInt256 {\n    int256 private constant _INT256_MIN = type(int256).min;\n\n    /// @dev Returns the multiplication of two signed integers, reverting on\n    /// overflow.\n\n    /// Counterpart to Solidity's `*` operator.\n\n    /// Requirements:\n\n    /// - Multiplication cannot overflow.\n\n    function mul(int256 a, int256 b) internal pure returns (int256 c) {\n        c = a * b;\n        if (a == -1) require (b == 0 || c / b == a);\n        else require (a == 0 || c / a == b);\n    }\n\n    /// @dev Returns the integer division of two signed integers. Reverts on\n    /// division by zero. The result is rounded towards zero.\n\n    /// Counterpart to Solidity's `/` operator. Note: this function uses a\n    /// `revert` opcode (which leaves remaining gas untouched) while Solidity\n    /// uses an invalid opcode to revert (consuming all remaining gas).\n\n    /// Requirements:\n\n    /// - The divisor cannot be zero.\n\n    function div(int256 a, int256 b) internal pure returns (int256 c) {\n        require(!(b == -1 && a == _INT256_MIN)); // dev: int256 div overflow\n        // NOTE: solidity will automatically revert on divide by zero\n        c = a / b;\n    }\n\n    function sub(int256 x, int256 y) internal pure returns (int256 z) {\n        //  taken from uniswap v3\n        require((z = x - y) <= x == (y >= 0));\n    }\n\n    function add(int256 x, int256 y) internal pure returns (int256 z) {\n        require((z = x + y) >= x == (y >= 0));\n    }\n\n    function neg(int256 x) internal pure returns (int256 y) {\n        return mul(-1, x);\n    }\n\n    function abs(int256 x) internal pure returns (int256) {\n        if (x < 0) return neg(x);\n        else return x;\n    }\n\n    function subNoNeg(int256 x, int256 y) internal pure returns (int256 z) {\n        z = sub(x, y);\n        require(z >= 0); // dev: int256 sub to negative\n\n        return z;\n    }\n\n    /// @dev Calculates x * RATE_PRECISION / y while checking overflows\n    function divInRatePrecision(int256 x, int256 y) internal pure returns (int256) {\n        return div(mul(x, Constants.RATE_PRECISION), y);\n    }\n\n    /// @dev Calculates x * y / RATE_PRECISION while checking overflows\n    function mulInRatePrecision(int256 x, int256 y) internal pure returns (int256) {\n        return div(mul(x, y), Constants.RATE_PRECISION);\n    }\n\n    function toUint(int256 x) internal pure returns (uint256) {\n        require(x >= 0);\n        return uint256(x);\n    }\n\n    function toInt(uint256 x) internal pure returns (int256) {\n        require (x <= uint256(type(int256).max)); // dev: toInt overflow\n        return int256(x);\n    }\n\n    function toInt80(int256 x) internal pure returns (int80) {\n        require (int256(type(int80).min) <= x && x <= int256(type(int80).max)); // dev: toInt overflow\n        return int80(x);\n    }\n\n    function toInt88(int256 x) internal pure returns (int88) {\n        require (int256(type(int88).min) <= x && x <= int256(type(int88).max)); // dev: toInt overflow\n        return int88(x);\n    }\n\n    function toInt128(int256 x) internal pure returns (int128) {\n        require (int256(type(int128).min) <= x && x <= int256(type(int128).max)); // dev: toInt overflow\n        return int128(x);\n    }\n\n    function max(int256 x, int256 y) internal pure returns (int256) {\n        return x > y ? x : y;\n    }\n\n    function min(int256 x, int256 y) internal pure returns (int256) {\n        return x < y ? x : y;\n    }\n\n    /// @notice Returns the net change in negative signed values, used for\n    /// determining the (positive) amount of debt change\n    function negChange(int256 start, int256 end) internal pure returns (int256) {\n        // No change in these two scenarios\n        if (start == end || (start >= 0 && end >= 0)) return 0;\n        if (start <= 0 && 0 < end) {\n            // Negative portion has been eliminated so the net change on the\n            // negative side is start (i.e. a reduction in the negative balance)\n            return start;\n        } else if (end <= 0 && 0 < start) {\n            // Entire negative portion has been created so the net change on the\n            // negative side is -end (i.e. an increase in the negative balance)\n            return neg(end);\n        } else if (start <= 0 && end <= 0) {\n            // There is some net change in the negative amounts.\n            // If start < end then this is negative, debt has been reduced\n            // If end < start then this is positive, debt has been increased\n            return sub(start, end);\n        }\n\n        // Should never get to this point\n        revert();\n    }\n}\n"
      },
      "interfaces/chainlink/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\ninterface AggregatorInterface {\n  function latestAnswer() external view returns (int256);\n  function latestTimestamp() external view returns (uint256);\n  function latestRound() external view returns (uint256);\n  function getAnswer(uint256 roundId) external view returns (int256);\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}"
      },
      "interfaces/chainlink/AggregatorV2V3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface\n{\n}"
      },
      "interfaces/chainlink/AggregatorV3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\ninterface AggregatorV3Interface {\n\n  function decimals() external view returns (uint8);\n  function description() external view returns (string memory);\n  function version() external view returns (uint256);\n\n  // getRoundData and latestRoundData should both raise \"No data present\"\n  // if they do not have data to report, instead of returning unset values\n  // which could be misinterpreted as actual reported values.\n  function getRoundData(uint80 _roundId)\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n\n  function latestRoundData()\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}