creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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    /**\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 `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, 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 `from` to `to` 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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
      },
      "contracts/BulkActionsEntry.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\nimport { IBulkActionsEntry } from \"./interfaces/IBulkActionsEntry.sol\";\nimport { ICegaState } from \"./interfaces/ICegaState.sol\";\nimport { IProduct } from \"./interfaces/IProduct.sol\";\nimport { IFCNVault } from \"./interfaces/IFCNVault.sol\";\n\ncontract BulkActionsEntry is IBulkActionsEntry {\n    // IMMUTABLES\n\n    bytes32 public constant TRADER_ADMIN_ROLE = keccak256(\"TRADER_ADMIN_ROLE\");\n\n    ICegaState public immutable cegaState;\n\n    // MODIFIERS\n\n    modifier onlyTraderAdmin() {\n        require(cegaState.isTraderAdmin(msg.sender), \"403:TA\");\n        _;\n    }\n\n    // CONSTRUCTOR\n\n    constructor(address _cegaState) {\n        cegaState = ICegaState(_cegaState);\n    }\n\n    // EXTERNAL FUNCTIONS\n\n    function bulkOpenVaultDeposits(address[] calldata vaultAddresses) external onlyTraderAdmin {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).openVaultDeposits(vaultAddresses[i]);\n        }\n    }\n\n    function bulkProcessDepositQueues(ProcessQueueParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            _getProduct(params[i].vaultAddress).processDepositQueue(params[i].vaultAddress, params[i].maxProcessCount);\n        }\n    }\n\n    function bulkSetTradeData(SetTradeDataParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            _getProduct(params[i].vaultAddress).setTradeData(\n                params[i].vaultAddress,\n                params[i].tradeDate,\n                params[i].tradeExpiry,\n                params[i].aprBps,\n                params[i].tenorInDays\n            );\n        }\n    }\n\n    function bulkUpdateOptionBarriers(UpdateOptionBarrierParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            _getProduct(params[i].vaultAddress).updateOptionBarrier(\n                params[i].vaultAddress,\n                params[i].index,\n                params[i].asset,\n                params[i].strikeAbsoluteValue,\n                params[i].barrierAbsoluteValue\n            );\n        }\n    }\n\n    function bulkSendAssetsToTrade(SendAssetsToTradeParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            _getProduct(params[i].vaultAddress).sendAssetsToTrade(\n                params[i].vaultAddress,\n                params[i].receiver,\n                params[i].amount\n            );\n        }\n    }\n\n    function bulkCheckBarriers(address[] calldata vaultAddresses) external {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).checkBarriers(vaultAddresses[i]);\n        }\n    }\n\n    function bulkCalculateCurrentYield(address[] calldata vaultAddresses) external {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).calculateCurrentYield(vaultAddresses[i]);\n        }\n    }\n\n    function bulkCalculateVaultFinalPayoffs(address[] calldata vaultAddresses) external {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).calculateVaultFinalPayoff(vaultAddresses[i]);\n        }\n    }\n\n    function bulkMoveAssetsToProducts(MoveAssetsToProductParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            cegaState.moveAssetsToProduct(params[i].productName, params[i].vaultAddress, params[i].amount);\n        }\n    }\n\n    function bulkCollectFees(address[] calldata vaultAddresses) external onlyTraderAdmin {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).collectFees(vaultAddresses[i]);\n        }\n    }\n\n    function bulkProcessWithdrawalQueues(ProcessQueueParams[] calldata params) external onlyTraderAdmin {\n        for (uint256 i = 0; i < params.length; i++) {\n            _getProduct(params[i].vaultAddress).processWithdrawalQueue(\n                params[i].vaultAddress,\n                params[i].maxProcessCount\n            );\n        }\n    }\n\n    function bulkRolloverVaults(address[] calldata vaultAddresses) external onlyTraderAdmin {\n        for (uint256 i = 0; i < vaultAddresses.length; i++) {\n            _getProduct(vaultAddresses[i]).rolloverVault(vaultAddresses[i]);\n        }\n    }\n\n    // INTERNAL FUNCTIONS\n\n    function _getProduct(address vaultAddress) internal view returns (IProduct) {\n        return IProduct(IFCNVault(vaultAddress).fcnProduct());\n    }\n}\n"
      },
      "contracts/interfaces/IBulkActionsEntry.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\ninterface IBulkActionsEntry {\n    // STRUCTS\n\n    struct ProcessQueueParams {\n        address vaultAddress;\n        uint256 maxProcessCount;\n    }\n\n    struct SetTradeDataParams {\n        address vaultAddress;\n        uint256 tradeDate;\n        uint256 tradeExpiry;\n        uint256 aprBps;\n        uint256 tenorInDays;\n    }\n\n    struct UpdateOptionBarrierParams {\n        address vaultAddress;\n        uint256 index;\n        string asset;\n        uint256 strikeAbsoluteValue;\n        uint256 barrierAbsoluteValue;\n    }\n\n    struct SendAssetsToTradeParams {\n        address vaultAddress;\n        address receiver;\n        uint256 amount;\n    }\n\n    struct MoveAssetsToProductParams {\n        string productName;\n        address vaultAddress;\n        uint256 amount;\n    }\n\n    // FUNCTIONS\n\n    function bulkOpenVaultDeposits(address[] calldata vaultAddresses) external;\n\n    function bulkProcessDepositQueues(ProcessQueueParams[] calldata params) external;\n\n    function bulkSetTradeData(SetTradeDataParams[] calldata params) external;\n\n    function bulkUpdateOptionBarriers(UpdateOptionBarrierParams[] calldata params) external;\n\n    function bulkSendAssetsToTrade(SendAssetsToTradeParams[] calldata params) external;\n\n    function bulkCheckBarriers(address[] calldata vaultAddresses) external;\n\n    function bulkCalculateCurrentYield(address[] calldata vaultAddresses) external;\n\n    function bulkCalculateVaultFinalPayoffs(address[] calldata vaultAddresses) external;\n\n    function bulkMoveAssetsToProducts(MoveAssetsToProductParams[] calldata params) external;\n\n    function bulkCollectFees(address[] calldata vaultAddresses) external;\n\n    function bulkProcessWithdrawalQueues(ProcessQueueParams[] calldata params) external;\n\n    function bulkRolloverVaults(address[] calldata vaultAddresses) external;\n}\n"
      },
      "contracts/interfaces/ICegaState.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\ninterface ICegaState {\n    function marketMakerAllowList(address marketMaker) external view returns (bool);\n\n    function products(string memory productName) external view returns (address);\n\n    function oracleAddresses(string memory oracleName) external view returns (address);\n\n    function oracleNames() external view returns (string[] memory);\n\n    function productNames() external view returns (string[] memory);\n\n    function feeRecipient() external view returns (address);\n\n    function isDefaultAdmin(address sender) external view returns (bool);\n\n    function isTraderAdmin(address sender) external view returns (bool);\n\n    function isOperatorAdmin(address sender) external view returns (bool);\n\n    function isServiceAdmin(address sender) external view returns (bool);\n\n    function getOracleNames() external view returns (string[] memory);\n\n    function addOracle(string memory oracleName, address oracleAddress) external;\n\n    function removeOracle(string memory oracleName) external;\n\n    function getProductNames() external view returns (string[] memory);\n\n    function addProduct(string memory productName, address product) external;\n\n    function removeProduct(string memory productName) external;\n\n    function updateMarketMakerPermission(address marketMaker, bool allow) external;\n\n    function setFeeRecipient(address _feeRecipient) external;\n\n    function moveAssetsToProduct(string memory productName, address vaultAddress, uint256 amount) external;\n}\n"
      },
      "contracts/interfaces/IFCNVault.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\n\ninterface IFCNVault is IERC20 {\n    function asset() external view returns (address);\n\n    function owner() external view returns (address);\n\n    function fcnProduct() external view returns (address);\n\n    function totalAssets() external view returns (uint256);\n\n    function convertToAssets(uint256 shares) external view returns (uint256);\n\n    function convertToShares(uint256 assets) external view returns (uint256);\n\n    function deposit(uint256 assets, address receiver) external returns (uint256);\n\n    function redeem(uint256 shares) external returns (uint256);\n}\n"
      },
      "contracts/interfaces/IProduct.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\nimport { Deposit, FCNVaultMetadata, OptionBarrierType, OptionBarrier, VaultStatus, Withdrawal } from \"../Structs.sol\";\n\ninterface IProduct {\n    // View functions\n    function asset() external view returns (address);\n\n    function cegaState() external view returns (address);\n\n    function getVaultMetadata(address vaultAddress) external view returns (FCNVaultMetadata memory);\n\n    function managementFeeBps() external view returns (uint256);\n\n    function minDepositAmount() external view returns (uint256);\n\n    function minWithdrawalAmount() external view returns (uint256);\n\n    function name() external view returns (string memory);\n\n    function vaults(\n        address vaultAddress\n    )\n        external\n        view\n        returns (\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            address,\n            VaultStatus,\n            bool\n        );\n\n    function withdrawalQueues(address vaultAddress, uint256 index) external view returns (Withdrawal memory);\n\n    function yieldFeeBps() external view returns (uint256);\n\n    // External functions\n\n    function addOptionBarrier(address vaultAddress, OptionBarrier calldata optionBarrier) external;\n\n    function addToWithdrawalQueue(address vaultAddress, uint256 amountShares, address receiver) external;\n\n    function calculateCurrentYield(address vaultAddress) external;\n\n    function calculateVaultFinalPayoff(address vaultAddress) external returns (uint256 vaultFinalPayoff);\n\n    function checkBarriers(address vaultAddress) external;\n\n    function collectFees(address vaultAddress) external;\n\n    function openVaultDeposits(address vaultAddress) external;\n\n    function processDepositQueue(address vaultAddress, uint256 maxProcessCount) external;\n\n    function processWithdrawalQueue(address vaultAddress, uint256 maxProcessCount) external;\n\n    function receiveAssetsFromCegaState(address vaultAddress, uint256 amount) external;\n\n    function removeOptionBarrier(address vaultAddress, uint256 index, string calldata _asset) external;\n\n    function removeVault(uint256 index) external;\n\n    function rolloverVault(address vaultAddress) external;\n\n    function sendAssetsToTrade(address vaultAddress, address receiver, uint256 amount) external;\n\n    function setIsDepositQueueOpen(bool _isDepositQueueOpen) external;\n\n    function setKnockInStatus(address vaultAddress, bool newState) external;\n\n    function setManagementFeeBps(uint256 _managementFeeBps) external;\n\n    function setMaxDepositAmountLimit(uint256 _maxDepositAmountLimit) external;\n\n    function setMinDepositAmount(uint256 _minDepositAmount) external;\n\n    function setMinWithdrawalAmount(uint256 _minWithdrawalAmount) external;\n\n    function setTradeData(\n        address vaultAddress,\n        uint256 _tradeDate,\n        uint256 _tradeExpiry,\n        uint256 _aprBps,\n        uint256 _tenorInDays\n    ) external;\n\n    function setVaultMetadata(address vaultAddress, FCNVaultMetadata calldata metadata) external;\n\n    function setVaultStatus(address vaultAddress, VaultStatus _vaultStatus) external;\n\n    function setYieldFeeBps(uint256 _yieldFeeBps) external;\n\n    function updateOptionBarrier(\n        address vaultAddress,\n        uint256 index,\n        string calldata _asset,\n        uint256 _strikeAbsoluteValue,\n        uint256 _barrierAbsoluteValue\n    ) external;\n\n    function updateOptionBarrierOracle(\n        address vaultAddress,\n        uint256 index,\n        string calldata _asset,\n        string memory newOracleName\n    ) external;\n}\n"
      },
      "contracts/Structs.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.17;\n\nenum OptionBarrierType {\n    None,\n    KnockIn\n}\n\nstruct Deposit {\n    uint256 amount;\n    address receiver;\n}\n\nstruct Withdrawal {\n    uint256 amountShares;\n    address receiver;\n}\n\nenum VaultStatus {\n    DepositsClosed,\n    DepositsOpen,\n    NotTraded,\n    Traded,\n    TradeExpired,\n    PayoffCalculated,\n    FeesCollected,\n    WithdrawalQueueProcessed,\n    Zombie\n}\n\nstruct OptionBarrier {\n    uint256 barrierBps;\n    uint256 barrierAbsoluteValue;\n    uint256 strikeBps;\n    uint256 strikeAbsoluteValue;\n    string asset;\n    string oracleName;\n    OptionBarrierType barrierType;\n}\n\nstruct FCNVaultMetadata {\n    uint256 vaultStart;\n    uint256 tradeDate;\n    uint256 tradeExpiry;\n    uint256 aprBps;\n    uint256 tenorInDays;\n    uint256 underlyingAmount; // This is how many assets were ever deposited into the vault\n    uint256 currentAssetAmount; // This is how many assets are currently allocated for the vault (not sent for trade)\n    uint256 totalCouponPayoff;\n    uint256 vaultFinalPayoff;\n    uint256 queuedWithdrawalsSharesAmount;\n    uint256 queuedWithdrawalsCount;\n    uint256 optionBarriersCount;\n    uint256 leverage;\n    address vaultAddress;\n    VaultStatus vaultStatus;\n    bool isKnockedIn;\n    OptionBarrier[] optionBarriers;\n}\n\nstruct RoundData {\n    int256 answer;\n    uint256 startedAt;\n    uint256 updatedAt;\n    uint80 answeredInRound;\n}\n\nstruct LeverageMetadata {\n    bool isAllowed;\n    bool isDepositQueueOpen;\n    uint256 maxDepositAmountLimit;\n    uint256 sumVaultUnderlyingAmounts;\n    uint256 queuedDepositsTotalAmount;\n    address[] vaultAddresses;\n}\n\nstruct FCNVaultAssetInfo {\n    address vaultAddress;\n    uint256 totalAssets;\n    uint256 totalSupply;\n    uint256 inputAssets;\n    uint256 outputShares;\n    uint256 inputShares;\n    uint256 outputAssets;\n}\n"
      }
    },
    "settings": {
      "metadata": {
        "bytecodeHash": "none"
      },
      "optimizer": {
        "enabled": true,
        "runs": 200,
        "details": {
          "yul": true
        }
      },
      "viaIR": true,
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}