creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/cryptography/MerkleProof.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\n */\nlibrary MerkleProof {\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        bytes32 computedHash = leaf;\n\n        for (uint256 i = 0; i < proof.length; i++) {\n            bytes32 proofElement = proof[i];\n\n            if (computedHash <= proofElement) {\n                // Hash(current computed hash + current element of the proof)\n                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n            } else {\n                // Hash(current element of the proof + current computed hash)\n                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n            }\n        }\n\n        // Check if the computed hash (root) is equal to the provided root\n        return computedHash == root;\n    }\n}\n"
      },
      "contracts/external/adapters/SecondaryRewarder.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity =0.7.6;\n\nimport {GenericToken} from \"../../internal/balances/protocols/GenericToken.sol\";\nimport {IRewarder} from \"../../../interfaces/notional/IRewarder.sol\";\nimport {NotionalProxy} from \"../../../interfaces/notional/NotionalProxy.sol\";\nimport {IERC20} from \"../../../interfaces/IERC20.sol\";\nimport {IEIP20NonStandard} from \"../../../interfaces/IEIP20NonStandard.sol\";\nimport {Constants} from \"../../global/Constants.sol\";\nimport {SafeInt256} from \"../../math/SafeInt256.sol\";\nimport {SafeUint256} from \"../../math/SafeUint256.sol\";\nimport {FloatingPoint} from \"../../math/FloatingPoint.sol\";\nimport {MerkleProof} from \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\n\ncontract SecondaryRewarder is IRewarder {\n    using SafeUint256 for uint256;\n    using SafeInt256 for int256;\n\n    NotionalProxy public immutable NOTIONAL;\n    address public immutable override NTOKEN_ADDRESS;\n    address public immutable REWARD_TOKEN;\n    uint8 public immutable REWARD_TOKEN_DECIMALS;\n    uint16 public immutable override CURRENCY_ID;\n\n    /// @notice When a rewarder is detached, it converts to an airdrop contract using the\n    /// this merkleRoot that is set.\n    /// @dev Uses a single storage slot\n    bytes32 public merkleRoot;\n\n    /* Rest of storage variables are packed into 256 bits */\n    /// @notice When true user needs to call contract directly to claim any rewards left\n    bool public override detached;\n\n    /// @notice Marks the timestamp when incentives will end. Will always be less than block.timestamp\n    /// if detached is true.\n    uint32 public endTime;\n\n    /// @notice Last time the contract accumulated the reward\n    uint32 public override lastAccumulatedTime;\n\n    // The emission rate of REWARD_TOKEN in INTERNAL_TOKEN_PRECISION packed to uint56\n    uint56 private packedEmissionRatePerYear;\n\n    /// @notice Aggregate tokens accumulated per nToken at `lastAccumulateTime` \n    //  in INCENTIVE_ACCUMULATION_PRECISION\n    uint128 public override accumulatedRewardPerNToken;\n\n    /// @notice Reward debt per account stored in 18 decimals.\n    mapping(address => uint128) public rewardDebtPerAccount;\n\n    modifier onlyOwner() {\n        require(msg.sender == NOTIONAL.owner(), \"Only owner\");\n        _;\n    }\n\n    modifier onlyNotional() {\n        require(msg.sender == address(NOTIONAL), \"Only Notional\");\n        _;\n    }\n\n    constructor(\n        NotionalProxy notional,\n        uint16 currencyId,\n        IERC20 incentive_token,\n        uint128 _emissionRatePerYear, // in INTERNAL_TOKEN_PRECISION\n        uint32 _endTime\n    ) {\n        NOTIONAL = notional;\n        CURRENCY_ID = currencyId;\n        NTOKEN_ADDRESS = notional.nTokenAddress(currencyId);\n        REWARD_TOKEN = address(incentive_token);\n        REWARD_TOKEN_DECIMALS = IERC20(address(incentive_token)).decimals();\n\n        packedEmissionRatePerYear = FloatingPoint.packTo56Bits(_emissionRatePerYear);\n        lastAccumulatedTime = uint32(block.timestamp);\n        require(lastAccumulatedTime < _endTime, \"Invalid End Time\");\n        endTime = _endTime;\n    }\n\n    /// @notice The emission rate of REWARD_TOKEN in INTERNAL_TOKEN_PRECISION\n    function emissionRatePerYear() public view override returns(uint128) {\n        return uint128(FloatingPoint.unpackFromBits(packedEmissionRatePerYear));\n    }\n\n    /// @notice Get amount of reward account can claim at specified block time, only called before rewarder is detached\n    /// @param account address to get reward amount for\n    /// @param blockTime block time at which to get reward amount\n    function getAccountRewardClaim(address account, uint32 blockTime)\n        external\n        view\n        override\n        returns (uint256 rewardToClaim)\n    {\n        require(!detached, \"Detached\");\n        require(lastAccumulatedTime <= blockTime, \"Invalid block time\");\n\n        uint256 totalSupply = IERC20(NTOKEN_ADDRESS).totalSupply();\n        uint256 nTokenBalance = IERC20(NTOKEN_ADDRESS).balanceOf(account);\n\n        uint32 time = uint32(SafeInt256.min(blockTime, endTime));\n        uint128 rewardsPerNToken = _getAccumulatedRewardPerToken(time, totalSupply);\n        rewardToClaim = _calculateRewardToClaim(account, nTokenBalance, rewardsPerNToken);\n    }\n\n    /// @notice Get amount of reward still left for account to claim, only called after rewarder is detached\n    /// and merkle root is set\n    /// @param account address to get reward amount for\n    /// @param nTokenBalanceAtDetach nToken balance of account at time of detachment\n    /// @param proof merkle proof to prove account and nTokenBalanceAtDetach are in tree\n    function getAccountRewardClaim(address account, uint256 nTokenBalanceAtDetach, bytes32[] calldata proof)\n        external\n        view\n        override\n        returns (uint256 rewardToClaim)\n    {\n        require(detached && merkleRoot != bytes32(0), \"Not detached\");\n\n        _checkProof(account, nTokenBalanceAtDetach, proof);\n        // no need to accumulate, it was already accumulated when rewarder was detached\n        rewardToClaim = _calculateRewardToClaim(account, nTokenBalanceAtDetach, accumulatedRewardPerNToken);\n    }\n\n    /// @notice Set incentive emission rate and incentive period end time, called only in case emission\n    /// rate or incentive period changes since it is already set at deploy time, only can be called before\n    /// rewarder is detached\n    /// @param _emissionRatePerYear emission rate per year in INTERNAL_TOKEN_PRECISION\n    /// @param _endTime time in seconds when incentive period will end\n    function setIncentiveEmissionRate(uint128 _emissionRatePerYear, uint32 _endTime) external onlyOwner {\n        require(!detached, \"Detached\");\n        uint256 totalSupply = IERC20(NTOKEN_ADDRESS).totalSupply();\n\n        _accumulateRewardPerNToken(uint32(block.timestamp), totalSupply);\n\n        packedEmissionRatePerYear = FloatingPoint.packTo56Bits(_emissionRatePerYear);\n        // lastAccumulatedTime is at block.timestamp here, ensure that the end time is always\n        // further in the future.\n        require(lastAccumulatedTime < _endTime, \"Invalid End Time\");\n        endTime = _endTime;\n\n        emit RewardEmissionUpdate(FloatingPoint.unpackFromBits(packedEmissionRatePerYear), _endTime);\n    }\n\n    /// @notice Set merkle root, only called after rewarder is detached\n    /// @param _merkleRoot merkle root of the tree that contains accounts and nToken balances at detach time\n    function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {\n        require(_merkleRoot != bytes32(0), \"Invalid\");\n        merkleRoot = _merkleRoot;\n    }\n\n    /// @notice Allows owner to recover any ERC20 or ETH mistakenly sent to this contract\n    /// @param token address of the token to recover, in case of ETH pass address(0)\n    /// @param amount amount to recover\n    function recover(address token, uint256 amount) external onlyOwner {\n        if (Constants.ETH_ADDRESS == token) {\n            (bool status,) = msg.sender.call{value: amount}(\"\");\n            require(status);\n        } else {\n            GenericToken.safeTransferOut(token, msg.sender, amount);\n        }\n    }\n\n    /// @dev Called from Notional system to detach rewarder when switching to a new rewarder or when incentive\n    /// period is over, after this merkle tree of user nToken balances at detach time should be generated\n    /// offline and merkle root uploaded to this contract\n    function detach() external override onlyNotional {\n        require(!detached, \"Already detached\");\n\n        // accumulate for the last time if needed\n        uint256 totalSupply = IERC20(NTOKEN_ADDRESS).totalSupply();\n        _accumulateRewardPerNToken(uint32(block.timestamp), totalSupply);\n\n        detached = true;\n        packedEmissionRatePerYear = 0;\n\n        if (block.timestamp < endTime) {\n            endTime = uint32(block.timestamp);\n        }\n\n        emit RewardEmissionUpdate(0, endTime);\n    }\n\n    /// @notice Allows claiming rewards after rewarder has been detached\n    /// @param account address to claim rewards for\n    /// @param nTokenBalanceAtDetach nToken balance of account at time of detachment\n    /// @param proof merkle proof to prove account and nTokenBalanceAtDetach are in tree\n    function claimRewardsDirect(address account, uint256 nTokenBalanceAtDetach, bytes32[] calldata proof)\n        external\n        override\n    {\n        require(detached, \"Not detached\");\n\n        _checkProof(account, nTokenBalanceAtDetach, proof);\n\n        _claimRewards(account, nTokenBalanceAtDetach, nTokenBalanceAtDetach);\n    }\n\n    /// @notice Allows claiming rewards but only from Notional system, called on each nToken balance change\n    /// @param account address to claim rewards for\n    /// @param currencyId id number of the currency\n    /// @param nTokenBalanceBefore account nToken balance before the change\n    /// @param nTokenBalanceAfter account nToken balance after the change\n    /// @param priorNTokenSupply total nToken supply before the change\n    function claimRewards(\n        address account,\n        uint16 currencyId,\n        uint256 nTokenBalanceBefore,\n        uint256 nTokenBalanceAfter,\n        uint256 priorNTokenSupply\n    ) external override onlyNotional {\n        require(!detached, \"Detached\");\n        require(currencyId == CURRENCY_ID, \"Wrong currency id\");\n\n        _accumulateRewardPerNToken(uint32(block.timestamp), priorNTokenSupply);\n        _claimRewards(account, nTokenBalanceBefore, nTokenBalanceAfter);\n    }\n\n    function _claimRewards(address account, uint256 nTokenBalanceBefore, uint256 nTokenBalanceAfter) private {\n        uint256 rewardToClaim = _calculateRewardToClaim(account, nTokenBalanceBefore, accumulatedRewardPerNToken);\n\n        // Precision here is:\n        //  nTokenBalanceAfter (INTERNAL_TOKEN_PRECISION)\n        //  accumulatedRewardPerNToken (INCENTIVE_ACCUMULATION_PRECISION)\n        // DIVIDE BY\n        //  INTERNAL_TOKEN_PRECISION\n        //  => INCENTIVE_ACCUMULATION_PRECISION (1e18)\n        rewardDebtPerAccount[account] = nTokenBalanceAfter\n            .mul(accumulatedRewardPerNToken)\n            .div(uint256(Constants.INTERNAL_TOKEN_PRECISION))\n            .toUint128();\n\n        if (0 < rewardToClaim) {\n            try IEIP20NonStandard(REWARD_TOKEN).transfer(account, rewardToClaim) {\n                bool success = checkReturnCode();\n                if (success) {\n                    emit RewardTransfer(REWARD_TOKEN, account, rewardToClaim);\n                }\n            // ignore failed reward transfers\n            } catch {}\n        }\n    }\n\n    function _getAccumulatedRewardPerToken(uint32 time, uint256 totalSupply) private view returns (uint128) {\n        uint256 additionalIncentiveAccumulatedPerNToken;\n        if (lastAccumulatedTime < time && 0 < totalSupply) {\n            // NOTE: no underflow, checked in if statement\n            uint256 timeSinceLastAccumulation = time - lastAccumulatedTime;\n            // Precision here is:\n            //  timeSinceLastAccumulation (SECONDS)\n            //  INCENTIVE_ACCUMULATION_PRECISION (1e18)\n            //  INTERNAL_TOKEN_PRECISION (1e8)\n            // DIVIDE BY\n            //  YEAR (SECONDS)\n            //  INTERNAL_TOKEN_PRECISION (1e8)\n            // => Precision = INCENTIVE_ACCUMULATION_PRECISION * INTERNAL_TOKEN_PRECISION / INTERNAL_TOKEN_PRECISION\n            // => 1e18\n            additionalIncentiveAccumulatedPerNToken = timeSinceLastAccumulation\n                .mul(Constants.INCENTIVE_ACCUMULATION_PRECISION)\n                .mul(emissionRatePerYear())\n                .div(Constants.YEAR)\n                .div(totalSupply);\n        }\n\n        return uint256(accumulatedRewardPerNToken).add(additionalIncentiveAccumulatedPerNToken).toUint128();\n    }\n\n    function _accumulateRewardPerNToken(uint32 blockTime, uint256 totalSupply) private {\n        // Ensure that end time is set to some value\n        require(0 < endTime);\n        uint32 time = uint32(SafeInt256.min(blockTime, endTime));\n\n        accumulatedRewardPerNToken = _getAccumulatedRewardPerToken(time, totalSupply);\n\n        lastAccumulatedTime = uint32(block.timestamp);\n    }\n\n    function _calculateRewardToClaim(address account, uint256 nTokenBalanceAtLastClaim, uint128 rewardsPerNToken)\n        private\n        view\n        returns (uint256)\n    {\n        // Precision here is:\n        //   nTokenBalanceAtLastClaim (INTERNAL_TOKEN_PRECISION)\n        //   mul rewardsPerNToken (INCENTIVE_ACCUMULATION_PRECISION)\n        //   div INTERNAL_TOKEN_PRECISION\n        // => INCENTIVE_ACCUMULATION_PRECISION\n        // SUB rewardDebtPerAccount (INCENTIVE_ACCUMULATION_PRECISION)\n        //\n        // - mul REWARD_TOKEN_DECIMALS\n        // - div INCENTIVE_ACCUMULATION_PRECISION\n        // => REWARD_TOKEN_DECIMALS\n        return uint256(nTokenBalanceAtLastClaim)\n            .mul(rewardsPerNToken)\n            .div(uint256(Constants.INTERNAL_TOKEN_PRECISION))\n            .sub(rewardDebtPerAccount[account])\n            .mul(10 ** REWARD_TOKEN_DECIMALS)\n            .div(Constants.INCENTIVE_ACCUMULATION_PRECISION);\n    }\n\n    /// @notice Verify merkle proof, or revert if not in tree\n    function _checkProof(address account, uint256 balance, bytes32[] calldata proof) private view {\n        // Verify merkle proof, or revert if not in tree\n        bytes32 leaf = keccak256(abi.encodePacked(account, balance));\n        bool isValidLeaf = MerkleProof.verify(proof, merkleRoot, leaf);\n        require(isValidLeaf, \"NotInMerkle\");\n    }\n\n    function checkReturnCode() private pure returns(bool success) {\n        uint256[1] memory result;\n        assembly {\n            switch returndatasize()\n                case 0 {\n                    // This is a non-standard ERC-20\n                    success := 1 // set success to true\n                }\n                case 32 {\n                    // This is a compliant ERC-20\n                    returndatacopy(result, 0, 32)\n                    success := mload(result) // Set `success = returndata` of external call\n                }\n                default {\n                    // This is an excessively non-compliant ERC-20.\n                    success := 0\n                }\n        }\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/global/Deployments.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\n\nimport {WETH9} from \"../../interfaces/WETH9.sol\";\nimport {IUpgradeableBeacon} from \"../proxy/beacon/IBeacon.sol\";\nimport {AggregatorV2V3Interface} from \"../../interfaces/chainlink/AggregatorV2V3Interface.sol\";\n\n/// @title Hardcoded deployed contracts are listed here. These are hardcoded to reduce\n/// gas costs for immutable addresses. They must be updated per environment that Notional\n/// is deployed to.\nlibrary Deployments {\n    uint256 internal constant MAINNET = 1;\n    uint256 internal constant ARBITRUM_ONE = 42161;\n    uint256 internal constant LOCAL = 1337;\n\n    // MAINNET: 0xCFEAead4947f0705A14ec42aC3D44129E1Ef3eD5\n    address internal constant NOTE_TOKEN_ADDRESS = 0xCFEAead4947f0705A14ec42aC3D44129E1Ef3eD5;\n    // ARBITRUM: 0x019bE259BC299F3F653688c7655C87F998Bc7bC1\n    // address internal constant NOTE_TOKEN_ADDRESS = 0x019bE259BC299F3F653688c7655C87F998Bc7bC1;\n\n    // MAINNET: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n    WETH9 internal constant WETH = WETH9(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);\n    // ARBITRUM: 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\n    // WETH9 internal constant WETH = WETH9(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1);\n    // OPTIMISM: 0x4200000000000000000000000000000000000006\n\n    // Chainlink L2 Sequencer Uptime: https://docs.chain.link/data-feeds/l2-sequencer-feeds/\n    // MAINNET: NOT SET\n    AggregatorV2V3Interface internal constant SEQUENCER_UPTIME_ORACLE = AggregatorV2V3Interface(address(0));\n    // ARBITRUM: 0xFdB631F5EE196F0ed6FAa767959853A9F217697D\n    // AggregatorV2V3Interface internal constant SEQUENCER_UPTIME_ORACLE = AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D);\n\n    enum BeaconType {\n        NTOKEN,\n        PCASH,\n        PDEBT,\n        WRAPPED_FCASH\n    }\n\n    // NOTE: these are temporary Beacon addresses\n    IUpgradeableBeacon internal constant NTOKEN_BEACON = IUpgradeableBeacon(0xc4FD259b816d081C8bdd22D6bbd3495DB1573DB7);\n    IUpgradeableBeacon internal constant PCASH_BEACON = IUpgradeableBeacon(0x1F681977aF5392d9Ca5572FB394BC4D12939A6A9);\n    IUpgradeableBeacon internal constant PDEBT_BEACON = IUpgradeableBeacon(0xDF08039c0af34E34660aC7c2705C0Da953247640);\n    // Mainnet:\n    IUpgradeableBeacon internal constant WRAPPED_FCASH_BEACON = IUpgradeableBeacon(0xEBe1BF1653d55d31F6ED38B1A4CcFE2A92338f66);\n    // Arbitrum:\n    // IUpgradeableBeacon internal constant WRAPPED_FCASH_BEACON = IUpgradeableBeacon(0xD676d720E4e8B14F545F9116F0CAD47aF32329DD);\n    \n\n    // NOTE: this is unused and should be removed if the contract is ever deployed again\n    uint256 internal constant NOTIONAL_V2_FINAL_SETTLEMENT = 0;\n}\n"
      },
      "contracts/global/Types.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../interfaces/chainlink/AggregatorV2V3Interface.sol\";\nimport \"../../interfaces/notional/IPrimeCashHoldingsOracle.sol\";\nimport \"../../interfaces/notional/AssetRateAdapter.sol\";\n\n/// @notice Different types of internal tokens\n///  - UnderlyingToken: underlying asset for a cToken (except for Ether)\n///  - cToken: Compound interest bearing token\n///  - cETH: Special handling for cETH tokens\n///  - Ether: the one and only\n///  - NonMintable: tokens that do not have an underlying (therefore not cTokens)\n///  - aToken: Aave interest bearing tokens\nenum TokenType {\n    UnderlyingToken,\n    cToken,\n    cETH,\n    Ether,\n    NonMintable,\n    aToken\n}\n\n/// @notice Specifies the different trade action types in the system. Each trade action type is\n/// encoded in a tightly packed bytes32 object. Trade action type is the first big endian byte of the\n/// 32 byte trade action object. The schemas for each trade action type are defined below.\nenum TradeActionType {\n    // (uint8 TradeActionType, uint8 MarketIndex, uint88 fCashAmount, uint32 minImpliedRate, uint120 unused)\n    Lend,\n    // (uint8 TradeActionType, uint8 MarketIndex, uint88 fCashAmount, uint32 maxImpliedRate, uint128 unused)\n    Borrow,\n    // (uint8 TradeActionType, uint8 MarketIndex, uint88 primeCashAmount, uint32 minImpliedRate, uint32 maxImpliedRate, uint88 unused)\n    AddLiquidity,\n    // (uint8 TradeActionType, uint8 MarketIndex, uint88 tokenAmount, uint32 minImpliedRate, uint32 maxImpliedRate, uint88 unused)\n    RemoveLiquidity,\n    // (uint8 TradeActionType, uint32 Maturity, int88 fCashResidualAmount, uint128 unused)\n    PurchaseNTokenResidual,\n    // (uint8 TradeActionType, address CounterpartyAddress, int88 fCashAmountToSettle)\n    SettleCashDebt\n}\n\n/// @notice Specifies different deposit actions that can occur during BalanceAction or BalanceActionWithTrades\nenum DepositActionType {\n    // No deposit action\n    None,\n    // Deposit asset cash, depositActionAmount is specified in asset cash external precision\n    DepositAsset,\n    // Deposit underlying tokens that are mintable to asset cash, depositActionAmount is specified in underlying token\n    // external precision\n    DepositUnderlying,\n    // Deposits specified asset cash external precision amount into an nToken and mints the corresponding amount of\n    // nTokens into the account\n    DepositAssetAndMintNToken,\n    // Deposits specified underlying in external precision, mints asset cash, and uses that asset cash to mint nTokens\n    DepositUnderlyingAndMintNToken,\n    // Redeems an nToken balance to asset cash. depositActionAmount is specified in nToken precision. Considered a deposit action\n    // because it deposits asset cash into an account. If there are fCash residuals that cannot be sold off, will revert.\n    RedeemNToken,\n    // Converts specified amount of asset cash balance already in Notional to nTokens. depositActionAmount is specified in\n    // Notional internal 8 decimal precision.\n    ConvertCashToNToken\n}\n\n/// @notice Used internally for PortfolioHandler state\nenum AssetStorageState {\n    NoChange,\n    Update,\n    Delete,\n    RevertIfStored\n}\n\n/****** Calldata objects ******/\n\n/// @notice Defines a batch lending action\nstruct BatchLend {\n    uint16 currencyId;\n    // True if the contract should try to transfer underlying tokens instead of asset tokens\n    bool depositUnderlying;\n    // Array of tightly packed 32 byte objects that represent trades. See TradeActionType documentation\n    bytes32[] trades;\n}\n\n/// @notice Defines a balance action for batchAction\nstruct BalanceAction {\n    // Deposit action to take (if any)\n    DepositActionType actionType;\n    uint16 currencyId;\n    // Deposit action amount must correspond to the depositActionType, see documentation above.\n    uint256 depositActionAmount;\n    // Withdraw an amount of asset cash specified in Notional internal 8 decimal precision\n    uint256 withdrawAmountInternalPrecision;\n    // If set to true, will withdraw entire cash balance. Useful if there may be an unknown amount of asset cash\n    // residual left from trading.\n    bool withdrawEntireCashBalance;\n    // If set to true, will redeem asset cash to the underlying token on withdraw.\n    bool redeemToUnderlying;\n}\n\n/// @notice Defines a balance action with a set of trades to do as well\nstruct BalanceActionWithTrades {\n    DepositActionType actionType;\n    uint16 currencyId;\n    uint256 depositActionAmount;\n    uint256 withdrawAmountInternalPrecision;\n    bool withdrawEntireCashBalance;\n    bool redeemToUnderlying;\n    // Array of tightly packed 32 byte objects that represent trades. See TradeActionType documentation\n    bytes32[] trades;\n}\n\n/****** In memory objects ******/\n/// @notice Internal object that represents settled cash balances\nstruct SettleAmount {\n    uint16 currencyId;\n    int256 positiveSettledCash;\n    int256 negativeSettledCash;\n    PrimeRate presentPrimeRate;\n}\n\n/// @notice Internal object that represents a token\nstruct Token {\n    address tokenAddress;\n    bool hasTransferFee;\n    int256 decimals;\n    TokenType tokenType;\n    uint256 deprecated_maxCollateralBalance;\n}\n\n/// @notice Internal object that represents an nToken portfolio\nstruct nTokenPortfolio {\n    CashGroupParameters cashGroup;\n    PortfolioState portfolioState;\n    int256 totalSupply;\n    int256 cashBalance;\n    uint256 lastInitializedTime;\n    bytes6 parameters;\n    address tokenAddress;\n}\n\n/// @notice Internal object used during liquidation\nstruct LiquidationFactors {\n    address account;\n    // Aggregate free collateral of the account denominated in ETH underlying, 8 decimal precision\n    int256 netETHValue;\n    // Amount of net local currency asset cash before haircuts and buffers available\n    int256 localPrimeAvailable;\n    // Amount of net collateral currency asset cash before haircuts and buffers available\n    int256 collateralAssetAvailable;\n    // Haircut value of nToken holdings denominated in asset cash, will be local or collateral nTokens based\n    // on liquidation type\n    int256 nTokenHaircutPrimeValue;\n    // nToken parameters for calculating liquidation amount\n    bytes6 nTokenParameters;\n    // ETH exchange rate from local currency to ETH\n    ETHRate localETHRate;\n    // ETH exchange rate from collateral currency to ETH\n    ETHRate collateralETHRate;\n    // Asset rate for the local currency, used in cross currency calculations to calculate local asset cash required\n    PrimeRate localPrimeRate;\n    // Used during currency liquidations if the account has liquidity tokens\n    CashGroupParameters collateralCashGroup;\n    // Used during currency liquidations if it is only a calculation, defaults to false\n    bool isCalculation;\n}\n\n/// @notice Internal asset array portfolio state\nstruct PortfolioState {\n    // Array of currently stored assets\n    PortfolioAsset[] storedAssets;\n    // Array of new assets to add\n    PortfolioAsset[] newAssets;\n    uint256 lastNewAssetIndex;\n    // Holds the length of stored assets after accounting for deleted assets\n    uint256 storedAssetLength;\n}\n\n/// @notice In memory ETH exchange rate used during free collateral calculation.\nstruct ETHRate {\n    // The decimals (i.e. 10^rateDecimalPlaces) of the exchange rate, defined by the rate oracle\n    int256 rateDecimals;\n    // The exchange rate from base to ETH (if rate invert is required it is already done)\n    int256 rate;\n    // Amount of buffer as a multiple with a basis of 100 applied to negative balances.\n    int256 buffer;\n    // Amount of haircut as a multiple with a basis of 100 applied to positive balances\n    int256 haircut;\n    // Liquidation discount as a multiple with a basis of 100 applied to the exchange rate\n    // as an incentive given to liquidators.\n    int256 liquidationDiscount;\n}\n\n/// @notice Internal object used to handle balance state during a transaction\nstruct BalanceState {\n    uint16 currencyId;\n    // Cash balance stored in balance state at the beginning of the transaction\n    int256 storedCashBalance;\n    // nToken balance stored at the beginning of the transaction\n    int256 storedNTokenBalance;\n    // The net cash change as a result of asset settlement or trading\n    int256 netCashChange;\n    // Amount of prime cash to redeem and withdraw from the system\n    int256 primeCashWithdraw;\n    // Net token transfers into or out of the account\n    int256 netNTokenTransfer;\n    // Net token supply change from minting or redeeming\n    int256 netNTokenSupplyChange;\n    // The last time incentives were claimed for this currency\n    uint256 lastClaimTime;\n    // Accumulator for incentives that the account no longer has a claim over\n    uint256 accountIncentiveDebt;\n    // Prime rate for converting prime cash balances\n    PrimeRate primeRate;\n}\n\n/// @dev Asset rate used to convert between underlying cash and asset cash\nstruct Deprecated_AssetRateParameters {\n    // Address of the asset rate oracle\n    AssetRateAdapter rateOracle;\n    // The exchange rate from base to quote (if invert is required it is already done)\n    int256 rate;\n    // The decimals of the underlying, the rate converts to the underlying decimals\n    int256 underlyingDecimals;\n}\n\n/// @dev Cash group when loaded into memory\nstruct CashGroupParameters {\n    uint16 currencyId;\n    uint256 maxMarketIndex;\n    PrimeRate primeRate;\n    bytes32 data;\n}\n\n/// @dev A portfolio asset when loaded in memory\nstruct PortfolioAsset {\n    // Asset currency id\n    uint16 currencyId;\n    uint256 maturity;\n    // Asset type, fCash or liquidity token.\n    uint256 assetType;\n    // fCash amount or liquidity token amount\n    int256 notional;\n    // Used for managing portfolio asset state\n    uint256 storageSlot;\n    // The state of the asset for when it is written to storage\n    AssetStorageState storageState;\n}\n\n/// @dev Market object as represented in memory\nstruct MarketParameters {\n    bytes32 storageSlot;\n    uint256 maturity;\n    // Total amount of fCash available for purchase in the market.\n    int256 totalfCash;\n    // Total amount of cash available for purchase in the market.\n    int256 totalPrimeCash;\n    // Total amount of liquidity tokens (representing a claim on liquidity) in the market.\n    int256 totalLiquidity;\n    // This is the previous annualized interest rate in RATE_PRECISION that the market traded\n    // at. This is used to calculate the rate anchor to smooth interest rates over time.\n    uint256 lastImpliedRate;\n    // Time lagged version of lastImpliedRate, used to value fCash assets at market rates while\n    // remaining resistent to flash loan attacks.\n    uint256 oracleRate;\n    // This is the timestamp of the previous trade\n    uint256 previousTradeTime;\n}\n\n/****** Storage objects ******/\n\n/// @dev Token object in storage:\n///  20 bytes for token address\n///  1 byte for hasTransferFee\n///  1 byte for tokenType\n///  1 byte for tokenDecimals\n///  9 bytes for maxCollateralBalance (may not always be set)\nstruct TokenStorage {\n    // Address of the token\n    address tokenAddress;\n    // Transfer fees will change token deposit behavior\n    bool hasTransferFee;\n    TokenType tokenType;\n    uint8 decimalPlaces;\n    uint72 deprecated_maxCollateralBalance;\n}\n\n/// @dev Exchange rate object as it is represented in storage, total storage is 25 bytes.\nstruct ETHRateStorage {\n    // Address of the rate oracle\n    AggregatorV2V3Interface rateOracle;\n    // The decimal places of precision that the rate oracle uses\n    uint8 rateDecimalPlaces;\n    // True of the exchange rate must be inverted\n    bool mustInvert;\n    // NOTE: both of these governance values are set with BUFFER_DECIMALS precision\n    // Amount of buffer to apply to the exchange rate for negative balances.\n    uint8 buffer;\n    // Amount of haircut to apply to the exchange rate for positive balances\n    uint8 haircut;\n    // Liquidation discount in percentage point terms, 106 means a 6% discount\n    uint8 liquidationDiscount;\n}\n\n/// @dev Asset rate oracle object as it is represented in storage, total storage is 21 bytes.\nstruct AssetRateStorage {\n    // Address of the rate oracle\n    AssetRateAdapter rateOracle;\n    // The decimal places of the underlying asset\n    uint8 underlyingDecimalPlaces;\n}\n\n/// @dev Governance parameters for a cash group, total storage is 9 bytes + 7 bytes for liquidity token haircuts\n/// and 7 bytes for rate scalars, total of 23 bytes. Note that this is stored packed in the storage slot so there\n/// are no indexes stored for liquidityTokenHaircuts or rateScalars, maxMarketIndex is used instead to determine the\n/// length.\nstruct CashGroupSettings {\n    // Index of the AMMs on chain that will be made available. Idiosyncratic fCash\n    // that is dated less than the longest AMM will be tradable.\n    uint8 maxMarketIndex;\n    // Time window in 5 minute increments that the rate oracle will be averaged over\n    uint8 rateOracleTimeWindow5Min;\n    // Absolute maximum discount factor as a discount from 1e9, specified in five basis points\n    // subtracted from 1e9\n    uint8 maxDiscountFactor5BPS;\n    // Share of the fees given to the protocol, denominated in percentage\n    uint8 reserveFeeShare;\n    // Debt buffer specified in 5 BPS increments\n    uint8 debtBuffer25BPS;\n    // fCash haircut specified in 5 BPS increments\n    uint8 fCashHaircut25BPS;\n    // Minimum oracle interest rates for fCash per market, specified in 25 bps increments\n    uint8 minOracleRate25BPS;\n    // If an account has fCash that is being liquidated, this is the discount that the liquidator can purchase it for\n    uint8 liquidationfCashHaircut25BPS;\n    // If an account has fCash that is being liquidated, this is the discount that the liquidator can purchase it for\n    uint8 liquidationDebtBuffer25BPS;\n    // Max oracle rate specified in 25bps increments as a discount from the max rate in the market.\n    uint8 maxOracleRate25BPS;\n}\n\n/// @dev Holds account level context information used to determine settlement and\n/// free collateral actions. Total storage is 28 bytes\nstruct AccountContext {\n    // Used to check when settlement must be triggered on an account\n    uint40 nextSettleTime;\n    // For lenders that never incur debt, we use this flag to skip the free collateral check.\n    bytes1 hasDebt;\n    // Length of the account's asset array\n    uint8 assetArrayLength;\n    // If this account has bitmaps set, this is the corresponding currency id\n    uint16 bitmapCurrencyId;\n    // 9 total active currencies possible (2 bytes each)\n    bytes18 activeCurrencies;\n    // If this is set to true, the account can borrow variable prime cash and incur\n    // negative cash balances inside BatchAction. This does not impact the settlement\n    // of negative fCash to prime cash which will happen regardless of this setting. This\n    // exists here mainly as a safety setting to ensure that accounts do not accidentally\n    // incur negative cash balances.\n    bool allowPrimeBorrow;\n}\n\n/// @dev Holds nToken context information mapped via the nToken address, total storage is\n/// 16 bytes\nstruct nTokenContext {\n    // Currency id that the nToken represents\n    uint16 currencyId;\n    // Annual incentive emission rate denominated in WHOLE TOKENS (multiply by\n    // INTERNAL_TOKEN_PRECISION to get the actual rate)\n    uint32 incentiveAnnualEmissionRate;\n    // The last block time at utc0 that the nToken was initialized at, zero if it\n    // has never been initialized\n    uint32 lastInitializedTime;\n    // Length of the asset array, refers to the number of liquidity tokens an nToken\n    // currently holds\n    uint8 assetArrayLength;\n    // Each byte is a specific nToken parameter\n    bytes6 nTokenParameters;\n    // Reserved bytes for future usage\n    bytes14 _unused;\n    // Set to true if a secondary rewarder is set\n    bool hasSecondaryRewarder;\n}\n\n/// @dev Holds account balance information, total storage 32 bytes\nstruct BalanceStorage {\n    // Number of nTokens held by the account\n    uint80 nTokenBalance;\n    // Last time the account claimed their nTokens\n    uint32 lastClaimTime;\n    // Incentives that the account no longer has a claim over\n    uint56 accountIncentiveDebt;\n    // Cash balance of the account\n    int88 cashBalance;\n}\n\n/// @dev Holds information about a settlement rate, total storage 25 bytes\nstruct SettlementRateStorage {\n    uint40 blockTime;\n    uint128 settlementRate;\n    uint8 underlyingDecimalPlaces;\n}\n\n/// @dev Holds information about a market, total storage is 42 bytes so this spans\n/// two storage words\nstruct MarketStorage {\n    // Total fCash in the market\n    uint80 totalfCash;\n    // Total asset cash in the market\n    uint80 totalPrimeCash;\n    // Last annualized interest rate the market traded at\n    uint32 lastImpliedRate;\n    // Last recorded oracle rate for the market\n    uint32 oracleRate;\n    // Last time a trade was made\n    uint32 previousTradeTime;\n    // This is stored in slot + 1\n    uint80 totalLiquidity;\n}\n\nstruct InterestRateParameters {\n    // First kink for the utilization rate in RATE_PRECISION\n    uint256 kinkUtilization1;\n    // Second kink for the utilization rate in RATE_PRECISION\n    uint256 kinkUtilization2;\n    // First kink interest rate in RATE_PRECISION\n    uint256 kinkRate1;\n    // Second kink interest rate in RATE_PRECISION\n    uint256 kinkRate2;\n    // Max interest rate in RATE_PRECISION\n    uint256 maxRate;\n    // Minimum fee charged in RATE_PRECISION\n    uint256 minFeeRate;\n    // Maximum fee charged in RATE_PRECISION\n    uint256 maxFeeRate;\n    // Percentage of the interest rate that will be applied as a fee\n    uint256 feeRatePercent;\n}\n\n// Specific interest rate curve settings for each market\nstruct InterestRateCurveSettings {\n    // First kink for the utilization rate, specified as a percentage\n    // between 1-100\n    uint8 kinkUtilization1;\n    // Second kink for the utilization rate, specified as a percentage\n    // between 1-100\n    uint8 kinkUtilization2;\n    // Interest rate at the first kink, set as 1/256 units from the kink\n    // rate max\n    uint8 kinkRate1;\n    // Interest rate at the second kink, set as 1/256 units from the kink\n    // rate max\n    uint8 kinkRate2;\n    // Max interest rate, set in units in 25bps increments less than or equal to 150\n    // and 150bps increments from 151 to 255.\n    uint8 maxRateUnits;\n    // Minimum fee charged in basis points\n    uint8 minFeeRate5BPS;\n    // Maximum fee charged in basis points\n    uint8 maxFeeRate25BPS;\n    // Percentage of the interest rate that will be applied as a fee\n    uint8 feeRatePercent;\n}\n\nstruct ifCashStorage {\n    // Notional amount of fCash at the slot, limited to int128 to allow for\n    // future expansion\n    int128 notional;\n}\n\n/// @dev A single portfolio asset in storage, total storage of 19 bytes\nstruct PortfolioAssetStorage {\n    // Currency Id for the asset\n    uint16 currencyId;\n    // Maturity of the asset\n    uint40 maturity;\n    // Asset type (fCash or Liquidity Token marker)\n    uint8 assetType;\n    // Notional\n    int88 notional;\n}\n\n/// @dev nToken total supply factors for the nToken, includes factors related\n/// to claiming incentives, total storage 32 bytes. This is the deprecated version\nstruct nTokenTotalSupplyStorage_deprecated {\n    // Total supply of the nToken\n    uint96 totalSupply;\n    // Integral of the total supply used for calculating the average total supply\n    uint128 integralTotalSupply;\n    // Last timestamp the supply value changed, used for calculating the integralTotalSupply\n    uint32 lastSupplyChangeTime;\n}\n\n/// @dev nToken total supply factors for the nToken, includes factors related\n/// to claiming incentives, total storage 32 bytes.\nstruct nTokenTotalSupplyStorage {\n    // Total supply of the nToken\n    uint96 totalSupply;\n    // How many NOTE incentives should be issued per nToken in 1e18 precision\n    uint128 accumulatedNOTEPerNToken;\n    // Last timestamp when the accumulation happened\n    uint32 lastAccumulatedTime;\n}\n\n/// @dev Used in view methods to return account balances in a developer friendly manner\nstruct AccountBalance {\n    uint16 currencyId;\n    int256 cashBalance;\n    int256 nTokenBalance;\n    uint256 lastClaimTime;\n    uint256 accountIncentiveDebt;\n}\n\nstruct VaultConfigParams {\n    uint16 flags;\n    uint16 borrowCurrencyId;\n    uint256 minAccountBorrowSize;\n    uint16 minCollateralRatioBPS;\n    uint8 feeRate5BPS;\n    uint8 liquidationRate;\n    uint8 reserveFeeShare;\n    uint8 maxBorrowMarketIndex;\n    uint16 maxDeleverageCollateralRatioBPS;\n    uint16[2] secondaryBorrowCurrencies;\n    uint16 maxRequiredAccountCollateralRatioBPS;\n    uint256[2] minAccountSecondaryBorrow;\n    uint8 excessCashLiquidationBonus;\n}\n\nstruct VaultConfigStorage {\n    // Vault Flags (documented in VaultConfiguration.sol)\n    uint16 flags;\n    // Primary currency the vault borrows in\n    uint16 borrowCurrencyId;\n    // Specified in whole tokens in 1e8 precision, allows a 4.2 billion min borrow size\n    uint32 minAccountBorrowSize;\n    // Minimum collateral ratio for a vault specified in basis points, valid values are greater than 10_000\n    // where the largest minimum collateral ratio is 65_536 which is much higher than anything reasonable.\n    uint16 minCollateralRatioBPS;\n    // Allows up to a 12.75% annualized fee\n    uint8 feeRate5BPS;\n    // A percentage that represents the share of the cash raised that will go to the liquidator\n    uint8 liquidationRate;\n    // A percentage of the fee given to the protocol\n    uint8 reserveFeeShare;\n    // Maximum market index where a vault can borrow from\n    uint8 maxBorrowMarketIndex;\n    // Maximum collateral ratio that a liquidator can push a an account to during deleveraging\n    uint16 maxDeleverageCollateralRatioBPS;\n    // An optional list of secondary borrow currencies\n    uint16[2] secondaryBorrowCurrencies;\n    // Required collateral ratio for accounts to stay inside a vault, prevents accounts\n    // from \"free riding\" on vaults. Enforced on entry and exit, not on deleverage.\n    uint16 maxRequiredAccountCollateralRatioBPS;\n    // Specified in whole tokens in 1e8 precision, allows a 4.2 billion min borrow size\n    uint32[2] minAccountSecondaryBorrow;\n    // Specified as a percent discount off the exchange rate of the excess cash that will be paid to\n    // the liquidator during liquidateExcessVaultCash\n    uint8 excessCashLiquidationBonus;\n    // 8 bytes left\n}\n\nstruct VaultBorrowCapacityStorage {\n    // Total fCash across all maturities that caps the borrow capacity\n    uint80 maxBorrowCapacity;\n    // Total fCash debt across all maturities\n    uint80 totalfCashDebt;\n}\n\nstruct VaultAccountSecondaryDebtShareStorage {\n    // Maturity for the account's secondary borrows. This is stored separately from\n    // the vault account maturity to ensure that we have access to the proper state\n    // during a roll borrow position. It should never be allowed to deviate from the\n    // vaultAccount.maturity value (unless it is cleared to zero).\n    uint40 maturity;\n    // Account debt for the first secondary currency in either fCash or pCash denomination\n    uint80 accountDebtOne;\n    // Account debt for the second secondary currency in either fCash or pCash denomination\n    uint80 accountDebtTwo;\n}\n\nstruct VaultConfig {\n    address vault;\n    uint16 flags;\n    uint16 borrowCurrencyId;\n    int256 minAccountBorrowSize;\n    int256 feeRate;\n    int256 minCollateralRatio;\n    int256 liquidationRate;\n    int256 reserveFeeShare;\n    uint256 maxBorrowMarketIndex;\n    int256 maxDeleverageCollateralRatio;\n    uint16[2] secondaryBorrowCurrencies;\n    PrimeRate primeRate;\n    int256 maxRequiredAccountCollateralRatio;\n    int256[2] minAccountSecondaryBorrow;\n    int256 excessCashLiquidationBonus;\n}\n\n/// @notice Represents a Vault's current borrow and collateral state\nstruct VaultStateStorage {\n    // This represents the total amount of borrowing in the vault for the current\n    // vault term. If the vault state is the prime cash maturity, this is stored in\n    // prime cash debt denomination, if fCash then it is stored in internal underlying.\n    uint80 totalDebt;\n    // The total amount of prime cash in the pool held as a result of emergency settlement\n    uint80 deprecated_totalPrimeCash;\n    // Total vault shares in this maturity\n    uint80 totalVaultShares;\n    // Set to true if a vault's debt position has been migrated to the prime cash vault\n    bool isSettled;\n    // NOTE: 8 bits left\n    // ----- This breaks into a new storage slot -------    \n    // The total amount of strategy tokens held in the pool\n    uint80 deprecated_totalStrategyTokens;\n    // Valuation of a strategy token at settlement\n    int80 deprecated_settlementStrategyTokenValue;\n    // NOTE: 96 bits left\n}\n\n/// @notice Represents the remaining assets in a vault post settlement\nstruct Deprecated_VaultSettledAssetsStorage {\n    // Remaining strategy tokens that have not been withdrawn\n    uint80 remainingStrategyTokens;\n    // Remaining asset cash that has not been withdrawn\n    int80 remainingPrimeCash;\n}\n\nstruct VaultState {\n    uint256 maturity;\n    // Total debt is always denominated in underlying on the stack\n    int256 totalDebtUnderlying;\n    uint256 totalVaultShares;\n    bool isSettled;\n}\n\n/// @notice Represents an account's position within an individual vault\nstruct VaultAccountStorage {\n    // Total amount of debt for the account in the primary borrowed currency.\n    // If the account is borrowing prime cash, this is stored in prime cash debt\n    // denomination, if fCash then it is stored in internal underlying.\n    uint80 accountDebt;\n    // Vault shares that the account holds\n    uint80 vaultShares;\n    // Maturity when the vault shares and fCash will mature\n    uint40 maturity;\n    // Last time when a vault was entered or exited, used to ensure that vault accounts do not\n    // flash enter/exit. While there is no specified attack vector here, we can use it to prevent\n    // an entire class of attacks from happening without reducing UX.\n    // NOTE: in the original version this value was set to the block.number, however, in this\n    // version it is being changed to time based. On ETH mainnet block heights are much smaller\n    // than block times, accounts that migrate from lastEntryBlockHeight => lastUpdateBlockTime\n    // will not see any issues with entering / exiting the protocol.\n    uint32 lastUpdateBlockTime;\n    // ----------------  Second Storage Slot ----------------------\n    // Cash balances held by the vault account as a result of lending at zero interest or due\n    // to deleveraging (liquidation). In the previous version of leveraged vaults, accounts would\n    // simply lend at zero interest which was not a problem. However, with vaults being able to\n    // discount fCash to present value, lending at zero percent interest may have an adverse effect\n    // on the account's collateral position (i.e. lending at zero puts them further into danger).\n    // Holding cash against debt will eliminate that risk, making vault liquidation more similar to\n    // regular Notional liquidation.\n    uint80 primaryCash;\n    uint80 secondaryCashOne;\n    uint80 secondaryCashTwo;\n}\n\nstruct VaultAccount {\n    // On the stack, account debts are always in underlying\n    int256 accountDebtUnderlying;\n    uint256 maturity;\n    uint256 vaultShares;\n    address account;\n    // This cash balance is used just within a transaction to track deposits\n    // and withdraws for an account. Must be zeroed by the time we store the account\n    int256 tempCashBalance;\n    uint256 lastUpdateBlockTime;\n}\n\n// Used to hold vault account liquidation factors in memory\nstruct VaultAccountHealthFactors {\n    // Account's calculated collateral ratio\n    int256 collateralRatio;\n    // Total outstanding debt across all borrowed currencies in primary\n    int256 totalDebtOutstandingInPrimary;\n    // Total value of vault shares in underlying denomination\n    int256 vaultShareValueUnderlying;\n    // Debt outstanding in local currency denomination after present value and\n    // account cash held netting applied. Can be positive if the account holds cash\n    // in excess of debt.\n    int256[3] netDebtOutstanding;\n}\n\n// PrimeCashInterestRateParameters take up 16 bytes, this takes up 32 bytes so we\n// can expand another 16 bytes to increase the storage slots a bit....\nstruct PrimeCashFactorsStorage {\n    // Storage slot 1 [Prime Supply Factors, 248 bytes]\n    uint40 lastAccrueTime;\n    uint88 totalPrimeSupply;\n    uint88 lastTotalUnderlyingValue;\n    // Overflows at 429% interest using RATE_PRECISION\n    uint32 oracleSupplyRate;\n    bool allowDebt;\n\n    // Storage slot 2 [Prime Debt Factors, 256 bytes]\n    uint88 totalPrimeDebt;\n    // Each one of these values below is stored as a FloatingPoint32 value which\n    // gives us approx 7 digits of precision for each value. Because these are used\n    // to maintain supply and borrow caps, they are not required to be exact.\n    uint32 maxUnderlyingSupply;\n    // The maximum utilization that prime debt is allowed to reach by users borrowing prime\n    // debt via the markets directly. This cap is not applied to liquidations and settlement.\n    uint8 maxPrimeDebtUtilization;\n    uint120 _reserved;\n    // Reserving the next 128 bytes for future use in case we decide to implement debt\n    // caps on a currency. In that case, we will need to track the total fcash overall\n    // and subtract the total debt held in vaults.\n    // uint32 maxUnderlyingDebt;\n    // uint32 totalfCashDebtOverall;\n    // uint32 totalfCashDebtInVaults;\n    // uint32 totalPrimeDebtInVaults;\n    // 8 bytes left\n    \n    // Storage slot 3 [Prime Scalars, 240 bytes]\n    // Scalars are stored in 18 decimal precision (i.e. double rate precision) and uint80\n    // maxes out at approx 1,210,000e18\n    // ln(1,210,000) = rate * years = 14\n    // Approx 46 years at 30% interest\n    // Approx 233 years at 6% interest\n    uint80 underlyingScalar;\n    uint80 supplyScalar;\n    uint80 debtScalar;\n    // The time window in 5 min increments that the rate oracle will be averaged over\n    uint8 rateOracleTimeWindow5Min;\n    // 8 bytes left\n}\n\nstruct PrimeCashFactors {\n    uint256 lastAccrueTime;\n    uint256 totalPrimeSupply;\n    uint256 totalPrimeDebt;\n    uint256 oracleSupplyRate;\n    uint256 lastTotalUnderlyingValue;\n    uint256 underlyingScalar;\n    uint256 supplyScalar;\n    uint256 debtScalar;\n    uint256 rateOracleTimeWindow;\n}\n\nstruct PrimeRate {\n    int256 supplyFactor;\n    int256 debtFactor;\n    uint256 oracleSupplyRate;\n}\n\nstruct PrimeSettlementRateStorage {\n    uint80 supplyScalar;\n    uint80 debtScalar;\n    uint80 underlyingScalar;\n    bool isSet;\n}\n\nstruct PrimeCashHoldingsOracle {\n   IPrimeCashHoldingsOracle oracle; \n}\n\n// Per currency rebalancing context\nstruct RebalancingContextStorage {\n    // Holds the previous supply factor to calculate the oracle money market rate\n    uint128 previousSupplyFactorAtRebalance;\n    // Rebalancing has a cool down period that sets the time averaging of the oracle money market rate\n    uint40 rebalancingCooldownInSeconds;\n    uint40 lastRebalanceTimestampInSeconds;\n    // 48 bytes left\n}\n\nstruct TotalfCashDebtStorage {\n    uint80 totalfCashDebt;\n    // These two variables are used to track fCash lend at zero\n    // edge conditions for leveraged vaults.\n    uint80 fCashDebtHeldInSettlementReserve;\n    uint80 primeCashHeldInSettlementReserve;\n}\n\nstruct RebalancingTargetData {\n    uint8 targetUtilization;\n    uint16 externalWithdrawThreshold;\n}"
      },
      "contracts/internal/balances/protocols/GenericToken.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\n\nimport {Deployments} from \"../../../global/Deployments.sol\";\nimport {IEIP20NonStandard} from \"../../../../interfaces/IEIP20NonStandard.sol\";\nimport {SafeUint256} from \"../../../math/SafeUint256.sol\";\n\nlibrary GenericToken {\n    using SafeUint256 for uint256;\n\n    event LowLevelCallFailed(address indexed target, uint256 msgValue, bytes callData, string revertMessage);\n\n    function transferNativeTokenOut(\n        address account,\n        uint256 amount,\n        bool withdrawWrapped\n    ) internal {\n        // Native token withdraws are processed using .transfer() which is may not work\n        // for certain contracts that do not implement receive() with minimal gas requirements.\n        // Prior to the prime cash upgrade, these contracts could withdraw cETH, however, post\n        // upgrade they no longer have this option. For these contracts, wrap the Native token\n        // (i.e. WETH) and transfer that as an ERC20 instead.\n        if (withdrawWrapped) {\n            Deployments.WETH.deposit{value: amount}();\n            safeTransferOut(address(Deployments.WETH), account, amount);\n        } else {\n            // TODO: consider using .call with a manual amount of gas forwarding\n            payable(account).transfer(amount);\n        }\n    }\n\n    function safeTransferOut(\n        address token,\n        address account,\n        uint256 amount\n    ) internal {\n        IEIP20NonStandard(token).transfer(account, amount);\n        checkReturnCode();\n    }\n\n    function safeTransferIn(\n        address token,\n        address account,\n        uint256 amount\n    ) internal returns (uint256) {\n        uint256 startingBalance = IEIP20NonStandard(token).balanceOf(address(this));\n\n        IEIP20NonStandard(token).transferFrom(account, address(this), amount);\n        checkReturnCode();\n\n        uint256 endingBalance = IEIP20NonStandard(token).balanceOf(address(this));\n\n        return endingBalance.sub(startingBalance);\n    }\n\n    function safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal {\n        IEIP20NonStandard(token).transferFrom(from, to, amount);\n        checkReturnCode();\n    }\n\n    function executeLowLevelCall(\n        address target,\n        uint256 msgValue,\n        bytes memory callData\n    ) internal  {\n        (bool status, bytes memory returnData) = target.call{value: msgValue}(callData);\n        require(status, checkRevertMessage(returnData));\n    }\n\n    function checkRevertMessage(bytes memory returnData) internal pure returns (string memory) {\n        // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n        if (returnData.length < 68) return \"Silent Revert\";\n\n        assembly {\n            // Slice the sighash.\n            returnData := add(returnData, 0x04)\n        }\n        return abi.decode(returnData, (string)); // All that remains is the revert string\n    }\n\n    function checkReturnCode() internal pure {\n        bool success;\n        uint256[1] memory result;\n        assembly {\n            switch returndatasize()\n                case 0 {\n                    // This is a non-standard ERC-20\n                    success := 1 // set success to true\n                }\n                case 32 {\n                    // This is a compliant ERC-20\n                    returndatacopy(result, 0, 32)\n                    success := mload(result) // Set `success = returndata` of external call\n                }\n                default {\n                    // This is an excessively non-compliant ERC-20, revert.\n                    revert(0, 0)\n                }\n        }\n\n        require(success, \"ERC20\");\n    }\n\n}"
      },
      "contracts/math/Bitmap.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\npragma abicoder v2;\n\nimport {Constants} from \"../global/Constants.sol\";\n\n/// @notice Helper methods for bitmaps, they are big-endian and 1-indexed.\nlibrary Bitmap {\n\n    /// @notice Set a bit on or off in a bitmap, index is 1-indexed\n    function setBit(\n        bytes32 bitmap,\n        uint256 index,\n        bool setOn\n    ) internal pure returns (bytes32) {\n        require(index >= 1 && index <= 256); // dev: set bit index bounds\n\n        if (setOn) {\n            return bitmap | (Constants.MSB >> (index - 1));\n        } else {\n            return bitmap & ~(Constants.MSB >> (index - 1));\n        }\n    }\n\n    /// @notice Check if a bit is set\n    function isBitSet(bytes32 bitmap, uint256 index) internal pure returns (bool) {\n        require(index >= 1 && index <= 256); // dev: set bit index bounds\n        return ((bitmap << (index - 1)) & Constants.MSB) == Constants.MSB;\n    }\n\n    /// @notice Count the total bits set\n    function totalBitsSet(bytes32 bitmap) internal pure returns (uint256) {\n        uint256 x = uint256(bitmap);\n        x = (x & 0x5555555555555555555555555555555555555555555555555555555555555555) + (x >> 1 & 0x5555555555555555555555555555555555555555555555555555555555555555);\n        x = (x & 0x3333333333333333333333333333333333333333333333333333333333333333) + (x >> 2 & 0x3333333333333333333333333333333333333333333333333333333333333333);\n        x = (x & 0x0707070707070707070707070707070707070707070707070707070707070707) + (x >> 4);\n        x = (x & 0x000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F) + (x >> 8 & 0x000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F);\n        x = x + (x >> 16);\n        x = x + (x >> 32);\n        x = x  + (x >> 64);\n        return (x & 0xFF) + (x >> 128 & 0xFF);\n    }\n\n    // Does a binary search over x to get the position of the most significant bit\n    function getMSB(uint256 x) internal pure returns (uint256 msb) {\n        // If x == 0 then there is no MSB and this method will return zero. That would\n        // be the same as the return value when x == 1 (MSB is zero indexed), so instead\n        // we have this require here to ensure that the values don't get mixed up.\n        require(x != 0); // dev: get msb zero value\n        if (x >= 0x100000000000000000000000000000000) {\n            x >>= 128;\n            msb += 128;\n        }\n        if (x >= 0x10000000000000000) {\n            x >>= 64;\n            msb += 64;\n        }\n        if (x >= 0x100000000) {\n            x >>= 32;\n            msb += 32;\n        }\n        if (x >= 0x10000) {\n            x >>= 16;\n            msb += 16;\n        }\n        if (x >= 0x100) {\n            x >>= 8;\n            msb += 8;\n        }\n        if (x >= 0x10) {\n            x >>= 4;\n            msb += 4;\n        }\n        if (x >= 0x4) {\n            x >>= 2;\n            msb += 2;\n        }\n        if (x >= 0x2) msb += 1; // No need to shift xc anymore\n    }\n\n    /// @dev getMSB returns a zero indexed bit number where zero is the first bit counting\n    /// from the right (little endian). Asset Bitmaps are counted from the left (big endian)\n    /// and one indexed.\n    function getNextBitNum(bytes32 bitmap) internal pure returns (uint256 bitNum) {\n        // Short circuit the search if bitmap is all zeros\n        if (bitmap == 0x00) return 0;\n\n        return 255 - getMSB(uint256(bitmap)) + 1;\n    }\n}\n"
      },
      "contracts/math/FloatingPoint.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\n\nimport {Bitmap} from \"./Bitmap.sol\";\nimport {SafeInt256} from \"./SafeInt256.sol\";\nimport {SafeUint256} from \"./SafeUint256.sol\";\n\n/**\n * Packs an uint value into a \"floating point\" storage slot. Used for storing\n * lastClaimIntegralSupply values in balance storage. For these values, we don't need\n * to maintain exact precision but we don't want to be limited by storage size overflows.\n *\n * A floating point value is defined by the 48 most significant bits and an 8 bit number\n * of bit shifts required to restore its precision. The unpacked value will always be less\n * than the packed value with a maximum absolute loss of precision of (2 ** bitShift) - 1.\n */\nlibrary FloatingPoint {\n    using SafeInt256 for int256;\n    using SafeUint256 for uint256;\n\n    function packTo56Bits(uint256 value) internal pure returns (uint56) {\n        uint256 bitShift;\n        // If the value is over the uint48 max value then we will shift it down\n        // given the index of the most significant bit. We store this bit shift \n        // in the least significant byte of the 56 bit slot available.\n        if (value > type(uint48).max) bitShift = (Bitmap.getMSB(value) - 47);\n\n        uint256 shiftedValue = value >> bitShift;\n        return uint56((shiftedValue << 8) | bitShift);\n    }\n\n    function packTo32Bits(uint256 value) internal pure returns (uint32) {\n        uint256 bitShift;\n        // If the value is over the uint24 max value then we will shift it down\n        // given the index of the most significant bit. We store this bit shift \n        // in the least significant byte of the 32 bit slot available.\n        if (value > type(uint24).max) bitShift = (Bitmap.getMSB(value) - 23);\n\n        uint256 shiftedValue = value >> bitShift;\n        return uint32((shiftedValue << 8) | bitShift);\n    }\n\n    function unpackFromBits(uint256 value) internal pure returns (uint256) {\n        // The least significant 8 bits will be the amount to bit shift\n        uint256 bitShift = uint256(uint8(value));\n        return ((value >> 8) << bitShift);\n    }\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"
      },
      "contracts/math/SafeUint256.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity =0.7.6;\n\nimport {Constants} from \"../global/Constants.sol\";\n\nlibrary SafeUint256 {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a);\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a);\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) return 0;\n        uint256 c = a * b;\n        require(c / a == b);\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting 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(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0);\n        return a / b;\n    }\n\n    function max(uint256 x, uint256 y) internal pure returns (uint256) {\n        return x > y ? x : y;\n    }\n\n    function min(uint256 x, uint256 y) internal pure returns (uint256) {\n        return x < y ? x : y;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0);\n        return a % b;\n    }\n\n    function divInRatePrecision(uint256 x, uint256 y) internal pure returns (uint256) {\n        return div(mul(x, uint256(Constants.RATE_PRECISION)), y);\n    }\n\n    function mulInRatePrecision(uint256 x, uint256 y) internal pure returns (uint256) {\n        return div(mul(x, y), uint256(Constants.RATE_PRECISION));\n    }\n\n    function divInScalarPrecision(uint256 x, uint256 y) internal pure returns (uint256) {\n        return div(mul(x, Constants.SCALAR_PRECISION), y);\n    }\n\n    function mulInScalarPrecision(uint256 x, uint256 y) internal pure returns (uint256) {\n        return div(mul(x, y), Constants.SCALAR_PRECISION);\n    }\n\n    function toUint8(uint256 x) internal pure returns (uint8) {\n        require(x <= type(uint8).max);\n        return uint8(x);\n    }\n\n    function toUint32(uint256 x) internal pure returns (uint32) {\n        require(x <= type(uint32).max);\n        return uint32(x);\n    }\n\n    function toUint40(uint256 x) internal pure returns (uint40) {\n        require(x <= type(uint40).max);\n        return uint40(x);\n    }\n\n    function toUint48(uint256 x) internal pure returns (uint48) {\n        require(x <= type(uint48).max);\n        return uint48(x);\n    }\n\n    function toUint56(uint256 x) internal pure returns (uint56) {\n        require(x <= type(uint56).max);\n        return uint56(x);\n    }\n\n    function toUint72(uint256 x) internal pure returns (uint72) {\n        require(x <= type(uint72).max);\n        return uint72(x);\n    }\n    \n    function toUint80(uint256 x) internal pure returns (uint80) {\n        require(x <= type(uint80).max);\n        return uint80(x);\n    }\n\n    function toUint88(uint256 x) internal pure returns (uint88) {\n        require(x <= type(uint88).max);\n        return uint88(x);\n    }\n\n    function toUint104(uint256 x) internal pure returns (uint104) {\n        require(x <= type(uint104).max);\n        return uint104(x);\n    }\n\n    function toUint112(uint256 x) internal pure returns (uint112) {\n        require(x <= type(uint112).max);\n        return uint112(x);\n    }\n\n    function toUint128(uint256 x) internal pure returns (uint128) {\n        require(x <= type(uint128).max);\n        return uint128(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}"
      },
      "contracts/proxy/beacon/IBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.3.2 (proxy/beacon/IBeacon.sol)\n\npragma solidity >=0.7.6;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n\ninterface IUpgradeableBeacon is IBeacon {\n    function upgradeTo(address newImplementation) external;\n}\n"
      },
      "interfaces/aave/ILendingPool.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nstruct LendingPoolStorage {\n  ILendingPool lendingPool;\n}\n\ninterface ILendingPool {\n\n  /**\n   * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.\n   * - E.g. User deposits 100 USDC and gets in return 100 aUSDC\n   * @param asset The address of the underlying asset to deposit\n   * @param amount The amount to be deposited\n   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user\n   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens\n   *   is a different wallet\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function deposit(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned\n   * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC\n   * @param asset The address of the underlying asset to withdraw\n   * @param amount The underlying amount to be withdrawn\n   *   - Send the value type(uint256).max in order to withdraw the whole aToken balance\n   * @param to Address that will receive the underlying, same as msg.sender if the user\n   *   wants to receive it on his own wallet, or a different address if the beneficiary is a\n   *   different wallet\n   * @return The final amount withdrawn\n   **/\n  function withdraw(\n    address asset,\n    uint256 amount,\n    address to\n  ) external returns (uint256);\n\n  /**\n   * @dev Returns the normalized income normalized income of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The reserve's normalized income\n   */\n  function getReserveNormalizedIncome(address asset) external view returns (uint256);\n\n    /**\n   * @dev Returns the state and configuration of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The state of the reserve\n   **/\n  function getReserveData(address asset) external view returns (ReserveData memory);\n\n  struct ReserveData {\n    ReserveConfigurationMap configuration;\n    uint128 liquidityIndex;\n    uint128 currentLiquidityRate;\n    uint128 variableBorrowIndex;\n    uint128 currentVariableBorrowRate;\n    uint128 currentStableBorrowRate;\n    uint40 lastUpdateTimestamp;\n    uint16 id;\n    address aTokenAddress;\n    address stableDebtTokenAddress;\n    address variableDebtTokenAddress;\n    address interestRateStrategyAddress;\n    uint128 accruedToTreasury;\n    uint128 unbacked;\n    uint128 isolationModeTotalDebt;\n  }\n\n  struct ReserveConfigurationMap {\n    //bit 0-15: LTV\n    //bit 16-31: Liq. threshold\n    //bit 32-47: Liq. bonus\n    //bit 48-55: Decimals\n    //bit 56: Reserve is active\n    //bit 57: reserve is frozen\n    //bit 58: borrowing is enabled\n    //bit 59: stable rate borrowing enabled\n    //bit 60-63: reserved\n    //bit 64-79: reserve factor\n    uint256 data;\n  }\n\n  struct UserConfigurationMap {\n    uint256 data;\n  }\n\n  enum InterestRateMode {NONE, STABLE, VARIABLE}\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}"
      },
      "interfaces/IEIP20NonStandard.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\n\n/**\n * @title EIP20NonStandardInterface\n * @dev Version of ERC20 with no return values for `transfer` and `transferFrom`\n *  See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ninterface IEIP20NonStandard {\n\n    /**\n     * @notice Get the total number of tokens in circulation\n     * @return The supply of tokens\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @notice Gets the balance of the specified address\n     * @param owner The address from which the balance will be retrieved\n     * @return balance\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    ///\n    /// !!!!!!!!!!!!!!\n    /// !!! NOTICE !!! `transfer` does not return a value, in violation of the ERC-20 specification\n    /// !!!!!!!!!!!!!!\n    ///\n\n    /**\n      * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      */\n    function transfer(address dst, uint256 amount) external;\n\n    ///\n    /// !!!!!!!!!!!!!!\n    /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the ERC-20 specification\n    /// !!!!!!!!!!!!!!\n    ///\n\n    /**\n      * @notice Transfer `amount` tokens from `src` to `dst`\n      * @param src The address of the source account\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      */\n    function transferFrom(address src, address dst, uint256 amount) external;\n\n    ///\n    /// !!!!!!!!!!!!!!\n    /// !!! NOTICE !!! `approve` does not return a value, in violation of the ERC-20 specification\n    /// !!!!!!!!!!!!!!\n    ///\n\n    /**\n      * @notice Approve `spender` to transfer up to `amount` from `src`\n      * @dev This will overwrite the approval amount for `spender`\n      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n      * @param spender The address of the account which may transfer tokens\n      * @param amount The number of tokens that are approved\n      */\n    function approve(address spender, uint256 amount) external;\n\n    /**\n      * @notice Get the current allowance from `owner` for `spender`\n      * @param owner The address of the account which owns the tokens to be spent\n      * @param spender The address of the account which may transfer tokens\n      * @return remaining The number of tokens allowed to be spent\n      */\n    function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n}"
      },
      "interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    function decimals() external view returns (uint8);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "interfaces/notional/AssetRateAdapter.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.0;\n\n/// @notice Used as a wrapper for tokens that are interest bearing for an\n/// underlying token. Follows the cToken interface, however, can be adapted\n/// for other interest bearing tokens.\ninterface AssetRateAdapter {\n    function token() external view returns (address);\n\n    function decimals() external view returns (uint8);\n\n    function description() external view returns (string memory);\n\n    function version() external view returns (uint256);\n\n    function underlying() external view returns (address);\n\n    function getExchangeRateStateful() external returns (int256);\n\n    function getExchangeRateView() external view returns (int256);\n\n    function getAnnualizedSupplyRate() external view returns (uint256);\n}\n"
      },
      "interfaces/notional/IPrimeCashHoldingsOracle.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.0;\npragma abicoder v2;\n\nstruct DepositData {\n    address[] targets;\n    bytes[] callData;\n    uint256[] msgValue;\n    uint256 underlyingDepositAmount;\n    address assetToken;\n    uint8 rebasingTokenBalanceAdjustment;\n}\n\nstruct RedeemData {\n    address[] targets;\n    bytes[] callData;\n    uint256 expectedUnderlying;\n    address assetToken;\n    uint8 rebasingTokenBalanceAdjustment;\n}\n\nstruct OracleData {\n    address holding;\n    uint256 externalUnderlyingAvailableForWithdraw;\n    uint256 currentExternalUnderlyingLend;\n    uint256 maxExternalDeposit;\n}\n\ninterface IPrimeCashHoldingsOracle {\n    /// @notice Returns a list of the various holdings for the prime cash\n    /// currency\n    function holdings() external view returns (address[] memory);\n\n    /// @notice Returns the underlying token that all holdings can be redeemed\n    /// for.\n    function underlying() external view returns (address);\n\n    /// @notice Returns the native decimal precision of the underlying token\n    function decimals() external view returns (uint8);\n\n    /// @notice Returns the total underlying held by the caller in all the\n    /// listed holdings\n    function getTotalUnderlyingValueStateful() external returns (\n        uint256 nativePrecision,\n        uint256 internalPrecision\n    );\n\n    function getTotalUnderlyingValueView() external view returns (\n        uint256 nativePrecision,\n        uint256 internalPrecision\n    );\n\n    /// @notice Returns calldata for how to withdraw an amount\n    function getRedemptionCalldata(uint256 withdrawAmount) external view returns (\n        RedeemData[] memory redeemData\n    );\n\n    function holdingValuesInUnderlying() external view returns (uint256[] memory);\n\n    function getRedemptionCalldataForRebalancing(\n        address[] calldata _holdings, \n        uint256[] calldata withdrawAmounts\n    ) external view returns (\n        RedeemData[] memory redeemData\n    );\n\n    function getDepositCalldataForRebalancing(\n        address[] calldata _holdings,\n        uint256[] calldata depositAmounts\n    ) external view returns (\n        DepositData[] memory depositData\n    );\n\n    function getOracleData() external view returns (OracleData memory);\n}"
      },
      "interfaces/notional/IRewarder.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\n\ninterface IRewarder {\n    event RewardTransfer(address indexed rewardToken, address indexed account, uint256 amount);\n    event RewardEmissionUpdate(uint256 emissionRatePerYear, uint256 endTime);\n\n    function NTOKEN_ADDRESS() external returns(address);\n\n    function CURRENCY_ID() external returns(uint16);\n\n    function detached() external returns(bool);\n\n    function claimRewards(\n        address account,\n        uint16 currencyId,\n        uint256 nTokenBalanceBefore,\n        uint256 nTokenBalanceAfter,\n        uint256 totalSupply\n    ) external;\n\n    function getAccountRewardClaim(address account, uint32 blockTime) external returns (uint256);\n\n    function getAccountRewardClaim(address account, uint256 nTokenBalanceAtDetach, bytes32[] calldata proof)\n        external\n        returns (uint256);\n\n    function claimRewardsDirect(address account, uint256 nTokenBalanceAtDetach, bytes32[] calldata proof) external;\n\n    function accumulatedRewardPerNToken() external returns (uint128);\n\n    function lastAccumulatedTime() external returns (uint32);\n\n    function emissionRatePerYear() external returns (uint128);\n\n    function detach() external;\n}\n"
      },
      "interfaces/notional/IVaultController.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport {\n    VaultConfigParams,\n    VaultConfigStorage,\n    VaultConfig,\n    VaultState,\n    VaultAccount,\n    VaultAccountHealthFactors,\n    PrimeRate\n} from \"../../contracts/global/Types.sol\";\n\ninterface IVaultAction {\n    /// @notice Emitted when a new vault is listed or updated\n    event VaultUpdated(address indexed vault, bool enabled, uint80 maxPrimaryBorrowCapacity);\n    /// @notice Emitted when a vault's status is updated\n    event VaultPauseStatus(address indexed vault, bool enabled);\n    /// @notice Emitted when a vault's deleverage status is updated\n    event VaultDeleverageStatus(address indexed vaultAddress, bool disableDeleverage);\n    /// @notice Emitted when a secondary currency borrow capacity is updated\n    event VaultUpdateSecondaryBorrowCapacity(address indexed vault, uint16 indexed currencyId, uint80 maxSecondaryBorrowCapacity);\n    /// @notice Emitted when the borrow capacity on a vault changes\n    event VaultBorrowCapacityChange(address indexed vault, uint16 indexed currencyId, uint256 totalUsedBorrowCapacity);\n\n    /// @notice Emitted when a vault executes a secondary borrow\n    event VaultSecondaryTransaction(\n        address indexed vault,\n        address indexed account,\n        uint16 indexed currencyId,\n        uint256 maturity,\n        int256 netUnderlyingDebt,\n        int256 netPrimeSupply\n    );\n\n    /** Vault Action Methods */\n\n    /// @notice Governance only method to whitelist a particular vault\n    function updateVault(\n        address vaultAddress,\n        VaultConfigParams memory vaultConfig,\n        uint80 maxPrimaryBorrowCapacity\n    ) external;\n\n    /// @notice Governance only method to pause a particular vault\n    function setVaultPauseStatus(\n        address vaultAddress,\n        bool enable\n    ) external;\n\n    function setVaultDeleverageStatus(\n        address vaultAddress,\n        bool disableDeleverage\n    ) external;\n\n    /// @notice Governance only method to set the borrow capacity\n    function setMaxBorrowCapacity(\n        address vaultAddress,\n        uint80 maxVaultBorrowCapacity\n    ) external;\n\n    /// @notice Governance only method to update a vault's secondary borrow capacity\n    function updateSecondaryBorrowCapacity(\n        address vaultAddress,\n        uint16 secondaryCurrencyId,\n        uint80 maxBorrowCapacity\n    ) external;\n\n    function borrowSecondaryCurrencyToVault(\n        address account,\n        uint256 maturity,\n        uint256[2] calldata underlyingToBorrow,\n        uint32[2] calldata maxBorrowRate,\n        uint32[2] calldata minRollLendRate\n    ) external returns (int256[2] memory underlyingTokensTransferred);\n\n    function repaySecondaryCurrencyFromVault(\n        address account,\n        uint256 maturity,\n        uint256[2] calldata underlyingToRepay,\n        uint32[2] calldata minLendRate\n    ) external payable returns (int256[2] memory underlyingDepositExternal);\n\n    function settleSecondaryBorrowForAccount(address vault, address account) external;\n}\n\ninterface IVaultAccountAction {\n    /**\n     * @notice Borrows a specified amount of fCash in the vault's borrow currency and deposits it\n     * all plus the depositAmountExternal into the vault to mint strategy tokens.\n     *\n     * @param account the address that will enter the vault\n     * @param vault the vault to enter\n     * @param depositAmountExternal some amount of additional collateral in the borrowed currency\n     * to be transferred to vault\n     * @param maturity the maturity to borrow at\n     * @param fCash amount to borrow\n     * @param maxBorrowRate maximum interest rate to borrow at\n     * @param vaultData additional data to pass to the vault contract\n     */\n    function enterVault(\n        address account,\n        address vault,\n        uint256 depositAmountExternal,\n        uint256 maturity,\n        uint256 fCash,\n        uint32 maxBorrowRate,\n        bytes calldata vaultData\n    ) external payable returns (uint256 strategyTokensAdded);\n\n    /**\n     * @notice Re-enters the vault at a longer dated maturity. The account's existing borrow\n     * position will be closed and a new borrow position at the specified maturity will be\n     * opened. All strategy token holdings will be rolled forward.\n     *\n     * @param account the address that will reenter the vault\n     * @param vault the vault to reenter\n     * @param fCashToBorrow amount of fCash to borrow in the next maturity\n     * @param maturity new maturity to borrow at\n     */\n    function rollVaultPosition(\n        address account,\n        address vault,\n        uint256 fCashToBorrow,\n        uint256 maturity,\n        uint256 depositAmountExternal,\n        uint32 minLendRate,\n        uint32 maxBorrowRate,\n        bytes calldata enterVaultData\n    ) external payable returns (uint256 strategyTokensAdded);\n\n    /**\n     * @notice Prior to maturity, allows an account to withdraw their position from the vault. Will\n     * redeem some number of vault shares to the borrow currency and close the borrow position by\n     * lending `fCashToLend`. Any shortfall in cash from lending will be transferred from the account,\n     * any excess profits will be transferred to the account.\n     *\n     * Post maturity, will net off the account's debt against vault cash balances and redeem all remaining\n     * strategy tokens back to the borrowed currency and transfer the profits to the account.\n     *\n     * @param account the address that will exit the vault\n     * @param vault the vault to enter\n     * @param vaultSharesToRedeem amount of vault tokens to exit, only relevant when exiting pre-maturity\n     * @param fCashToLend amount of fCash to lend\n     * @param minLendRate the minimum rate to lend at\n     * @param exitVaultData passed to the vault during exit\n     * @return underlyingToReceiver amount of underlying tokens returned to the receiver on exit\n     */\n    function exitVault(\n        address account,\n        address vault,\n        address receiver,\n        uint256 vaultSharesToRedeem,\n        uint256 fCashToLend,\n        uint32 minLendRate,\n        bytes calldata exitVaultData\n    ) external payable returns (uint256 underlyingToReceiver);\n\n    function settleVaultAccount(address account, address vault) external;\n}\n\ninterface IVaultLiquidationAction {\n    event VaultDeleverageAccount(\n        address indexed vault,\n        address indexed account,\n        uint16 currencyId,\n        uint256 vaultSharesToLiquidator,\n        int256 depositAmountPrimeCash\n    );\n\n    event VaultLiquidatorProfit(\n        address indexed vault,\n        address indexed account,\n        address indexed liquidator,\n        uint256 vaultSharesToLiquidator,\n        bool transferSharesToLiquidator\n    );\n    \n    event VaultAccountCashLiquidation(\n        address indexed vault,\n        address indexed account,\n        address indexed liquidator,\n        uint16 currencyId,\n        int256 fCashDeposit,\n        int256 cashToLiquidator\n    );\n\n    /**\n     * @notice If an account is below the minimum collateral ratio, this method wil deleverage (liquidate)\n     * that account. `depositAmountExternal` in the borrow currency will be transferred from the liquidator\n     * and used to offset the account's debt position. The liquidator will receive either vaultShares or\n     * cash depending on the vault's configuration.\n     * @param account the address that will exit the vault\n     * @param vault the vault to enter\n     * @param liquidator the address that will receive profits from liquidation\n     * @param depositAmountPrimeCash amount of cash to deposit\n     * @return vaultSharesFromLiquidation amount of vaultShares received from liquidation\n     */\n    function deleverageAccount(\n        address account,\n        address vault,\n        address liquidator,\n        uint16 currencyIndex,\n        int256 depositUnderlyingInternal\n    ) external payable returns (uint256 vaultSharesFromLiquidation, int256 depositAmountPrimeCash);\n\n    function liquidateVaultCashBalance(\n        address account,\n        address vault,\n        address liquidator,\n        uint256 currencyIndex,\n        int256 fCashDeposit\n    ) external returns (int256 cashToLiquidator);\n\n    function liquidateExcessVaultCash(\n        address account,\n        address vault,\n        address liquidator,\n        uint256 excessCashIndex,\n        uint256 debtIndex,\n        uint256 _depositUnderlyingInternal\n    ) external payable returns (int256 cashToLiquidator);\n}\n\ninterface IVaultAccountHealth {\n    function getVaultAccountHealthFactors(address account, address vault) external view returns (\n        VaultAccountHealthFactors memory h,\n        int256[3] memory maxLiquidatorDepositUnderlying,\n        uint256[3] memory vaultSharesToLiquidator\n    );\n\n    function calculateDepositAmountInDeleverage(\n        uint256 currencyIndex,\n        VaultAccount memory vaultAccount,\n        VaultConfig memory vaultConfig,\n        VaultState memory vaultState,\n        int256 depositUnderlyingInternal\n    ) external returns (int256 depositInternal, uint256 vaultSharesToLiquidator, PrimeRate memory);\n\n    function getfCashRequiredToLiquidateCash(\n        uint16 currencyId,\n        uint256 maturity,\n        int256 vaultAccountCashBalance\n    ) external view returns (int256 fCashRequired, int256 discountFactor);\n\n    function checkVaultAccountCollateralRatio(address vault, address account, bool checkDebtCap) external;\n\n    function getVaultAccount(address account, address vault) external view returns (VaultAccount memory);\n    function getVaultAccountWithFeeAccrual(\n        address account, address vault\n    ) external view returns (VaultAccount memory, int256 accruedPrimeVaultFeeInUnderlying);\n\n    function getVaultConfig(address vault) external view returns (VaultConfig memory vaultConfig);\n\n    function getBorrowCapacity(address vault, uint16 currencyId) external view returns (\n        uint256 currentPrimeDebtUnderlying,\n        uint256 totalfCashDebt,\n        uint256 maxBorrowCapacity\n    );\n\n    function getSecondaryBorrow(address vault, uint16 currencyId, uint256 maturity) \n        external view returns (int256 totalDebt);\n\n    /// @notice View method to get vault state\n    function getVaultState(address vault, uint256 maturity) external view returns (VaultState memory vaultState);\n\n    function getVaultAccountSecondaryDebt(address account, address vault) external view returns (\n        uint256 maturity,\n        int256[2] memory accountSecondaryDebt,\n        int256[2] memory accountSecondaryCashHeld\n    );\n\n    function signedBalanceOfVaultTokenId(address account, uint256 id) external view returns (int256);\n}\n\ninterface IVaultController is IVaultAccountAction, IVaultAction, IVaultLiquidationAction, IVaultAccountHealth {}\n"
      },
      "interfaces/notional/nERC1155Interface.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../contracts/global/Types.sol\";\n\ninterface nERC1155Interface {\n    event TransferSingle(\n        address indexed operator,\n        address indexed from,\n        address indexed to,\n        uint256 id,\n        uint256 value\n    );\n    event TransferBatch(\n        address indexed operator,\n        address indexed from,\n        address indexed to,\n        uint256[] ids,\n        uint256[] values\n    );\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n    event URI(string value, uint256 indexed id);\n\n    function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n        external\n        view\n        returns (uint256[] memory);\n\n    function signedBalanceOf(address account, uint256 id) external view returns (int256);\n\n    function signedBalanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n        external\n        view\n        returns (int256[] memory);\n\n    function setApprovalForAll(address operator, bool approved) external;\n\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes calldata data\n    ) external payable;\n\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] calldata ids,\n        uint256[] calldata amounts,\n        bytes calldata data\n    ) external payable;\n\n    function decodeToAssets(uint256[] calldata ids, uint256[] calldata amounts)\n        external\n        view\n        returns (PortfolioAsset[] memory);\n\n    function encodeToId(\n        uint16 currencyId,\n        uint40 maturity,\n        uint8 assetType\n    ) external pure returns (uint256 id);\n}\n"
      },
      "interfaces/notional/NotionalCalculations.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../contracts/global/Types.sol\";\n\ninterface NotionalCalculations {\n    function calculateNTokensToMint(uint16 currencyId, uint88 amountToDepositExternalPrecision)\n        external\n        view\n        returns (uint256);\n\n    function nTokenPresentValueAssetDenominated(uint16 currencyId) external view returns (int256);\n\n    function nTokenPresentValueUnderlyingDenominated(uint16 currencyId)\n        external\n        view\n        returns (int256);\n\n    function convertNTokenToUnderlying(uint16 currencyId, int256 nTokenBalance) external view returns (int256);\n\n    function getfCashAmountGivenCashAmount(\n        uint16 currencyId,\n        int88 netCashToAccount,\n        uint256 marketIndex,\n        uint256 blockTime\n    ) external view returns (int256);\n\n    function getCashAmountGivenfCashAmount(\n        uint16 currencyId,\n        int88 fCashAmount,\n        uint256 marketIndex,\n        uint256 blockTime\n    ) external view returns (int256, int256);\n\n    function nTokenGetClaimableIncentives(address account, uint256 blockTime)\n        external\n        view\n        returns (uint256);\n\n    function getPresentfCashValue(\n        uint16 currencyId,\n        uint256 maturity,\n        int256 notional,\n        uint256 blockTime,\n        bool riskAdjusted\n    ) external view returns (int256 presentValue);\n\n    function getMarketIndex(\n        uint256 maturity,\n        uint256 blockTime\n    ) external pure returns (uint8 marketIndex);\n\n    function getfCashLendFromDeposit(\n        uint16 currencyId,\n        uint256 depositAmountExternal,\n        uint256 maturity,\n        uint32 minLendRate,\n        uint256 blockTime,\n        bool useUnderlying\n    ) external view returns (\n        uint88 fCashAmount,\n        uint8 marketIndex,\n        bytes32 encodedTrade\n    );\n\n    function getfCashBorrowFromPrincipal(\n        uint16 currencyId,\n        uint256 borrowedAmountExternal,\n        uint256 maturity,\n        uint32 maxBorrowRate,\n        uint256 blockTime,\n        bool useUnderlying\n    ) external view returns (\n        uint88 fCashDebt,\n        uint8 marketIndex,\n        bytes32 encodedTrade\n    );\n\n    function getDepositFromfCashLend(\n        uint16 currencyId,\n        uint256 fCashAmount,\n        uint256 maturity,\n        uint32 minLendRate,\n        uint256 blockTime\n    ) external view returns (\n        uint256 depositAmountUnderlying,\n        uint256 depositAmountAsset,\n        uint8 marketIndex,\n        bytes32 encodedTrade\n    );\n\n    function getPrincipalFromfCashBorrow(\n        uint16 currencyId,\n        uint256 fCashBorrow,\n        uint256 maturity,\n        uint32 maxBorrowRate,\n        uint256 blockTime\n    ) external view returns (\n        uint256 borrowAmountUnderlying,\n        uint256 borrowAmountAsset,\n        uint8 marketIndex,\n        bytes32 encodedTrade\n    );\n\n    function convertCashBalanceToExternal(\n        uint16 currencyId,\n        int256 cashBalanceInternal,\n        bool useUnderlying\n    ) external view returns (int256);\n\n    function convertUnderlyingToPrimeCash(\n        uint16 currencyId,\n        int256 underlyingExternal\n    ) external view returns (int256);\n\n    function convertSettledfCash(\n        uint16 currencyId,\n        uint256 maturity,\n        int256 fCashBalance,\n        uint256 blockTime\n    ) external view returns (int256 signedPrimeSupplyValue);\n\n    function accruePrimeInterest(\n        uint16 currencyId\n    ) external returns (PrimeRate memory pr, PrimeCashFactors memory);\n}\n"
      },
      "interfaces/notional/NotionalGovernance.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../contracts/global/Deployments.sol\";\nimport \"../../contracts/global/Types.sol\";\nimport \"../../interfaces/chainlink/AggregatorV2V3Interface.sol\";\nimport \"../../interfaces/notional/NotionalGovernance.sol\";\nimport \"../../interfaces/notional/IRewarder.sol\";\nimport \"../../interfaces/aave/ILendingPool.sol\";\nimport {IPrimeCashHoldingsOracle} from \"../../interfaces/notional/IPrimeCashHoldingsOracle.sol\";\n\ninterface NotionalGovernance {\n    event ListCurrency(uint16 newCurrencyId);\n    event UpdateETHRate(uint16 currencyId);\n    event UpdateAssetRate(uint16 currencyId);\n    event UpdateCashGroup(uint16 currencyId);\n    event DeployNToken(uint16 currencyId, address nTokenAddress);\n    event UpdateDepositParameters(uint16 currencyId);\n    event UpdateInitializationParameters(uint16 currencyId);\n    event UpdateTokenCollateralParameters(uint16 currencyId);\n    event UpdateGlobalTransferOperator(address operator, bool approved);\n    event UpdateAuthorizedCallbackContract(address operator, bool approved);\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n    event PauseRouterAndGuardianUpdated(address indexed pauseRouter, address indexed pauseGuardian);\n    event UpdateInterestRateCurve(uint16 indexed currencyId, uint8 indexed marketIndex);\n    event UpdateMaxUnderlyingSupply(uint16 indexed currencyId, uint256 maxUnderlyingSupply);\n    event PrimeProxyDeployed(uint16 indexed currencyId, address proxy, bool isCashProxy);\n\n    function transferOwnership(address newOwner, bool direct) external;\n\n    function claimOwnership() external;\n\n    function upgradeBeacon(Deployments.BeaconType proxy, address newBeacon) external;\n\n    function setPauseRouterAndGuardian(address pauseRouter_, address pauseGuardian_) external;\n\n    function listCurrency(\n        TokenStorage calldata underlyingToken,\n        ETHRateStorage memory ethRate,\n        InterestRateCurveSettings calldata primeDebtCurve,\n        IPrimeCashHoldingsOracle primeCashHoldingsOracle,\n        bool allowPrimeCashDebt,\n        uint8 rateOracleTimeWindow5Min,\n        string calldata underlyingName,\n        string calldata underlyingSymbol\n    ) external returns (uint16 currencyId);\n\n    function enableCashGroup(\n        uint16 currencyId,\n        CashGroupSettings calldata cashGroup,\n        string calldata underlyingName,\n        string calldata underlyingSymbol\n    ) external;\n\n    function updateDepositParameters(\n        uint16 currencyId,\n        uint32[] calldata depositShares,\n        uint32[] calldata leverageThresholds\n    ) external;\n\n    function updateInitializationParameters(\n        uint16 currencyId,\n        uint32[] calldata annualizedAnchorRates,\n        uint32[] calldata proportions\n    ) external;\n\n\n    function updateTokenCollateralParameters(\n        uint16 currencyId,\n        uint8 residualPurchaseIncentive10BPS,\n        uint8 pvHaircutPercentage,\n        uint8 residualPurchaseTimeBufferHours,\n        uint8 cashWithholdingBuffer10BPS,\n        uint8 liquidationHaircutPercentage,\n        uint8 maxMintDeviationPercentage\n    ) external;\n\n    function updateCashGroup(uint16 currencyId, CashGroupSettings calldata cashGroup) external;\n\n    function updateInterestRateCurve(\n        uint16 currencyId,\n        uint8[] calldata marketIndices,\n        InterestRateCurveSettings[] calldata settings\n    ) external;\n\n    function setMaxUnderlyingSupply(\n        uint16 currencyId,\n        uint256 maxUnderlyingSupply,\n        uint8 maxPrimeDebtUtilization\n    ) external;\n\n    function updatePrimeCashHoldingsOracle(\n        uint16 currencyId,\n        IPrimeCashHoldingsOracle primeCashHoldingsOracle\n    ) external;\n\n    function updatePrimeCashCurve(\n        uint16 currencyId,\n        InterestRateCurveSettings calldata primeDebtCurve\n    ) external;\n\n    function enablePrimeDebt(\n        uint16 currencyId,\n        string calldata underlyingName,\n        string calldata underlyingSymbol\n    ) external;\n\n    function updateETHRate(\n        uint16 currencyId,\n        AggregatorV2V3Interface rateOracle,\n        bool mustInvert,\n        uint8 buffer,\n        uint8 haircut,\n        uint8 liquidationDiscount\n    ) external;\n\n    function updateAuthorizedCallbackContract(address operator, bool approved) external;\n}"
      },
      "interfaces/notional/NotionalProxy.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../contracts/global/Types.sol\";\nimport \"./nTokenERC20.sol\";\nimport \"./nERC1155Interface.sol\";\nimport \"./NotionalGovernance.sol\";\nimport \"./NotionalCalculations.sol\";\nimport \"./NotionalViews.sol\";\nimport \"./NotionalTreasury.sol\";\nimport {IVaultController} from \"./IVaultController.sol\";\n\ninterface NotionalProxy is\n    nTokenERC20,\n    nERC1155Interface,\n    NotionalGovernance,\n    NotionalTreasury,\n    NotionalCalculations,\n    NotionalViews,\n    IVaultController\n{\n    /** User trading events */\n    event MarketsInitialized(uint16 currencyId);\n    event SweepCashIntoMarkets(uint16 currencyId, int256 cashIntoMarkets);\n\n    /// @notice Emitted once when incentives are migrated\n    event IncentivesMigrated(\n        uint16 currencyId,\n        uint256 migrationEmissionRate,\n        uint256 finalIntegralTotalSupply,\n        uint256 migrationTime\n    );\n    /// @notice Emitted if a token address is migrated\n    event TokenMigrated(uint16 currencyId) ;\n    /// @notice Emitted whenever an account context has updated\n    event AccountContextUpdate(address indexed account);\n    /// @notice Emitted when an account has assets that are settled\n    event AccountSettled(address indexed account);\n\n    /* Liquidation Events */\n    event LiquidateLocalCurrency(\n        address indexed liquidated,\n        address indexed liquidator,\n        uint16 localCurrencyId,\n        int256 netLocalFromLiquidator\n    );\n\n    event LiquidateCollateralCurrency(\n        address indexed liquidated,\n        address indexed liquidator,\n        uint16 localCurrencyId,\n        uint16 collateralCurrencyId,\n        int256 netLocalFromLiquidator,\n        int256 netCollateralTransfer,\n        int256 netNTokenTransfer\n    );\n\n    event LiquidatefCashEvent(\n        address indexed liquidated,\n        address indexed liquidator,\n        uint16 localCurrencyId,\n        uint16 fCashCurrency,\n        int256 netLocalFromLiquidator,\n        uint256[] fCashMaturities,\n        int256[] fCashNotionalTransfer\n    );\n\n    event SetPrimeSettlementRate(\n        uint256 indexed currencyId,\n        uint256 indexed maturity,\n        int256 supplyFactor,\n        int256 debtFactor\n    );\n\n    /// @notice Emits every time interest is accrued\n    event PrimeCashInterestAccrued(\n        uint16 indexed currencyId,\n        uint256 underlyingScalar,\n        uint256 supplyScalar,\n        uint256 debtScalar\n    );\n\n    event PrimeCashCurveChanged(uint16 indexed currencyId);\n\n    event PrimeCashHoldingsOracleUpdated(uint16 indexed currencyId, address oracle);\n\n    /** UUPS Upgradeable contract calls */\n    function upgradeTo(address newImplementation) external;\n\n    function upgradeToAndCall(address newImplementation, bytes memory data) external payable;\n\n    function getImplementation() external view returns (address);\n\n    function owner() external view returns (address);\n\n    function pauseRouter() external view returns (address);\n\n    function pauseGuardian() external view returns (address);\n\n    /** Initialize Markets Action */\n    function initializeMarkets(uint16 currencyId, bool isFirstInit) external;\n\n    function sweepCashIntoMarkets(uint16 currencyId) external;\n\n    /** Account Action */\n    function nTokenRedeem(\n        address redeemer,\n        uint16 currencyId,\n        uint96 tokensToRedeem_\n    ) external returns (int256);\n\n    function enablePrimeBorrow(bool allowPrimeBorrow) external;\n\n    function enableBitmapCurrency(uint16 currencyId) external;\n\n    function settleAccount(address account) external;\n\n    function depositUnderlyingToken(\n        address account,\n        uint16 currencyId,\n        uint256 amountExternalPrecision\n    ) external payable returns (uint256);\n\n    function withdraw(\n        uint16 currencyId,\n        uint88 amountInternalPrecision,\n        bool redeemToUnderlying\n    ) external returns (uint256);\n\n    function withdrawViaProxy(\n        uint16 currencyId,\n        address owner,\n        address receiver,\n        address spender,\n        uint88 withdrawAmountPrimeCash\n    ) external returns (uint256);\n\n    /** Batch Action */\n    function batchBalanceAction(address account, BalanceAction[] calldata actions) external payable;\n\n    function batchBalanceAndTradeAction(address account, BalanceActionWithTrades[] calldata actions)\n        external\n        payable;\n\n    function batchBalanceAndTradeActionWithCallback(\n        address account,\n        BalanceActionWithTrades[] calldata actions,\n        bytes calldata callbackData\n    ) external payable;\n\n    function batchLend(address account, BatchLend[] calldata actions) external;\n\n    /** Liquidation Action */\n    function calculateLocalCurrencyLiquidation(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint96 maxNTokenLiquidation\n    ) external returns (int256, int256);\n\n    function liquidateLocalCurrency(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint96 maxNTokenLiquidation\n    ) external payable returns (int256, int256);\n\n    function calculateCollateralCurrencyLiquidation(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint16 collateralCurrency,\n        uint128 maxCollateralLiquidation,\n        uint96 maxNTokenLiquidation\n    ) external returns (int256, int256, int256);\n\n    function liquidateCollateralCurrency(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint16 collateralCurrency,\n        uint128 maxCollateralLiquidation,\n        uint96 maxNTokenLiquidation,\n        bool withdrawCollateral,\n        bool redeemToUnderlying\n    ) external payable returns (int256, int256, int256);\n\n    function calculatefCashLocalLiquidation(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint256[] calldata fCashMaturities,\n        uint256[] calldata maxfCashLiquidateAmounts\n    ) external returns (int256[] memory, int256);\n\n    function liquidatefCashLocal(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint256[] calldata fCashMaturities,\n        uint256[] calldata maxfCashLiquidateAmounts\n    ) external payable returns (int256[] memory, int256);\n\n    function calculatefCashCrossCurrencyLiquidation(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint16 fCashCurrency,\n        uint256[] calldata fCashMaturities,\n        uint256[] calldata maxfCashLiquidateAmounts\n    ) external returns (int256[] memory, int256);\n\n    function liquidatefCashCrossCurrency(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint16 fCashCurrency,\n        uint256[] calldata fCashMaturities,\n        uint256[] calldata maxfCashLiquidateAmounts\n    ) external payable returns (int256[] memory, int256);\n}\n"
      },
      "interfaces/notional/NotionalTreasury.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport {IRewarder} from \"./IRewarder.sol\";\n\ninterface NotionalTreasury {\n    event UpdateIncentiveEmissionRate(uint16 currencyId, uint32 newEmissionRate);\n    event UpdateSecondaryIncentiveRewarder(uint16 indexed currencyId, address rewarder);\n\n    struct RebalancingTargetConfig {\n        address holding;\n        uint8 targetUtilization;\n        uint16 externalWithdrawThreshold;\n    }\n\n    /// @notice Emitted when reserve balance is updated\n    event ReserveBalanceUpdated(uint16 indexed currencyId, int256 newBalance);\n    /// @notice Emitted when reserve balance is harvested\n    event ExcessReserveBalanceHarvested(uint16 indexed currencyId, int256 harvestAmount);\n    /// @dev Emitted when treasury manager is updated\n    event TreasuryManagerChanged(address indexed previousManager, address indexed newManager);\n    /// @dev Emitted when reserve buffer value is updated\n    event ReserveBufferUpdated(uint16 currencyId, uint256 bufferAmount);\n\n    event RebalancingTargetsUpdated(uint16 currencyId, RebalancingTargetConfig[] targets);\n\n    event RebalancingCooldownUpdated(uint16 currencyId, uint40 cooldownTimeInSeconds);\n\n    event CurrencyRebalanced(uint16 currencyId, uint256 supplyFactor, uint256 annualizedInterestRate);\n\n    /// @notice Emitted when the interest accrued on asset deposits is harvested \n    event AssetInterestHarvested(uint16 indexed currencyId, address assetToken, uint256 harvestAmount);\n\n    function transferReserveToTreasury(uint16[] calldata currencies) external returns (uint256[] memory);\n\n    function harvestAssetInterest(uint16[] calldata currencies) external;\n\n    function setTreasuryManager(address manager) external;\n\n    function setRebalancingBot(address _rebalancingBot) external;\n\n    function setReserveBuffer(uint16 currencyId, uint256 amount) external;\n\n    function setReserveCashBalance(uint16 currencyId, int256 reserveBalance) external;\n\n    function setRebalancingTargets(uint16 currencyId, RebalancingTargetConfig[] calldata targets) external;\n\n    function setRebalancingCooldown(uint16 currencyId, uint40 cooldownTimeInSeconds) external;\n\n    function checkRebalance() external view returns (uint16[] memory currencyIds);\n\n    function rebalance(uint16 currencyId) external;\n\n    function updateIncentiveEmissionRate(uint16 currencyId, uint32 newEmissionRate) external;\n\n    function setSecondaryIncentiveRewarder(uint16 currencyId, IRewarder rewarder) external;\n}"
      },
      "interfaces/notional/NotionalViews.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport \"../../contracts/global/Types.sol\";\n\ninterface NotionalViews {\n    function getMaxCurrencyId() external view returns (uint16);\n\n    function getCurrencyId(address tokenAddress) external view returns (uint16 currencyId);\n\n    function getCurrency(uint16 currencyId)\n        external\n        view\n        returns (Token memory assetToken, Token memory underlyingToken);\n\n    function getRateStorage(uint16 currencyId)\n        external\n        view\n        returns (ETHRateStorage memory ethRate, AssetRateStorage memory assetRate);\n\n    function getCurrencyAndRates(uint16 currencyId)\n        external\n        view\n        returns (\n            Token memory assetToken,\n            Token memory underlyingToken,\n            ETHRate memory ethRate,\n            Deprecated_AssetRateParameters memory assetRate\n        );\n\n    function getCashGroup(uint16 currencyId) external view returns (CashGroupSettings memory);\n\n    function getCashGroupAndAssetRate(uint16 currencyId)\n        external\n        view\n        returns (CashGroupSettings memory cashGroup, Deprecated_AssetRateParameters memory assetRate);\n\n    function getInterestRateCurve(uint16 currencyId) external view returns (\n        InterestRateParameters[] memory nextInterestRateCurve,\n        InterestRateParameters[] memory activeInterestRateCurve\n    );\n\n    function getInitializationParameters(uint16 currencyId)\n        external\n        view\n        returns (int256[] memory annualizedAnchorRates, int256[] memory proportions);\n\n    function getDepositParameters(uint16 currencyId)\n        external\n        view\n        returns (int256[] memory depositShares, int256[] memory leverageThresholds);\n\n    function nTokenAddress(uint16 currencyId) external view returns (address);\n\n    function pCashAddress(uint16 currencyId) external view returns (address);\n\n    function pDebtAddress(uint16 currencyId) external view returns (address);\n\n    function getNoteToken() external view returns (address);\n\n    function getOwnershipStatus() external view returns (address owner, address pendingOwner);\n\n    function getGlobalTransferOperatorStatus(address operator)\n        external\n        view\n        returns (bool isAuthorized);\n\n    function getAuthorizedCallbackContractStatus(address callback)\n        external\n        view\n        returns (bool isAuthorized);\n\n    function getSecondaryIncentiveRewarder(uint16 currencyId)\n        external\n        view\n        returns (address incentiveRewarder);\n\n    function getPrimeFactors(uint16 currencyId, uint256 blockTime) external view returns (\n        PrimeRate memory primeRate,\n        PrimeCashFactors memory factors,\n        uint256 maxUnderlyingSupply,\n        uint256 totalUnderlyingSupply,\n        uint256 maxUnderlyingDebt,\n        uint256 totalUnderlyingDebt\n    );\n\n    function getPrimeFactorsStored(uint16 currencyId) external view returns (PrimeCashFactors memory);\n\n    function getPrimeCashHoldingsOracle(uint16 currencyId) external view returns (address);\n\n    function getPrimeInterestRateCurve(uint16 currencyId) external view returns (InterestRateParameters memory);\n\n    function getPrimeInterestRate(uint16 currencyId) external view returns (\n        uint256 annualDebtRatePreFee,\n        uint256 annualDebtRatePostFee,\n        uint256 annualSupplyRate\n    );\n\n    function getTotalfCashDebtOutstanding(uint16 currencyId, uint256 maturity) external view returns (\n        int256 totalfCashDebt,\n        int256 fCashDebtHeldInSettlementReserve,\n        int256 primeCashHeldInSettlementReserve\n    );\n\n    function getSettlementRate(uint16 currencyId, uint40 maturity)\n        external\n        view\n        returns (PrimeRate memory);\n\n    function getMarket(\n        uint16 currencyId,\n        uint256 maturity,\n        uint256 settlementDate\n    ) external view returns (MarketParameters memory);\n\n    function getActiveMarkets(uint16 currencyId) external view returns (MarketParameters[] memory);\n\n    function getActiveMarketsAtBlockTime(uint16 currencyId, uint32 blockTime)\n        external\n        view\n        returns (MarketParameters[] memory);\n\n    function getReserveBalance(uint16 currencyId) external view returns (int256 reserveBalance);\n\n    function getNTokenPortfolio(address tokenAddress)\n        external\n        view\n        returns (PortfolioAsset[] memory liquidityTokens, PortfolioAsset[] memory netfCashAssets);\n\n    function getNTokenAccount(address tokenAddress)\n        external\n        view\n        returns (\n            uint16 currencyId,\n            uint256 totalSupply,\n            uint256 incentiveAnnualEmissionRate,\n            uint256 lastInitializedTime,\n            bytes6 nTokenParameters,\n            int256 cashBalance,\n            uint256 accumulatedNOTEPerNToken,\n            uint256 lastAccumulatedTime\n        );\n\n    function getAccount(address account)\n        external\n        view\n        returns (\n            AccountContext memory accountContext,\n            AccountBalance[] memory accountBalances,\n            PortfolioAsset[] memory portfolio\n        );\n\n    function getAccountContext(address account) external view returns (AccountContext memory);\n\n    function getAccountPrimeDebtBalance(uint16 currencyId, address account) external view returns (\n        int256 debtBalance\n    );\n\n    function getAccountBalance(uint16 currencyId, address account)\n        external\n        view\n        returns (\n            int256 cashBalance,\n            int256 nTokenBalance,\n            uint256 lastClaimTime\n        );\n\n    function getBalanceOfPrimeCash(\n        uint16 currencyId,\n        address account\n    ) external view returns (int256 cashBalance);\n\n    function getAccountPortfolio(address account) external view returns (PortfolioAsset[] memory);\n\n    function getfCashNotional(\n        address account,\n        uint16 currencyId,\n        uint256 maturity\n    ) external view returns (int256);\n\n    function getAssetsBitmap(address account, uint16 currencyId) external view returns (bytes32);\n\n    function getFreeCollateral(address account) external view returns (int256, int256[] memory);\n\n    function getTreasuryManager() external view returns (address);\n\n    function getReserveBuffer(uint16 currencyId) external view returns (uint256);\n\n    function getRebalancingFactors(uint16 currencyId) external view\n      returns (address holding, uint8 target, uint16 externalWithdrawThreshold, RebalancingContextStorage memory context);\n\n    function getStoredTokenBalances(address[] calldata tokens) external view returns (uint256[] memory balances);\n\n    function decodeERC1155Id(uint256 id) external view returns (\n        uint16 currencyId,\n        uint256 maturity,\n        uint256 assetType,\n        address vaultAddress,\n        bool isfCashDebt\n    );\n\n    function encode(\n        uint16 currencyId,\n        uint256 maturity,\n        uint256 assetType,\n        address vaultAddress,\n        bool isfCashDebt\n    ) external pure returns (uint256);\n}"
      },
      "interfaces/notional/nTokenERC20.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface nTokenERC20 {\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    function nTokenTotalSupply(address nTokenAddress) external view returns (uint256);\n\n    function nTokenBalanceOf(uint16 currencyId, address account) external view returns (uint256);\n\n    function nTokenTransferAllowance(\n        uint16 currencyId,\n        address owner,\n        address spender\n    ) external view returns (uint256);\n\n    function pCashTransferAllowance(\n        uint16 currencyId,\n        address owner,\n        address spender\n    ) external view returns (uint256);\n\n    function nTokenTransferApprove(\n        uint16 currencyId,\n        address owner,\n        address spender,\n        uint256 amount\n    ) external returns (bool);\n\n    function pCashTransferApprove(\n        uint16 currencyId,\n        address owner,\n        address spender,\n        uint256 amount\n    ) external returns (bool);\n\n    function nTokenTransfer(\n        uint16 currencyId,\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    function pCashTransfer(\n        uint16 currencyId,\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    function nTokenTransferFrom(\n        uint16 currencyId,\n        address spender,\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    function pCashTransferFrom(\n        uint16 currencyId,\n        address spender,\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    function nTokenTransferApproveAll(address spender, uint256 amount) external returns (bool);\n\n    function nTokenClaimIncentives() external returns (uint256);\n\n}\n"
      },
      "interfaces/WETH9.sol": {
        "content": "// SPDX-License-Identifier: BSUL-1.1\npragma solidity >=0.7.6;\n\ninterface WETH9 {\n    function deposit() external payable;\n\n    function withdraw(uint256 wad) external;\n\n    function transfer(address dst, uint256 wad) external returns (bool);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}