creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/v2/AeraVaultHooks.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/IERC20.sol\";\nimport \"@openzeppelin/ERC165.sol\";\nimport \"@openzeppelin/SafeERC20.sol\";\nimport \"@openzeppelin/IERC20IncreaseAllowance.sol\";\nimport \"./interfaces/IHooks.sol\";\nimport \"./interfaces/IAeraVaultHooksEvents.sol\";\nimport \"./interfaces/IVault.sol\";\nimport \"./Sweepable.sol\";\nimport \"./TargetSighashLib.sol\";\nimport \"./Types.sol\";\nimport {ONE} from \"./Constants.sol\";\n\n/// @title AeraVaultHooks\n/// @notice Default hooks contract which implements several safeguards.\n/// @dev Connected vault MUST only call submit with tokens that can increase allowances with approve and increaseAllowance.\ncontract AeraVaultHooks is IHooks, IAeraVaultHooksEvents, Sweepable, ERC165 {\n    using SafeERC20 for IERC20;\n\n    /// @notice Min bound on minimum fraction of vault value that the vault has to retain\n    ///         between submissions during a single day.\n    /// @dev    Loose bound to mitigate initialization error.\n    uint256 private constant _LOWEST_MIN_DAILY_VALUE = ONE / 2;\n\n    /// @notice The minimum fraction of vault value that the vault has to\n    ///         retain per day during submit transactions.\n    ///         e.g. 0.9 (in 18-decimal form) allows the vault to lose up to\n    ///         10% in value across consecutive submissions.\n    uint256 public immutable minDailyValue;\n\n    /// STORAGE ///\n\n    /// @notice The address of the vault.\n    address public vault;\n\n    /// @notice Current day (UTC).\n    uint256 public currentDay;\n\n    /// @notice Accumulated value multiplier during submit transactions.\n    uint256 public cumulativeDailyMultiplier;\n\n    /// @notice Allowed target contract and sighash combinations.\n    mapping(TargetSighash => bool) internal _targetSighashAllowed;\n\n    /// @notice Total value of assets in vault before submission.\n    /// @dev Assigned in `beforeSubmit` and used in `afterSubmit`.\n    uint256 internal _beforeValue;\n\n    /// ERRORS ///\n\n    error Aera__CallerIsNotVault();\n    error Aera__VaultIsZeroAddress();\n    error Aera__HooksOwnerIsGuardian();\n    error Aera__HooksOwnerIsVault();\n    error Aera__MinDailyValueTooLow();\n    error Aera__MinDailyValueIsNotLessThanOne();\n    error Aera__NoCodeAtTarget(address target);\n    error Aera__CallIsNotAllowed(Operation operation);\n    error Aera__VaultValueBelowMinDailyValue();\n    error Aera__AllowanceIsNotZero(address asset, address spender);\n    error Aera__HooksInitialOwnerIsZeroAddress();\n    error Aera__RemovingNonexistentTargetSighash(TargetSighash targetSighash);\n    error Aera__AddingDuplicateTargetSighash(TargetSighash targetSighash);\n\n    /// MODIFIERS ///\n\n    /// @dev Throws if called by any account other than the vault.\n    modifier onlyVault() {\n        if (msg.sender != vault) {\n            revert Aera__CallerIsNotVault();\n        }\n        _;\n    }\n\n    /// FUNCTIONS ///\n\n    /// @param owner_ Initial owner address.\n    /// @param vault_ Vault address.\n    /// @param minDailyValue_ The minimum fraction of value that the vault has to retain\n    ///                       during the day in the course of submissions.\n    /// @param targetSighashAllowlist Array of target contract and sighash combinations to allow.\n    constructor(\n        address owner_,\n        address vault_,\n        uint256 minDailyValue_,\n        TargetSighashData[] memory targetSighashAllowlist\n    ) Ownable() {\n        // Requirements: validate vault.\n        if (vault_ == address(0)) {\n            revert Aera__VaultIsZeroAddress();\n        }\n        if (owner_ == address(0)) {\n            revert Aera__HooksInitialOwnerIsZeroAddress();\n        }\n\n        // Requirements: check that hooks initial owner is disaffiliated.\n        if (owner_ == vault_) {\n            revert Aera__HooksOwnerIsVault();\n        }\n        // Only check vault if it has been deployed already.\n        // This will happen if we are deploying a new Hooks contract for an existing vault.\n        if (vault_.code.length > 0) {\n            address guardian = IVault(vault_).guardian();\n            if (owner_ == guardian) {\n                revert Aera__HooksOwnerIsGuardian();\n            }\n        }\n\n        // Requirements: check that minimum daily value doesn't mandate vault growth.\n        if (minDailyValue_ >= ONE) {\n            revert Aera__MinDailyValueIsNotLessThanOne();\n        }\n\n        // Requirements: check that minimum daily value enforces a lower bound.\n        if (minDailyValue_ < _LOWEST_MIN_DAILY_VALUE) {\n            revert Aera__MinDailyValueTooLow();\n        }\n\n        uint256 numTargetSighashAllowlist = targetSighashAllowlist.length;\n\n        // Effects: initialize target sighash allowlist.\n        for (uint256 i = 0; i < numTargetSighashAllowlist;) {\n            _addTargetSighash(\n                targetSighashAllowlist[i].target,\n                targetSighashAllowlist[i].selector\n            );\n\n            unchecked {\n                i++; // gas savings\n            }\n        }\n\n        // Effects: initialize state variables.\n        vault = vault_;\n        minDailyValue = minDailyValue_;\n        currentDay = block.timestamp / 1 days;\n        cumulativeDailyMultiplier = ONE;\n\n        // Effects: set new owner.\n        _transferOwnership(owner_);\n    }\n\n    /// @notice Add targetSighash pair to allowlist.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    function addTargetSighash(\n        address target,\n        bytes4 selector\n    ) external onlyOwner {\n        _addTargetSighash(target, selector);\n    }\n\n    /// @notice Remove targetSighash pair from allowlist.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    function removeTargetSighash(\n        address target,\n        bytes4 selector\n    ) external onlyOwner {\n        TargetSighash targetSighash =\n            TargetSighashLib.toTargetSighash(target, selector);\n\n        // Requirements: check that current target sighash is set.\n        if (!_targetSighashAllowed[targetSighash]) {\n            revert Aera__RemovingNonexistentTargetSighash(targetSighash);\n        }\n\n        // Effects: remove target sighash combination from the allowlist.\n        delete _targetSighashAllowed[targetSighash];\n\n        // Log the removal.\n        emit TargetSighashRemoved(target, selector);\n    }\n\n    /// @inheritdoc IHooks\n    function beforeDeposit(AssetValue[] memory amounts)\n        external\n        override\n        onlyVault\n    {}\n\n    /// @inheritdoc IHooks\n    function afterDeposit(AssetValue[] memory amounts)\n        external\n        override\n        onlyVault\n    {}\n\n    /// @inheritdoc IHooks\n    function beforeWithdraw(AssetValue[] memory amounts)\n        external\n        override\n        onlyVault\n    {}\n\n    /// @inheritdoc IHooks\n    function afterWithdraw(AssetValue[] memory amounts)\n        external\n        override\n        onlyVault\n    {}\n\n    /// @inheritdoc IHooks\n    function beforeSubmit(Operation[] calldata operations)\n        external\n        override\n        onlyVault\n    {\n        uint256 numOperations = operations.length;\n        bytes4 selector;\n\n        // Requirements: validate that all operations are allowed.\n        for (uint256 i = 0; i < numOperations;) {\n            selector = bytes4(operations[i].data[0:4]);\n\n            TargetSighash sigHash = TargetSighashLib.toTargetSighash(\n                operations[i].target, selector\n            );\n\n            // Requirements: validate that the target sighash combination is allowed.\n            if (!_targetSighashAllowed[sigHash]) {\n                revert Aera__CallIsNotAllowed(operations[i]);\n            }\n\n            unchecked {\n                i++;\n            } // gas savings\n        }\n\n        // Effects: remember current vault value and ETH balance for use in afterSubmit.\n        _beforeValue = IVault(vault).value();\n    }\n\n    /// @inheritdoc IHooks\n    function afterSubmit(Operation[] calldata operations)\n        external\n        override\n        onlyVault\n    {\n        uint256 newMultiplier;\n        uint256 currentMultiplier = cumulativeDailyMultiplier;\n        uint256 day = block.timestamp / 1 days;\n\n        if (_beforeValue > 0) {\n            // Initialize new cumulative multiplier with the current submit multiplier.\n            newMultiplier = currentDay == day ? currentMultiplier : ONE;\n            newMultiplier =\n                (newMultiplier * IVault(vault).value()) / _beforeValue;\n\n            // Requirements: check that daily execution loss is within bounds.\n            if (newMultiplier < minDailyValue) {\n                revert Aera__VaultValueBelowMinDailyValue();\n            }\n\n            // Effects: update the daily multiplier.\n            if (currentMultiplier != newMultiplier) {\n                cumulativeDailyMultiplier = newMultiplier;\n            }\n        }\n\n        // Effects: reset current day for the next submission.\n        if (currentDay != day) {\n            currentDay = day;\n        }\n\n        // Effects: reset prior vault value for the next submission.\n        _beforeValue = 0;\n\n        uint256 numOperations = operations.length;\n        bytes4 selector;\n        address spender;\n        uint256 amount;\n        IERC20 token;\n\n        // Requirements: check that there are no outgoing allowances that were introduced.\n        for (uint256 i = 0; i < numOperations;) {\n            selector = bytes4(operations[i].data[0:4]);\n            if (_isAllowanceSelector(selector)) {\n                // Extract spender and amount from the allowance transaction.\n                (spender, amount) =\n                    abi.decode(operations[i].data[4:], (address, uint256));\n\n                // If amount is 0 then allowance hasn't been increased.\n                if (amount == 0) {\n                    unchecked {\n                        i++;\n                    } // gas savings\n                    continue;\n                }\n\n                token = IERC20(operations[i].target);\n\n                // Requirements: check that the current outgoing allowance for this token is zero.\n                if (token.allowance(vault, spender) > 0) {\n                    revert Aera__AllowanceIsNotZero(address(token), spender);\n                }\n            }\n            unchecked {\n                i++;\n            } // gas savings\n        }\n    }\n\n    /// @inheritdoc IHooks\n    function beforeFinalize() external override onlyVault {}\n\n    /// @inheritdoc IHooks\n    function afterFinalize() external override onlyVault {\n        // Effects: release storage\n        currentDay = 0;\n        cumulativeDailyMultiplier = 0;\n    }\n\n    /// @inheritdoc IHooks\n    function decommission() external override onlyVault {\n        // Effects: reset vault address.\n        vault = address(0);\n\n        // Effects: release storage\n        currentDay = 0;\n        cumulativeDailyMultiplier = 0;\n\n        // Log decommissioning.\n        emit Decommissioned();\n    }\n\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId)\n        public\n        view\n        override\n        returns (bool)\n    {\n        return interfaceId == type(IHooks).interfaceId\n            || super.supportsInterface(interfaceId);\n    }\n\n    /// @notice Check whether target and sighash combination is allowed.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    function targetSighashAllowed(\n        address target,\n        bytes4 selector\n    ) external view returns (bool) {\n        return _targetSighashAllowed[TargetSighashLib.toTargetSighash(\n            target, selector\n        )];\n    }\n\n    /// INTERNAL FUNCTIONS ///\n\n    /// @notice Add targetSighash pair to allowlist.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    function _addTargetSighash(address target, bytes4 selector) internal {\n        // Requirements: check there is code at target.\n        if (target.code.length == 0) {\n            revert Aera__NoCodeAtTarget(target);\n        }\n\n        TargetSighash targetSighash =\n            TargetSighashLib.toTargetSighash(target, selector);\n\n        // Requirements: check that current target sighash is not set.\n        if (_targetSighashAllowed[targetSighash]) {\n            revert Aera__AddingDuplicateTargetSighash(targetSighash);\n        }\n\n        // Effects: add target sighash combination to the allowlist.\n        _targetSighashAllowed[targetSighash] = true;\n\n        // Log the addition.\n        emit TargetSighashAdded(target, selector);\n    }\n\n    /// @notice Check whether selector is allowance related selector or not.\n    /// @param selector Selector of calldata to check.\n    /// @return isAllowanceSelector True if selector is allowance related selector.\n    function _isAllowanceSelector(bytes4 selector)\n        internal\n        pure\n        returns (bool isAllowanceSelector)\n    {\n        return selector == IERC20.approve.selector\n            || selector == IERC20IncreaseAllowance.increaseAllowance.selector;\n    }\n\n    /// @notice Check that owner is not the vault or the guardian.\n    /// @param owner_ Hooks owner address.\n    /// @param vault_ Vault address.\n    function _checkHooksOwner(address owner_, address vault_) internal view {\n        if (owner_ == vault_) {\n            revert Aera__HooksOwnerIsVault();\n        }\n\n        address guardian = IVault(vault_).guardian();\n        if (owner_ == guardian) {\n            revert Aera__HooksOwnerIsGuardian();\n        }\n    }\n\n    /// @inheritdoc Ownable2Step\n    function transferOwnership(address newOwner) public override onlyOwner {\n        // Requirements: check that new owner is disaffiliated from existing roles.\n        _checkHooksOwner(newOwner, vault);\n\n        // Effects: initiate ownership transfer.\n        super.transferOwnership(newOwner);\n    }\n}\n"
      },
      "src/v2/dependencies/openzeppelin/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP.\r\n */\r\ninterface IERC20 {\r\n    /**\r\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n     * another (`to`).\r\n     *\r\n     * Note that `value` may be zero.\r\n     */\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n    /**\r\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n     * a call to {approve}. `value` is the new allowance.\r\n     */\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n\r\n    /**\r\n     * @dev Returns the amount of tokens in existence.\r\n     */\r\n    function totalSupply() external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Returns the amount of tokens owned by `account`.\r\n     */\r\n    function balanceOf(address account) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from the caller's account to `to`.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function transfer(address to, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Returns the remaining number of tokens that `spender` will be\r\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\r\n     * zero by default.\r\n     *\r\n     * This value changes when {approve} or {transferFrom} are called.\r\n     */\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n     * that someone may use both the old and the new allowance by unfortunate\r\n     * transaction ordering. One possible solution to mitigate this race\r\n     * condition is to first reduce the spender's allowance to 0 and set the\r\n     * desired value afterwards:\r\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n     *\r\n     * Emits an {Approval} event.\r\n     */\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from `from` to `to` using the\r\n     * allowance mechanism. `amount` is then deducted from the caller's\r\n     * allowance.\r\n     *\r\n     * Returns a boolean value indicating whether the operation succeeded.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\r\n}\r\n"
      },
      "src/v2/dependencies/openzeppelin/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./IERC165.sol\";\r\n\r\n/**\r\n * @dev Implementation of the {IERC165} interface.\r\n *\r\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\r\n * for the additional interface id that will be supported. For example:\r\n *\r\n * ```solidity\r\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\r\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\r\n * }\r\n * ```\r\n *\r\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\r\n */\r\nabstract contract ERC165 is IERC165 {\r\n    /**\r\n     * @dev See {IERC165-supportsInterface}.\r\n     */\r\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\r\n        return interfaceId == type(IERC165).interfaceId;\r\n    }\r\n}\r\n"
      },
      "src/v2/dependencies/openzeppelin/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./IERC20.sol\";\r\nimport \"./IERC20Permit.sol\";\r\nimport \"./Address.sol\";\r\n\r\n/**\r\n * @title SafeERC20\r\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\r\n * contract returns false). Tokens that return no value (and instead revert or\r\n * throw on failure) are also supported, non-reverting calls are assumed to be\r\n * successful.\r\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\r\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\r\n */\r\nlibrary SafeERC20 {\r\n    using Address for address;\r\n\r\n    /**\r\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\r\n     * non-reverting calls are assumed to be successful.\r\n     */\r\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\r\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\r\n    }\r\n\r\n    /**\r\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\r\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\r\n     */\r\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\r\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\r\n    }\r\n\r\n    /**\r\n     * @dev Deprecated. This function has issues similar to the ones found in\r\n     * {IERC20-approve}, and its usage is discouraged.\r\n     *\r\n     * Whenever possible, use {safeIncreaseAllowance} and\r\n     * {safeDecreaseAllowance} instead.\r\n     */\r\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\r\n        // safeApprove should only be called when setting an initial allowance,\r\n        // or when resetting it to zero. To increase and decrease it, use\r\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\r\n        require(\r\n            (value == 0) || (token.allowance(address(this), spender) == 0),\r\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\r\n        );\r\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\r\n    }\r\n\r\n    /**\r\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\r\n     * non-reverting calls are assumed to be successful.\r\n     */\r\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n        uint256 oldAllowance = token.allowance(address(this), spender);\r\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\r\n    }\r\n\r\n    /**\r\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\r\n     * non-reverting calls are assumed to be successful.\r\n     */\r\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\r\n        unchecked {\r\n            uint256 oldAllowance = token.allowance(address(this), spender);\r\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\r\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\r\n     * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\r\n     * 0 before setting it to a non-zero value.\r\n     */\r\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\r\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\r\n\r\n        if (!_callOptionalReturnBool(token, approvalCall)) {\r\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\r\n            _callOptionalReturn(token, approvalCall);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\r\n     * Revert on invalid signature.\r\n     */\r\n    function safePermit(\r\n        IERC20Permit token,\r\n        address owner,\r\n        address spender,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) internal {\r\n        uint256 nonceBefore = token.nonces(owner);\r\n        token.permit(owner, spender, value, deadline, v, r, s);\r\n        uint256 nonceAfter = token.nonces(owner);\r\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\r\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\r\n     * @param token The token targeted by the call.\r\n     * @param data The call data (encoded using abi.encode or one of its variants).\r\n     */\r\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\r\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\r\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\r\n        // the target address contains contract code and also asserts for success in the low-level call.\r\n\r\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\r\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\r\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\r\n     * @param token The token targeted by the call.\r\n     * @param data The call data (encoded using abi.encode or one of its variants).\r\n     *\r\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\r\n     */\r\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\r\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\r\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\r\n        // and not revert is the subcall reverts.\r\n\r\n        (bool success, bytes memory returndata) = address(token).call(data);\r\n        return\r\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\r\n    }\r\n}\r\n"
      },
      "src/v2/dependencies/openzeppelin/IERC20IncreaseAllowance.sol": {
        "content": "pragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev ERC20 but not IERC20 defines increaseAllowance\r\n */\r\ninterface IERC20IncreaseAllowance {\r\n    /** \r\n     *  Atomically increases the allowance granted to spender by the caller. \r\n     *  This is an alternative to approve that can be used as a mitigation for \r\n     *  problems described in IERC20.approve. \r\n     *  Emits an Approval event indicating the updated allowance.\r\n     *  Requirements: \r\n     *  spender cannot be the zero address.\r\n     */ \r\n    function increaseAllowance(address spender, uint256 amount) external returns (bool);\r\n\r\n}\r\n"
      },
      "src/v2/interfaces/IHooks.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport {AssetValue, Operation} from \"../Types.sol\";\n\n/// @title IHooks\n/// @notice Interface for the hooks module.\ninterface IHooks {\n    /// @notice Get address of vault.\n    /// @return vault Vault address.\n    function vault() external view returns (address vault);\n\n    /// @notice Hook that runs before deposit.\n    /// @param amounts Struct details for assets and amounts to deposit.\n    /// @dev MUST revert if not called by vault.\n    function beforeDeposit(AssetValue[] memory amounts) external;\n\n    /// @notice Hook that runs after deposit.\n    /// @param amounts Struct details for assets and amounts to deposit.\n    /// @dev MUST revert if not called by vault.\n    function afterDeposit(AssetValue[] memory amounts) external;\n\n    /// @notice Hook that runs before withdraw.\n    /// @param amounts Struct details for assets and amounts to withdraw.\n    /// @dev MUST revert if not called by vault.\n    function beforeWithdraw(AssetValue[] memory amounts) external;\n\n    /// @notice Hook that runs after withdraw.\n    /// @param amounts Struct details for assets and amounts to withdraw.\n    /// @dev MUST revert if not called by vault.\n    function afterWithdraw(AssetValue[] memory amounts) external;\n\n    /// @notice Hook that runs before submit.\n    /// @param operations Array of struct details for target and calldata to submit.\n    /// @dev MUST revert if not called by vault.\n    function beforeSubmit(Operation[] memory operations) external;\n\n    /// @notice Hook that runs after submit.\n    /// @param operations Array of struct details for target and calldata to submit.\n    /// @dev MUST revert if not called by vault.\n    function afterSubmit(Operation[] memory operations) external;\n\n    /// @notice Hook that runs before finalize.\n    /// @dev MUST revert if not called by vault.\n    function beforeFinalize() external;\n\n    /// @notice Hook that runs after finalize.\n    /// @dev MUST revert if not called by vault.\n    function afterFinalize() external;\n\n    /// @notice Take hooks out of use.\n    function decommission() external;\n}\n"
      },
      "src/v2/interfaces/IAeraVaultHooksEvents.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport {TargetSighash} from \"../Types.sol\";\n\n/// @title Events emitted by AeraVaultHooks implementation.\ninterface IAeraVaultHooksEvents {\n    /// @notice Emitted when targetSighash is added to allowlist.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    event TargetSighashAdded(address indexed target, bytes4 indexed selector);\n\n    /// @notice Emitted when targetSighash is removed from allowlist.\n    /// @param target Address of target.\n    /// @param selector Selector of function.\n    event TargetSighashRemoved(\n        address indexed target, bytes4 indexed selector\n    );\n\n    /// @notice Emitted when hooks contract is decommissioned.\n    event Decommissioned();\n}\n"
      },
      "src/v2/interfaces/IVault.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/IERC20.sol\";\nimport \"./IAssetRegistry.sol\";\nimport \"./IVaultEvents.sol\";\nimport \"./IHooks.sol\";\n\n/// @title IVault\n/// @notice Interface for the vault.\n/// @dev Any implementation MUST also implement Ownable2Step.\ninterface IVault is IVaultEvents {\n    /// ERRORS ///\n\n    error Aera__AssetRegistryIsZeroAddress();\n    error Aera__AssetRegistryIsNotValid(address assetRegistry);\n    error Aera__AssetRegistryHasInvalidVault();\n    error Aera__HooksIsZeroAddress();\n    error Aera__HooksIsNotValid(address hooks);\n    error Aera__HooksHasInvalidVault();\n    error Aera__GuardianIsZeroAddress();\n    error Aera__GuardianIsOwner();\n    error Aera__InitialOwnerIsZeroAddress();\n    error Aera__FeeRecipientIsZeroAddress();\n    error Aera__ExecuteTargetIsHooksAddress();\n    error Aera__ExecuteTargetIsVaultAddress();\n    error Aera__SubmitTransfersAssetFromOwner();\n    error Aera__SubmitRedeemERC4626AssetFromOwner();\n    error Aera__SubmitTargetIsVaultAddress();\n    error Aera__SubmitTargetIsHooksAddress(uint256 index);\n    error Aera__FeeRecipientIsOwner();\n    error Aera__FeeIsAboveMax(uint256 actual, uint256 max);\n    error Aera__CallerIsNotOwnerAndGuardian();\n    error Aera__CallerIsNotGuardian();\n    error Aera__AssetIsNotRegistered(IERC20 asset);\n    error Aera__AmountExceedsAvailable(\n        IERC20 asset, uint256 amount, uint256 available\n    );\n    error Aera__ExecutionFailed(bytes result);\n    error Aera__VaultIsFinalized();\n    error Aera__SubmissionFailed(uint256 index, bytes result);\n    error Aera__CannotUseReservedFees();\n    error Aera__SpotPricesReverted();\n    error Aera__AmountsOrderIsIncorrect(uint256 index);\n    error Aera__NoAvailableFeesForCaller(address caller);\n    error Aera__NoClaimableFeesForCaller(address caller);\n    error Aera__NotWrappedNativeTokenContract();\n    error Aera__CannotRenounceOwnership();\n\n    /// FUNCTIONS ///\n\n    /// @notice Deposit assets.\n    /// @param amounts Assets and amounts to deposit.\n    /// @dev MUST revert if not called by owner.\n    function deposit(AssetValue[] memory amounts) external;\n\n    /// @notice Withdraw assets.\n    /// @param amounts Assets and amounts to withdraw.\n    /// @dev MUST revert if not called by owner.\n    function withdraw(AssetValue[] memory amounts) external;\n\n    /// @notice Set current guardian and fee recipient.\n    /// @param guardian New guardian address.\n    /// @param feeRecipient New fee recipient address.\n    /// @dev MUST revert if not called by owner.\n    function setGuardianAndFeeRecipient(\n        address guardian,\n        address feeRecipient\n    ) external;\n\n    /// @notice Sets the current hooks module.\n    /// @param hooks New hooks module address.\n    /// @dev MUST revert if not called by owner.\n    function setHooks(address hooks) external;\n\n    /// @notice Execute a transaction via the vault.\n    /// @dev Execution still should work when vault is finalized.\n    /// @param operation Struct details for target and calldata to execute.\n    /// @dev MUST revert if not called by owner.\n    function execute(Operation memory operation) external;\n\n    /// @notice Terminate the vault and return all funds to owner.\n    /// @dev MUST revert if not called by owner.\n    function finalize() external;\n\n    /// @notice Stops the guardian from submission and halts fee accrual.\n    /// @dev MUST revert if not called by owner or guardian.\n    function pause() external;\n\n    /// @notice Resume fee accrual and guardian submissions.\n    /// @dev MUST revert if not called by owner.\n    function resume() external;\n\n    /// @notice Submit a series of transactions for execution via the vault.\n    /// @param operations Sequence of operations to execute.\n    /// @dev MUST revert if not called by guardian.\n    function submit(Operation[] memory operations) external;\n\n    /// @notice Claim fees on behalf of a current or previous fee recipient.\n    function claim() external;\n\n    /// @notice Get the current guardian.\n    /// @return guardian Address of guardian.\n    function guardian() external view returns (address guardian);\n\n    /// @notice Get the current fee recipient.\n    /// @return feeRecipient Address of fee recipient.\n    function feeRecipient() external view returns (address feeRecipient);\n\n    /// @notice Get the current asset registry.\n    /// @return assetRegistry Address of asset registry.\n    function assetRegistry()\n        external\n        view\n        returns (IAssetRegistry assetRegistry);\n\n    /// @notice Get the current hooks module address.\n    /// @return hooks Address of hooks module.\n    function hooks() external view returns (IHooks hooks);\n\n    /// @notice Get fee per second.\n    /// @return fee Fee per second in 18 decimal fixed point format.\n    function fee() external view returns (uint256 fee);\n\n    /// @notice Get current balances of all assets.\n    /// @return assetAmounts Amounts of registered assets.\n    function holdings()\n        external\n        view\n        returns (AssetValue[] memory assetAmounts);\n\n    /// @notice Get current total value of assets in vault.\n    /// @return value Current total value.\n    function value() external view returns (uint256 value);\n}\n"
      },
      "src/v2/Sweepable.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/Ownable2Step.sol\";\nimport \"@openzeppelin/SafeERC20.sol\";\nimport \"./interfaces/ISweepable.sol\";\n\n/// @title Sweepable.\n/// @notice Aera Sweepable contract.\n/// @dev Allows owner of the contract to restore accidentally send tokens\n//       and the chain's native token.\ncontract Sweepable is ISweepable, Ownable2Step {\n    using SafeERC20 for IERC20;\n\n    /// @inheritdoc ISweepable\n    function sweep(address token, uint256 amount) external onlyOwner {\n        if (token == address(0)) {\n            msg.sender.call{value: amount}(\"\");\n        } else {\n            IERC20(token).safeTransfer(msg.sender, amount);\n        }\n\n        emit Sweep(token, amount);\n    }\n}\n"
      },
      "src/v2/TargetSighashLib.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport {TargetSighash} from \"./Types.sol\";\n\n/// @title TargetSighashLib\n/// @notice Conversion operations for the TargetSighash compound type.\nlibrary TargetSighashLib {\n    /// @notice Get sighash from target and selector.\n    /// @param target Target contract address.\n    /// @param selector Function selector.\n    /// @return targetSighash Packed value of target and selector.\n    function toTargetSighash(\n        address target,\n        bytes4 selector\n    ) internal pure returns (TargetSighash targetSighash) {\n        targetSighash = TargetSighash.wrap(\n            bytes20(target) | (bytes32(selector) >> (20 * 8))\n        );\n    }\n}\n"
      },
      "src/v2/Types.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/IERC20.sol\";\nimport \"./interfaces/IAssetRegistry.sol\";\n\n// Types.sol\n//\n// This file defines the types used in V2.\n\n/// @notice Combination of contract address and sighash to be used in allowlist.\n/// @dev It's packed as follows:\n///      [target 160 bits] [selector 32 bits] [<empty> 64 bits]\ntype TargetSighash is bytes32;\n\n/// @notice Struct encapulating an asset and an associated value.\n/// @param asset Asset address.\n/// @param value The associated value for this asset (e.g., amount or price).\nstruct AssetValue {\n    IERC20 asset;\n    uint256 value;\n}\n\n/// @notice Execution details for a vault operation.\n/// @param target Target contract address.\n/// @param value Native token amount.\n/// @param data Calldata.\nstruct Operation {\n    address target;\n    uint256 value;\n    bytes data;\n}\n\n/// @notice Contract address and sighash struct to be used in the public interface.\nstruct TargetSighashData {\n    address target;\n    bytes4 selector;\n}\n\n/// @notice Parameters for vault deployment.\n/// @param owner Initial owner address.\n/// @param assetRegistry Asset registry address.\n/// @param hooks Hooks address.\n/// @param guardian Guardian address.\n/// @param feeRecipient Fee recipient address.\n/// @param fee Fees accrued per second, denoted in 18 decimal fixed point format.\nstruct Parameters {\n    address owner;\n    address assetRegistry;\n    address hooks;\n    address guardian;\n    address feeRecipient;\n    uint256 fee;\n}\n\n/// @notice Vault parameters for vault deployment.\n/// @param owner Initial owner address.\n/// @param guardian Guardian address.\n/// @param feeRecipient Fee recipient address.\n/// @param fee Fees accrued per second, denoted in 18 decimal fixed point format.\nstruct VaultParameters {\n    address owner;\n    address guardian;\n    address feeRecipient;\n    uint256 fee;\n}\n\n/// @notice Asset registry parameters for asset registry deployment.\n/// @param factory Asset registry factory address.\n/// @param owner Initial owner address.\n/// @param assets Initial list of registered assets.\n/// @param numeraireToken Numeraire token address.\n/// @param feeToken Fee token address.\n/// @param sequencer Sequencer Uptime Feed address for L2.\nstruct AssetRegistryParameters {\n    address factory;\n    address owner;\n    IAssetRegistry.AssetInformation[] assets;\n    IERC20 numeraireToken;\n    IERC20 feeToken;\n    AggregatorV2V3Interface sequencer;\n}\n\n/// @notice Hooks parameters for hooks deployment.\n/// @param factory Hooks factory address.\n/// @param owner Initial owner address.\n/// @param minDailyValue The fraction of value that the vault has to retain per day\n///                      in the course of submissions.\n/// @param targetSighashAllowlist Array of target contract and sighash combinations to allow.\nstruct HooksParameters {\n    address factory;\n    address owner;\n    uint256 minDailyValue;\n    TargetSighashData[] targetSighashAllowlist;\n}\n"
      },
      "src/v2/Constants.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n// Constants.sol\n//\n// This file defines the constants used across several contracts in V2.\n\n/// @dev Fixed point multiplier.\nuint256 constant ONE = 1e18;\n"
      },
      "src/v2/dependencies/openzeppelin/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Interface of the ERC165 standard, as defined in the\r\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\r\n *\r\n * Implementers can declare support of contract interfaces, which can then be\r\n * queried by others ({ERC165Checker}).\r\n *\r\n * For an implementation, see {ERC165}.\r\n */\r\ninterface IERC165 {\r\n    /**\r\n     * @dev Returns true if this contract implements the interface defined by\r\n     * `interfaceId`. See the corresponding\r\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\r\n     * to learn more about how these ids are created.\r\n     *\r\n     * This function call must use less than 30 000 gas.\r\n     */\r\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\r\n}\r\n"
      },
      "src/v2/dependencies/openzeppelin/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\r\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\r\n *\r\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\r\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\r\n * need to send a transaction, and thus is not required to hold Ether at all.\r\n */\r\ninterface IERC20Permit {\r\n    /**\r\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\r\n     * given ``owner``'s signed approval.\r\n     *\r\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\r\n     * ordering also apply here.\r\n     *\r\n     * Emits an {Approval} event.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `spender` cannot be the zero address.\r\n     * - `deadline` must be a timestamp in the future.\r\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\r\n     * over the EIP712-formatted function arguments.\r\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\r\n     *\r\n     * For more information on the signature format, see the\r\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\r\n     * section].\r\n     */\r\n    function permit(\r\n        address owner,\r\n        address spender,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) external;\r\n\r\n    /**\r\n     * @dev Returns the current nonce for `owner`. This value must be\r\n     * included whenever a signature is generated for {permit}.\r\n     *\r\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\r\n     * prevents a signature from being used multiple times.\r\n     */\r\n    function nonces(address owner) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\r\n     */\r\n    // solhint-disable-next-line func-name-mixedcase\r\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\r\n}\r\n"
      },
      "src/v2/dependencies/openzeppelin/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\r\n\r\npragma solidity ^0.8.1;\r\n\r\n/**\r\n * @dev Collection of functions related to the address type\r\n */\r\nlibrary Address {\r\n    /**\r\n     * @dev Returns true if `account` is a contract.\r\n     *\r\n     * [IMPORTANT]\r\n     * ====\r\n     * It is unsafe to assume that an address for which this function returns\r\n     * false is an externally-owned account (EOA) and not a contract.\r\n     *\r\n     * Among others, `isContract` will return false for the following\r\n     * types of addresses:\r\n     *\r\n     *  - an externally-owned account\r\n     *  - a contract in construction\r\n     *  - an address where a contract will be created\r\n     *  - an address where a contract lived, but was destroyed\r\n     *\r\n     * Furthermore, `isContract` will also return true if the target contract within\r\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\r\n     * which only has an effect at the end of a transaction.\r\n     * ====\r\n     *\r\n     * [IMPORTANT]\r\n     * ====\r\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\r\n     *\r\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\r\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\r\n     * constructor.\r\n     * ====\r\n     */\r\n    function isContract(address account) internal view returns (bool) {\r\n        // This method relies on extcodesize/address.code.length, which returns 0\r\n        // for contracts in construction, since the code is only stored at the end\r\n        // of the constructor execution.\r\n\r\n        return account.code.length > 0;\r\n    }\r\n\r\n    /**\r\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\r\n     * `recipient`, forwarding all available gas and reverting on errors.\r\n     *\r\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\r\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\r\n     * imposed by `transfer`, making them unable to receive funds via\r\n     * `transfer`. {sendValue} removes this limitation.\r\n     *\r\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\r\n     *\r\n     * IMPORTANT: because control is transferred to `recipient`, care must be\r\n     * taken to not create reentrancy vulnerabilities. Consider using\r\n     * {ReentrancyGuard} or the\r\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\r\n     */\r\n    function sendValue(address payable recipient, uint256 amount) internal {\r\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\r\n\r\n        (bool success, ) = recipient.call{value: amount}(\"\");\r\n        require(success, \"Address: unable to send value, recipient may have reverted\");\r\n    }\r\n\r\n    /**\r\n     * @dev Performs a Solidity function call using a low level `call`. A\r\n     * plain `call` is an unsafe replacement for a function call: use this\r\n     * function instead.\r\n     *\r\n     * If `target` reverts with a revert reason, it is bubbled up by this\r\n     * function (like regular Solidity function calls).\r\n     *\r\n     * Returns the raw returned data. To convert to the expected return value,\r\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `target` must be a contract.\r\n     * - calling `target` with `data` must not revert.\r\n     *\r\n     * _Available since v3.1._\r\n     */\r\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\r\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\r\n     * `errorMessage` as a fallback revert reason when `target` reverts.\r\n     *\r\n     * _Available since v3.1._\r\n     */\r\n    function functionCall(\r\n        address target,\r\n        bytes memory data,\r\n        string memory errorMessage\r\n    ) internal returns (bytes memory) {\r\n        return functionCallWithValue(target, data, 0, errorMessage);\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n     * but also transferring `value` wei to `target`.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - the calling contract must have an ETH balance of at least `value`.\r\n     * - the called Solidity function must be `payable`.\r\n     *\r\n     * _Available since v3.1._\r\n     */\r\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\r\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\r\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\r\n     *\r\n     * _Available since v3.1._\r\n     */\r\n    function functionCallWithValue(\r\n        address target,\r\n        bytes memory data,\r\n        uint256 value,\r\n        string memory errorMessage\r\n    ) internal returns (bytes memory) {\r\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\r\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\r\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n     * but performing a static call.\r\n     *\r\n     * _Available since v3.3._\r\n     */\r\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\r\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n     * but performing a static call.\r\n     *\r\n     * _Available since v3.3._\r\n     */\r\n    function functionStaticCall(\r\n        address target,\r\n        bytes memory data,\r\n        string memory errorMessage\r\n    ) internal view returns (bytes memory) {\r\n        (bool success, bytes memory returndata) = target.staticcall(data);\r\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\r\n     * but performing a delegate call.\r\n     *\r\n     * _Available since v3.4._\r\n     */\r\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\r\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\r\n     * but performing a delegate call.\r\n     *\r\n     * _Available since v3.4._\r\n     */\r\n    function functionDelegateCall(\r\n        address target,\r\n        bytes memory data,\r\n        string memory errorMessage\r\n    ) internal returns (bytes memory) {\r\n        (bool success, bytes memory returndata) = target.delegatecall(data);\r\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\r\n    }\r\n\r\n    /**\r\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\r\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\r\n     *\r\n     * _Available since v4.8._\r\n     */\r\n    function verifyCallResultFromTarget(\r\n        address target,\r\n        bool success,\r\n        bytes memory returndata,\r\n        string memory errorMessage\r\n    ) internal view returns (bytes memory) {\r\n        if (success) {\r\n            if (returndata.length == 0) {\r\n                // only check isContract if the call was successful and the return data is empty\r\n                // otherwise we already know that it was a contract\r\n                require(isContract(target), \"Address: call to non-contract\");\r\n            }\r\n            return returndata;\r\n        } else {\r\n            _revert(returndata, errorMessage);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\r\n     * revert reason or using the provided one.\r\n     *\r\n     * _Available since v4.3._\r\n     */\r\n    function verifyCallResult(\r\n        bool success,\r\n        bytes memory returndata,\r\n        string memory errorMessage\r\n    ) internal pure returns (bytes memory) {\r\n        if (success) {\r\n            return returndata;\r\n        } else {\r\n            _revert(returndata, errorMessage);\r\n        }\r\n    }\r\n\r\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\r\n        // Look for revert reason and bubble it up if present\r\n        if (returndata.length > 0) {\r\n            // The easiest way to bubble the revert reason is using memory via assembly\r\n            /// @solidity memory-safe-assembly\r\n            assembly {\r\n                let returndata_size := mload(returndata)\r\n                revert(add(32, returndata), returndata_size)\r\n            }\r\n        } else {\r\n            revert(errorMessage);\r\n        }\r\n    }\r\n}\r\n"
      },
      "src/v2/interfaces/IAssetRegistry.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@chainlink/interfaces/AggregatorV2V3Interface.sol\";\nimport \"@openzeppelin/IERC20.sol\";\n\n/// @title IAssetRegistry\n/// @notice Asset registry interface.\n/// @dev Any implementation MUST also implement Ownable2Step and ERC165.\ninterface IAssetRegistry {\n    /// @param asset Asset address.\n    /// @param heartbeat Frequency of oracle price updates.\n    /// @param isERC4626 True if yield-bearing asset, false if just an ERC20 asset.\n    /// @param oracle If applicable, oracle address for asset.\n    struct AssetInformation {\n        IERC20 asset;\n        uint256 heartbeat;\n        bool isERC4626;\n        AggregatorV2V3Interface oracle;\n    }\n\n    /// @param asset Asset address.\n    /// @param spotPrice Spot price of an asset in Numeraire token terms.\n    struct AssetPriceReading {\n        IERC20 asset;\n        uint256 spotPrice;\n    }\n\n    /// @notice Get address of vault.\n    /// @return vault Address of vault.\n    function vault() external view returns (address vault);\n\n    /// @notice Get a list of all registered assets.\n    /// @return assets List of assets.\n    /// @dev MUST return assets in an order sorted by address.\n    function assets()\n        external\n        view\n        returns (AssetInformation[] memory assets);\n\n    /// @notice Get address of fee token.\n    /// @return feeToken Address of fee token.\n    /// @dev Represented as an address for efficiency reasons.\n    /// @dev MUST be present in assets array.\n    function feeToken() external view returns (IERC20 feeToken);\n\n    /// @notice Get the index of the Numeraire token in the assets array.\n    /// @return numeraireToken Numeraire token address.\n    /// @dev Represented as an index for efficiency reasons.\n    /// @dev MUST be a number between 0 (inclusive) and the length of assets array (exclusive).\n    function numeraireToken() external view returns (IERC20 numeraireToken);\n\n    /// @notice Calculate spot prices of non-ERC4626 assets.\n    /// @return spotPrices Spot prices of non-ERC4626 assets in 18 decimals.\n    /// @dev MUST return assets in the same order as in assets but with ERC4626 assets filtered out.\n    /// @dev MUST also include Numeraire token (spot price = 1).\n    /// @dev MAY revert if oracle prices for any asset are unreliable at the time.\n    function spotPrices()\n        external\n        view\n        returns (AssetPriceReading[] memory spotPrices);\n}\n"
      },
      "src/v2/interfaces/IVaultEvents.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport \"@openzeppelin/IERC20.sol\";\n\nimport {AssetValue, Operation} from \"../Types.sol\";\n\n/// @title Interface for vault events.\ninterface IVaultEvents {\n    /// @notice Emitted when deposit is called.\n    /// @param owner Owner address.\n    /// @param asset Deposited asset.\n    /// @param amount Deposited asset amount.\n    event Deposit(address indexed owner, IERC20 indexed asset, uint256 amount);\n\n    /// @notice Emitted when withdraw is called.\n    /// @param owner Owner address.\n    /// @param asset Withdrawn asset.\n    /// @param amount Withdrawn asset amount.\n    event Withdraw(\n        address indexed owner, IERC20 indexed asset, uint256 amount\n    );\n\n    /// @notice Emitted when guardian is set.\n    /// @param guardian Address of new guardian.\n    /// @param feeRecipient Address of new fee recipient.\n    event SetGuardianAndFeeRecipient(\n        address indexed guardian, address indexed feeRecipient\n    );\n\n    /// @notice Emitted when asset registry is set.\n    /// @param assetRegistry Address of new asset registry.\n    event SetAssetRegistry(address assetRegistry);\n\n    /// @notice Emitted when hooks is set.\n    /// @param hooks Address of new hooks.\n    event SetHooks(address hooks);\n\n    /// @notice Emitted when execute is called.\n    /// @param owner Owner address.\n    /// @param operation Struct details for target and calldata.\n    event Executed(address indexed owner, Operation operation);\n\n    /// @notice Emitted when vault is finalized.\n    /// @param owner Owner address.\n    /// @param withdrawnAmounts Struct details for withdrawn assets and amounts (sent to owner).\n    event Finalized(address indexed owner, AssetValue[] withdrawnAmounts);\n\n    /// @notice Emitted when submit is called.\n    /// @param guardian Guardian address.\n    /// @param operations Array of struct details for targets and calldatas.\n    event Submitted(address indexed guardian, Operation[] operations);\n\n    /// @notice Emitted when guardian fees are claimed.\n    /// @param feeRecipient Fee recipient address.\n    /// @param claimedFee Claimed amount of fee token.\n    /// @param unclaimedFee Unclaimed amount of fee token (unclaimed because Vault does not have enough balance of feeToken).\n    /// @param feeTotal New total reserved fee value.\n    event Claimed(\n        address indexed feeRecipient,\n        uint256 claimedFee,\n        uint256 unclaimedFee,\n        uint256 feeTotal\n    );\n\n    /// @notice Emitted when new fees are reserved for recipient.\n    /// @param feeRecipient Fee recipient address.\n    /// @param newFee Fee amount reserved.\n    /// @param lastFeeCheckpoint Updated fee checkpoint.\n    /// @param lastValue Last registered vault value.\n    /// @param lastFeeTokenPrice Last registered fee token price.\n    /// @param feeTotal New total reserved fee value.\n    event FeesReserved(\n        address indexed feeRecipient,\n        uint256 newFee,\n        uint256 lastFeeCheckpoint,\n        uint256 lastValue,\n        uint256 lastFeeTokenPrice,\n        uint256 feeTotal\n    );\n\n    /// @notice Emitted when no fees are reserved.\n    /// @param lastFeeCheckpoint Updated fee checkpoint.\n    /// @param lastValue Last registered vault value.\n    /// @param feeTotal New total reserved fee value.\n    event NoFeesReserved(\n        uint256 lastFeeCheckpoint,\n        uint256 lastValue,\n        uint256 feeTotal\n    );\n\n    /// @notice Emitted when the call to get spot prices from the asset registry reverts.\n    /// @param reason Revert reason.\n    event SpotPricesReverted(bytes reason);\n}\n"
      },
      "src/v2/dependencies/openzeppelin/Ownable2Step.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n        _transferOwnership(sender);\n    }\n}\n"
      },
      "src/v2/interfaces/ISweepable.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @title Interface for sweepable module.\ninterface ISweepable {\n    /// @notice Emitted when sweep is called.\n    /// @param token Token address or zero address if recovering the chain's native token.\n    /// @param amount Withdrawn amount of token.\n    event Sweep(address token, uint256 amount);\n\n    /// @notice Withdraw any tokens accidentally sent to contract.\n    /// @param token Token address to withdraw or zero address for the chain's native token.\n    /// @param amount Amount to withdraw.\n    function sweep(address token, uint256 amount) external;\n}\n"
      },
      "src/v2/dependencies/chainlink/interfaces/AggregatorV2V3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./AggregatorInterface.sol\";\r\nimport \"./AggregatorV3Interface.sol\";\r\n\r\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}"
      },
      "src/v2/dependencies/openzeppelin/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\nimport \"./Context.sol\";\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * By default, the owner account will be the one that deploys the contract. This\r\n * can later be changed with {transferOwnership}.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be applied to your functions to restrict their use to\r\n * the owner.\r\n */\r\nabstract contract Ownable is Context {\r\n    address private _owner;\r\n\r\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n    /**\r\n     * @dev Initializes the contract setting the deployer as the initial owner.\r\n     */\r\n    constructor() {\r\n        _transferOwnership(_msgSender());\r\n    }\r\n\r\n    /**\r\n     * @dev Throws if called by any account other than the owner.\r\n     */\r\n    modifier onlyOwner() {\r\n        _checkOwner();\r\n        _;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the address of the current owner.\r\n     */\r\n    function owner() public view virtual returns (address) {\r\n        return _owner;\r\n    }\r\n\r\n    /**\r\n     * @dev Throws if the sender is not the owner.\r\n     */\r\n    function _checkOwner() internal view virtual {\r\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\r\n    }\r\n\r\n    /**\r\n     * @dev Leaves the contract without owner. It will not be possible to call\r\n     * `onlyOwner` functions. Can only be called by the current owner.\r\n     *\r\n     * NOTE: Renouncing ownership will leave the contract without an owner,\r\n     * thereby disabling any functionality that is only available to the owner.\r\n     */\r\n    function renounceOwnership() public virtual onlyOwner {\r\n        _transferOwnership(address(0));\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Can only be called by the current owner.\r\n     */\r\n    function transferOwnership(address newOwner) public virtual onlyOwner {\r\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\r\n        _transferOwnership(newOwner);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Internal function without access restriction.\r\n     */\r\n    function _transferOwnership(address newOwner) internal virtual {\r\n        address oldOwner = _owner;\r\n        _owner = newOwner;\r\n        emit OwnershipTransferred(oldOwner, newOwner);\r\n    }\r\n}\r\n"
      },
      "src/v2/dependencies/chainlink/interfaces/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\ninterface AggregatorInterface {\r\n  function latestAnswer() external view returns (int256);\r\n\r\n  function latestTimestamp() external view returns (uint256);\r\n\r\n  function latestRound() external view returns (uint256);\r\n\r\n  function getAnswer(uint256 roundId) external view returns (int256);\r\n\r\n  function getTimestamp(uint256 roundId) external view returns (uint256);\r\n\r\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\r\n\r\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\r\n}"
      },
      "src/v2/dependencies/chainlink/interfaces/AggregatorV3Interface.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\ninterface AggregatorV3Interface {\r\n  function decimals() external view returns (uint8);\r\n\r\n  function description() external view returns (string memory);\r\n\r\n  function version() external view returns (uint256);\r\n\r\n  // getRoundData and latestRoundData should both raise \"No data present\"\r\n  // if they do not have data to report, instead of returning unset values\r\n  // which could be misinterpreted as actual reported values.\r\n  function getRoundData(uint80 _roundId)\r\n    external\r\n    view\r\n    returns (\r\n      uint80 roundId,\r\n      int256 answer,\r\n      uint256 startedAt,\r\n      uint256 updatedAt,\r\n      uint80 answeredInRound\r\n    );\r\n\r\n  function latestRoundData()\r\n    external\r\n    view\r\n    returns (\r\n      uint80 roundId,\r\n      int256 answer,\r\n      uint256 startedAt,\r\n      uint256 updatedAt,\r\n      uint80 answeredInRound\r\n    );\r\n}"
      },
      "src/v2/dependencies/openzeppelin/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\r\n\r\npragma solidity ^0.8.0;\r\n\r\n/**\r\n * @dev Provides information about the current execution context, including the\r\n * sender of the transaction and its data. While these are generally available\r\n * via msg.sender and msg.data, they should not be accessed in such a direct\r\n * manner, since when dealing with meta-transactions the account sending and\r\n * paying for execution may not be the actual sender (as far as an application\r\n * is concerned).\r\n *\r\n * This contract is only required for intermediate, library-like contracts.\r\n */\r\nabstract contract Context {\r\n    function _msgSender() internal view virtual returns (address) {\r\n        return msg.sender;\r\n    }\r\n\r\n    function _msgData() internal view virtual returns (bytes calldata) {\r\n        return msg.data;\r\n    }\r\n}\r\n"
      }
    },
    "settings": {
      "remappings": [
        "src/=src/",
        "test/=test/",
        "@chainlink/=src/v2/dependencies/chainlink/",
        "@openzeppelin/=src/v2/dependencies/openzeppelin/",
        "@uniswap/v3-periphery/=lib/v3-periphery/",
        "@uniswap/v3-core/=lib/v3-core/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "v3-core/=lib/v3-core/",
        "v3-periphery/=lib/v3-periphery/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": true,
      "libraries": {}
    }
  }}