creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/vaults/balancer/BalancerComposableAuraVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {BalancerSpotPrice} from \"./BalancerSpotPrice.sol\";\nimport {\n    AuraStakingMixin,\n    AuraVaultDeploymentParams,\n    DeploymentParams\n} from \"./mixins/AuraStakingMixin.sol\";\nimport {IERC20} from \"@contracts/utils/TokenUtils.sol\";\nimport {IComposablePool} from \"@interfaces/balancer/IBalancerPool.sol\";\nimport {IBalancerVault} from \"@interfaces/balancer/IBalancerVault.sol\";\n\ncontract BalancerComposableAuraVault is AuraStakingMixin {\n    /// @notice Helper singleton function to calculate spot prices\n    BalancerSpotPrice immutable SPOT_PRICE;\n\n    constructor(\n        NotionalProxy notional_,\n        AuraVaultDeploymentParams memory params,\n        BalancerSpotPrice _spotPrice\n    ) AuraStakingMixin(notional_, params) {\n        // BPT_INDEX must be defined for a composable pool\n        require(BPT_INDEX != NOT_FOUND);\n        SPOT_PRICE = _spotPrice;\n        (IERC20[] memory tokens, /* */) = TOKENS();\n        for (uint256 i; i < NUM_TOKENS(); i++) {\n            if (i == BPT_INDEX) continue;\n            // This version of the composable vault does not allow for BPT tokens\n            // to be held as one of the assets in the pool. More work needs to be\n            // done to support emergency withdraw and trading to enter and exit\n            // pools that hold BPT tokens.\n            require(_isBPT(address(tokens[i])) == false);\n        }\n    }\n\n    /// @notice strategy identifier\n    function strategy() external override virtual pure returns (bytes4) {\n        return bytes4(keccak256(\"BalancerComposableAuraVault\"));\n    }\n\n    function _joinPoolAndStake(\n        uint256[] memory amounts, uint256 minPoolClaim\n    ) internal override returns (uint256 lpTokens) {\n        // Composable pool custom data does not include the BPT token amount so \n        // we loop here to remove it from the customData\n        uint256[] memory amountsWithoutBpt = new uint256[](amounts.length - 1);\n        uint256 j;\n        for (uint256 i; i < amounts.length; i++) {\n            if (i == BPT_INDEX) continue;\n            amountsWithoutBpt[j] = amounts[i];\n            j++;\n        }\n\n        bytes memory customData = abi.encode(\n            IBalancerVault.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT,\n            amountsWithoutBpt,\n            minPoolClaim\n        );\n\n        lpTokens = _joinPoolExactTokensIn(amounts, customData);\n\n        // Transfer token to Aura protocol for boosted staking\n        bool success = AURA_BOOSTER.deposit(AURA_POOL_ID, lpTokens, true);\n        require(success);\n    }\n\n    function _unstakeAndExitPool(\n        uint256 poolClaim, uint256[] memory minAmounts, bool isSingleSided\n    ) internal override returns (uint256[] memory exitBalances) {\n        bool success = AURA_REWARD_POOL.withdrawAndUnwrap(poolClaim, false); // claimRewards = false\n        require(success);\n\n        bytes memory customData;\n        if (isSingleSided) {\n            // See this line here:\n            // https://github.com/balancer/balancer-v2-monorepo/blob/c7d4abbea39834e7778f9ff7999aaceb4e8aa048/pkg/pool-stable/contracts/ComposableStablePool.sol#L927\n            // While \"assets\" sent to the vault include the BPT token the tokenIndex passed in by this\n            // function does not include the BPT. primaryIndex in this code is inclusive of the BPT token in\n            // the assets array. Therefore, if primaryIndex > bptIndex subtract one to ensure that the primaryIndex\n            // does not include the BPT token here.\n            uint256 primaryIndex = PRIMARY_INDEX();\n            customData = abi.encode(\n                IBalancerVault.ComposableExitKind.EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,\n                poolClaim,\n                primaryIndex < BPT_INDEX ?  primaryIndex : primaryIndex - 1\n            );\n        } else {\n            customData = abi.encode(\n                IBalancerVault.ComposableExitKind.EXACT_BPT_IN_FOR_ALL_TOKENS_OUT,\n                poolClaim\n            );\n        }\n\n        exitBalances = _exitPoolExactBPTIn(minAmounts, customData);\n    }\n \n    function _checkPriceAndCalculateValue() internal view override returns (uint256) {\n        (/* */, uint8[] memory decimals) = TOKENS();\n        (uint256[] memory balances, uint256[] memory spotPrices) = SPOT_PRICE.getComposableSpotPrices(\n            BALANCER_POOL_ID,\n            address(BALANCER_POOL_TOKEN),\n            PRIMARY_INDEX(),\n            BPT_INDEX,\n            decimals\n        );\n\n        return _calculateLPTokenValue(balances, spotPrices);\n    }\n\n    /// @notice Composable pools have a different method to get the total supply\n    function _totalPoolSupply() internal view override returns (uint256) {\n        return IComposablePool(address(BALANCER_POOL_TOKEN)).getActualSupply();\n    }\n}\n"
      },
      "interfaces/notional/NotionalProxy.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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 CashBalanceChange(\n        address indexed account,\n        uint16 indexed currencyId,\n        int256 netCashChange\n    );\n    event nTokenSupplyChange(\n        address indexed account,\n        uint16 indexed currencyId,\n        int256 tokenSupplyChange\n    );\n    event MarketsInitialized(uint16 currencyId);\n    event SweepCashIntoMarkets(uint16 currencyId, int256 cashIntoMarkets);\n    event SettledCashDebt(\n        address indexed settledAccount,\n        uint16 indexed currencyId,\n        address indexed settler,\n        int256 amountToSettleAsset,\n        int256 fCashAmount\n    );\n    event nTokenResidualPurchase(\n        uint16 indexed currencyId,\n        uint40 indexed maturity,\n        address indexed purchaser,\n        int256 fCashAmountToPurchase,\n        int256 netAssetCashNToken\n    );\n    event LendBorrowTrade(\n        address indexed account,\n        uint16 indexed currencyId,\n        uint40 maturity,\n        int256 netAssetCash,\n        int256 netfCash\n    );\n    event AddRemoveLiquidity(\n        address indexed account,\n        uint16 indexed currencyId,\n        uint40 maturity,\n        int256 netAssetCash,\n        int256 netfCash,\n        int256 netLiquidityTokens\n    );\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\n    /// @notice Emitted when reserve fees are accrued\n    event ReserveFeeAccrued(uint16 indexed currencyId, int256 fee);\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    /// @notice Emitted when an asset rate is settled\n    event SetSettlementRate(uint256 indexed currencyId, uint256 indexed maturity, uint128 rate);\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    /** 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    /** Redeem nToken Action */\n    function nTokenRedeem(\n        address redeemer,\n        uint16 currencyId,\n        uint96 tokensToRedeem_,\n        bool sellTokenAssets,\n        bool acceptResidualAssets\n    ) external returns (int256);\n\n    /** Account Action */\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 depositAssetToken(\n        address account,\n        uint16 currencyId,\n        uint256 amountExternalPrecision\n    ) external returns (uint256);\n\n    function withdraw(\n        uint16 currencyId,\n        uint88 amountInternalPrecision,\n        bool redeemToUnderlying\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 returns (int256, int256);\n\n    function calculateCollateralCurrencyLiquidation(\n        address liquidateAccount,\n        uint16 localCurrency,\n        uint16 collateralCurrency,\n        uint128 maxCollateralLiquidation,\n        uint96 maxNTokenLiquidation\n    )\n        external\n        returns (\n            int256,\n            int256,\n            int256\n        );\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    )\n        external\n        returns (\n            int256,\n            int256,\n            int256\n        );\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 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 returns (int256[] memory, int256);\n}\n"
      },
      "contracts/global/mainnet/Deployments.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\n\nimport {Constants} from \"../Constants.sol\";\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {IWstETH} from \"@interfaces/IWstETH.sol\";\nimport {IBalancerVault, IAsset} from \"@interfaces/balancer/IBalancerVault.sol\";\nimport {WETH9} from \"@interfaces/WETH9.sol\";\nimport {ISwapRouter as UniV3ISwapRouter} from \"@interfaces/uniswap/v3/ISwapRouter.sol\";\nimport {IUniV2Router2} from \"@interfaces/uniswap/v2/IUniV2Router2.sol\";\nimport {ICurveRouter} from \"@interfaces/curve/ICurveRouter.sol\";\nimport {ICurveRegistry} from \"@interfaces/curve/ICurveRegistry.sol\";\nimport {ICurveMetaRegistry} from \"@interfaces/curve/ICurveMetaRegistry.sol\";\nimport {ICurveRouterV2} from \"@interfaces/curve/ICurveRouterV2.sol\";\nimport {ITradingModule} from \"@interfaces/trading/ITradingModule.sol\";\nimport {IWrappedfCashFactory} from \"@interfaces/notional/IWrappedfCashFactory.sol\";\nimport {AggregatorV2V3Interface} from \"@interfaces/chainlink/AggregatorV2V3Interface.sol\";\n\n/// @title Hardcoded Deployment Addresses for Mainnet\nlibrary Deployments {\n    uint256 internal constant CHAIN_ID = Constants.CHAIN_ID_MAINNET;\n    NotionalProxy internal constant NOTIONAL = NotionalProxy(0x6e7058c91F85E0F6db4fc9da2CA41241f5e4263f);\n    address internal constant ETH_ADDRESS = address(0);\n    WETH9 internal constant WETH = WETH9(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);\n    IBalancerVault internal constant BALANCER_VAULT =\n        IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);\n\n    UniV3ISwapRouter internal constant UNIV3_ROUTER = UniV3ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);\n    address internal constant ZERO_EX = 0xDef1C0ded9bec7F1a1670819833240f027b25EfF;\n    IUniV2Router2 internal constant UNIV2_ROUTER = IUniV2Router2(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);\n\n    address internal constant ALT_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    ICurveRouterV2 public constant CURVE_ROUTER_V2 = ICurveRouterV2(0x99a58482BD75cbab83b27EC03CA68fF489b5788f);\n    ICurveMetaRegistry public constant CURVE_META_REGISTRY = ICurveMetaRegistry(0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC);\n    address internal constant CURVE_V1_HANDLER = 0x46a8a9CF4Fc8e99EC3A14558ACABC1D93A27de68;\n    address internal constant CURVE_V2_HANDLER = 0xC4F389020002396143B863F6325aA6ae481D19CE;\n\n    ITradingModule internal constant TRADING_MODULE = ITradingModule(0x594734c7e06C3D483466ADBCe401C6Bd269746C8);\n    address internal constant TREASURY_MANAGER = 0x53144559C0d4a3304e2DD9dAfBD685247429216d;\n    // Notional Inc\n    address internal constant EMERGENCY_EXIT_MANAGER = 0x02479BFC7Dce53A02e26fE7baea45a0852CB0909;\n    address internal constant BALANCER_SPOT_PRICE = 0xA153B3E85833F8a323E60Dcdc08F6286eae28728;\n    IWrappedfCashFactory internal constant WRAPPED_FCASH_FACTORY = IWrappedfCashFactory(address(0));\n\n    // Chainlink L2 Sequencer Uptime: https://docs.chain.link/data-feeds/l2-sequencer-feeds/\n    AggregatorV2V3Interface internal constant SEQUENCER_UPTIME_ORACLE = AggregatorV2V3Interface(address(0));\n}"
      },
      "contracts/vaults/balancer/BalancerSpotPrice.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {StableMath} from \"./math/StableMath.sol\";\nimport {IComposablePool, IWeightedPool} from \"@interfaces/balancer/IBalancerPool.sol\";\nimport {IBalancerVault} from \"@interfaces/balancer/IBalancerVault.sol\";\n\n/**\n * @notice External, singleton helper contract deployed to calculate spot prices for Balancer pools.\n * Currently supports Composable pools with any number of tokens and Weighted2Token pools.\n */\ncontract BalancerSpotPrice {\n    uint256 internal constant BALANCER_PRECISION = 1e18;\n    uint256 internal constant TOKEN_AMOUNT_IN = 1e18;\n\n    constructor() {\n        require(Deployments.CHAIN_ID == block.chainid);\n    }\n\n    /// @notice Returns the weighted pool spot price and balances. Only the spot price on the\n    /// secondary token is returned.\n    function getWeightedSpotPrices(\n        bytes32 poolId,\n        address poolAddress,\n        uint256 primaryIndex\n    ) external view returns (uint256[] memory balances, uint256[] memory spotPrices) {\n        (/* */, balances, /* */) = Deployments.BALANCER_VAULT.getPoolTokens(poolId);\n        // Only two token pools are supported\n        require(balances.length == 2);\n        spotPrices = new uint256[](2);\n\n        uint256[] memory weights = IWeightedPool(poolAddress).getNormalizedWeights();\n        uint256[] memory scalingFactors = IWeightedPool(poolAddress).getScalingFactors();\n\n        // Spot price calculation is specified at the link below. Do not account for swap fees\n        // because we're using this price to compare to the oracle price and adding swap fees\n        // would unnecessarily increase the price deviation.\n        // https://docs.balancer.fi/reference/math/weighted-math.html#typescript\n        // secondaryBalance * primaryWeight * primaryDecimals \n        // --------------------------------------------------- \n        //          primaryBalance * secondaryWeight\n        uint256 secondaryIndex = 1 - primaryIndex;\n\n        // There is a chance of a uint256 overflow if the balances[secondaryIndex] > 10**36\n        uint256 numerator = balances[secondaryIndex] * weights[primaryIndex] * scalingFactors[secondaryIndex];\n        uint256 denominator = balances[primaryIndex] * weights[secondaryIndex] * scalingFactors[primaryIndex];\n\n        // Due to the scaling factors above, this spot price is returned in Balancer POOL_PRECISION decimals\n        spotPrices[secondaryIndex] = numerator * BALANCER_PRECISION / denominator;\n    }\n\n    /// @notice Returns the composable pool spot price and balances. Pool token spot\n    /// prices are not returned, pool token balance is returned.\n    function getComposableSpotPrices(\n        bytes32 poolId,\n        address poolAddress,\n        uint256 primaryIndex,\n        uint256 bptIndex,\n        uint8[] calldata decimals\n    ) external view returns (uint256[] memory balances, uint256[] memory spotPrices) {\n        (/* */, balances, /* */) = Deployments.BALANCER_VAULT.getPoolTokens(poolId);\n        uint256[] memory scalingFactors = IComposablePool(poolAddress).getScalingFactors();\n        spotPrices = new uint256[](balances.length);\n\n        uint256 ampParam;\n        {\n            uint256 precision;\n            (ampParam, /* */, precision) = IComposablePool(poolAddress).getAmplificationParameter();\n            require(precision == StableMath._AMP_PRECISION);\n        }\n\n        (uint256[] memory scaledBalances, uint256 invariant) = _getScaledBalancesAndInvariant(\n            balances,\n            scalingFactors,\n            bptIndex,\n            ampParam\n        );\n\n        // Exclude the bptIndex for the primary token (tokenIndexIn)\n        uint256 tokenIndexIn = primaryIndex < bptIndex ? primaryIndex : primaryIndex - 1;\n        for (uint256 i; i < balances.length; i++) {\n            // The primary index spot price is left as zero and skip the bpt index\n            if (i == primaryIndex || i == bptIndex) continue;\n\n            // tokensOut have scaling factors applied\n            uint256 tokensOut = StableMath._calcOutGivenIn(\n                ampParam, scaledBalances,\n                tokenIndexIn,\n                // Change the token in and token out to exclude the bpt token when doing calcOutGivenIn\n                i < bptIndex ? i : i - 1,\n                TOKEN_AMOUNT_IN, invariant\n            );\n\n            // Remove scaling factors from spot price. Scaling factors play two different roles in\n            // composable stable pools. For wrapped tokens like wstETH, the scaling factors\n            // \"undo\" the rebasing on wstETH back to an ETH denomination. Scaling factors may also\n            // scale balances to 18 decimal precision for the stable math spot price calculation.\n            // The scalingFactors must be applied here to account for both potential use cases\n            // for scalingFactors. The resulting precision is:\n            //   spotPrice in BALANCER_PRECISION * 10 ^ (secondaryDecimals - primaryDecimals)\n            // The BalancerComposableAuraVault will convert this scaled spot price back to\n            // the BALANCER_PRECISION by applying another decimal scale factor.\n            spotPrices[i] = (tokensOut * BALANCER_PRECISION * scalingFactors[primaryIndex]) / \n                (TOKEN_AMOUNT_IN * scalingFactors[i]);\n        }\n\n        // Spot prices need to be scaled by secondaryDecimals - primaryDecimals, see the comment inside\n        // The final precision of the spot prices will be POOL_PRECISION().\n        uint8 primaryDecimals = decimals[primaryIndex];\n        for (uint256 i; i < spotPrices.length; i++) {\n            uint8 secondaryDecimals = decimals[i];\n            // If primaryDecimals == secondaryDecimals no scaling is necessary.\n            if (primaryDecimals < secondaryDecimals) {\n                spotPrices[i] = spotPrices[i] / 10 ** (secondaryDecimals - primaryDecimals);\n            } else if (secondaryDecimals < primaryDecimals) {\n                spotPrices[i] = spotPrices[i] * 10 ** (primaryDecimals - secondaryDecimals);\n            }\n        }\n    }\n\n    function _getScaledBalancesAndInvariant(\n        uint256[] memory balances,\n        uint256[] memory scalingFactors,\n        uint256 bptIndex,\n        uint256 ampParam\n    ) private pure returns (uint256[] memory scaledBalances, uint256 invariant) {\n        // Scale all balances before calculating the invariant, exclude the BPT from the scaled\n        // balances\n        scaledBalances = new uint256[](balances.length - 1);\n        uint256 j;\n        for (uint256 i; i < balances.length; i++) {\n            if (i == bptIndex) continue;\n            scaledBalances[j] = balances[i] * scalingFactors[i] / BALANCER_PRECISION;\n            j++;\n        }\n\n        invariant = StableMath._calculateInvariant(ampParam, scaledBalances);\n    }\n}"
      },
      "contracts/vaults/balancer/mixins/AuraStakingMixin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {IAuraBooster, IAuraBoosterLite} from \"@interfaces/aura/IAuraBooster.sol\";\nimport {IAuraRewardPool} from \"@interfaces/aura/IAuraRewardPool.sol\";\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {BalancerPoolMixin, DeploymentParams} from \"./BalancerPoolMixin.sol\";\nimport {TokenUtils} from \"@contracts/utils/TokenUtils.sol\";\n\n/// @notice Deployment parameters with Aura staking\nstruct AuraVaultDeploymentParams {\n    /// @notice Aura reward pool address\n    IAuraRewardPool rewardPool;\n    address whitelistedReward;\n    /// @notice Base deployment parameters\n    DeploymentParams baseParams;\n}\n\nabstract contract AuraStakingMixin is BalancerPoolMixin {\n    using TokenUtils for IERC20;\n\n    /// @notice Aura booster contract used for staking BPT\n    IAuraBooster internal immutable AURA_BOOSTER;\n    /// @notice Aura reward pool contract used for unstaking and claiming reward tokens\n    IAuraRewardPool internal immutable AURA_REWARD_POOL;\n    /// @notice Aura pool ID used for staking\n    uint256 internal immutable AURA_POOL_ID;\n    address immutable WHITELISTED_REWARD;\n\n    constructor(NotionalProxy notional_, AuraVaultDeploymentParams memory params)\n        BalancerPoolMixin(notional_, params.baseParams) {\n        AURA_REWARD_POOL = params.rewardPool;\n\n        AURA_BOOSTER = IAuraBooster(AURA_REWARD_POOL.operator());\n        AURA_POOL_ID = AURA_REWARD_POOL.pid();\n        // Allows one of the pool tokens to be whitelisted as a reward token to be re-entered\n        // back into the pool to increase LP shares.\n        WHITELISTED_REWARD = params.whitelistedReward;\n    }\n\n    function _isInvalidRewardToken(address token) internal override view returns (bool) {\n        // ETH is also at address(0) but that is never given out as a reward token\n        if (WHITELISTED_REWARD != address(0) && token == WHITELISTED_REWARD) return false;\n\n        return (\n            token == TOKEN_1 ||\n            token == TOKEN_2 ||\n            token == TOKEN_3 ||\n            token == TOKEN_4 ||\n            token == TOKEN_5 ||\n            token == address(BALANCER_POOL_TOKEN) ||\n            token == address(AURA_BOOSTER) ||\n            token == address(AURA_REWARD_POOL) ||\n            token == address(Deployments.WETH) ||\n            token == address(Deployments.ETH_ADDRESS)\n        );\n    }\n\n    /// @notice Called once on initialization to set token approvals\n    function _initialApproveTokens() internal override {\n        (IERC20[] memory tokens, /* */) = TOKENS();\n        for (uint256 i; i < tokens.length; i++) {\n            tokens[i].checkApprove(address(Deployments.BALANCER_VAULT), type(uint256).max);\n        }\n\n        // Approve Aura to transfer pool tokens for staking\n        POOL_TOKEN().checkApprove(address(AURA_BOOSTER), type(uint256).max);\n    }\n\n    /// @notice Claim reward tokens\n    function _claimRewardTokens() internal override {\n        // Claim all reward tokens including extra tokens\n        bool success = AURA_REWARD_POOL.getReward(address(this), true); // claimExtraRewards = true\n        require(success);\n    }\n}"
      },
      "contracts/utils/TokenUtils.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {IEIP20NonStandard} from \"@interfaces/IEIP20NonStandard.sol\";\nimport {Deployments} from \"@deployments/Deployments.sol\";\n\nlibrary TokenUtils {\n    error ERC20Error();\n\n    function getDecimals(address token) internal view returns (uint8 decimals) {\n        decimals = (token == Deployments.ETH_ADDRESS || token == Deployments.ALT_ETH_ADDRESS) ?\n            18 : IERC20(token).decimals();\n        require(decimals <= 18);\n    }\n\n    function tokenBalance(address token) internal view returns (uint256) {\n        return\n            token == Deployments.ETH_ADDRESS\n                ? address(this).balance\n                : IERC20(token).balanceOf(address(this));\n    }\n\n    function checkApprove(IERC20 token, address spender, uint256 amount) internal {\n        if (address(token) == address(0)) return;\n\n        IEIP20NonStandard(address(token)).approve(spender, 0);\n        _checkReturnCode();\n        if (amount > 0) {\n            IEIP20NonStandard(address(token)).approve(spender, amount);\n            _checkReturnCode();\n        }\n    }\n\n    function checkRevoke(IERC20 token, address spender) internal {\n        if (address(token) == address(0)) return;\n\n        IEIP20NonStandard(address(token)).approve(spender, 0);\n        _checkReturnCode();\n    }\n\n    function checkTransfer(IERC20 token, address receiver, uint256 amount) internal {\n        IEIP20NonStandard(address(token)).transfer(receiver, amount);\n        _checkReturnCode();\n    }\n\n    // Supports checking return codes on non-standard ERC20 contracts\n    function _checkReturnCode() private 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        if (!success) revert ERC20Error();\n    }\n}"
      },
      "interfaces/balancer/IBalancerPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\nimport {IERC20} from \"../IERC20.sol\";\n\ninterface IBalancerPool is IERC20 {\n    function getScalingFactors() external view returns (uint256[] memory);\n    function getPoolId() external view returns (bytes32); \n    function getSwapFeePercentage() external view returns (uint256);\n}\n\ninterface IWeightedPool is IBalancerPool {\n    function getNormalizedWeights() external view returns (uint256[] memory);\n    function getActualSupply() external view returns (uint256);\n}\n\ninterface IComposablePool is IBalancerPool {\n    function getAmplificationParameter() external view returns (\n        uint256 value,\n        bool isUpdating,\n        uint256 precision\n    );\n    function getActualSupply() external view returns (uint256);\n}"
      },
      "interfaces/balancer/IBalancerVault.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface IAsset {\n    // solhint-disable-previous-line no-empty-blocks\n}\n\ninterface IBalancerVault {\n    enum PoolSpecialization {\n        GENERAL,\n        MINIMAL_SWAP_INFO,\n        TWO_TOKEN\n    }\n    enum JoinKind {\n        INIT,\n        EXACT_TOKENS_IN_FOR_BPT_OUT,\n        TOKEN_IN_FOR_EXACT_BPT_OUT,\n        ALL_TOKENS_IN_FOR_EXACT_BPT_OUT\n    }\n    enum MetaStableExitKind {\n        EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,\n        EXACT_BPT_IN_FOR_TOKENS_OUT,\n        BPT_IN_FOR_EXACT_TOKENS_OUT,\n        MANAGEMENT_FEE_TOKENS_OUT // for ManagedPool\n    }\n    enum ComposableExitKind {\n        EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,\n        BPT_IN_FOR_EXACT_TOKENS_OUT,\n        EXACT_BPT_IN_FOR_ALL_TOKENS_OUT\n    }\n    enum WeightedPoolExitKind {\n        EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,\n        EXACT_BPT_IN_FOR_TOKENS_OUT,\n        BPT_IN_FOR_EXACT_TOKENS_OUT,\n        MANAGEMENT_FEE_TOKENS_OUT // for InvestmentPool\n    }\n\n\n    enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL }\n\n    /**\n     * @dev Returns a Pool's contract address and specialization setting.\n     */\n    function getPool(bytes32 poolId)\n        external\n        view\n        returns (address, PoolSpecialization);\n\n    function joinPool(\n        bytes32 poolId,\n        address sender,\n        address recipient,\n        JoinPoolRequest memory request\n    ) external payable;\n\n    struct JoinPoolRequest {\n        IAsset[] assets;\n        uint256[] maxAmountsIn;\n        bytes userData;\n        bool fromInternalBalance;\n    }\n\n    function exitPool(\n        bytes32 poolId,\n        address sender,\n        address payable recipient,\n        ExitPoolRequest memory request\n    ) external;\n\n    struct ExitPoolRequest {\n        IAsset[] assets;\n        uint256[] minAmountsOut;\n        bytes userData;\n        bool toInternalBalance;\n    }\n\n    enum SwapKind {\n        GIVEN_IN,\n        GIVEN_OUT\n    }\n\n    struct SingleSwap {\n        bytes32 poolId;\n        SwapKind kind;\n        IAsset assetIn;\n        IAsset assetOut;\n        uint256 amount;\n        bytes userData;\n    }\n\n    struct FundManagement {\n        address sender;\n        bool fromInternalBalance;\n        address payable recipient;\n        bool toInternalBalance;\n    }\n\n    function swap(\n        SingleSwap memory singleSwap,\n        FundManagement memory funds,\n        uint256 limit,\n        uint256 deadline\n    ) external payable returns (uint256);\n\n    struct BatchSwapStep {\n        bytes32 poolId;\n        uint256 assetInIndex;\n        uint256 assetOutIndex;\n        uint256 amount;\n        bytes userData;\n    }\n\n    function batchSwap(\n        SwapKind kind,\n        BatchSwapStep[] memory swaps,\n        IAsset[] memory assets,\n        FundManagement memory funds,\n        int256[] memory limits,\n        uint256 deadline\n    ) external payable returns (int256[] memory);\n\n    function getPoolTokens(bytes32 poolId)\n        external\n        view\n        returns (\n            address[] memory tokens,\n            uint256[] memory balances,\n            uint256 lastChangeBlock\n        );\n\n    function flashLoan(\n        address recipient, \n        address[] calldata tokens, \n        uint256[] calldata amounts, \n        bytes calldata userData\n    ) external;\n\n    struct UserBalanceOp {\n        UserBalanceOpKind kind;\n        IAsset asset;\n        uint256 amount;\n        address sender;\n        address payable recipient;\n    }\n\n    function manageUserBalance(UserBalanceOp[] memory ops) external payable;\n}\n"
      },
      "contracts/global/Types.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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    // Total fees per trade, specified in BPS\n    uint8 totalFeeBPS;\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 debtBuffer5BPS;\n    // fCash haircut specified in 5 BPS increments\n    uint8 fCashHaircut5BPS;\n    // If an account has a negative cash balance, it can be settled by incurring debt at the 3 month market. This\n    // is the basis points for the penalty rate that will be added the current 3 month oracle rate.\n    uint8 settlementPenaltyRate5BPS;\n    // If an account has fCash that is being liquidated, this is the discount that the liquidator can purchase it for\n    uint8 liquidationfCashHaircut5BPS;\n    // If an account has fCash that is being liquidated, this is the discount that the liquidator can purchase it for\n    uint8 liquidationDebtBuffer5BPS;\n    // Liquidity token haircut applied to cash claims, specified as a percentage between 0 and 100\n    uint8[] liquidityTokenHaircuts;\n    // Rate scalar used to determine the slippage of the market\n    uint8[] rateScalars;\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    bytes5 nTokenParameters;\n    // Reserved bytes for future usage\n    bytes15 _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 25 bps increments\n    uint8 maxRate25BPS;\n    // Minimum fee charged in basis points\n    uint8 minFeeRateBPS;\n    // Maximum fee charged in basis points\n    uint8 maxFeeRateBPS;\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    // 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    uint256 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    uint256[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}\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}\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\n    int256[3] debtOutstanding;\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    uint128 _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 underlying scalar to calculate the oracle money market rate\n    uint80 previousUnderlyingScalarAtRebalance;\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    // The annualized underlying money market interest rate calculated based on the underlying scalar\n    uint32 oracleMoneyMarketRate;\n    // 64 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"
      },
      "interfaces/notional/nTokenERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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/notional/nERC1155Interface.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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/NotionalGovernance.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\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\";\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 UpdateIncentiveEmissionRate(uint16 currencyId, uint32 newEmissionRate);\n    event UpdateTokenCollateralParameters(uint16 currencyId);\n    event UpdateGlobalTransferOperator(address operator, bool approved);\n    event UpdateAuthorizedCallbackContract(address operator, bool approved);\n    event UpdateMaxCollateralBalance(uint16 currencyId, uint72 maxCollateralBalance);\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n    event PauseRouterAndGuardianUpdated(address indexed pauseRouter, address indexed pauseGuardian);\n    event UpdateSecondaryIncentiveRewarder(uint16 indexed currencyId, address rewarder);\n    event UpdateLendingPool(address pool);\n\n    function transferOwnership(address newOwner, bool direct) external;\n\n    function claimOwnership() external;\n\n    function upgradeNTokenBeacon(address newImplementation) external;\n\n    function setPauseRouterAndGuardian(address pauseRouter_, address pauseGuardian_) external;\n\n    function listCurrency(\n        TokenStorage calldata assetToken,\n        TokenStorage calldata underlyingToken,\n        AggregatorV2V3Interface rateOracle,\n        bool mustInvert,\n        uint8 buffer,\n        uint8 haircut,\n        uint8 liquidationDiscount\n    ) external returns (uint16 currencyId);\n\n    function updateMaxCollateralBalance(\n        uint16 currencyId,\n        uint72 maxCollateralBalanceInternalPrecision\n    ) external;\n\n    function enableCashGroup(\n        uint16 currencyId,\n        AssetRateAdapter assetRateOracle,\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    function updateIncentiveEmissionRate(uint16 currencyId, uint32 newEmissionRate) external;\n\n    function updateTokenCollateralParameters(\n        uint16 currencyId,\n        uint8 residualPurchaseIncentive10BPS,\n        uint8 pvHaircutPercentage,\n        uint8 residualPurchaseTimeBufferHours,\n        uint8 cashWithholdingBuffer10BPS,\n        uint8 liquidationHaircutPercentage\n    ) external;\n\n    function updateCashGroup(uint16 currencyId, CashGroupSettings calldata cashGroup) external;\n\n    function updateAssetRate(uint16 currencyId, AssetRateAdapter rateOracle) 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 updateGlobalTransferOperator(address operator, bool approved) external;\n\n    function updateAuthorizedCallbackContract(address operator, bool approved) external;\n\n    function setLendingPool(ILendingPool pool) external;\n\n    function setSecondaryIncentiveRewarder(uint16 currencyId, IRewarder rewarder) external;\n}\n"
      },
      "interfaces/notional/NotionalCalculations.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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/NotionalViews.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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    );\n\n    function getPrimeFactorsStored(uint16 currencyId) external view returns (PrimeCashFactors memory);\n\n    function getPrimeCashHoldingsOracle(uint16 currencyId) external view returns (address);\n\n    function getTotalfCashDebtOutstanding(uint16 currencyId, uint256 maturity) external view returns (int256);\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            bytes5 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 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 getRebalancingTarget(uint16 currencyId, address holding) external view returns (uint8);\n\n    function getRebalancingCooldown(uint16 currencyId) external view returns (uint40);\n\n    function getStoredTokenBalances(address[] calldata tokens) external view returns (uint256[] memory balances);\n}\n"
      },
      "interfaces/notional/NotionalTreasury.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface NotionalTreasury {\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    function claimCOMPAndTransfer(address[] calldata ctokens) external returns (uint256);\n\n    function transferReserveToTreasury(uint16[] calldata currencies)\n        external\n        returns (uint256[] memory);\n\n    function setTreasuryManager(address manager) external;\n\n    function setReserveBuffer(uint16 currencyId, uint256 amount) external;\n\n    function setReserveCashBalance(uint16 currencyId, int256 reserveBalance) external;\n}\n"
      },
      "interfaces/notional/IVaultController.sol": {
        "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport {\n    VaultConfigParams,\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) 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 {}"
      },
      "contracts/global/Constants.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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    address internal constant ETH_ADDRESS = address(0);\n    uint256 internal constant ETH_CURRENCY_ID = 1;\n    uint8 internal constant ETH_DECIMAL_PLACES = 18;\n    int256 internal constant ETH_DECIMALS = 1e18;\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 reserve account\n    address internal constant RESERVE = address(0);\n\n    // Most significant bit\n    bytes32 internal constant MSB = 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    // 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    // This is a constant that represents the time period that all rates are normalized by, 360 days\n    uint256 internal constant IMPLIED_RATE_TIME = 360 * DAY;\n    // Number of decimal places that rates are stored in, equals 100%\n    int256 internal constant RATE_PRECISION = 1e9;\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\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    int128 internal constant LOG_RATE_PRECISION_64x64 = 382276781265598821176;\n    // Limit the market proportion so that borrowing cannot hit extremely high interest rates\n    int256 internal constant MAX_MARKET_PROPORTION = RATE_PRECISION * 99 / 100;\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\n    // Used for converting bool to bytes1, solidity does not have a native conversion\n    // method for this\n    bytes1 internal constant BOOL_FALSE = 0x00;\n    bytes1 internal constant BOOL_TRUE = 0x01;\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    uint256 internal constant SLIPPAGE_LIMIT_PRECISION = 1e8;\n\n    /// @notice Precision for all percentages used by the vault\n    /// 1e4 = 100% (i.e. maxPoolShare)\n    uint16 internal constant VAULT_PERCENT_BASIS = 1e4;\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    uint256 internal constant CHAIN_ID_MAINNET = 1;\n    uint256 internal constant CHAIN_ID_ARBITRUM = 42161;\n}\n"
      },
      "interfaces/IWstETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\nimport {IERC20} from \"./IERC20.sol\";\n\ninterface IWstETH is IERC20 {\n    function unwrap(uint256 _wstETHAmount) external returns (uint256);\n    function wrap(uint256 _stETHAmount) external returns (uint256);\n    function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);\n    function stEthPerToken() external view returns (uint256);\n    function stETH() external view returns (address);\n}"
      },
      "interfaces/WETH9.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface WETH9 {\n    function deposit() external payable;\n\n    function withdraw(uint256 wad) external;\n}\n"
      },
      "interfaces/uniswap/v3/ISwapRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\npragma abicoder v2;\n\nimport './IUniswapV3SwapCallback.sol';\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter is IUniswapV3SwapCallback {\n    struct ExactInputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 deadline;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another token\n    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);\n\n    struct ExactInputParams {\n        bytes path;\n        address recipient;\n        uint256 deadline;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n\n    struct ExactOutputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 deadline;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another token\n    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);\n\n    struct ExactOutputParams {\n        bytes path;\n        address recipient;\n        uint256 deadline;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);\n}\n"
      },
      "interfaces/uniswap/v2/IUniV2Router2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\npragma abicoder v2;\n\ninterface IUniV2Router2 {\n    function swapETHForExactTokens(\n        uint256 amountOut,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256[] memory amounts);\n\n    function swapExactETHForTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256[] memory amounts);\n\n    function swapTokensForExactETH(\n        uint256 amountOut,\n        uint256 amountInMax,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n\n    function swapExactTokensForETH(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n\n    function swapTokensForExactTokens(\n        uint256 amountOut,\n        uint256 amountInMax,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n}\n"
      },
      "interfaces/curve/ICurveRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface ICurveRouter {\n    function exchange(\n        uint256 _amount,\n        address[6] calldata _route,\n        uint256[8] calldata _indices,\n        uint256 _min_received\n    ) external payable;\n\n    function get_exchange_routing(\n        address _initial,\n        address _target,\n        uint256 _amount\n    ) external view returns (\n        address[6] memory route,\n        uint256[8] memory indexes,\n        uint256 expectedOutputAmount\n    );\n\n    function can_route(address _initial, address _target) external view returns (bool);\n}\n"
      },
      "interfaces/curve/ICurveRegistry.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface ICurveRegistry {\n    function find_pool_for_coins(address _from, address _to, uint256 i)\n        external\n        view\n        returns (address);\n}\n"
      },
      "interfaces/curve/ICurveMetaRegistry.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface ICurveMetaRegistry {\n    function get_registry_handlers_from_pool(address _pool)\n        external\n        view\n        returns (address[10] memory);\n}\n"
      },
      "interfaces/curve/ICurveRouterV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface ICurveRouterV2 {\n    function exchange(\n        address _pool,\n        address _from,\n        address _to,\n        uint256 _amount,\n        uint256 _expected,\n        address _receiver\n    ) external returns (uint256);\n\n    function exchange_multiple(\n        address[9] calldata _route,\n        uint256[3][4] calldata _swap_params,\n        uint256 _amount,\n        uint256 _expected,\n        address[4] calldata _pools,\n        address _receiver\n    ) external returns (uint256);\n}\n"
      },
      "interfaces/trading/ITradingModule.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\nimport \"../chainlink/AggregatorV2V3Interface.sol\";\n\nenum DexId {\n    _UNUSED,        // flag = 1\n    UNISWAP_V2,     // flag = 2\n    UNISWAP_V3,     // flag = 4\n    ZERO_EX,        // flag = 8\n    BALANCER_V2,    // flag = 16\n    // NOTE: this id is unused in the TradingModule\n    CURVE,          // flag = 32 \n    NOTIONAL_VAULT, // flag = 64\n    CURVE_V2        // flag = 128\n}\n\nenum TradeType {\n    EXACT_IN_SINGLE,  // flag = 1\n    EXACT_OUT_SINGLE, // flag = 2\n    EXACT_IN_BATCH,   // flag = 4\n    EXACT_OUT_BATCH   // flag = 8\n}\n\nstruct Trade {\n    TradeType tradeType;\n    address sellToken;\n    address buyToken;\n    uint256 amount;\n    /// minBuyAmount or maxSellAmount\n    uint256 limit;\n    uint256 deadline;\n    bytes exchangeData;\n}\n\nerror InvalidTrade();\nerror DynamicTradeFailed();\nerror TradeFailed();\n\ninterface ITradingModule {\n    struct TokenPermissions {\n        bool allowSell;\n        /// @notice allowed DEXes\n        uint32 dexFlags;\n        /// @notice allowed trade types\n        uint32 tradeTypeFlags; \n    }\n\n    event TradeExecuted(\n        address indexed sellToken,\n        address indexed buyToken,\n        uint256 sellAmount,\n        uint256 buyAmount\n    );\n\n    event PriceOracleUpdated(address token, address oracle);\n    event MaxOracleFreshnessUpdated(uint32 currentValue, uint32 newValue);\n    event TokenPermissionsUpdated(address sender, address token, TokenPermissions permissions);\n\n    function priceOracles(address token) external view returns (AggregatorV2V3Interface oracle, uint8 rateDecimals);\n\n    function getExecutionData(uint16 dexId, address from, Trade calldata trade)\n        external view returns (\n            address spender,\n            address target,\n            uint256 value,\n            bytes memory params\n        );\n\n    function setPriceOracle(address token, AggregatorV2V3Interface oracle) external;\n\n    function setTokenPermissions(\n        address sender, \n        address token, \n        TokenPermissions calldata permissions\n    ) external;\n\n    function getOraclePrice(address inToken, address outToken)\n        external view returns (int256 answer, int256 decimals);\n\n    function executeTrade(\n        uint16 dexId,\n        Trade calldata trade\n    ) external payable returns (uint256 amountSold, uint256 amountBought);\n\n    function executeTradeWithDynamicSlippage(\n        uint16 dexId,\n        Trade memory trade,\n        uint32 dynamicSlippageLimit\n    ) external payable returns (uint256 amountSold, uint256 amountBought);\n\n    function getLimitAmount(\n        address from,\n        TradeType tradeType,\n        address sellToken,\n        address buyToken,\n        uint256 amount,\n        uint32 slippageLimit\n    ) external view returns (uint256 limitAmount);\n\n    function canExecuteTrade(address from, uint16 dexId, Trade calldata trade) external view returns (bool);\n}\n"
      },
      "interfaces/notional/IWrappedfCashFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\n\ninterface IWrappedfCashFactory {\n    function deployWrapper(uint16 currencyId, uint40 maturity) external returns (address);\n    function computeAddress(uint16 currencyId, uint40 maturity) external view returns (address);\n}\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}"
      },
      "contracts/vaults/balancer/math/StableMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {Math} from \"./Math.sol\";\nimport {FixedPoint} from \"./FixedPoint.sol\";\n\nlibrary StableMath {\n    using FixedPoint for uint256;\n    \n    uint256 internal constant _AMP_PRECISION = 1e3;\n\n    error CalculationDidNotConverge();\n\n    // Note on unchecked arithmetic:\n    // This contract performs a large number of additions, subtractions, multiplications and divisions, often inside\n    // loops. Since many of these operations are gas-sensitive (as they happen e.g. during a swap), it is important to\n    // not make any unnecessary checks. We rely on a set of invariants to avoid having to use checked arithmetic (the\n    // Math library), including:\n    //  - the number of tokens is bounded by _MAX_STABLE_TOKENS\n    //  - the amplification parameter is bounded by _MAX_AMP * _AMP_PRECISION, which fits in 23 bits\n    //  - the token balances are bounded by 2^112 (guaranteed by the Vault) times 1e18 (the maximum scaling factor),\n    //    which fits in 172 bits\n    //\n    // This means e.g. we can safely multiply a balance by the amplification parameter without worrying about overflow.\n\n    // About swap fees on joins and exits:\n    // Any join or exit that is not perfectly balanced (e.g. all single token joins or exits) is mathematically\n    // equivalent to a perfectly balanced join or  exit followed by a series of swaps. Since these swaps would charge\n    // swap fees, it follows that (some) joins and exits should as well.\n    // On these operations, we split the token amounts in 'taxable' and 'non-taxable' portions, where the 'taxable' part\n    // is the one to which swap fees are applied.\n\n    // Computes the invariant given the current balances, using the Newton-Raphson approximation.\n    // The amplification parameter equals: A n^(n-1)\n    // See: https://github.com/curvefi/curve-contract/blob/b0bbf77f8f93c9c5f4e415bce9cd71f0cdee960e/contracts/pool-templates/base/SwapTemplateBase.vy#L206\n    // solhint-disable-previous-line max-line-length\n    function _calculateInvariant(\n        uint256 amplificationParameter,\n        uint256[] memory balances\n    ) internal pure returns (uint256) {\n        /**********************************************************************************************\n        // invariant                                                                                 //\n        // D = invariant                                                  D^(n+1)                    //\n        // A = amplification coefficient      A  n^n S + D = A D n^n + -----------                   //\n        // S = sum of balances                                             n^n P                     //\n        // P = product of balances                                                                   //\n        // n = number of tokens                                                                      //\n        **********************************************************************************************/\n\n        // Always round down, to match Vyper's arithmetic (which always truncates).\n        unchecked {\n            uint256 sum = 0; // S in the Curve version\n            uint256 numTokens = balances.length;\n            for (uint256 i = 0; i < numTokens; i++) {\n                sum = sum.add(balances[i]);\n            }\n            if (sum == 0) {\n                return 0;\n            }\n\n            uint256 prevInvariant; // Dprev in the Curve version\n            uint256 invariant = sum; // D in the Curve version\n            uint256 ampTimesTotal = amplificationParameter * numTokens; // Ann in the Curve version\n\n            for (uint256 i = 0; i < 255; i++) {\n                uint256 D_P = invariant;\n\n                for (uint256 j = 0; j < numTokens; j++) {\n                    // (D_P * invariant) / (balances[j] * numTokens)\n                    D_P = Math.divDown(Math.mul(D_P, invariant), Math.mul(balances[j], numTokens));\n                }\n\n                prevInvariant = invariant;\n\n                invariant = Math.divDown(\n                    Math.mul(\n                        // (ampTimesTotal * sum) / AMP_PRECISION + D_P * numTokens\n                        (Math.divDown(Math.mul(ampTimesTotal, sum), _AMP_PRECISION).add(Math.mul(D_P, numTokens))),\n                        invariant\n                    ),\n                    // ((ampTimesTotal - _AMP_PRECISION) * invariant) / _AMP_PRECISION + (numTokens + 1) * D_P\n                    (\n                        Math.divDown(Math.mul((ampTimesTotal - _AMP_PRECISION), invariant), _AMP_PRECISION).add(\n                            Math.mul((numTokens + 1), D_P)\n                        )\n                    )\n                );\n\n                if (invariant > prevInvariant) {\n                    if (invariant - prevInvariant <= 1) {\n                        return invariant;\n                    }\n                } else if (prevInvariant - invariant <= 1) {\n                    return invariant;\n                }\n            }\n        }\n\n        revert CalculationDidNotConverge();\n    }\n\n    // This function calculates the balance of a given token (tokenIndex)\n    // given all the other balances and the invariant\n    function _getTokenBalanceGivenInvariantAndAllOtherBalances(\n        uint256 amplificationParameter,\n        uint256[] memory balances,\n        uint256 invariant,\n        uint256 tokenIndex\n    ) internal pure returns (uint256) {\n        // Rounds result up overall\n        unchecked {\n            uint256 ampTimesTotal = amplificationParameter * balances.length;\n            uint256 sum = balances[0];\n            uint256 P_D = balances[0] * balances.length;\n            for (uint256 j = 1; j < balances.length; j++) {\n                P_D = Math.divDown(Math.mul(Math.mul(P_D, balances[j]), balances.length), invariant);\n                sum = sum.add(balances[j]);\n            }\n            // No need to use safe math, based on the loop above `sum` is greater than or equal to `balances[tokenIndex]`\n            sum = sum - balances[tokenIndex];\n\n            uint256 inv2 = Math.mul(invariant, invariant);\n            // We remove the balance from c by multiplying it\n            uint256 c = Math.mul(\n                Math.mul(Math.divUp(inv2, Math.mul(ampTimesTotal, P_D)), _AMP_PRECISION),\n                balances[tokenIndex]\n            );\n            uint256 b = sum.add(Math.mul(Math.divDown(invariant, ampTimesTotal), _AMP_PRECISION));\n\n            // We iterate to find the balance\n            uint256 prevTokenBalance = 0;\n            // We multiply the first iteration outside the loop with the invariant to set the value of the\n            // initial approximation.\n            uint256 tokenBalance = Math.divUp(inv2.add(c), invariant.add(b));\n\n            for (uint256 i = 0; i < 255; i++) {\n                prevTokenBalance = tokenBalance;\n\n                tokenBalance = Math.divUp(\n                    Math.mul(tokenBalance, tokenBalance).add(c),\n                    Math.mul(tokenBalance, 2).add(b).sub(invariant)\n                );\n\n                if (tokenBalance > prevTokenBalance) {\n                    if (tokenBalance - prevTokenBalance <= 1) {\n                        return tokenBalance;\n                    }\n                } else if (prevTokenBalance - tokenBalance <= 1) {\n                    return tokenBalance;\n                }\n            }\n        }\n\n        revert CalculationDidNotConverge();\n    }\n\n    // Computes how many tokens can be taken out of a pool if `tokenAmountIn` are sent, given the current balances.\n    // The amplification parameter equals: A n^(n-1)\n    function _calcOutGivenIn(\n        uint256 amplificationParameter,\n        uint256[] memory balances,\n        uint256 tokenIndexIn,\n        uint256 tokenIndexOut,\n        uint256 tokenAmountIn,\n        uint256 invariant\n    ) internal pure returns (uint256) {\n        /**************************************************************************************************************\n        // outGivenIn token x for y - polynomial equation to solve                                                   //\n        // ay = amount out to calculate                                                                              //\n        // by = balance token out                                                                                    //\n        // y = by - ay (finalBalanceOut)                                                                             //\n        // D = invariant                                               D                     D^(n+1)                 //\n        // A = amplification coefficient               y^2 + ( S + ----------  - D) * y -  ------------- = 0         //\n        // n = number of tokens                                    (A * n^n)               A * n^2n * P              //\n        // S = sum of final balances but y                                                                           //\n        // P = product of final balances but y                                                                       //\n        **************************************************************************************************************/\n\n        // Amount out, so we round down overall.\n        unchecked {\n            balances[tokenIndexIn] = balances[tokenIndexIn].add(tokenAmountIn);\n\n            uint256 finalBalanceOut = _getTokenBalanceGivenInvariantAndAllOtherBalances(\n                amplificationParameter,\n                balances,\n                invariant,\n                tokenIndexOut\n            );\n\n            // No need to use checked arithmetic since `tokenAmountIn` was actually added to the same balance right before\n            // calling `_getTokenBalanceGivenInvariantAndAllOtherBalances` which doesn't alter the balances array.\n            balances[tokenIndexIn] = balances[tokenIndexIn] - tokenAmountIn;\n\n            return balances[tokenIndexOut].sub(finalBalanceOut).sub(1);\n        }\n    }\n}\n\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    function decimals() external view returns (uint8);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\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/aura/IAuraBooster.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface IAuraBoosterBase {\n    function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns(bool);\n}\n\ninterface IAuraBooster is IAuraBoosterBase {\n    function stakerRewards() external view returns(address);\n}\n\ninterface IAuraBoosterLite is IAuraBoosterBase {\n    function crv() external view returns(address);\n    function rewards() external view returns(address);\n}\n"
      },
      "interfaces/aura/IAuraRewardPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\nimport {IRewardPool} from \"../common/IRewardPool.sol\";\nimport {IERC4626} from \"../IERC4626.sol\";\n\ninterface IAuraRewardPool is IRewardPool, IERC4626 { }\n\ninterface IAuraL2Coordinator {\n    function auraOFT() external view returns (address);\n}"
      },
      "contracts/vaults/balancer/mixins/BalancerPoolMixin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {IBalancerVault, IAsset} from \"@interfaces/balancer/IBalancerVault.sol\";\nimport {IBalancerPool} from \"@interfaces/balancer/IBalancerPool.sol\";\nimport {SingleSidedLPVaultBase} from \"../../common/SingleSidedLPVaultBase.sol\";\nimport {TokenUtils} from \"@contracts/utils/TokenUtils.sol\";\nimport {ITradingModule} from \"@interfaces/trading/ITradingModule.sol\";\n\n/// @notice Deployment parameters\nstruct DeploymentParams {\n    /// @notice primary currency id\n    uint16 primaryBorrowCurrencyId;\n    /// @notice balancer pool ID\n    bytes32 balancerPoolId;\n    /// @notice trading module proxy\n    ITradingModule tradingModule;\n}\n\n/** Base class for all Balancer LP strategies */\nabstract contract BalancerPoolMixin is SingleSidedLPVaultBase {\n\n    uint256 internal constant BALANCER_PRECISION = 1e18;\n\n    bytes32 internal immutable BALANCER_POOL_ID;\n    IERC20 internal immutable BALANCER_POOL_TOKEN;\n\n    uint256 internal immutable _NUM_TOKENS;\n    uint256 internal immutable _PRIMARY_INDEX;\n    uint256 internal immutable BPT_INDEX;\n\n    /// @notice this implementation currently supports up to 5 tokens\n    address internal immutable TOKEN_1;\n    address internal immutable TOKEN_2;\n    address internal immutable TOKEN_3;\n    address internal immutable TOKEN_4;\n    address internal immutable TOKEN_5;\n\n    uint8 internal immutable DECIMALS_1;\n    uint8 internal immutable DECIMALS_2;\n    uint8 internal immutable DECIMALS_3;\n    uint8 internal immutable DECIMALS_4;\n    uint8 internal immutable DECIMALS_5;\n\n    function NUM_TOKENS() internal view override returns (uint256) { return _NUM_TOKENS; }\n    function PRIMARY_INDEX() internal view override returns (uint256) { return _PRIMARY_INDEX; }\n    function POOL_TOKEN() internal view override returns (IERC20) { return BALANCER_POOL_TOKEN; }\n    function POOL_PRECISION() internal pure override returns (uint256) { return BALANCER_PRECISION; }\n    function TOKENS() public view virtual override returns (IERC20[] memory, uint8[] memory) {\n        IERC20[] memory tokens = new IERC20[](_NUM_TOKENS);\n        uint8[] memory decimals = new uint8[](_NUM_TOKENS);\n\n        if (_NUM_TOKENS > 0) (tokens[0], decimals[0]) = (IERC20(TOKEN_1), DECIMALS_1);\n        if (_NUM_TOKENS > 1) (tokens[1], decimals[1]) = (IERC20(TOKEN_2), DECIMALS_2);\n        if (_NUM_TOKENS > 2) (tokens[2], decimals[2]) = (IERC20(TOKEN_3), DECIMALS_3);\n        if (_NUM_TOKENS > 3) (tokens[3], decimals[3]) = (IERC20(TOKEN_4), DECIMALS_4);\n        if (_NUM_TOKENS > 4) (tokens[4], decimals[4]) = (IERC20(TOKEN_5), DECIMALS_5);\n\n        return (tokens, decimals);\n    }\n\n    /// @notice Used to get type compatibility with the Balancer join and exit methods.\n    function ASSETS() internal virtual view returns (IAsset[] memory) {\n        IAsset[] memory assets = new IAsset[](_NUM_TOKENS);\n        if (_NUM_TOKENS > 0) assets[0] = IAsset(TOKEN_1);\n        if (_NUM_TOKENS > 1) assets[1] = IAsset(TOKEN_2);\n        if (_NUM_TOKENS > 2) assets[2] = IAsset(TOKEN_3);\n        if (_NUM_TOKENS > 3) assets[3] = IAsset(TOKEN_4);\n        if (_NUM_TOKENS > 4) assets[4] = IAsset(TOKEN_5);\n        return assets;\n    }\n\n    constructor(NotionalProxy notional_, DeploymentParams memory params)\n        SingleSidedLPVaultBase(notional_, params.tradingModule) {\n\n        BALANCER_POOL_ID = params.balancerPoolId;\n        (address pool, /* */) = Deployments.BALANCER_VAULT.getPool(params.balancerPoolId);\n        BALANCER_POOL_TOKEN = IERC20(pool);\n\n        // Fetch all the token addresses in the pool\n        (\n            address[] memory tokens,\n            /* uint256[] memory balances */,\n            /* uint256 lastChangeBlock */\n        ) = Deployments.BALANCER_VAULT.getPoolTokens(params.balancerPoolId);\n\n        require(tokens.length <= MAX_TOKENS);\n        _NUM_TOKENS = uint8(tokens.length);\n\n        TOKEN_1 = _NUM_TOKENS > 0 ? _rewriteWETH(tokens[0]) : address(0);\n        TOKEN_2 = _NUM_TOKENS > 1 ? _rewriteWETH(tokens[1]) : address(0);\n        TOKEN_3 = _NUM_TOKENS > 2 ? _rewriteWETH(tokens[2]) : address(0);\n        TOKEN_4 = _NUM_TOKENS > 3 ? _rewriteWETH(tokens[3]) : address(0);\n        TOKEN_5 = _NUM_TOKENS > 4 ? _rewriteWETH(tokens[4]) : address(0);\n\n        DECIMALS_1 = _NUM_TOKENS > 0 ? TokenUtils.getDecimals(TOKEN_1) : 0;\n        DECIMALS_2 = _NUM_TOKENS > 1 ? TokenUtils.getDecimals(TOKEN_2) : 0;\n        DECIMALS_3 = _NUM_TOKENS > 2 ? TokenUtils.getDecimals(TOKEN_3) : 0;\n        DECIMALS_4 = _NUM_TOKENS > 3 ? TokenUtils.getDecimals(TOKEN_4) : 0;\n        DECIMALS_5 = _NUM_TOKENS > 4 ? TokenUtils.getDecimals(TOKEN_5) : 0;\n\n        // Returns the primary borrowed currency address\n        address primaryAddress = _getNotionalUnderlyingToken(params.primaryBorrowCurrencyId);\n        if (primaryAddress == Deployments.ETH_ADDRESS) {\n            // Balancer uses WETH when calling `getPoolTokens` so rewrite it here to\n            // when we match on the primary index later.\n            primaryAddress = address(Deployments.WETH);\n        }\n\n        uint8 primaryIndex = NOT_FOUND;\n        uint8 bptIndex = NOT_FOUND;\n        for (uint8 i; i < tokens.length; i++) {\n            if (tokens[i] == primaryAddress) primaryIndex = i; \n            else if (tokens[i] == address(BALANCER_POOL_TOKEN)) bptIndex = i;\n        }\n\n        // Primary Index must exist for all balancer pools, but BPT_INDEX\n        // will only exist for ComposableStablePools\n        require(primaryIndex != NOT_FOUND);\n\n        _PRIMARY_INDEX = primaryIndex;\n        BPT_INDEX = bptIndex;\n    }\n\n    function _rewriteWETH(address token) private pure returns (address) {\n        return token == address(Deployments.WETH) ? Deployments.ETH_ADDRESS : address(token);\n    }\n\n    // Checks if a token in the pool is a BPT. Used in cases where a BPT is one of the\n    // tokens within the pool (not the self BPT in the case of the Composable Stable Pool).\n    function _isBPT(address token) internal view returns (bool) {\n        // Need to check for zero address since this breaks the try / catch\n        if (token == address(0)) return false;\n\n        try IBalancerPool(token).getPoolId() returns (bytes32 /* poolId */) {\n            return true;\n        } catch {\n            return false;\n        }\n    }\n\n    /// @notice the re-entrancy context is checked during liquidation to prevent read-only\n    /// reentrancy on all balancer pools.\n    function _checkReentrancyContext() internal override {\n        IBalancerVault.UserBalanceOp[] memory noop = new IBalancerVault.UserBalanceOp[](0);\n        Deployments.BALANCER_VAULT.manageUserBalance(noop);\n    }\n\n    /// @notice Joins a balancer pool using the supplied amounts of tokens\n    function _joinPoolExactTokensIn(\n        uint256[] memory amounts,\n        bytes memory customData\n    ) internal returns (uint256 bptAmount) {\n        uint256 msgValue;\n        IAsset[] memory assets = ASSETS();\n        require(assets.length == amounts.length);\n        for (uint256 i; i < assets.length; i++) {\n            // Sets the msgValue of transferring ETH\n            if (address(assets[i]) == Deployments.ETH_ADDRESS) {\n                msgValue = amounts[i];\n                break;\n            }\n        }\n\n        bptAmount = BALANCER_POOL_TOKEN.balanceOf(address(this));\n        Deployments.BALANCER_VAULT.joinPool{value: msgValue}(\n            BALANCER_POOL_ID,\n            address(this), // sender\n            address(this), //  Vault will receive the pool tokens\n            IBalancerVault.JoinPoolRequest(\n                ASSETS(),\n                amounts,\n                customData,\n                false // Don't use internal balances\n            )\n        );\n\n        // Calculate the amount of BPT minted\n        bptAmount = BALANCER_POOL_TOKEN.balanceOf(address(this)) - bptAmount;\n    }\n\n    /// @notice Exits a balancer pool using exact BPT in\n    function _exitPoolExactBPTIn(\n        uint256[] memory amounts,\n        bytes memory customData\n    ) internal returns (uint256[] memory exitBalances) {\n        // For composable pools, the asset array includes the BPT token (i.e. poolToken). The balance\n        // will decrease in an exit while all of the other balances increase, causing a subtraction\n        // underflow in the final loop. For that reason, exit balances are not calculated of the poolToken\n        // is included in the array of assets.\n        exitBalances = new uint256[](_NUM_TOKENS);\n        IAsset[] memory assets = ASSETS();\n\n        for (uint256 i; i < _NUM_TOKENS; i++) {\n            if (address(assets[i]) == address(BALANCER_POOL_TOKEN)) continue;\n            exitBalances[i] = TokenUtils.tokenBalance(address(assets[i]));\n        }\n\n        Deployments.BALANCER_VAULT.exitPool(\n            BALANCER_POOL_ID,\n            address(this), // sender\n            payable(address(this)), // Vault will receive the underlying assets\n            IBalancerVault.ExitPoolRequest(\n                assets,\n                amounts,\n                customData,\n                false // Don't use internal balances\n            )\n        );\n\n        // Calculate the amounts of underlying tokens after the exit\n        for (uint256 i; i < _NUM_TOKENS; i++) {\n            if (address(assets[i]) == address(BALANCER_POOL_TOKEN)) continue;\n            uint256 balanceAfter = TokenUtils.tokenBalance(address(assets[i]));\n            exitBalances[i] = balanceAfter - exitBalances[i];\n        }\n    }\n\n    uint256[40] private __gap; // Storage gap for future potential upgrades\n}\n"
      },
      "interfaces/IEIP20NonStandard.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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/notional/IPrimeCashHoldingsOracle.sol": {
        "content": "// SPDX-License-Identifier: GPL-v3\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}\n\nstruct RedeemData {\n    address[] targets;\n    bytes[] callData;\n    uint256 expectedUnderlying;\n    address assetToken;\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"
      },
      "interfaces/notional/AssetRateAdapter.sol": {
        "content": "// SPDX-License-Identifier: GPL-v3\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/IRewarder.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\n\ninterface IRewarder {\n    function claimRewards(\n        address account,\n        uint16 currencyId,\n        uint256 nTokenBalanceBefore,\n        uint256 nTokenBalanceAfter,\n        int256  netNTokenSupplyChange,\n        uint256 NOTETokensClaimed\n    ) external;\n}"
      },
      "interfaces/aave/ILendingPool.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\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  // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.\n  struct ReserveData {\n    //stores the reserve configuration\n    ReserveConfigurationMap configuration;\n    //the liquidity index. Expressed in ray\n    uint128 liquidityIndex;\n    //variable borrow index. Expressed in ray\n    uint128 variableBorrowIndex;\n    //the current supply rate. Expressed in ray\n    uint128 currentLiquidityRate;\n    //the current variable borrow rate. Expressed in ray\n    uint128 currentVariableBorrowRate;\n    //the current stable borrow rate. Expressed in ray\n    uint128 currentStableBorrowRate;\n    uint40 lastUpdateTimestamp;\n    //tokens addresses\n    address aTokenAddress;\n    address stableDebtTokenAddress;\n    address variableDebtTokenAddress;\n    //address of the interest rate strategy\n    address interestRateStrategyAddress;\n    //the id of the reserve. Represents the position in the list of the active reserves\n    uint8 id;\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}\n"
      },
      "interfaces/uniswap/v3/IUniswapV3SwapCallback.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n    /// @dev In the implementation you must pay the pool tokens owed for the swap.\n    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n    function uniswapV3SwapCallback(\n        int256 amount0Delta,\n        int256 amount1Delta,\n        bytes calldata data\n    ) external;\n}\n"
      },
      "interfaces/chainlink/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\ninterface AggregatorInterface {\n  function latestAnswer() external view returns (int256);\n  function latestTimestamp() external view returns (uint256);\n  function latestRound() external view returns (uint256);\n  function getAnswer(uint256 roundId) external view returns (int256);\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}"
      },
      "interfaces/chainlink/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}"
      },
      "contracts/vaults/balancer/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow checks.\n * Adapted from OpenZeppelin's SafeMath library\n */\nlibrary Math {\n    /**\n     * @dev Returns the addition of two unsigned integers of 256 bits, reverting on overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the addition of two signed integers, reverting on overflow.\n     */\n    function add(int256 a, int256 b) internal pure returns (int256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers of 256 bits, reverting on overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two signed integers, reverting on overflow.\n     */\n    function sub(int256 a, int256 b) internal pure returns (int256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the largest of two numbers of 256 bits.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >= b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers of 256 bits.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    function div(\n        uint256 a,\n        uint256 b,\n        bool roundUp\n    ) internal pure returns (uint256) {\n        return roundUp ? divUp(a, b) : divDown(a, b);\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        } else {\n            return 1 + (a - 1) / b;\n        }\n    }\n}"
      },
      "contracts/vaults/balancer/math/FixedPoint.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity 0.8.24;\n\n/* solhint-disable private-vars-leading-underscore */\n\nlibrary FixedPoint {\n    uint256 internal constant ONE = 1e18; // 18 decimal places\n    uint256 internal constant MAX_POW_RELATIVE_ERROR = 10000; // 10^(-14)\n\n    // Minimum base for the power function when the exponent is 'free' (larger than ONE).\n    uint256 internal constant MIN_POW_BASE_FREE_EXPONENT = 0.7e18;\n\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Fixed Point addition is the same as regular checked addition\n\n        return a + b;\n    }\n\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Fixed Point addition is the same as regular checked addition\n\n        return a - b;\n    }\n\n    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 product = a * b;\n        return product / ONE;\n    }\n\n    function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 product = a * b;\n\n        if (product == 0) {\n            return 0;\n        } else {\n            // The traditional divUp formula is:\n            // divUp(x, y) := (x + y - 1) / y\n            // To avoid intermediate overflow in the addition, we distribute the division and get:\n            // divUp(x, y) := (x - 1) / y + 1\n            // Note that this requires x != 0, which we already tested for.\n\n            return ((product - 1) / ONE) + 1;\n        }\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n\n        if (a == 0) {\n            return 0;\n        } else {\n            uint256 aInflated = a * ONE;\n            return aInflated / b;\n        }\n    }\n\n    function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        } else {\n            uint256 aInflated = a * ONE;\n\n            // The traditional divUp formula is:\n            // divUp(x, y) := (x + y - 1) / y\n            // To avoid intermediate overflow in the addition, we distribute the division and get:\n            // divUp(x, y) := (x - 1) / y + 1\n            // Note that this requires x != 0, which we already tested for.\n\n            return ((aInflated - 1) / b) + 1;\n        }\n    }\n\n    /**\n     * @dev Returns the complement of a value (1 - x), capped to 0 if x is larger than 1.\n     *\n     * Useful when computing the complement for values with some level of relative error, as it strips this error and\n     * prevents intermediate negative values.\n     */\n    function complement(uint256 x) internal pure returns (uint256) {\n        return (x < ONE) ? (ONE - x) : 0;\n    }\n}"
      },
      "interfaces/common/IRewardPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\ninterface IRewardPool {\n    function withdrawAndUnwrap(uint256 amount, bool claim) external returns(bool);\n    function getReward(address _account, bool _claimExtras) external returns(bool);\n    function balanceOf(address _account) external view returns(uint256);\n    function pid() external view returns(uint256);\n    function operator() external view returns(address);\n}\n"
      },
      "interfaces/IERC4626.sol": {
        "content": "pragma solidity ^0.8.0;\n\ninterface IERC4626 {\n    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed caller,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /**\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n     *\n     * - MUST be an ERC-20 token contract.\n     * - MUST NOT revert.\n     */\n    function asset() external view returns (address assetTokenAddress);\n\n    /**\n     * @dev Returns the total amount of the underlying asset that is \"managed\" by Vault.\n     *\n     * - SHOULD include any compounding that occurs from yield.\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT revert.\n     */\n    function totalAssets() external view returns (uint256 totalManagedAssets);\n\n    /**\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the \"per-user\" price-per-share, and instead should reflect the\n     * \"average-user's\" price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the \"per-user\" price-per-share, and instead should reflect the\n     * \"average-user's\" price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n     * through a deposit call.\n     *\n     * - MUST return a limited value if receiver is subject to some deposit limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n     * - MUST NOT revert.\n     */\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n     *   in the same transaction.\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   deposit execution, and are accounted for during deposit.\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\n     * - MUST return a limited value if receiver is subject to some mint limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\n     * - MUST NOT revert.\n     */\n    function maxMint(address receiver) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\n     *   same transaction.\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\n     */\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\n     *   execution, and are accounted for during mint.\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\n     * Vault, through a withdraw call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\n     *   called\n     *   in the same transaction.\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   withdraw execution, and are accounted for during withdraw.\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function withdraw(\n        uint256 assets,\n        address receiver,\n        address owner\n    ) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\n     * through a redeem call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\n     *   same transaction.\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\n     */\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   redeem execution, and are accounted for during redeem.\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function redeem(\n        uint256 shares,\n        address receiver,\n        address owner\n    ) external returns (uint256 assets);\n}\n"
      },
      "contracts/vaults/common/SingleSidedLPVaultBase.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\n\nimport {BaseStrategyVault} from \"./BaseStrategyVault.sol\";\nimport {Errors} from \"@contracts/global/Errors.sol\";\nimport {Constants} from \"@contracts/global/Constants.sol\";\nimport {TypeConvert} from \"@contracts/global/TypeConvert.sol\";\nimport {TokenUtils} from \"@contracts/utils/TokenUtils.sol\";\nimport {StrategyUtils} from \"./StrategyUtils.sol\";\nimport {VaultStorage} from \"./VaultStorage.sol\";\n\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {\n    ISingleSidedLPStrategyVault,\n    StrategyVaultSettings,\n    InitParams,\n    StrategyVaultState,\n    SingleSidedRewardTradeParams,\n    DepositParams,\n    DepositTradeParams,\n    RedeemParams,\n    TradeParams\n} from \"@interfaces/notional/ISingleSidedLPStrategyVault.sol\";\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {ITradingModule, DexId} from \"@interfaces/trading/ITradingModule.sol\";\n\n/**\n * @notice Base contract for the SingleSidedLP strategy. This strategy deposits into an LP\n * pool given a single borrowed currency. Allows for users to trade via external exchanges\n * during entry and exit, but the general expected behavior is single sided entries and\n * exits. Inheriting contracts will fill in the implementation details for integration with\n * the external DEX pool.\n */\nabstract contract SingleSidedLPVaultBase is BaseStrategyVault, UUPSUpgradeable, ISingleSidedLPStrategyVault {\n    using TypeConvert for uint256;\n    using VaultStorage for StrategyVaultState;\n\n    uint256 internal constant MAX_TOKENS = 5;\n    uint8 internal constant NOT_FOUND = type(uint8).max;\n    /// @notice Bit mask for the 'LOCKED\" flag big\n    uint32 internal constant FLAG_LOCKED = 1 << 0;\n\n    /************************************************************************\n     * VIRTUAL FUNCTIONS                                                    *\n     * These virtual functions are used to isolate implementation specific  *\n     * behavior.                                                            *\n     ************************************************************************/\n\n    /// @notice Total number of tokens held by the LP token\n    function NUM_TOKENS() internal view virtual returns (uint256);\n\n    /// @notice Addresses of tokens held and decimal places of each token. ETH will always be\n    /// recorded in this array as Deployments.ETH_Address\n    function TOKENS() public view virtual returns (IERC20[] memory, uint8[] memory decimals);\n\n    /// @notice Address of the LP token\n    function POOL_TOKEN() internal view virtual returns (IERC20);\n\n    /// @notice Index of the TOKENS() array that refers to the primary borrowed currency by the\n    /// leveraged vault. All valuations are done in terms of this currency.\n    function PRIMARY_INDEX() internal view virtual returns (uint256);\n\n    /// @notice Precision (i.e. 10 ** decimals) of the LP token.\n    function POOL_PRECISION() internal view virtual returns (uint256);\n\n    /// @notice Returns the value of one LP token in terms of the primary borrowed currency by this\n    /// strategy. Will revert if the spot price on the pool is not within some deviation tolerance of\n    /// the implied oracle price. This is intended to prevent any pool manipulation.\n    /// The value of the LP token is calculated as the value of the token if all the balance claims are\n    /// withdrawn proportionally and then converted to the primary currency at the oracle price. Slippage\n    /// from selling the tokens is not considered, any slippage effects will be captured by the maximum\n    /// leverage ratio allowed before liquidation.\n    function _checkPriceAndCalculateValue() internal view virtual returns (uint256 oneLPValueInPrimary);\n\n    /// @notice Called once during initialization to set the initial token approvals.\n    function _initialApproveTokens() internal virtual;\n\n    /// @notice Called to claim reward tokens\n    function _claimRewardTokens() internal virtual;\n\n    /// @notice Called during reward reinvestment to validate that the token being sold is not one\n    /// of the tokens that is required for the vault to function properly (i.e. one of the pool tokens\n    /// or any of the reward booster tokens).\n    function _isInvalidRewardToken(address token) internal view virtual returns (bool);\n\n    /// @notice Implementation specific wrapper for joining a pool with the given amounts. Will also\n    /// stake on the relevant booster protocol.\n    function _joinPoolAndStake(\n        uint256[] memory amounts, uint256 minPoolClaim\n    ) internal virtual returns (uint256 lpTokens);\n\n    /// @notice Implementation specific wrapper for unstaking from the booster protocol and withdrawing\n    /// funds from the LP pool\n    function _unstakeAndExitPool(\n        uint256 poolClaim, uint256[] memory minAmounts, bool isSingleSided\n    ) internal virtual returns (uint256[] memory exitBalances);\n\n    /// @notice Returns the total supply of the pool token. Is a virtual function because\n    /// ComposableStablePools use a \"virtual supply\" and a different method must be called\n    /// to get the actual total supply.\n    function _totalPoolSupply() internal view virtual returns (uint256) {\n        return POOL_TOKEN().totalSupply();\n    }\n\n    /************************************************************************\n     * CLASS FUNCTIONS                                                      *\n     * Below are class functions that represent the base implementation     *\n     * of the Single Sided LP strategy.                                     *\n     ************************************************************************/\n\n    constructor(NotionalProxy notional_, ITradingModule tradingModule_)\n        BaseStrategyVault(notional_, tradingModule_) {}\n\n    /************************************************************************\n     * EXTERNAL VIEW FUNCTIONS                                              *\n     ************************************************************************/\n\n    /// @notice Returns basic information about the vault for use in the user interface.\n    function getStrategyVaultInfo() external view override returns (SingleSidedLPStrategyVaultInfo memory) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        StrategyVaultSettings memory settings = VaultStorage.getStrategyVaultSettings();\n\n        return SingleSidedLPStrategyVaultInfo({\n            pool: address(POOL_TOKEN()),\n            singleSidedTokenIndex: uint8(PRIMARY_INDEX()),\n            totalLPTokens: state.totalPoolClaim,\n            totalVaultShares: state.totalVaultSharesGlobal,\n            maxPoolShare: settings.maxPoolShare,\n            oraclePriceDeviationLimitPercent: settings.oraclePriceDeviationLimitPercent\n        });\n    }\n\n    /// @notice Returns the current locked status of the vault\n    function isLocked() public view returns (bool) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        return _hasFlag(state.flags, FLAG_LOCKED);\n    }\n\n    /// @notice Returns the current price of a vault share, even when there are no vault shares\n    /// in the strategy. Used by the user interface to collect historical valuation information.\n    function getExchangeRate(uint256 /* maturity */) external view override returns (int256) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        uint256 oneLPValueInPrimary = _checkPriceAndCalculateValue();\n        // If inside an emergency exit, just report the one LP value in primary since the total\n        // pool claim will be 0\n        if (state.totalVaultSharesGlobal == 0 || isLocked()) {\n            return oneLPValueInPrimary.toInt();\n        } else {\n            uint256 lpTokensPerVaultShare = (uint256(Constants.INTERNAL_TOKEN_PRECISION) * state.totalPoolClaim)\n                / state.totalVaultSharesGlobal;\n            return (oneLPValueInPrimary * lpTokensPerVaultShare / POOL_PRECISION()).toInt();\n        }\n    }\n\n    /************************************************************************\n     * ADMIN FUNCTIONS                                                      *\n     * Administrative functions to set settings and initialize the vault.   *\n     * These methods are only callable by the Notional owner.               *\n     ************************************************************************/\n\n    /// @notice Allow Notional owner to upgrade the contract\n    function _authorizeUpgrade(\n        address /* newImplementation */\n    ) internal override onlyNotionalOwner {}\n\n    /// @notice Updates the vault settings include the maximum oracle deviation limit and the\n    /// maximum percent of the LP pool that the vault can hold.\n    function setStrategyVaultSettings(StrategyVaultSettings calldata settings) external onlyNotionalOwner {\n        // Validation occurs inside this method\n        VaultStorage.setStrategyVaultSettings(settings);\n    }\n\n    /// @notice Called to initialize the vault and set the initial approvals. All of the other vault\n    /// parameters are set via immutable parameters already.\n    function initialize(InitParams calldata params) external override initializer onlyNotionalOwner {\n        // Initialize the base vault\n        __INIT_VAULT(params.name, params.borrowCurrencyId);\n\n        // Settings are validated in setStrategyVaultSettings\n        VaultStorage.setStrategyVaultSettings(params.settings);\n\n        _initialApproveTokens();\n    }\n\n    /************************************************************************\n     * USER FUNCTIONS                                                       *\n     * These functions are called during normal usage of the vault.         *\n     * They allow for deposits and redemptions from the vault as well as a  *\n     * valuation check that is used by Notional to determine if the user is *\n     * properly collateralized.                                             *\n     ************************************************************************/\n\n    /// @notice This is a virtual function called by BaseStrategyVault which ensures that\n    /// this method is only called by Notional after an initial borrow has been made and\n    /// the deposit amount has been transferred to this vault. Will join the LP pool with\n    /// the funds given and then return the total vault shares minted.\n    function _depositFromNotional(\n        address /* account */, uint256 deposit, uint256 /* maturity */, bytes calldata data\n    ) internal override virtual whenNotLocked returns (uint256 vaultSharesMinted) {\n        // Short circuit any zero deposit amounts\n        if (deposit == 0) return 0;\n\n        DepositParams memory params = abi.decode(data, (DepositParams));\n        uint256[] memory amounts = new uint256[](NUM_TOKENS());\n        amounts[PRIMARY_INDEX()] = deposit;\n\n        // If depositTrades are specified, then parts of the initial deposit are traded\n        // for corresponding amounts of the other pool tokens via external exchanges. If\n        // these amounts are not specified then the pool will just be joined single sided.\n        // Deposit trades are not automatically enabled on vaults since the trading module\n        // requires explicit permission for every token that can be sold by an address.\n        if (params.depositTrades.length > 0) {\n            (IERC20[] memory tokens, /* */) = TOKENS();\n            // This is an external library call so the memory location of amounts is\n            // different before and after the call.\n            amounts = StrategyUtils.executeDepositTrades(\n                tokens,\n                amounts,\n                params.depositTrades,\n                PRIMARY_INDEX()\n            );\n        }\n\n        uint256 lpTokens = _joinPoolAndStake(amounts, params.minPoolClaim);\n        return _mintVaultShares(lpTokens);\n    }\n\n    /// @notice Given a number of LP tokens minted, issues vault shares back to the holder. Vault\n    /// shares are claim on the LP tokens held by the vault. As rewards are reinvested, one vault\n    /// share is a claim on an increasing amount of LP tokens.\n    function _mintVaultShares(uint256 lpTokens) internal returns (uint256 vaultShares) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        if (state.totalPoolClaim == 0) {\n            // Vault Shares are in 8 decimal precision\n            vaultShares = (lpTokens * uint256(Constants.INTERNAL_TOKEN_PRECISION)) / POOL_PRECISION();\n        } else {\n            vaultShares = (lpTokens * state.totalVaultSharesGlobal) / state.totalPoolClaim;\n        }\n\n        // Updates internal storage here\n        state.totalPoolClaim += lpTokens;\n        state.totalVaultSharesGlobal += vaultShares.toUint80();\n        state.setStrategyVaultState();\n\n        // Checks that the vault does not own too large of a portion of the pool. If this is the case,\n        // single sided exits may have a detrimental effect on the liquidity.\n        uint256 maxPoolShare = VaultStorage.getStrategyVaultSettings().maxPoolShare;\n        uint256 maxSupplyThreshold = (_totalPoolSupply() * maxPoolShare) / Constants.VAULT_PERCENT_BASIS;\n        if (maxSupplyThreshold < state.totalPoolClaim)\n            revert Errors.PoolShareTooHigh(state.totalPoolClaim, maxSupplyThreshold);\n    }\n\n    /// @notice This is a virtual function called by BaseStrategyVault which ensures that\n    /// this method is only called by Notional after an initial position has been made. Will\n    /// withdraw the LP tokens from the pool, either single sided or proportionally. On a\n    /// proportional exit, will trade all the tokens back to the primary in order to exit the pool.\n    /// @return finalPrimaryBalance which is the amount of funds that the vault will transfer back\n    /// to Notional and the account to repay debts and withdraw profits.\n    function _redeemFromNotional(\n        address /* account */, uint256 vaultShares, uint256 /* maturity */, bytes calldata data\n    ) internal override virtual whenNotLocked returns (uint256 finalPrimaryBalance) {\n        // Short circuit any zero redemption amounts, this can occur during rolling positions\n        // or withdraw cash balances post liquidation.\n        if (vaultShares == 0) return 0;\n\n        // Updates internal account to deduct the vault shares.\n        uint256 poolClaim = _redeemVaultShares(vaultShares);\n        RedeemParams memory params = abi.decode(data, (RedeemParams));\n\n        bool isSingleSided = params.redemptionTrades.length == 0;\n        // Returns the amount of each token that has been withdrawn from the pool.\n        uint256[] memory exitBalances = _unstakeAndExitPool(poolClaim, params.minAmounts, isSingleSided);\n        if (!isSingleSided) {\n            // If not a single sided trade, will execute trades back to the primary token on\n            // external exchanges. This method will execute EXACT_IN trades to ensure that\n            // all of the balance in the other tokens is sold for primary.\n            (IERC20[] memory tokens, /* */) = TOKENS();\n            // Redemption trades are not automatically enabled on vaults since the trading module\n            // requires explicit permission for every token that can be sold by an address.\n            return StrategyUtils.executeRedemptionTrades(\n                tokens,\n                exitBalances,\n                params.redemptionTrades,\n                PRIMARY_INDEX()\n            );\n        } else {\n            // No explicit check is done here to ensure that the other balances are zero, assumed\n            // that the `_unstakeAndExitPool` method on the implementation is correct and will only\n            // ever withdraw to a single balance.\n            return exitBalances[PRIMARY_INDEX()];\n        }\n    }\n\n    /// @notice Updates internal account for vault share redemption.\n    function _redeemVaultShares(uint256 vaultShares) internal returns (uint256 poolClaim) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        // Will revert on divide by zero, which is the correct behavior\n        poolClaim = (vaultShares * state.totalPoolClaim) / state.totalVaultSharesGlobal;\n\n        state.totalPoolClaim -= poolClaim;\n        // Will revert on underflow if vault shares is greater than total shares global\n        state.totalVaultSharesGlobal -= vaultShares.toUint80();\n        state.setStrategyVaultState();\n    }\n\n    /// @notice Converts the vault shares to an oracle value in underlying tokens. Used by Notional\n    /// to determine the collateral position of a vault user. If the vault is locked due to an\n    /// emergency exit, this function will revert which will prevent users from entering, exiting,\n    /// and being liquidated. During emergency exit, the vault will not be holding any LP tokens and\n    /// therefore this calculation will not be correct.\n    function convertStrategyToUnderlying(\n        address /* */, uint256 vaultShares, uint256 /* */\n    ) public view virtual override whenNotLocked returns (int256 underlyingValue) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        // Will revert on divide by zero, which is the correct behavior\n        uint256 lpTokens = (vaultShares * state.totalPoolClaim) / state.totalVaultSharesGlobal;\n        uint256 oneLPValueInPrimary = _checkPriceAndCalculateValue();\n\n        return (oneLPValueInPrimary * lpTokens / POOL_PRECISION()).toInt();\n    }\n\n    /// @notice Returns the pair price of two tokens via the TRADING_MODULE which holds a registry\n    /// of oracles. Will revert of the oracle pair is not listed.\n    function _getOraclePairPrice(address base, address quote) internal view returns (uint256) {\n        (int256 rate, int256 precision) = TRADING_MODULE.getOraclePrice(base, quote);\n        require(rate > 0);\n        require(precision > 0);\n        return uint256(rate) * POOL_PRECISION() / uint256(precision);\n    }\n\n    /// @notice Helper method called by _checkPriceAndCalculateValue which will supply the relevant\n    /// pool balances and spot prices. Calculates the claim of one LP token on relevant pool balances\n    /// and compares the oracle price to the spot price, reverting if the deviation is too high.\n    /// @return oneLPValueInPrimary the value of one LP token in terms of the primary borrowed currency\n    function _calculateLPTokenValue(\n        uint256[] memory balances,\n        uint256[] memory spotPrices\n    ) internal view returns (uint256 oneLPValueInPrimary) {\n        (IERC20[] memory tokens, uint8[] memory decimals) = TOKENS();\n        address primaryToken = address(tokens[PRIMARY_INDEX()]);\n        uint256 primaryDecimals = 10 ** decimals[PRIMARY_INDEX()];\n        uint256 totalSupply = _totalPoolSupply();\n        uint256 limit = VaultStorage.getStrategyVaultSettings().oraclePriceDeviationLimitPercent;\n\n        for (uint256 i; i < tokens.length; i++) {\n            // Skip the pool token if it is in the token list (i.e. ComposablePools)\n            if (address(tokens[i]) == address(POOL_TOKEN())) continue;\n            // This is the claim on the pool balance of 1 LP token.\n            uint256 tokenClaim = balances[i] * POOL_PRECISION() / totalSupply;\n            if (i == PRIMARY_INDEX()) {\n                oneLPValueInPrimary += tokenClaim;\n            } else {\n                uint256 price = _getOraclePairPrice(primaryToken, address(tokens[i]));\n\n                // Check that the spot price and the oracle price are near each other. If this is\n                // not true then we assume that the LP pool is being manipulated.\n                uint256 lowerLimit = price * (Constants.VAULT_PERCENT_BASIS - limit) / Constants.VAULT_PERCENT_BASIS;\n                uint256 upperLimit = price * (Constants.VAULT_PERCENT_BASIS + limit) / Constants.VAULT_PERCENT_BASIS;\n                if (spotPrices[i] < lowerLimit || upperLimit < spotPrices[i]) {\n                    revert Errors.InvalidPrice(price, spotPrices[i]);\n                }\n\n                // Convert the token claim to primary using the oracle pair price.\n                uint256 secondaryDecimals = 10 ** decimals[i];\n                oneLPValueInPrimary += (tokenClaim * POOL_PRECISION() * primaryDecimals) / \n                    (price * secondaryDecimals);\n            }\n        }\n    }\n\n    /************************************************************************\n     * REWARD REINVESTMENT                                                  *\n     * Methods used by bots to claim reward tokens and reinvest them as LP  *\n     * tokens which are donated to all vault users.                         *\n     ************************************************************************/\n\n    /// @notice Ensures that only whitelisted bots can claim reward tokens.\n    function claimRewardTokens() external override onlyRole(REWARD_REINVESTMENT_ROLE) {\n        _claimRewardTokens();\n    }\n\n    /// @notice Ensures that only whitelisted bots can reinvest rewards. Since rewards\n    /// are typically less liquid than pool tokens and lack oracles, reward reinvestment\n    /// is done using explicitly set slippage limits by the reinvestment bots. Reinvestment\n    /// will fail if the spot prices are not close to the oracle prices to ensure that\n    /// there is no front running the reinvestment.\n    function reinvestReward(\n        SingleSidedRewardTradeParams[] calldata trades,\n        uint256 minPoolClaim\n    ) external whenNotLocked onlyRole(REWARD_REINVESTMENT_ROLE) returns (\n        address rewardToken,\n        uint256 amountSold,\n        uint256 poolClaimAmount\n    ) {\n        // Will revert if spot prices are not in line with the oracle values\n        _checkPriceAndCalculateValue();\n\n        // Require one trade per token, if we do not want to buy any tokens at a\n        // given index then the amount should be set to zero. This applies to pool\n        // tokens like in the ComposableStablePool.\n        require(trades.length == NUM_TOKENS());\n        uint256[] memory amounts;\n        // The sell token on all trades must be the same (checked inside executeRewardTrades) so\n        // just validate here that the sellToken is a valid reward token (i.e. none of the tokens\n        // used in the regular functioning of the vault).\n        rewardToken = trades[0].sellToken;\n        if (_isInvalidRewardToken(rewardToken)) revert Errors.InvalidRewardToken(rewardToken);\n        (amountSold, amounts) = _executeRewardTrades(trades, rewardToken);\n\n        poolClaimAmount = _joinPoolAndStake(amounts, minPoolClaim);\n\n        // Increase LP token amount without minting additional vault shares\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        // Do not re-invest if there are no vault shares\n        require(state.totalVaultSharesGlobal > 0);\n        state.totalPoolClaim += poolClaimAmount;\n        state.setStrategyVaultState();\n    }\n\n    function _executeRewardTrades(\n        SingleSidedRewardTradeParams[] calldata trades,\n        address rewardToken\n    ) internal returns (uint256 amountSold, uint256[] memory amounts) {\n        (IERC20[] memory tokens, /* */) = TOKENS();\n        (amounts, amountSold) = StrategyUtils.executeRewardTrades(\n            tokens, trades, rewardToken, address(POOL_TOKEN())\n        );\n    }\n\n    /************************************************************************\n     * EMERGENCY EXIT                                                       *\n     * In case of an emergency, will allow a whitelisted guardian to exit   *\n     * funds on the vault and locks the vault from further usage. The owner *\n     * can restore funds to the LP pool and reinstate vault usage. If the   *\n     * vault cannot be fully restored after an exit, the vault will need to *\n     * be upgraded and unwound manually to ensure that debts are repaid and *\n     * users can withdraw their funds.                                      *\n     ************************************************************************/\n\n    /// @notice Allows the function to execute only when the vault is not locked\n    modifier whenNotLocked() {\n        if (isLocked()) revert Errors.VaultLocked();\n        _;\n    }\n\n    /// @notice Allows the function to execute only when the vault is locked\n    modifier whenLocked() {\n        if (!isLocked()) revert Errors.VaultNotLocked();\n        _;\n    }\n\n    /// @notice Checks if a flag bit is set\n    function _hasFlag(uint32 flags, uint32 flagID) private pure returns (bool) {\n        return (flags & flagID) == flagID;\n    }\n\n    /// @notice Locks the vault, preventing deposits and redemptions. Used during\n    /// emergency exit\n    function _lockVault() internal {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        // Set locked flag\n        state.flags = state.flags | FLAG_LOCKED;\n        VaultStorage.setStrategyVaultState(state);\n        emit VaultLocked();\n    }\n\n    /// @notice Unlocks the vault, called during restore vault.\n    function _unlockVault() internal {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        // Remove locked flag\n        state.flags = state.flags & ~FLAG_LOCKED;\n        VaultStorage.setStrategyVaultState(state);\n        emit VaultUnlocked();\n    }\n\n    /// @notice Allows the emergency exit role to trigger an emergency exit on the vault.\n    /// In this situation, the `claimToExit` is withdrawn proportionally to the underlying\n    /// tokens and held on the vault. The vault is locked so that no entries, exits or\n    /// valuations of vaultShares can be performed.\n    /// @param claimToExit if this is set to zero, the entire pool claim is withdrawn\n    function emergencyExit(\n        uint256 claimToExit, bytes calldata /* data */\n    ) external override onlyRole(EMERGENCY_EXIT_ROLE) {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n        if (claimToExit == 0 || claimToExit > state.totalPoolClaim) claimToExit = state.totalPoolClaim;\n\n        // By setting min amounts to zero, we will accept whatever tokens come from the pool\n        // in a proportional exit. Front running will not have an effect since no trading will\n        // occur during a proportional exit.\n        uint256[] memory exitBalances = _unstakeAndExitPool(claimToExit, new uint256[](NUM_TOKENS()), false);\n\n        state.totalPoolClaim = state.totalPoolClaim - claimToExit;\n        state.setStrategyVaultState();\n\n        emit EmergencyExit(claimToExit, exitBalances);\n        _lockVault();\n    }\n\n    /// @notice Restores withdrawn tokens from emergencyExit back into the vault proportionally.\n    /// Unlocks the vault after restoration so that normal functionality is restored.\n    /// @param minPoolClaim slippage limit to prevent front running\n    /// @param data the owner will pass in an array of amounts for the pool to re-enter the vault.\n    /// This prevents any front running or manipulation of the vault balances.\n    function restoreVault(\n        uint256 minPoolClaim, bytes calldata data\n    ) external override whenLocked onlyNotionalOwner {\n        StrategyVaultState memory state = VaultStorage.getStrategyVaultState();\n\n        uint256[] memory amounts = abi.decode(data, (uint256[]));\n\n        // No trades are specified so this joins proportionally using the\n        // amounts specified.\n        uint256 poolTokens = _joinPoolAndStake(amounts, minPoolClaim);\n\n        state.totalPoolClaim = state.totalPoolClaim + poolTokens;\n        state.setStrategyVaultState();\n\n        _unlockVault();\n    }\n\n    /// @notice This is a trusted method that can only be executed while the vault is locked. The owner\n    /// may trade tokens prior to restoring the vault if the tokens withdrawn are imbalanced. In this\n    /// method, one of the tokens held is sold for other tokens that go into the pool. If multiple tokens\n    /// need to be sold then this method will be called multiple times prior to restoreVault.\n    function tradeTokensBeforeRestore(\n        SingleSidedRewardTradeParams[] calldata trades\n    ) external override whenLocked onlyNotionalOwner {\n        // The sell token on all trades must be the same (checked inside executeRewardTrades). In this\n        // method we do not validate the sell token so we can sell any of the tokens held on the vault\n        // in exchange for any other token that goes into the pool.\n        _executeRewardTrades(trades, trades[0].sellToken);\n    }\n\n    // Storage gap for future potential upgrades\n    uint256[100] private __gap;\n}"
      },
      "lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n    address private immutable __self = address(this);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        require(address(this) != __self, \"Function must be called through delegatecall\");\n        require(_getImplementation() == __self, \"Function must be called through active proxy\");\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n        _;\n    }\n\n    /**\n     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n        return _IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function upgradeTo(address newImplementation) external virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeTo} and {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal override onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n"
      },
      "contracts/vaults/common/BaseStrategyVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {AccessControlUpgradeable} from \"../../proxy/AccessControlUpgradeable.sol\";\n\nimport {Token, TokenType} from \"@contracts/global/Types.sol\";\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {Constants} from \"@contracts/global/Constants.sol\";\nimport {IStrategyVault} from \"@interfaces/notional/IStrategyVault.sol\";\nimport {NotionalProxy} from \"@interfaces/notional/NotionalProxy.sol\";\nimport {ITradingModule, Trade} from \"@interfaces/trading/ITradingModule.sol\";\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {TokenUtils} from \"@contracts/utils/TokenUtils.sol\";\nimport {TradeHandler} from \"../../trading/TradeHandler.sol\";\nimport {nProxy} from \"../../proxy/nProxy.sol\";\n\nabstract contract BaseStrategyVault is Initializable, IStrategyVault, AccessControlUpgradeable {\n    using TokenUtils for IERC20;\n    using TradeHandler for Trade;\n\n    bytes32 internal constant EMERGENCY_EXIT_ROLE = keccak256(\"EMERGENCY_EXIT_ROLE\");\n    bytes32 internal constant REWARD_REINVESTMENT_ROLE = keccak256(\"REWARD_REINVESTMENT_ROLE\");\n    bytes32 internal constant STATIC_SLIPPAGE_TRADING_ROLE = keccak256(\"STATIC_SLIPPAGE_TRADING_ROLE\");\n\n    /// @notice Hardcoded on the implementation contract during deployment\n    NotionalProxy internal immutable NOTIONAL;\n    ITradingModule internal immutable TRADING_MODULE;\n    uint8 constant internal INTERNAL_TOKEN_DECIMALS = 8;\n\n    // Borrowing Currency ID the vault is configured with\n    uint16 private _BORROW_CURRENCY_ID;\n    // True if the underlying is ETH\n    bool private _UNDERLYING_IS_ETH;\n    // Address of the underlying token\n    IERC20 private _UNDERLYING_TOKEN;\n    // NOTE: end of first storage slot here\n\n    // Name of the vault\n    string private _NAME;\n\n\n    /**************************************************************************/\n    /* Global Modifiers, Constructor and Initializer                          */\n    /**************************************************************************/\n    modifier onlyNotional() {\n        require(msg.sender == address(NOTIONAL), \"Unauthorized\");\n        _;\n    }\n\n    modifier onlyNotionalOwner() {\n        require(msg.sender == address(NOTIONAL.owner()), \"Unauthorized\");\n        _;\n    }\n    \n    /// @notice Set the NOTIONAL address on deployment\n    constructor(NotionalProxy notional_, ITradingModule tradingModule_) initializer {\n        // Make sure we are using the correct Deployments lib\n        require(Deployments.CHAIN_ID == block.chainid);\n\n        NOTIONAL = notional_;\n        TRADING_MODULE = tradingModule_;\n    }\n\n    /// @notice Override this method and revert if the contract should not receive ETH.\n    /// Upgradeable proxies must have this implemented on the proxy for transfer calls\n    /// succeed (use nProxy for this).\n    receive() external virtual payable {\n        // Allow ETH transfers to succeed\n    }\n\n    /// @notice All strategy vaults MUST implement 8 decimal precision\n    function decimals() public override pure returns (uint8) {\n        return INTERNAL_TOKEN_DECIMALS;\n    }\n\n    function name() external override view returns (string memory) {\n        return _NAME;\n    }\n\n    function strategy() external virtual view returns (bytes4);\n\n    function _borrowCurrencyId() internal view returns (uint16) {\n        return _BORROW_CURRENCY_ID;\n    }\n\n    function _underlyingToken() internal view returns (IERC20) {\n        return _UNDERLYING_TOKEN;\n    }\n\n    function _isUnderlyingETH() internal view returns (bool) {\n        return _UNDERLYING_IS_ETH;\n    }\n\n    /// @notice Can only be called once during initialization\n    function __INIT_VAULT(\n        string memory name_,\n        uint16 borrowCurrencyId_\n    ) internal onlyInitializing {\n        _NAME = name_;\n        _BORROW_CURRENCY_ID = borrowCurrencyId_;\n\n        address underlyingAddress = _getNotionalUnderlyingToken(borrowCurrencyId_);\n        _UNDERLYING_TOKEN = IERC20(underlyingAddress);\n        _UNDERLYING_IS_ETH = underlyingAddress == address(0);\n        _setupRole(DEFAULT_ADMIN_ROLE, NOTIONAL.owner());\n    }\n\n    function _getNotionalUnderlyingToken(uint16 currencyId) internal view returns (address) {\n        (/* */, Token memory underlyingToken) = NOTIONAL.getCurrency(currencyId);\n        return underlyingToken.tokenAddress;\n    }\n\n    /// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\n    /// a trade.\n    function _executeTrade(\n        uint16 dexId,\n        Trade memory trade\n    ) internal returns (uint256 amountSold, uint256 amountBought) {\n        return trade._executeTrade(dexId);\n    }\n\n    /**************************************************************************/\n    /* Virtual Methods Requiring Implementation                               */\n    /**************************************************************************/\n    function convertStrategyToUnderlying(\n        address account,\n        uint256 vaultShares,\n        uint256 maturity\n    ) public view virtual returns (int256 underlyingValue);\n\n    function getExchangeRate(uint256 maturity) external virtual view returns (int256);\n    \n    // Vaults need to implement these two methods\n    function _depositFromNotional(\n        address account,\n        uint256 deposit,\n        uint256 maturity,\n        bytes calldata data\n    ) internal virtual returns (uint256 vaultSharesMinted);\n\n    function _redeemFromNotional(\n        address account,\n        uint256 vaultShares,\n        uint256 maturity,\n        bytes calldata data\n    ) internal virtual returns (uint256 tokensFromRedeem);\n\n    function _convertVaultSharesToPrimeMaturity(\n        address /* account */,\n        uint256 /* vaultShares */,\n        uint256 /* maturity */\n    ) internal virtual returns (uint256 /* primeVaultShares */) {\n        revert();\n    }\n\n    function _checkReentrancyContext() internal virtual;\n\n    /**************************************************************************/\n    /* Default External Method Implementations                                */\n    /**************************************************************************/\n    function depositFromNotional(\n        address account,\n        uint256 deposit,\n        uint256 maturity,\n        bytes calldata data\n    ) external payable onlyNotional returns (uint256 vaultSharesMinted) {\n        return _depositFromNotional(account, deposit, maturity, data);\n    }\n\n    function redeemFromNotional(\n        address account,\n        address receiver,\n        uint256 vaultShares,\n        uint256 maturity,\n        uint256 underlyingToRepayDebt,\n        bytes calldata data\n    ) external onlyNotional returns (uint256 transferToReceiver) {\n        uint256 borrowedCurrencyAmount = _redeemFromNotional(account, vaultShares, maturity, data);\n\n        uint256 transferToNotional;\n        if (account == address(this) || borrowedCurrencyAmount <= underlyingToRepayDebt) {\n            // It may be the case that insufficient tokens were redeemed to repay the debt. If this\n            // happens the Notional will attempt to recover the shortfall from the account directly.\n            // This can happen if an account wants to reduce their leverage by paying off debt but\n            // does not want to sell strategy tokens to do so.\n            // The other situation would be that the vault is calling redemption to deleverage or\n            // settle. In that case all tokens go back to Notional.\n            transferToNotional = borrowedCurrencyAmount;\n        } else {\n            transferToNotional = underlyingToRepayDebt;\n            unchecked { transferToReceiver = borrowedCurrencyAmount - underlyingToRepayDebt; }\n        }\n\n        if (_UNDERLYING_IS_ETH) {\n            if (transferToReceiver > 0) payable(receiver).transfer(transferToReceiver);\n            if (transferToNotional > 0) payable(address(NOTIONAL)).transfer(transferToNotional);\n        } else {\n            if (transferToReceiver > 0) _UNDERLYING_TOKEN.checkTransfer(receiver, transferToReceiver);\n            if (transferToNotional > 0) _UNDERLYING_TOKEN.checkTransfer(address(NOTIONAL), transferToNotional);\n        }\n    }\n\n    function convertVaultSharesToPrimeMaturity(\n        address account,\n        uint256 vaultShares,\n        uint256 maturity\n    ) external onlyNotional returns (uint256 primeVaultShares) { \n        require(maturity != Constants.PRIME_CASH_VAULT_MATURITY);\n        return _convertVaultSharesToPrimeMaturity(account, vaultShares, maturity);\n    }\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        require(msg.sender == liquidator);\n        _checkReentrancyContext();\n        return NOTIONAL.deleverageAccount{value: msg.value}(\n            account, vault, liquidator, currencyIndex, depositUnderlyingInternal\n        );\n    }\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        require(msg.sender == liquidator);\n        return NOTIONAL.liquidateVaultCashBalance(\n            account, vault, liquidator, currencyIndex, fCashDeposit\n        );\n    }\n\n    function _canUseStaticSlippage() internal view returns (bool) {\n        return hasRole(STATIC_SLIPPAGE_TRADING_ROLE, msg.sender);\n    }\n\n    // Storage gap for future potential upgrades\n    uint256[45] private __gap;\n}"
      },
      "contracts/global/Errors.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\n\n/**\n * Common vault errors\n */\nlibrary Errors {\n    /// @notice Pool price deviates too much from the oracle price\n    error InvalidPrice(uint256 oraclePrice, uint256 poolPrice);\n    /// @notice The provided slippage is above the configured limit\n    error SlippageTooHigh(uint256 slippage, uint32 limit);\n    /// @notice Attemping to trade an invalid token\n    error InvalidRewardToken(address token);\n    /// @notice The vault occupies too much of the underlying pool\n    error PoolShareTooHigh(uint256 totalPoolClaim, uint256 poolClaimThreshold);\n    /// @notice Staking operation failed\n    error StakeFailed();\n    /// @notice Unstaking operation failed\n    error UnstakeFailed();\n    /// @notice Zero pool claim returned due to rounding error\n    error ZeroPoolClaim();\n    /// @notice Zero vault shares returned due to rounding error\n    error ZeroStrategyTokens();\n    /// @notice Operation is only permitted when the vault is unlocked\n    error VaultLocked();\n    /// @notice Operation is only permitted when the vault is locked\n    error VaultNotLocked();\n    /// @notice Trading through the specified dex is not permitted\n    error InvalidDexId(uint256 dexId);\n}\n"
      },
      "contracts/global/TypeConvert.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nlibrary TypeConvert {\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 toUint80(uint256 x) internal pure returns (uint80) {\n        require (x <= uint256(type(uint80).max));\n        return uint80(x);\n    }\n}\n"
      },
      "contracts/vaults/common/StrategyUtils.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {IERC20} from \"@interfaces/IERC20.sol\";\nimport {\n    TradeParams,\n    DepositTradeParams,\n    RedeemParams,\n    SingleSidedRewardTradeParams\n} from \"@interfaces/notional/ISingleSidedLPStrategyVault.sol\";\nimport {TradeHandler} from \"../../trading/TradeHandler.sol\";\nimport {Deployments} from \"@deployments/Deployments.sol\";\nimport {Constants} from \"@contracts/global/Constants.sol\";\nimport {Errors} from \"@contracts/global/Errors.sol\";\nimport {ITradingModule, Trade, TradeType, DexId} from \"@interfaces/trading/ITradingModule.sol\";\n\n/**\n * @notice External library deployed for the purposes of handling SingleSidedLP trades. All\n * the methods in this library are called inside a `delegateCall` context which ensures that\n * the library has access to the calling vault's token balances\n */\nlibrary StrategyUtils {\n    using TradeHandler for Trade;\n\n    /// @notice Trades the amount of primary token into other secondary tokens prior\n    /// to entering a pool.\n    function executeDepositTrades(\n        IERC20[] memory tokens,\n        uint256[] memory amounts,\n        DepositTradeParams[] memory depositTrades,\n        uint256 primaryIndex\n    ) external returns (uint256[] memory) {\n        address primaryToken = address(tokens[primaryIndex]);\n\n        for (uint256 i; i < amounts.length; i++) {\n            if (i == primaryIndex) continue;\n            DepositTradeParams memory t = depositTrades[i];\n            // Do not allow ZERO_EX trading in this method since we cannot validate\n            // the arbitrary exchange data.\n            if (DexId(t.tradeParams.dexId) == DexId.ZERO_EX) revert Errors.InvalidDexId(uint256(DexId.ZERO_EX));\n\n            if (t.tradeAmount > 0) {\n                // Always selling the primaryToken and buying the secondary token.\n                (uint256 amountSold, uint256 amountBought) = _executeDynamicSlippageTradeExactIn(\n                    t.tradeParams, primaryToken, address(tokens[i]), t.tradeAmount\n                );\n\n                amounts[i] = amountBought;\n                // Will revert on underflow if over-selling the primary borrowed\n                amounts[primaryIndex] -= amountSold;\n            }\n        }\n\n        return amounts;\n    }\n\n    /// @notice Trades the amount of secondary tokens into the primary token after\n    /// exiting a pool.\n    function executeRedemptionTrades(\n        IERC20[] memory tokens,\n        uint256[] memory exitBalances,\n        TradeParams[] memory redemptionTrades,\n        uint256 primaryIndex\n    ) external returns (uint256 finalPrimaryBalance) {\n        address primaryToken = address(tokens[primaryIndex]);\n\n        for (uint256 i; i < exitBalances.length; i++) {\n            if (i == primaryIndex) {\n                finalPrimaryBalance += exitBalances[i];\n                continue;\n            }\n\n            TradeParams memory t = redemptionTrades[i];\n            // Do not allow ZERO_EX trading in this method since we cannot validate\n            // the arbitrary exchange data.\n            if (DexId(t.dexId) == DexId.ZERO_EX) revert Errors.InvalidDexId(uint256(DexId.ZERO_EX));\n\n            // Always sell the entire exit balance to the primary token\n            if (exitBalances[i] > 0) {\n                (/* */, uint256 amountBought) = _executeDynamicSlippageTradeExactIn(\n                    t, address(tokens[i]), primaryToken, exitBalances[i]\n                );\n\n                finalPrimaryBalance += amountBought;\n            }\n        }\n    }\n\n    /// @notice Executes a set of trades to sell the reward token for constituent pool tokens.\n    function executeRewardTrades(\n        IERC20[] memory tokens,\n        SingleSidedRewardTradeParams[] calldata trades,\n        address rewardToken,\n        address poolToken\n    ) external returns(uint256[] memory amounts, uint256 amountSold) {\n        amounts = new uint256[](trades.length);\n        uint256 initialRewardBalance = IERC20(rewardToken).balanceOf(address(this));\n        for (uint256 i; i < trades.length; i++) {\n            // All trades must sell the same token.\n            require(trades[i].sellToken == rewardToken);\n            // Bypass certain invalid trades\n            if (trades[i].amount == 0) continue;\n            if (trades[i].buyToken == poolToken) continue;\n\n            // The reward trade can only purchase tokens that go into the pool\n            require(trades[i].buyToken == address(tokens[i]));\n\n            uint256 sold;\n            uint256 bought;\n            if (rewardToken == trades[i].buyToken) {\n                // In some rare cases the reward token is actually one of the the tokens\n                // in the pool and we do not want to execute a trade against it. In these\n                // cases we skip the trade and just mark the amount as \"sold\" with\n                // an equal amount \"bought\".\n                sold = trades[i].amount;\n                bought = sold;\n            } else {\n                // It may be possible that the entire balance of reward tokens is not sold by the vault,\n                // but that is ok.\n                (sold, bought) = _executeTradeWithStaticSlippage(\n                    trades[i].tradeParams, rewardToken, trades[i].buyToken, trades[i].amount\n                );\n            }\n\n            amounts[i] = bought;\n            amountSold += sold;\n        }\n\n        // Ensures that in the case when the reward token is one of the tokens in the pool we do not\n        // over sell the actual reward token balance.\n        require(amountSold <= initialRewardBalance, \"Insufficient Reward Tokens\");\n    }\n\n    /// @notice Executes a trade that uses a dynamic slippage amount relative to the current\n    /// oracle price.\n    function _executeDynamicSlippageTradeExactIn(\n        TradeParams memory params,\n        address sellToken,\n        address buyToken,\n        uint256 amount\n    ) internal returns (uint256 amountSold, uint256 amountBought) {\n        // Can only do exact in trades\n        require(\n            params.tradeType == TradeType.EXACT_IN_SINGLE ||\n            params.tradeType == TradeType.EXACT_IN_BATCH\n        );\n        // Ensure that the slippage percent is valid\n        require(params.oracleSlippagePercentOrLimit <= Constants.SLIPPAGE_LIMIT_PRECISION);\n\n        Trade memory trade = Trade(\n            params.tradeType,\n            sellToken,\n            buyToken,\n            amount,\n            0, // No absolute slippage limit is set here\n            block.timestamp, // deadline\n            params.exchangeData\n        );\n\n        (amountSold, amountBought) = trade._executeTradeWithDynamicSlippage(\n            params.dexId, uint32(params.oracleSlippagePercentOrLimit)\n        );\n    }\n\n    /// @notice Executes a trade with a static slippage limit, only used during\n    /// reward reinvestment trades since oracles between the reward token and the\n    /// purchased tokens may not exist.\n    function _executeTradeWithStaticSlippage(\n        TradeParams memory params,\n        address sellToken,\n        address buyToken,\n        uint256 amount\n    ) internal returns (uint256 amountSold, uint256 amountBought) {\n        require(\n            params.tradeType == TradeType.EXACT_IN_SINGLE ||\n            params.tradeType == TradeType.EXACT_IN_BATCH\n        );\n\n        Trade memory trade = Trade(\n            params.tradeType,\n            sellToken,\n            buyToken,\n            amount,\n            params.oracleSlippagePercentOrLimit,\n            block.timestamp, // deadline\n            params.exchangeData\n        );\n\n        // Execute trade using the absolute slippage limit set by `oracleSlippagePercentOrLimit`\n        (amountSold, amountBought) = trade._executeTrade(params.dexId);\n    }\n\n    function getLibInfo() external pure returns (address notional, address tradingModule) {\n        notional = address(Deployments.NOTIONAL);\n        tradingModule = address(Deployments.TRADING_MODULE);\n    }\n}\n"
      },
      "contracts/vaults/common/VaultStorage.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.8.24;\n\nimport {StrategyVaultSettings, StrategyVaultState} from \"@interfaces/notional/ISingleSidedLPStrategyVault.sol\";\nimport {Constants} from \"@contracts/global/Constants.sol\";\n\n/** \n * Common vault storage slots\n */\nlibrary VaultStorage {\n    /// @notice Emitted when vault settings are updated\n    event StrategyVaultSettingsUpdated(StrategyVaultSettings settings);\n\n    /// @notice Storage slot for vault settings\n    uint256 private constant STRATEGY_VAULT_SETTINGS_SLOT = 1000001;\n    /// @notice Storage slot for vault state\n    uint256 private constant STRATEGY_VAULT_STATE_SLOT    = 1000002;\n    /// @notice Append only\n\n    /// @notice returns the storage slot that contains the vault settings\n    function _settings() private pure returns (mapping(uint256 => StrategyVaultSettings) storage store) {\n        // Assign storage slot\n        assembly { store.slot := STRATEGY_VAULT_SETTINGS_SLOT }\n    }\n\n    /// @notice returns the storage slot that contains the vault state\n    function _state() private pure returns (mapping(uint256 => StrategyVaultState) storage store) {\n        // Assign storage slot\n        assembly { store.slot := STRATEGY_VAULT_STATE_SLOT }\n    }\n\n    /// @notice returns strategy vault settings\n    /// @return vault settings\n    function getStrategyVaultSettings() internal view returns (StrategyVaultSettings memory) {\n        // Hardcode to the zero slot\n        return _settings()[0];\n    }\n\n    /// @notice writes the strategy vault settings to storage\n    /// @param settings vault settings\n    function setStrategyVaultSettings(StrategyVaultSettings memory settings) internal {\n        // Check limits\n        require(settings.maxPoolShare <= Constants.VAULT_PERCENT_BASIS);\n        require(settings.oraclePriceDeviationLimitPercent <= Constants.VAULT_PERCENT_BASIS);\n\n        mapping(uint256 => StrategyVaultSettings) storage store = _settings();\n        // Hardcode to the zero slot\n        store[0] = settings;\n\n        emit StrategyVaultSettingsUpdated(settings);\n    }\n\n    /// @notice returns the strategy vault state\n    /// @return vault state\n    function getStrategyVaultState() internal view returns (StrategyVaultState memory) {\n        // Hardcode to the zero slot\n        return _state()[0];\n    }\n\n    /// @notice writes the strategy vault state to storage\n    /// @param state vault state\n    function setStrategyVaultState(StrategyVaultState memory state) internal {\n        mapping(uint256 => StrategyVaultState) storage store = _state();\n        // Hardcode to the zero slot\n        store[0] = state;\n    }\n\n}\n"
      },
      "interfaces/notional/ISingleSidedLPStrategyVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >=0.7.6;\n\nimport {ITradingModule, Trade, TradeType} from \"../trading/ITradingModule.sol\";\nimport {IStrategyVault} from \"./IStrategyVault.sol\";\nimport {IERC20} from \"../IERC20.sol\";\n\n/// @notice Parameters for trades\nstruct TradeParams {\n    /// @notice DEX ID\n    uint16 dexId;\n    /// @notice Trade type (i.e. Single/Batch)\n    TradeType tradeType;\n    /// @notice For dynamic trades, this field specifies the slippage percentage relative to\n    /// the oracle price. For static trades, this field specifies the slippage limit amount.\n    uint256 oracleSlippagePercentOrLimit;\n    /// @notice DEX specific data\n    bytes exchangeData;\n}\n\n/// @notice Deposit trade parameters\nstruct DepositTradeParams {\n    /// @notice Amount of primary tokens to sell\n    uint256 tradeAmount;\n    /// @notice Trade parameters\n    TradeParams tradeParams;\n}\n\n/// @notice Deposit parameters\nstruct DepositParams {\n    /// @notice min pool claim for slippage control\n    uint256 minPoolClaim;\n    /// @notice DepositTradeParams or empty (single-sided entry)\n    DepositTradeParams[] depositTrades;\n}\n\n/// @notice Redeem parameters\nstruct RedeemParams {\n    /// @notice min amounts for slippage control\n    uint256[] minAmounts;\n    /// @notice Redemption trades or empty (single-sided exit)\n    TradeParams[] redemptionTrades;\n}\n\n/// @notice Single-sided reinvestment trading parameters\nstruct SingleSidedRewardTradeParams {\n    /// @notice Address of the token to sell (typically one of the reward tokens)\n    address sellToken;\n    /// @notice Address of the token to buy (typically one of the pool tokens)\n    address buyToken;\n    /// @notice Amount of tokens to sell\n    uint256 amount;\n    /// @notice Trade params\n    TradeParams tradeParams;\n}\n\n/// @notice Common strategy vault state\nstruct StrategyVaultState {\n    /// @notice Total number of pool tokens\n    uint256 totalPoolClaim;\n    /// @notice Total number of vault shares across all maturities\n    uint80 totalVaultSharesGlobal;\n    /// @notice Timestamp of previous settlement\n    uint32 lastSettlementTimestamp;\n    /// @notice Vault flags\n    uint32 flags;\n}\nstruct InitParams {\n    string name;\n    uint16 borrowCurrencyId;\n    StrategyVaultSettings settings;\n}\n\n/// @notice Common strategy vault settings\nstruct StrategyVaultSettings {\n    /// @notice Slippage limit for emergency settlement (vault owns too much of the pool)\n    uint32 deprecated_emergencySettlementSlippageLimitPercent;\n    /// @notice Max share of the pool that the vault is allowed to hold\n    uint16 maxPoolShare;\n    /// @notice Limits the amount of allowable deviation from the oracle price\n    uint16 oraclePriceDeviationLimitPercent;\n    /// @notice Slippage limit for joining/exiting pools\n    uint16 deprecated_poolSlippageLimitPercent;\n}\n\ninterface ISingleSidedLPStrategyVault {\n    /// @notice Emitted when vault settings are updated\n    event StrategyVaultSettingsUpdated(StrategyVaultSettings settings);\n    /// @notice Emitted after an emergency exit\n    event EmergencyExit(uint256 poolClaimExit, uint256[] exitBalances);\n    /// @notice Emitted when the vault is locked\n    event VaultLocked();\n    /// @notice Emitted when the vault is unlocked\n    event VaultUnlocked();\n\n    struct SingleSidedLPStrategyVaultInfo {\n        address pool;\n        uint8 singleSidedTokenIndex;\n        uint256 totalLPTokens;\n        uint256 totalVaultShares;\n        uint256 maxPoolShare;\n        uint256 oraclePriceDeviationLimitPercent;\n    }\n\n    function initialize(InitParams calldata params) external;\n    function TOKENS() external view returns (IERC20[] memory, uint8[] memory decimals);\n\n    function getStrategyVaultInfo() external view returns (SingleSidedLPStrategyVaultInfo memory);\n    function emergencyExit(uint256 claimToExit, bytes calldata data) external;\n    function restoreVault(uint256 minPoolClaim, bytes calldata data) external;\n    function isLocked() external view returns (bool);\n\n    function claimRewardTokens() external;\n    function reinvestReward(\n        SingleSidedRewardTradeParams[] calldata trades,\n        uint256 minPoolClaim\n    ) external returns (address rewardToken, uint256 amountSold, uint256 poolClaimAmount);\n\n    function tradeTokensBeforeRestore(SingleSidedRewardTradeParams[] calldata trades) external;\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = _setInitializedVersion(1);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !AddressUpgradeable.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"
      },
      "contracts/proxy/AccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                // string(\n                //     abi.encodePacked(\n                //         \"AccessControl: account \",\n                //         StringsUpgradeable.toHexString(uint160(account), 20),\n                //         \" is missing role \",\n                //         StringsUpgradeable.toHexString(uint256(role), 32)\n                //     )\n                // )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender());\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "interfaces/notional/IStrategyVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >=0.7.6;\n\ninterface IStrategyVault {\n\n    struct StrategyVaultRoles {\n        bytes32 emergencyExit;\n        bytes32 rewardReinvestment;\n        bytes32 staticSlippageTrading;\n    }\n\n    function decimals() external view returns (uint8);\n    function name() external view returns (string memory);\n    function strategy() external view returns (bytes4 strategyId);\n\n    // Tells a vault to deposit some amount of tokens from Notional and mint strategy tokens with it.\n    function depositFromNotional(\n        address account,\n        uint256 depositAmount,\n        uint256 maturity,\n        bytes calldata data\n    ) external payable returns (uint256 strategyTokensMinted);\n\n    // Tells a vault to redeem some amount of strategy tokens from Notional and transfer the resulting asset cash\n    function redeemFromNotional(\n        address account,\n        address receiver,\n        uint256 strategyTokens,\n        uint256 maturity,\n        uint256 underlyingToRepayDebt,\n        bytes calldata data\n    ) external returns (uint256 transferToReceiver);\n\n    function convertStrategyToUnderlying(\n        address account,\n        uint256 strategyTokens,\n        uint256 maturity\n    ) external view returns (int256 underlyingValue);\n\n    function getExchangeRate(uint256 maturity) external view returns (int256);\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 convertVaultSharesToPrimeMaturity(\n        address account,\n        uint256 vaultShares,\n        uint256 maturity\n    ) external returns (uint256 primeVaultShares);\n}"
      },
      "contracts/trading/TradeHandler.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport {\n    ITradingModule,\n    Trade,\n    TradeFailed,\n    DynamicTradeFailed\n} from \"@interfaces/trading/ITradingModule.sol\";\nimport { Deployments } from \"@deployments/Deployments.sol\";\nimport {nProxy} from \"../proxy/nProxy.sol\";\n\n/// @notice TradeHandler is an internal library to be compiled into StrategyVaults to interact\n/// with the TradeModule and execute trades\nlibrary TradeHandler {\n\n    /// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\n    /// a trade.\n    function _executeTradeWithDynamicSlippage(\n        Trade memory trade,\n        uint16 dexId,\n        uint32 dynamicSlippageLimit\n    ) internal returns (uint256 amountSold, uint256 amountBought) {\n        (bool success, bytes memory result) = nProxy(payable(address(Deployments.TRADING_MODULE))).getImplementation()\n            .delegatecall(abi.encodeWithSelector(\n                ITradingModule.executeTradeWithDynamicSlippage.selector,\n                dexId, trade, dynamicSlippageLimit\n            )\n        );\n        if (!success) revert DynamicTradeFailed();\n        (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\n    }\n\n    /// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\n    /// a trade.\n    function _executeTrade(\n        Trade memory trade,\n        uint16 dexId\n    ) internal returns (uint256 amountSold, uint256 amountBought) {\n        (bool success, bytes memory result) = nProxy(payable(address(Deployments.TRADING_MODULE))).getImplementation()\n            .delegatecall(abi.encodeWithSelector(ITradingModule.executeTrade.selector, dexId, trade));\n        if (!success) revert TradeFailed();\n        (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\n    }\n}\n"
      },
      "contracts/proxy/nProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\ncontract nProxy is ERC1967Proxy {\n    constructor(\n        address _logic,\n        bytes memory _data\n    ) ERC1967Proxy(_logic, _data) {}\n\n    receive() external payable override {\n        // Allow ETH transfers to succeed\n    }\n\n    function getImplementation() external view returns (address) {\n        return _getImplementation();\n    }\n}"
      },
      "lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\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"
      },
      "lib/openzeppelin-contracts/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/Proxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@interfaces/=interfaces/",
        "@contracts/=contracts/",
        "@deployments/=contracts/global/mainnet/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": false,
      "libraries": {
        "contracts/vaults/common/StrategyUtils.sol": {
          "StrategyUtils": "0xE78D09c8B6cCF9C1732d14353a708b75f6C67c67"
        }
      }
    }
  }}