creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/persistent/smart-accounts/share-price-throttled-asset-manager/SharePriceThrottledAssetManagerLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity 0.8.19;\n\nimport {IFundValueCalculator} from \"../../off-chain/fund-value-calculator/IFundValueCalculator.sol\";\nimport {MultiCallAccountMixin} from \"../utils/MultiCallAccountMixin.sol\";\nimport {ISharePriceThrottledAssetManagerLib} from \"./ISharePriceThrottledAssetManagerLib.sol\";\n\n/// @title SharePriceThrottledAssetManagerLib Contract\n/// @author Enzyme Council <security@enzyme.finance>\n/// @notice A smart account that throttles the signer's atomic value loss to a fund,\n/// by tracking cumulative atomic losses to the fund's share price over a rolling duration\n/// @dev Share price loss is tracked:\n/// - cumulatively (additive between subsequent txs)\n/// - relatively (as a percentage)\n/// - with a replenishing tolerance (based on time since last loss)\n/// This contract is version-agnostic, so long as the FundValueCalculatorRouter supports the fund's current version.\n/// Note that the FundValueCalculatorRouter is meant mostly for off-chain consumption (due to gas costs),\n/// but its gross share value functions are gas-efficient\ncontract SharePriceThrottledAssetManagerLib is ISharePriceThrottledAssetManagerLib, MultiCallAccountMixin {\n    event Initialized(\n        address indexed vaultProxy, uint64 lossTolerance, uint32 lossTolerancePeriodDuration, address indexed shutDowner\n    );\n\n    event ThrottleUpdated(uint256 nextCumulativeLoss);\n\n    error AlreadyInitialized();\n\n    error ExceedsOneHundredPercent();\n\n    error ToleranceExceeded(uint256 cumulativeLoss);\n\n    uint256 private constant ONE_HUNDRED_PERCENT = 1e18;\n    IFundValueCalculator private immutable FUND_VALUE_CALCULATOR_ROUTER;\n\n    // `shutdowner`: an admin who can shut down the smart account\n    address private shutdowner;\n    // `vaultProxyAddress`: the VaultProxy whose share price will be used for throttling\n    address private vaultProxyAddress;\n    // `lossTolerance`: the maximum cumulative percentage loss tolerated,\n    // see `ONE_HUNDRED_PERCENT` for precision\n    uint64 private lossTolerance;\n    // `lossTolerancePeriodDuration`: the number of seconds over which a `throttle` that has\n    // fully reached `LOSS_TOLERANCE` will reset to 0. This dictates the rate of replenishment\n    // of the throttle.\n    uint32 private lossTolerancePeriodDuration;\n\n    // `Throttle`: the cumulative loss info\n    Throttle private throttle;\n\n    constructor(\n        address _addressListRegistry,\n        uint256 _gsnTrustedForwardersAddressListId,\n        IFundValueCalculator _fundValueCalculatorRouter\n    ) MultiCallAccountMixin(_addressListRegistry, _gsnTrustedForwardersAddressListId) {\n        FUND_VALUE_CALCULATOR_ROUTER = _fundValueCalculatorRouter;\n    }\n\n    /// @dev Pseudo-constructor to be called upon proxy deployment\n    function init(\n        address _owner,\n        address _vaultProxyAddress,\n        uint64 _lossTolerance,\n        uint32 _lossTolerancePeriodDuration,\n        address _shutdowner\n    ) external override {\n        if (getVaultProxyAddress() != address(0)) {\n            revert AlreadyInitialized();\n        }\n\n        if (_lossTolerance > ONE_HUNDRED_PERCENT) {\n            revert ExceedsOneHundredPercent();\n        }\n\n        __setOwner(_owner);\n\n        vaultProxyAddress = _vaultProxyAddress;\n        lossTolerance = _lossTolerance;\n        lossTolerancePeriodDuration = _lossTolerancePeriodDuration;\n        shutdowner = _shutdowner;\n\n        emit Initialized(_vaultProxyAddress, _lossTolerance, _lossTolerancePeriodDuration, _shutdowner);\n    }\n\n    /// @inheritdoc MultiCallAccountMixin\n    function executeCalls(Call[] calldata _calls) public override {\n        uint256 prevSharePrice = __getSharePrice();\n\n        super.executeCalls(_calls);\n\n        __validateAndUpdateThrottle({_prevSharePrice: prevSharePrice});\n    }\n\n    /// @notice Shuts down the smart account\n    function shutdown() external {\n        if (__msgSender() != getShutdowner()) {\n            revert Unauthorized();\n        }\n\n        __setOwner(address(0));\n    }\n\n    // PRIVATE FUNCTIONS\n\n    /// @dev Helper to get the gross share price for the fund.\n    /// The quote asset is irrelevant, as the relative loss is what is tracked.\n    function __getSharePrice() private returns (uint256 sharePrice_) {\n        (, sharePrice_) = FUND_VALUE_CALCULATOR_ROUTER.calcGrossShareValue({_vaultProxy: getVaultProxyAddress()});\n    }\n\n    /// @dev Helper to update the throttle with any current loss,\n    /// and validate that its tolerance has not been breached\n    function __validateAndUpdateThrottle(uint256 _prevSharePrice) private {\n        uint256 currentSharePrice = __getSharePrice();\n        if (currentSharePrice >= _prevSharePrice) {\n            return;\n        }\n\n        uint256 nextCumulativeLoss = throttle.cumulativeLoss;\n\n        // Replenish tolerated loss, given the previous loss timestamp\n        if (nextCumulativeLoss > 0) {\n            uint256 cumulativeLossToRestore =\n                getLossTolerance() * (block.timestamp - throttle.lastLossTimestamp) / getLossTolerancePeriodDuration();\n            if (cumulativeLossToRestore < nextCumulativeLoss) {\n                nextCumulativeLoss -= cumulativeLossToRestore;\n            } else {\n                nextCumulativeLoss = 0;\n            }\n        }\n\n        // Add the new loss\n        uint256 newLoss = ONE_HUNDRED_PERCENT * (_prevSharePrice - currentSharePrice) / _prevSharePrice;\n        nextCumulativeLoss += newLoss;\n\n        // Validate that the new cumulative loss is within the tolerance\n        if (nextCumulativeLoss > getLossTolerance()) {\n            revert ToleranceExceeded(nextCumulativeLoss);\n        }\n\n        // Update the throttle\n        throttle.cumulativeLoss = uint64(nextCumulativeLoss);\n        throttle.lastLossTimestamp = uint64(block.timestamp);\n\n        emit ThrottleUpdated(nextCumulativeLoss);\n    }\n\n    ///////////////////\n    // STATE GETTERS //\n    ///////////////////\n\n    /// @notice Get the cumulative loss tolerance percentage that is used for the throttle\n    /// @return lossTolerance_ The loss tolerance percentage\n    function getLossTolerance() public view returns (uint256 lossTolerance_) {\n        return lossTolerance;\n    }\n\n    /// @notice Get the duration of the period governing the throttle\n    /// @return lossTolerancePeriodDuration_ The duration in seconds\n    function getLossTolerancePeriodDuration() public view returns (uint256 lossTolerancePeriodDuration_) {\n        return lossTolerancePeriodDuration;\n    }\n\n    /// @notice Gets the user who can shutdown the smart account\n    /// @return shutdowner_ The user who can shutdown the smart account\n    function getShutdowner() public view returns (address shutdowner_) {\n        return shutdowner;\n    }\n\n    /// @notice Get the latest throttle info\n    /// @return throttle_ The throttle info\n    function getThrottle() public view returns (Throttle memory throttle_) {\n        return throttle;\n    }\n\n    /// @notice Get the VaultProxy used to throttle share price\n    /// @return vaultProxyAddress_ The VaultProxy address\n    function getVaultProxyAddress() public view returns (address vaultProxyAddress_) {\n        return vaultProxyAddress;\n    }\n}\n"
      },
      "contracts/persistent/off-chain/fund-value-calculator/IFundValueCalculator.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity >=0.6.0 <0.9.0;\n\n/// @title IFundValueCalculator interface\n/// @author Enzyme Council <security@enzyme.finance>\ninterface IFundValueCalculator {\n    function calcGav(address _vaultProxy) external returns (address denominationAsset_, uint256 gav_);\n\n    function calcGavInAsset(address _vaultProxy, address _quoteAsset) external returns (uint256 gav_);\n\n    function calcGrossShareValue(address _vaultProxy)\n        external\n        returns (address denominationAsset_, uint256 grossShareValue_);\n\n    function calcGrossShareValueInAsset(address _vaultProxy, address _quoteAsset)\n        external\n        returns (uint256 grossShareValue_);\n\n    function calcNav(address _vaultProxy) external returns (address denominationAsset_, uint256 nav_);\n\n    function calcNavInAsset(address _vaultProxy, address _quoteAsset) external returns (uint256 nav_);\n\n    function calcNetShareValue(address _vaultProxy)\n        external\n        returns (address denominationAsset_, uint256 netShareValue_);\n\n    function calcNetShareValueInAsset(address _vaultProxy, address _quoteAsset)\n        external\n        returns (uint256 netShareValue_);\n\n    function calcNetValueForSharesHolder(address _vaultProxy, address _sharesHolder)\n        external\n        returns (address denominationAsset_, uint256 netValue_);\n\n    function calcNetValueForSharesHolderInAsset(address _vaultProxy, address _sharesHolder, address _quoteAsset)\n        external\n        returns (uint256 netValue_);\n}\n"
      },
      "contracts/persistent/smart-accounts/utils/MultiCallAccountMixin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity 0.8.19;\n\nimport {Address} from \"openzeppelin-solc-0.8/utils/Address.sol\";\nimport {GSNRecipientMixin} from \"../../../utils/0.8.19/gas-station-network/GSNRecipientMixin.sol\";\nimport {IMultiCallAccountMixin} from \"./interfaces/IMultiCallAccountMixin.sol\";\n\n/// @title MultiCallAccountMixin Contract\n/// @author Enzyme Council <security@enzyme.finance>\n/// @notice A basic smart account that allows its owner to execute multiple calls atomically\n/// @dev Owner must be set via by inheriting contracts via __setOwner()\nabstract contract MultiCallAccountMixin is IMultiCallAccountMixin, GSNRecipientMixin {\n    event OwnerSet(address nextOwner);\n\n    error Unauthorized();\n\n    address private owner;\n\n    constructor(address _addressListRegistry, uint256 _gsnTrustedForwardersAddressListId)\n        GSNRecipientMixin(_addressListRegistry, _gsnTrustedForwardersAddressListId)\n    {}\n\n    /// @notice Execute multiple external calls\n    /// @param _calls The calls to execute\n    /// @dev This doesn't need to be payable for Enzyme purposes\n    function executeCalls(Call[] calldata _calls) public virtual override {\n        if (__msgSender() != getOwner()) {\n            revert Unauthorized();\n        }\n\n        uint256 callsLength = _calls.length;\n        for (uint256 i; i < callsLength; i++) {\n            Call memory call = _calls[i];\n\n            Address.functionCall({target: call.target, data: call.data});\n        }\n    }\n\n    /// @notice Gets the owner\n    /// @return owner_ The owner\n    function getOwner() public view returns (address owner_) {\n        return owner;\n    }\n\n    /// @dev Helper to set the owner\n    function __setOwner(address _nextOwner) internal {\n        owner = _nextOwner;\n\n        emit OwnerSet(_nextOwner);\n    }\n}\n"
      },
      "contracts/persistent/smart-accounts/share-price-throttled-asset-manager/ISharePriceThrottledAssetManagerLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity >=0.6.0 <0.9.0;\n\n/// @title ISharePriceThrottledAssetManagerLib Interface\n/// @author Enzyme Council <security@enzyme.finance>\ninterface ISharePriceThrottledAssetManagerLib {\n    struct Throttle {\n        // `cumulativeLoss`: the cumulative loss to the fund's share price, as a percentage,\n        // after previous losses were replenished according to `lossTolerancePeriodDuration`\n        uint64 cumulativeLoss;\n        // `lastLossTimestamp`: the timestamp of the last loss to the fund's share price,\n        // and thus also the last time `cumulativeLoss` was updated\n        uint64 lastLossTimestamp;\n    }\n\n    function init(\n        address _owner,\n        address _vaultProxyAddress,\n        uint64 _lossTolerance,\n        uint32 _lossTolerancePeriodDuration,\n        address _shutdowner\n    ) external;\n}\n"
      },
      "lib/openzeppelin-solc-0.8/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \"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        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or 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            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\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            /// @solidity memory-safe-assembly\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"
      },
      "contracts/utils/0.8.19/gas-station-network/GSNRecipientMixin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity 0.8.19;\n\nimport {IAddressListRegistry} from \"../../../persistent/address-list-registry/IAddressListRegistry.sol\";\n\n/// @title GSNRecipientMixin Contract\n/// @author Enzyme Council <security@enzyme.finance>\n/// @notice Mixin for contracts that will receive relayable calls via Gas Station Network\n/// @dev Uses an AddressListRegistry list as a beacon for the trusted forwarder address\nabstract contract GSNRecipientMixin {\n    IAddressListRegistry internal immutable GSN_RECIPIENT_ADDRESS_LIST_REGISTRY;\n    uint256 internal immutable GSN_RECIPIENT_TRUSTED_FORWARDERS_LIST_ID;\n\n    constructor(address _addressListRegistry, uint256 _trustedForwardersAddressListId) {\n        GSN_RECIPIENT_ADDRESS_LIST_REGISTRY = IAddressListRegistry(_addressListRegistry);\n        GSN_RECIPIENT_TRUSTED_FORWARDERS_LIST_ID = _trustedForwardersAddressListId;\n    }\n\n    /// @dev Helper to check whether an address is a known GSN trusted forwarder\n    function __isGSNTrustedForwarder(address _who) internal view returns (bool isTrustedForwarder_) {\n        return\n            GSN_RECIPIENT_ADDRESS_LIST_REGISTRY.isInList({_id: GSN_RECIPIENT_TRUSTED_FORWARDERS_LIST_ID, _item: _who});\n    }\n\n    /// @dev Helper to parse the canonical msg sender from trusted forwarder relayed calls\n    /// See https://github.com/opengsn/gsn/blob/da4222b76e3ae1968608dc5c5d80074dcac7c4be/packages/contracts/src/ERC2771Recipient.sol#L41-L53\n    function __msgSender() internal view returns (address canonicalSender_) {\n        if (msg.data.length >= 20 && __isGSNTrustedForwarder(msg.sender)) {\n            assembly {\n                canonicalSender_ := shr(96, calldataload(sub(calldatasize(), 20)))\n            }\n\n            return canonicalSender_;\n        }\n\n        return msg.sender;\n    }\n}\n"
      },
      "contracts/persistent/smart-accounts/utils/interfaces/IMultiCallAccountMixin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity >=0.6.0 <0.9.0;\n\n/// @title IMultiCallAccountMixin Interface\n/// @author Enzyme Council <security@enzyme.finance>\ninterface IMultiCallAccountMixin {\n    struct Call {\n        address target;\n        bytes data;\n    }\n\n    function executeCalls(Call[] calldata _calls) external;\n}\n"
      },
      "contracts/persistent/address-list-registry/IAddressListRegistry.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n    This file is part of the Enzyme Protocol.\n\n    (c) Enzyme Council <council@enzyme.finance>\n\n    For the full license information, please view the LICENSE\n    file that was distributed with this source code.\n*/\n\npragma solidity >=0.6.0 <0.9.0;\npragma experimental ABIEncoderV2;\n\n/// @title IAddressListRegistry Interface\n/// @author Enzyme Council <security@enzyme.finance>\ninterface IAddressListRegistry {\n    enum UpdateType {\n        None,\n        AddOnly,\n        RemoveOnly,\n        AddAndRemove\n    }\n\n    struct ListInfo {\n        address owner;\n        UpdateType updateType;\n        mapping(address => bool) itemToIsInList;\n    }\n\n    /////////////////////\n    // LIST MANAGEMENT //\n    /////////////////////\n\n    function addToList(uint256 _id, address[] calldata _items) external;\n\n    function attestLists(uint256[] calldata _ids, string[] calldata _descriptions) external;\n\n    function createList(address _owner, UpdateType _updateType, address[] calldata _initialItems)\n        external\n        returns (uint256 id_);\n\n    function removeFromList(uint256 _id, address[] calldata _items) external;\n\n    function setListOwner(uint256 _id, address _nextOwner) external;\n\n    function setListUpdateType(uint256 _id, UpdateType _nextUpdateType) external;\n\n    /////////////////\n    // LIST SEARCH //\n    /////////////////\n\n    function areAllInAllLists(uint256[] memory _ids, address[] memory _items)\n        external\n        view\n        returns (bool areAllInAllLists_);\n\n    function areAllInList(uint256 _id, address[] memory _items) external view returns (bool areAllInList_);\n\n    function areAllInSomeOfLists(uint256[] memory _ids, address[] memory _items)\n        external\n        view\n        returns (bool areAllInSomeOfLists_);\n\n    function areAllNotInAnyOfLists(uint256[] memory _ids, address[] memory _items)\n        external\n        view\n        returns (bool areAllNotInAnyOfLists_);\n\n    function areAllNotInList(uint256 _id, address[] memory _items) external view returns (bool areAllNotInList_);\n\n    function isInAllLists(uint256[] memory _ids, address _item) external view returns (bool isInAllLists_);\n\n    function isInList(uint256 _id, address _item) external view returns (bool isInList_);\n\n    function isInSomeOfLists(uint256[] memory _ids, address _item) external view returns (bool isInSomeOfLists_);\n\n    ///////////////////\n    // STATE GETTERS //\n    ///////////////////\n\n    function getListCount() external view returns (uint256 count_);\n\n    function getListOwner(uint256 _id) external view returns (address owner_);\n\n    function getListUpdateType(uint256 _id) external view returns (UpdateType updateType_);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts/=lib/openzeppelin-solc-0.6/contracts/",
        "@uniswap/v3-core/=lib/uniswap-v3-core/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-solc-0.6/=lib/openzeppelin-solc-0.6/contracts/",
        "openzeppelin-solc-0.7/=lib/openzeppelin-solc-0.7/contracts/",
        "openzeppelin-solc-0.8/=lib/openzeppelin-solc-0.8/contracts/",
        "uniswap-v3-core/=lib/uniswap-v3-core/",
        "uniswap-v3-core-0.8/=lib/uniswap-v3-core-0.8/",
        "uniswap-v3-periphery/=lib/uniswap-v3-periphery/contracts/",
        "uniswap-v3-periphery-0.8/=lib/uniswap-v3-periphery-0.8/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200,
        "details": {
          "yul": false
        }
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": false
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}