creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/curve/factory/CRVPoolFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\nimport \"src/base/factory/PoolFactory.sol\";\n\nimport {IBooster} from \"src/base/interfaces/IBooster.sol\";\nimport {IConvexFactory} from \"src/base/interfaces/IConvexFactory.sol\";\nimport {IGaugeController} from \"src/base/interfaces/IGaugeController.sol\";\n\n/// @notice Inherit from PoolFactory to deploy a pool compatible with CRV gauges and check if the token is a valid extra rewards to add.\ncontract CRVPoolFactory is PoolFactory {\n    /// @notice Ve Funder is a special gauge not valid to be deployed as a pool.\n    address public constant CVX = 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B;\n\n    /// @notice Convex Booster.\n    address public constant BOOSTER = 0xF403C135812408BFbE8713b5A23a04b3D48AAE31;\n\n    /// @notice Ve Funder is a special gauge not valid to be deployed as a pool.\n    address public constant VE_FUNDER = 0xbAF05d7aa4129CA14eC45cC9d4103a9aB9A9fF60;\n\n    /// @notice Convex Minimal Proxy Factory for Only Boost.\n    address public constant CONVEX_MINIMAL_PROXY_FACTORY = 0x4E795A6f991e305e3f28A3b1b2B4B9789d2CD5A1;\n\n    /// @notice Curve Gauge Controller.\n    IGaugeController public constant GAUGE_CONTROLLER = IGaugeController(0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB);\n\n    /// @notice Event emitted when a pool is deployed with Only Boost.\n    event PoolDeployed(address vault, address rewardDistributor, address lp, address gauge, address stakingConvex);\n\n    constructor(\n        address _strategy,\n        address _rewardToken,\n        address _vaultImplementation,\n        address _liquidityGaugeImplementation,\n        address _rewardReceiverImplementation\n    )\n        PoolFactory(\n            _strategy,\n            _rewardToken,\n            _vaultImplementation,\n            _liquidityGaugeImplementation,\n            _rewardReceiverImplementation\n        )\n    {}\n\n    /// @notice Create a new pool for a given pid on the Convex platform.\n    /// @param _pid Pool id.\n    /// @param _deployPool To deploy the pool.\n    /// @param _deployConvex To deploy the convex staking.\n    /// @return vault Address of the vault.\n    /// @return rewardDistributor Address of the reward distributor.\n    /// @return stakingConvex Address of the staking convex.\n    function create(uint256 _pid, bool _deployPool, bool _deployConvex)\n        external\n        returns (address vault, address rewardDistributor, address stakingConvex)\n    {\n        (address _token,, address _gauge,,,) = IBooster(BOOSTER).poolInfo(_pid);\n\n        if (_deployConvex) {\n            stakingConvex = IConvexFactory(CONVEX_MINIMAL_PROXY_FACTORY).create(_token, _pid);\n        }\n\n        if (_deployPool) {\n            /// Create Stake DAO pool.\n            (vault, rewardDistributor) = _create(_gauge);\n\n            emit PoolDeployed(vault, rewardDistributor, _token, _gauge, stakingConvex);\n        } else {\n            address _rewardDistributor = strategy.rewardDistributors(_gauge);\n\n            /// We go through the execute function because if the pool is already deployed and have extra rewards,\n            /// We do not want CVX be distributed by the Reward Receiver.\n            /// Approve the reward distributor to spend the reward token.\n            if (ERC20(CVX).allowance(address(strategy), _rewardDistributor) == 0) {\n                strategy.execute(\n                    CVX,\n                    0,\n                    abi.encodeWithSignature(\n                        \"approve(address,address,uint)\", _rewardDistributor, address(strategy), type(uint256).max\n                    )\n                );\n            }\n\n            /// Add CVX in the case where Only Boost is enabled.\n            address distributor = ILiquidityGauge(rewardDistributor).reward_data(CVX).distributor;\n            if (distributor == address(0)) {\n                strategy.execute(\n                    _rewardDistributor,\n                    0,\n                    abi.encodeWithSignature(\"add_reward(address,address)\", CVX, address(strategy))\n                );\n            }\n        }\n    }\n\n    function syncExtraRewards(address _gauge) external {\n        address _rewardDistributor = strategy.rewardDistributors(_gauge);\n        if(_rewardDistributor == address(0)) return;\n\n        _addExtraRewards(_gauge, _rewardDistributor);\n    }\n\n    /// @notice Add the main reward token to the reward distributor.\n    /// @param _gauge Address of the _gauge.\n    function _addRewardToken(address _gauge) internal override {\n        /// The strategy should claim through the locker the reward token,\n        /// and distribute it to the reward distributor every harvest.\n        strategy.addRewardToken(_gauge, rewardToken);\n\n        /// Add CVX in the case where Only Boost is enabled.\n        strategy.addRewardToken(_gauge, CVX);\n    }\n\n    /// @inheritdoc PoolFactory\n    function _isValidToken(address _token) internal view override returns (bool) {\n        /// We can't add the reward token as extra reward.\n        /// We can't add special pools like the Ve Funder.\n        /// We can't add SDT as extra reward, as it's already added by default.\n        /// We can't add CVX as extra reward, as it's already added by default.\n        if (_token == rewardToken || _token == VE_FUNDER || _token == SDT || _token == CVX) return false;\n\n        /// If the token is available as an inflation receiver, it's not valid.\n        try GAUGE_CONTROLLER.gauge_types(_token) {\n            return false;\n        } catch {\n            return true;\n        }\n    }\n\n    /// inheritdoc PoolFactory\n    function _isValidGauge(address _gauge) internal view override returns (bool) {\n        bool isValid;\n        /// Check if the gauge is a valid candidate and available as an inflation receiver.\n        /// This call always reverts if the gauge is not valid.\n        try GAUGE_CONTROLLER.gauge_types(_gauge) {\n            isValid = true;\n        } catch {\n            return false;\n        }\n\n        /// Check if the gauge is not killed.\n        /// Not all the pools, but most of them, have this function.\n        try ILiquidityGauge(_gauge).is_killed() returns (bool isKilled) {\n            if (isKilled) return false;\n        } catch {}\n\n        /// If the gauge doesn't support the is_killed function, but is unofficially killed, it can be deployed.\n        return isValid;\n    }\n}\n"
      },
      "src/base/factory/PoolFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\nimport {ERC20} from \"solady/tokens/ERC20.sol\";\nimport {IVault} from \"src/base/interfaces/IVault.sol\";\nimport {LibClone} from \"solady/utils/LibClone.sol\";\nimport {IBooster} from \"src/base/interfaces/IBooster.sol\";\n\nimport {IStrategy} from \"src/base/interfaces/IStrategy.sol\";\nimport {IFallback} from \"src/base/interfaces/IFallback.sol\";\nimport {ILiquidityGauge} from \"src/base/interfaces/ILiquidityGauge.sol\";\nimport {ISDLiquidityGauge} from \"src/base/interfaces/ISDLiquidityGauge.sol\";\n\n/// @notice Factory built to be compatible with CRV gauges but can be overidden to support other gauges/protocols.\nabstract contract PoolFactory {\n    using LibClone for address;\n\n    /// @notice Denominator for fixed point math.\n    uint256 public constant DENOMINATOR = 10_000;\n\n    /// @notice Stake DAO strategy contract address.\n    IStrategy public immutable strategy;\n\n    /// @notice Reward token address.\n    address public immutable rewardToken;\n\n    /// @notice Staking Deposit implementation address.\n    address public immutable vaultImplementation;\n\n    /// @notice Reward Receiver implementation address.\n    address public immutable rewardReceiverImplementation;\n\n    /// @notice Liquidity Gauge implementation address.\n    address public immutable liquidityGaugeImplementation;\n\n    /// @notice Stake DAO token address.\n    address public constant SDT = 0x73968b9a57c6E53d41345FD57a6E6ae27d6CDB2F;\n\n    /// @notice Voting Escrow Stake DAO token address.\n    address public constant VESDT = 0x0C30476f66034E11782938DF8e4384970B6c9e8a;\n\n    /// @notice SDT VEBoost proxy address.\n    address public constant VE_BOOST_PROXY = 0xD67bdBefF01Fc492f1864E61756E5FBB3f173506;\n\n    /// @notice Claim helper contract address for LiquidityGauges.\n    address public constant CLAIM_HELPER = 0x539e65190a371cE73244A98DEc42BA635cCa512c;\n\n    /// @notice Stake DAO token distributor address.\n    address public constant SDT_DISTRIBUTOR = 0x9C99dffC1De1AfF7E7C1F36fCdD49063A281e18C;\n\n    /// @notice Throwed if the gauge is not valid candidate.\n    error INVALID_GAUGE();\n\n    /// @notice Throwed if the token is not valid.\n    error INVALID_TOKEN();\n\n    /// @notice Throwed if the gauge has been already used.\n    error GAUGE_ALREADY_USED();\n\n    /// @notice Emitted when a new pool is deployed.\n    event PoolDeployed(address vault, address rewardDistributor, address token, address gauge);\n\n    /// @notice Constructor.\n    /// @param _strategy Address of the strategy contract. This contract should have the ability to add new reward tokens.\n    /// @param _rewardToken Address of the main reward token.\n    /// @param _vaultImplementation Address of the staking deposit implementation. Main entry point.\n    /// @param _liquidityGaugeImplementation Address of the liquidity gauge implementation.\n    constructor(\n        address _strategy,\n        address _rewardToken,\n        address _vaultImplementation,\n        address _liquidityGaugeImplementation,\n        address _rewardReceiverImplementation\n    ) {\n        rewardToken = _rewardToken;\n        strategy = IStrategy(_strategy);\n        vaultImplementation = _vaultImplementation;\n        liquidityGaugeImplementation = _liquidityGaugeImplementation;\n        rewardReceiverImplementation = _rewardReceiverImplementation;\n    }\n\n    /// @notice Add new staking gauge to Stake DAO Locker.\n    /// @param _gauge Address of the liquidity gauge.\n    /// @return vault Address of the staking deposit.\n    /// @return rewardDistributor Address of the reward distributor to claim rewards.\n    function create(address _gauge) public virtual returns (address vault, address rewardDistributor) {\n        return _create(_gauge);\n    }\n\n    /// @notice Add new staking gauge to Stake DAO Locker.\n    function _create(address _gauge) internal returns (address vault, address rewardDistributor) {\n        /// Perform checks on the gauge to make sure it's valid and can be used.\n        if (!_isValidGauge(_gauge)) revert INVALID_GAUGE();\n\n        /// Perform checks on the strategy to make sure it's not already used.\n        if (strategy.rewardDistributors(_gauge) != address(0)) revert GAUGE_ALREADY_USED();\n\n        /// Retrieve the staking token.\n        address lp = _getGaugeStakingToken(_gauge);\n\n        /// Clone the Reward Distributor.\n        rewardDistributor = LibClone.clone(liquidityGaugeImplementation);\n\n        /// We use the LP token and the gauge address as salt to generate the vault address.\n        bytes32 salt = keccak256(abi.encodePacked(lp, _gauge));\n\n        /// We use CWIA setup. We encode the LP token, the strategy address and the reward distributor address as data\n        /// to be passed as immutable args to the vault.\n        bytes memory vaultData = abi.encodePacked(lp, address(strategy), rewardDistributor);\n\n        /// Clone the Vault.\n        vault = vaultImplementation.cloneDeterministic(vaultData, salt);\n\n        /// Retrieve the symbol to be used on the reward distributor.\n        (, string memory _symbol) = _getNameAndSymbol(lp);\n\n        /// Initialize the Reward Distributor.\n        ISDLiquidityGauge(rewardDistributor).initialize(\n            vault, address(this), SDT, VESDT, VE_BOOST_PROXY, SDT_DISTRIBUTOR, vault, _symbol\n        );\n\n        /// Initialize Vault.\n        IVault(vault).initialize();\n\n        /// Allow the vault to stake the LP token in the locker trough the strategy.\n        strategy.toggleVault(vault);\n\n        /// Map in the strategy the staking token to it's corresponding gauge.\n        strategy.setGauge(lp, _gauge);\n\n        /// Map the gauge to the reward distributor that should receive the rewards.\n        strategy.setRewardDistributor(_gauge, rewardDistributor);\n\n        /// Set ClaimHelper as claimer.\n        ISDLiquidityGauge(rewardDistributor).set_claimer(CLAIM_HELPER);\n\n        /// Transfer ownership of the reward distributor to the strategy.\n        ISDLiquidityGauge(rewardDistributor).commit_transfer_ownership(address(strategy));\n\n        /// Accept ownership of the reward distributor.\n        strategy.acceptRewardDistributorOwnership(rewardDistributor);\n\n        /// Add the reward token to the reward distributor.\n        _addRewardToken(_gauge);\n\n        /// Add extra rewards if any.\n        _addExtraRewards(_gauge, rewardDistributor);\n\n        emit PoolDeployed(vault, rewardDistributor, lp, _gauge);\n    }\n\n    /// @notice Add the main reward token to the reward distributor.\n    /// @param _gauge Address of the gauge.\n    function _addRewardToken(address _gauge) internal virtual {\n        /// The strategy should claim through the locker the reward token,\n        /// and distribute it to the reward distributor every harvest.\n        strategy.addRewardToken(_gauge, rewardToken);\n    }\n\n    /// @notice Add extra reward tokens to the reward distributor.\n    /// @param _gauge Address of the liquidity gauge.\n    function _addExtraRewards(address _gauge, address _rewardDistributor) internal virtual {\n        /// Check if the gauge supports extra rewards.\n        /// This function is not supported on all gauges, depending on when they were deployed.\n        bytes memory data = abi.encodeWithSignature(\"reward_tokens(uint256)\", 0);\n\n        /// Hence the call to the function is wrapped in a try catch.\n        (bool success,) = _gauge.call(data);\n        if (!success) {\n            /// If it fails, we set the LGtype to 1 to indicate that the gauge doesn't support extra rewards.\n            /// So the harvest would skip the extra rewards.\n            strategy.setLGtype(_gauge, 1);\n\n            return;\n        }\n\n        address rewardReceiver = strategy.rewardReceivers(_gauge);\n\n        /// Check if the gauge supports receivers.\n        data = abi.encodeWithSignature(\"rewards_receiver(address)\", strategy.locker());\n        (success,) = _gauge.call(data);\n\n        if (success && rewardReceiver == address(0)) {\n            bytes memory rewardReceiverData =\n                abi.encodePacked(_gauge, strategy.locker(), address(rewardToken), address(strategy), _rewardDistributor);\n\n            /// Clone the Vault.\n            rewardReceiver = rewardReceiverImplementation.clone(rewardReceiverData);\n\n            /// If it supports receivers, we add the reward receiver to the reward distributor.\n            strategy.addRewardReceiver(_gauge, rewardReceiver);\n        }\n\n        /// Loop through the extra reward tokens.\n        /// 8 is the maximum number of extra reward tokens supported by the gauges.\n        for (uint8 i = 0; i < 8;) {\n            /// Get the extra reward token address.\n            address _extraRewardToken = ISDLiquidityGauge(_gauge).reward_tokens(i);\n\n            /// If the address is 0, it means there are no more extra reward tokens.\n            if (_extraRewardToken == address(0)) break;\n\n            /// Performs checks on the extra reward token.\n            /// Checks like if the token is also an lp token that can be staked in the locker, these tokens are not supported.\n            address distributor = ILiquidityGauge(_rewardDistributor).reward_data(_extraRewardToken).distributor;\n\n            if (_isValidToken(_extraRewardToken) && distributor == address(0)) {\n                /// Then we add the extra reward token to the reward distributor through the strategy.\n                strategy.addRewardToken(_gauge, _extraRewardToken);\n            }\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /// @notice Perform checks on the gauge to make sure it's valid and can be used.\n    function _isValidGauge(address _gauge) internal view virtual returns (bool) {}\n\n    /// @notice Perform checks on the token to make sure it's valid and can be used.\n    function _isValidToken(address _token) internal view virtual returns (bool) {}\n\n    /// @notice Retrieve the staking token from the gauge.\n    /// @param _gauge Address of the liquidity gauge.\n    function _getGaugeStakingToken(address _gauge) internal view virtual returns (address lp) {\n        lp = ILiquidityGauge(_gauge).lp_token();\n    }\n\n    /// @notice Retrieve the name and symbol of the staking token.\n    /// @param _lp Address of the staking token.\n    function _getNameAndSymbol(address _lp) internal view virtual returns (string memory name, string memory symbol) {\n        name = ERC20(_lp).name();\n        symbol = ERC20(_lp).symbol();\n    }\n}\n"
      },
      "src/base/interfaces/IBooster.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.19;\n\ninterface IBooster {\n    function poolLength() external view returns (uint256);\n\n    function poolInfo(uint256 pid)\n        external\n        view\n        returns (address lpToken, address token, address gauge, address crvRewards, address stash, bool shutdown);\n\n    function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns (bool);\n\n    function earmarkRewards(uint256 _pid) external returns (bool);\n\n    function depositAll(uint256 _pid, bool _stake) external returns (bool);\n\n    function withdraw(uint256 _pid, uint256 _amount) external returns (bool);\n\n    function claimRewards(uint256 _pid, address gauge) external returns (bool);\n}\n"
      },
      "src/base/interfaces/IConvexFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ninterface IConvexFactory {\n    function protocolFeesPercent() external view returns (uint256);\n    function fallbacks(address gauge) external view returns (address);\n    function create(address token, uint256 pid) external returns (address);\n}\n"
      },
      "src/base/interfaces/IGaugeController.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ninterface IGaugeController {\n    struct VotedSlope {\n        uint256 slope;\n        uint256 power;\n        uint256 end;\n    }\n\n    function admin() external view returns (address);\n\n    function gauges(uint256) external view returns (address);\n\n    //solhint-disable-next-line\n    function gauge_types(address addr) external view returns (int128);\n\n    //solhint-disable-next-line\n    function gauge_relative_weight_write(address addr, uint256 timestamp) external returns (uint256);\n\n    //solhint-disable-next-line\n    function gauge_relative_weight(address addr) external view returns (uint256);\n\n    //solhint-disable-next-line\n    function gauge_relative_weight(address addr, uint256 timestamp) external view returns (uint256);\n\n    //solhint-disable-next-line\n    function get_total_weight() external view returns (uint256);\n\n    //solhint-disable-next-line\n    function get_gauge_weight(address addr) external view returns (uint256);\n\n    function get_type_weight(int128) external view returns (uint256);\n\n    function vote_for_gauge_weights(address, uint256) external;\n\n    function vote_user_slopes(address, address) external returns (VotedSlope memory);\n\n    function last_user_vote(address _user, address _gauge) external view returns (uint256);\n\n    function checkpoint_gauge(address _gauge) external;\n\n    function add_gauge(address, int128, uint256) external;\n\n    function add_type(string memory, uint256) external;\n\n    function commit_transfer_ownership(address) external;\n\n    function accept_transfer_ownership() external;\n}\n"
      },
      "lib/solady/src/tokens/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple ERC20 + EIP-2612 implementation.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)\n///\n/// @dev Note:\n/// - The ERC20 standard allows minting and transferring to and from the zero address,\n///   minting and transferring zero tokens, as well as self-approvals.\n///   For performance, this implementation WILL NOT revert for such actions.\n///   Please add any checks with overrides if desired.\n/// - The `permit` function uses the ecrecover precompile (0x1).\n///\n/// If you are overriding:\n/// - NEVER violate the ERC20 invariant:\n///   the total sum of all balances must be equal to `totalSupply()`.\n/// - Check that the overridden function is actually used in the function you want to\n///   change the behavior of. Much of the code has been manually inlined for performance.\nabstract contract ERC20 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The total supply has overflowed.\n    error TotalSupplyOverflow();\n\n    /// @dev The allowance has overflowed.\n    error AllowanceOverflow();\n\n    /// @dev The allowance has underflowed.\n    error AllowanceUnderflow();\n\n    /// @dev Insufficient balance.\n    error InsufficientBalance();\n\n    /// @dev Insufficient allowance.\n    error InsufficientAllowance();\n\n    /// @dev The permit is invalid.\n    error InvalidPermit();\n\n    /// @dev The permit has expired.\n    error PermitExpired();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted when `amount` tokens is transferred from `from` to `to`.\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`.\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    /// @dev `keccak256(bytes(\"Transfer(address,address,uint256)\"))`.\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;\n\n    /// @dev `keccak256(bytes(\"Approval(address,address,uint256)\"))`.\n    uint256 private constant _APPROVAL_EVENT_SIGNATURE =\n        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The storage slot for the total supply.\n    uint256 private constant _TOTAL_SUPPLY_SLOT = 0x05345cdf77eb68f44c;\n\n    /// @dev The balance slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x0c, _BALANCE_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let balanceSlot := keccak256(0x0c, 0x20)\n    /// ```\n    uint256 private constant _BALANCE_SLOT_SEED = 0x87a211a2;\n\n    /// @dev The allowance slot of (`owner`, `spender`) is given by:\n    /// ```\n    ///     mstore(0x20, spender)\n    ///     mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let allowanceSlot := keccak256(0x0c, 0x34)\n    /// ```\n    uint256 private constant _ALLOWANCE_SLOT_SEED = 0x7f5e9f20;\n\n    /// @dev The nonce slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x0c, _NONCES_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let nonceSlot := keccak256(0x0c, 0x20)\n    /// ```\n    uint256 private constant _NONCES_SLOT_SEED = 0x38377508;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev `(_NONCES_SLOT_SEED << 16) | 0x1901`.\n    uint256 private constant _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX = 0x383775081901;\n\n    /// @dev `keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")`.\n    bytes32 private constant _DOMAIN_TYPEHASH =\n        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev `keccak256(\"1\")`.\n    bytes32 private constant _VERSION_HASH =\n        0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;\n\n    /// @dev `keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\")`.\n    bytes32 private constant _PERMIT_TYPEHASH =\n        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ERC20 METADATA                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the name of the token.\n    function name() public view virtual returns (string memory);\n\n    /// @dev Returns the symbol of the token.\n    function symbol() public view virtual returns (string memory);\n\n    /// @dev Returns the decimals places of the token.\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           ERC20                            */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the amount of tokens in existence.\n    function totalSupply() public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := sload(_TOTAL_SUPPLY_SLOT)\n        }\n    }\n\n    /// @dev Returns the amount of tokens owned by `owner`.\n    function balanceOf(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`.\n    function allowance(address owner, address spender)\n        public\n        view\n        virtual\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x34))\n        }\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n    ///\n    /// Emits a {Approval} event.\n    function approve(address spender, uint256 amount) public virtual returns (bool) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and store the amount.\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x34), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x2c)))\n        }\n        return true;\n    }\n\n    /// @dev Transfer `amount` tokens from the caller to `to`.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount`.\n    ///\n    /// Emits a {Transfer} event.\n    function transfer(address to, uint256 amount) public virtual returns (bool) {\n        _beforeTokenTransfer(msg.sender, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, caller())\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(msg.sender, to, amount);\n        return true;\n    }\n\n    /// @dev Transfers `amount` tokens from `from` to `to`.\n    ///\n    /// Note: Does not update the allowance if it is the maximum uint256 value.\n    ///\n    /// Requirements:\n    /// - `from` must at least have `amount`.\n    /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`.\n    ///\n    /// Emits a {Transfer} event.\n    function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {\n        _beforeTokenTransfer(from, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let from_ := shl(96, from)\n            // Compute the allowance slot and load its value.\n            mstore(0x20, caller())\n            mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED))\n            let allowanceSlot := keccak256(0x0c, 0x34)\n            let allowance_ := sload(allowanceSlot)\n            // If the allowance is not the maximum uint256 value.\n            if add(allowance_, 1) {\n                // Revert if the amount to be transferred exceeds the allowance.\n                if gt(amount, allowance_) {\n                    mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.\n                    revert(0x1c, 0x04)\n                }\n                // Subtract and store the updated allowance.\n                sstore(allowanceSlot, sub(allowance_, amount))\n            }\n            // Compute the balance slot and load its value.\n            mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(from, to, amount);\n        return true;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          EIP-2612                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev For more performance, override to return the constant value\n    /// of `keccak256(bytes(name()))` if `name()` will never change.\n    function _constantNameHash() internal view virtual returns (bytes32 result) {}\n\n    /// @dev Returns the current nonce for `owner`.\n    /// This value is used to compute the signature for EIP-2612 permit.\n    function nonces(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the nonce slot and load its value.\n            mstore(0x0c, _NONCES_SLOT_SEED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`,\n    /// authorized by a signed approval by `owner`.\n    ///\n    /// Emits a {Approval} event.\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        bytes32 nameHash = _constantNameHash();\n        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.\n        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Revert if the block timestamp is greater than `deadline`.\n            if gt(timestamp(), deadline) {\n                mstore(0x00, 0x1a15a3cc) // `PermitExpired()`.\n                revert(0x1c, 0x04)\n            }\n            let m := mload(0x40) // Grab the free memory pointer.\n            // Clean the upper 96 bits.\n            owner := shr(96, shl(96, owner))\n            spender := shr(96, shl(96, spender))\n            // Compute the nonce slot and load its value.\n            mstore(0x0e, _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX)\n            mstore(0x00, owner)\n            let nonceSlot := keccak256(0x0c, 0x20)\n            let nonceValue := sload(nonceSlot)\n            // Prepare the domain separator.\n            mstore(m, _DOMAIN_TYPEHASH)\n            mstore(add(m, 0x20), nameHash)\n            mstore(add(m, 0x40), _VERSION_HASH)\n            mstore(add(m, 0x60), chainid())\n            mstore(add(m, 0x80), address())\n            mstore(0x2e, keccak256(m, 0xa0))\n            // Prepare the struct hash.\n            mstore(m, _PERMIT_TYPEHASH)\n            mstore(add(m, 0x20), owner)\n            mstore(add(m, 0x40), spender)\n            mstore(add(m, 0x60), value)\n            mstore(add(m, 0x80), nonceValue)\n            mstore(add(m, 0xa0), deadline)\n            mstore(0x4e, keccak256(m, 0xc0))\n            // Prepare the ecrecover calldata.\n            mstore(0x00, keccak256(0x2c, 0x42))\n            mstore(0x20, and(0xff, v))\n            mstore(0x40, r)\n            mstore(0x60, s)\n            let t := staticcall(gas(), 1, 0, 0x80, 0x20, 0x20)\n            // If the ecrecover fails, the returndatasize will be 0x00,\n            // `owner` will be checked if it equals the hash at 0x00,\n            // which evaluates to false (i.e. 0), and we will revert.\n            // If the ecrecover succeeds, the returndatasize will be 0x20,\n            // `owner` will be compared against the returned address at 0x20.\n            if iszero(eq(mload(returndatasize()), owner)) {\n                mstore(0x00, 0xddafbaef) // `InvalidPermit()`.\n                revert(0x1c, 0x04)\n            }\n            // Increment and store the updated nonce.\n            sstore(nonceSlot, add(nonceValue, t)) // `t` is 1 if ecrecover succeeds.\n            // Compute the allowance slot and store the value.\n            // The `owner` is already at slot 0x20.\n            mstore(0x40, or(shl(160, _ALLOWANCE_SLOT_SEED), spender))\n            sstore(keccak256(0x2c, 0x34), value)\n            // Emit the {Approval} event.\n            log3(add(m, 0x60), 0x20, _APPROVAL_EVENT_SIGNATURE, owner, spender)\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero pointer.\n        }\n    }\n\n    /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit.\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32 result) {\n        bytes32 nameHash = _constantNameHash();\n        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.\n        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Grab the free memory pointer.\n            mstore(m, _DOMAIN_TYPEHASH)\n            mstore(add(m, 0x20), nameHash)\n            mstore(add(m, 0x40), _VERSION_HASH)\n            mstore(add(m, 0x60), chainid())\n            mstore(add(m, 0x80), address())\n            result := keccak256(m, 0xa0)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL MINT FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints `amount` tokens to `to`, increasing the total supply.\n    ///\n    /// Emits a {Transfer} event.\n    function _mint(address to, uint256 amount) internal virtual {\n        _beforeTokenTransfer(address(0), to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let totalSupplyBefore := sload(_TOTAL_SUPPLY_SLOT)\n            let totalSupplyAfter := add(totalSupplyBefore, amount)\n            // Revert if the total supply overflows.\n            if lt(totalSupplyAfter, totalSupplyBefore) {\n                mstore(0x00, 0xe5cfe957) // `TotalSupplyOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            // Store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, totalSupplyAfter)\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(address(0), to, amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL BURN FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Burns `amount` tokens from `from`, reducing the total supply.\n    ///\n    /// Emits a {Transfer} event.\n    function _burn(address from, uint256 amount) internal virtual {\n        _beforeTokenTransfer(from, address(0), amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the balance slot and load its value.\n            mstore(0x0c, _BALANCE_SLOT_SEED)\n            mstore(0x00, from)\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Subtract and store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, sub(sload(_TOTAL_SUPPLY_SLOT), amount))\n            // Emit the {Transfer} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0)\n        }\n        _afterTokenTransfer(from, address(0), amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL TRANSFER FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Moves `amount` of tokens from `from` to `to`.\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        _beforeTokenTransfer(from, to, amount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let from_ := shl(96, from)\n            // Compute the balance slot and load its value.\n            mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))\n            let fromBalanceSlot := keccak256(0x0c, 0x20)\n            let fromBalance := sload(fromBalanceSlot)\n            // Revert if insufficient balance.\n            if gt(amount, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, amount))\n            // Compute the balance slot of `to`.\n            mstore(0x00, to)\n            let toBalanceSlot := keccak256(0x0c, 0x20)\n            // Add and store the updated balance of `to`.\n            // Will not overflow because the sum of all user balances\n            // cannot exceed the maximum uint256 value.\n            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))\n            // Emit the {Transfer} event.\n            mstore(0x20, amount)\n            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))\n        }\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL ALLOWANCE FUNCTIONS                */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Updates the allowance of `owner` for `spender` based on spent `amount`.\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the allowance slot and load its value.\n            mstore(0x20, spender)\n            mstore(0x0c, _ALLOWANCE_SLOT_SEED)\n            mstore(0x00, owner)\n            let allowanceSlot := keccak256(0x0c, 0x34)\n            let allowance_ := sload(allowanceSlot)\n            // If the allowance is not the maximum uint256 value.\n            if add(allowance_, 1) {\n                // Revert if the amount to be transferred exceeds the allowance.\n                if gt(amount, allowance_) {\n                    mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.\n                    revert(0x1c, 0x04)\n                }\n                // Subtract and store the updated allowance.\n                sstore(allowanceSlot, sub(allowance_, amount))\n            }\n        }\n    }\n\n    /// @dev Sets `amount` as the allowance of `spender` over the tokens of `owner`.\n    ///\n    /// Emits a {Approval} event.\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let owner_ := shl(96, owner)\n            // Compute the allowance slot and store the amount.\n            mstore(0x20, spender)\n            mstore(0x0c, or(owner_, _ALLOWANCE_SLOT_SEED))\n            sstore(keccak256(0x0c, 0x34), amount)\n            // Emit the {Approval} event.\n            mstore(0x00, amount)\n            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, owner_), shr(96, mload(0x2c)))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HOOKS TO OVERRIDE                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any transfer of tokens.\n    /// This includes minting and burning.\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /// @dev Hook that is called after any transfer of tokens.\n    /// This includes minting and burning.\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "src/base/interfaces/IVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.19;\n\ninterface IVault {\n    function deposit(address _recipient, uint256 _amount, bool _earn) external;\n    function withdraw(uint256 _shares) external;\n    function initialize() external;\n}\n"
      },
      "lib/solady/src/utils/LibClone.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Minimal proxy library.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibClone.sol)\n/// @author Minimal proxy by 0age (https://github.com/0age)\n/// @author Clones with immutable args by wighawag, zefram.eth, Saw-mon & Natalie\n/// (https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args)\n/// @author Minimal ERC1967 proxy by jtriley-eth (https://github.com/jtriley-eth/minimum-viable-proxy)\n///\n/// @dev Minimal proxy:\n/// Although the sw0nt pattern saves 5 gas over the erc-1167 pattern during runtime,\n/// it is not supported out-of-the-box on Etherscan. Hence, we choose to use the 0age pattern,\n/// which saves 4 gas over the erc-1167 pattern during runtime, and has the smallest bytecode.\n///\n/// @dev Minimal proxy (PUSH0 variant):\n/// This is a new minimal proxy that uses the PUSH0 opcode introduced during Shanghai.\n/// It is optimized first for minimal runtime gas, then for minimal bytecode.\n/// The PUSH0 clone functions are intentionally postfixed with a jarring \"_PUSH0\" as\n/// many EVM chains may not support the PUSH0 opcode in the early months after Shanghai.\n/// Please use with caution.\n///\n/// @dev Clones with immutable args (CWIA):\n/// The implementation of CWIA here implements a `receive()` method that emits the\n/// `ReceiveETH(uint256)` event. This skips the `DELEGATECALL` when there is no calldata,\n/// enabling us to accept hard gas-capped `sends` & `transfers` for maximum backwards\n/// composability. The minimal proxy implementation does not offer this feature.\n///\n/// @dev Minimal ERC1967 proxy:\n/// An minimal ERC1967 proxy, intended to be upgraded with UUPS.\n/// This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic.\n///\n/// @dev ERC1967I proxy:\n/// An variant of the minimal ERC1967 proxy, with a special code path that activates\n/// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the\n/// `implementation` address. The returned implementation is guaranteed to be valid if the\n/// keccak256 of the proxy's code is equal to `ERC1967I_CODE_HASH`.\nlibrary LibClone {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The keccak256 of the deployed code for the ERC1967 proxy.\n    bytes32 internal constant ERC1967_CODE_HASH =\n        0xaaa52c8cc8a0e3fd27ce756cc6b4e70c51423e9b597b11f32d3e49f8b1fc890d;\n\n    /// @dev The keccak256 of the deployed code for the ERC1967I proxy.\n    bytes32 internal constant ERC1967I_CODE_HASH =\n        0xce700223c0d4cea4583409accfc45adac4a093b3519998a9cbbe1504dadba6f7;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Unable to deploy the clone.\n    error DeploymentFailed();\n\n    /// @dev The salt must start with either the zero address or `by`.\n    error SaltDoesNotStartWith();\n\n    /// @dev The ETH transfer has failed.\n    error ETHTransferFailed();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  MINIMAL PROXY OPERATIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Deploys a clone of `implementation`.\n    function clone(address implementation) internal returns (address instance) {\n        instance = clone(0, implementation);\n    }\n\n    /// @dev Deploys a clone of `implementation`.\n    /// Deposits `value` ETH during deployment.\n    function clone(uint256 value, address implementation) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            /**\n             * --------------------------------------------------------------------------+\n             * CREATION (9 bytes)                                                        |\n             * --------------------------------------------------------------------------|\n             * Opcode     | Mnemonic          | Stack     | Memory                       |\n             * --------------------------------------------------------------------------|\n             * 60 runSize | PUSH1 runSize     | r         |                              |\n             * 3d         | RETURNDATASIZE    | 0 r       |                              |\n             * 81         | DUP2              | r 0 r     |                              |\n             * 60 offset  | PUSH1 offset      | o r 0 r   |                              |\n             * 3d         | RETURNDATASIZE    | 0 o r 0 r |                              |\n             * 39         | CODECOPY          | 0 r       | [0..runSize): runtime code   |\n             * f3         | RETURN            |           | [0..runSize): runtime code   |\n             * --------------------------------------------------------------------------|\n             * RUNTIME (44 bytes)                                                        |\n             * --------------------------------------------------------------------------|\n             * Opcode  | Mnemonic       | Stack                  | Memory                |\n             * --------------------------------------------------------------------------|\n             *                                                                           |\n             * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d      | RETURNDATASIZE | 0                      |                       |\n             * 3d      | RETURNDATASIZE | 0 0                    |                       |\n             * 3d      | RETURNDATASIZE | 0 0 0                  |                       |\n             * 3d      | RETURNDATASIZE | 0 0 0 0                |                       |\n             *                                                                           |\n             * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36      | CALLDATASIZE   | cds 0 0 0 0            |                       |\n             * 3d      | RETURNDATASIZE | 0 cds 0 0 0 0          |                       |\n             * 3d      | RETURNDATASIZE | 0 0 cds 0 0 0 0        |                       |\n             * 37      | CALLDATACOPY   | 0 0 0 0                | [0..cds): calldata    |\n             *                                                                           |\n             * ::: delegate call to the implementation contract :::::::::::::::::::::::: |\n             * 36      | CALLDATASIZE   | cds 0 0 0 0            | [0..cds): calldata    |\n             * 3d      | RETURNDATASIZE | 0 cds 0 0 0 0          | [0..cds): calldata    |\n             * 73 addr | PUSH20 addr    | addr 0 cds 0 0 0 0     | [0..cds): calldata    |\n             * 5a      | GAS            | gas addr 0 cds 0 0 0 0 | [0..cds): calldata    |\n             * f4      | DELEGATECALL   | success 0 0            | [0..cds): calldata    |\n             *                                                                           |\n             * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: |\n             * 3d      | RETURNDATASIZE | rds success 0 0        | [0..cds): calldata    |\n             * 3d      | RETURNDATASIZE | rds rds success 0 0    | [0..cds): calldata    |\n             * 93      | SWAP4          | 0 rds success 0 rds    | [0..cds): calldata    |\n             * 80      | DUP1           | 0 0 rds success 0 rds  | [0..cds): calldata    |\n             * 3e      | RETURNDATACOPY | success 0 rds          | [0..rds): returndata  |\n             *                                                                           |\n             * 60 0x2a | PUSH1 0x2a     | 0x2a success 0 rds     | [0..rds): returndata  |\n             * 57      | JUMPI          | 0 rds                  | [0..rds): returndata  |\n             *                                                                           |\n             * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * fd      | REVERT         |                        | [0..rds): returndata  |\n             *                                                                           |\n             * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b      | JUMPDEST       | 0 rds                  | [0..rds): returndata  |\n             * f3      | RETURN         |                        | [0..rds): returndata  |\n             * --------------------------------------------------------------------------+\n             */\n            mstore(0x21, 0x5af43d3d93803e602a57fd5bf3)\n            mstore(0x14, implementation)\n            mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73)\n            instance := create(value, 0x0c, 0x35)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Deploys a deterministic clone of `implementation` with `salt`.\n    function cloneDeterministic(address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        instance = cloneDeterministic(0, implementation, salt);\n    }\n\n    /// @dev Deploys a deterministic clone of `implementation` with `salt`.\n    /// Deposits `value` ETH during deployment.\n    function cloneDeterministic(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x21, 0x5af43d3d93803e602a57fd5bf3)\n            mstore(0x14, implementation)\n            mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73)\n            instance := create2(value, 0x0c, 0x35, salt)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Returns the initialization code of the clone of `implementation`.\n    function initCode(address implementation) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            mstore(add(result, 0x40), 0x5af43d3d93803e602a57fd5bf30000000000000000000000)\n            mstore(add(result, 0x28), implementation)\n            mstore(add(result, 0x14), 0x602c3d8160093d39f33d3d3d3d363d3d37363d73)\n            mstore(result, 0x35) // Store the length.\n            mstore(0x40, add(result, 0x60)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the clone of `implementation`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHash(address implementation) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x21, 0x5af43d3d93803e602a57fd5bf3)\n            mstore(0x14, implementation)\n            mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73)\n            hash := keccak256(0x0c, 0x35)\n            mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Returns the address of the deterministic clone of `implementation`,\n    /// with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddress(address implementation, bytes32 salt, address deployer)\n        internal\n        pure\n        returns (address predicted)\n    {\n        bytes32 hash = initCodeHash(implementation);\n        predicted = predictDeterministicAddress(hash, salt, deployer);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*          MINIMAL PROXY OPERATIONS (PUSH0 VARIANT)          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Deploys a PUSH0 clone of `implementation`.\n    function clone_PUSH0(address implementation) internal returns (address instance) {\n        instance = clone_PUSH0(0, implementation);\n    }\n\n    /// @dev Deploys a PUSH0 clone of `implementation`.\n    /// Deposits `value` ETH during deployment.\n    function clone_PUSH0(uint256 value, address implementation)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            /**\n             * --------------------------------------------------------------------------+\n             * CREATION (9 bytes)                                                        |\n             * --------------------------------------------------------------------------|\n             * Opcode     | Mnemonic          | Stack     | Memory                       |\n             * --------------------------------------------------------------------------|\n             * 60 runSize | PUSH1 runSize     | r         |                              |\n             * 5f         | PUSH0             | 0 r       |                              |\n             * 81         | DUP2              | r 0 r     |                              |\n             * 60 offset  | PUSH1 offset      | o r 0 r   |                              |\n             * 5f         | PUSH0             | 0 o r 0 r |                              |\n             * 39         | CODECOPY          | 0 r       | [0..runSize): runtime code   |\n             * f3         | RETURN            |           | [0..runSize): runtime code   |\n             * --------------------------------------------------------------------------|\n             * RUNTIME (45 bytes)                                                        |\n             * --------------------------------------------------------------------------|\n             * Opcode  | Mnemonic       | Stack                  | Memory                |\n             * --------------------------------------------------------------------------|\n             *                                                                           |\n             * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: |\n             * 5f      | PUSH0          | 0                      |                       |\n             * 5f      | PUSH0          | 0 0                    |                       |\n             *                                                                           |\n             * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36      | CALLDATASIZE   | cds 0 0                |                       |\n             * 5f      | PUSH0          | 0 cds 0 0              |                       |\n             * 5f      | PUSH0          | 0 0 cds 0 0            |                       |\n             * 37      | CALLDATACOPY   | 0 0                    | [0..cds): calldata    |\n             *                                                                           |\n             * ::: delegate call to the implementation contract :::::::::::::::::::::::: |\n             * 36      | CALLDATASIZE   | cds 0 0                | [0..cds): calldata    |\n             * 5f      | PUSH0          | 0 cds 0 0              | [0..cds): calldata    |\n             * 73 addr | PUSH20 addr    | addr 0 cds 0 0         | [0..cds): calldata    |\n             * 5a      | GAS            | gas addr 0 cds 0 0     | [0..cds): calldata    |\n             * f4      | DELEGATECALL   | success                | [0..cds): calldata    |\n             *                                                                           |\n             * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: |\n             * 3d      | RETURNDATASIZE | rds success            | [0..cds): calldata    |\n             * 5f      | PUSH0          | 0 rds success          | [0..cds): calldata    |\n             * 5f      | PUSH0          | 0 0 rds success        | [0..cds): calldata    |\n             * 3e      | RETURNDATACOPY | success                | [0..rds): returndata  |\n             *                                                                           |\n             * 60 0x29 | PUSH1 0x29     | 0x29 success           | [0..rds): returndata  |\n             * 57      | JUMPI          |                        | [0..rds): returndata  |\n             *                                                                           |\n             * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d      | RETURNDATASIZE | rds                    | [0..rds): returndata  |\n             * 5f      | PUSH0          | 0 rds                  | [0..rds): returndata  |\n             * fd      | REVERT         |                        | [0..rds): returndata  |\n             *                                                                           |\n             * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b      | JUMPDEST       |                        | [0..rds): returndata  |\n             * 3d      | RETURNDATASIZE | rds                    | [0..rds): returndata  |\n             * 5f      | PUSH0          | 0 rds                  | [0..rds): returndata  |\n             * f3      | RETURN         |                        | [0..rds): returndata  |\n             * --------------------------------------------------------------------------+\n             */\n            mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16\n            mstore(0x14, implementation) // 20\n            mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9\n            instance := create(value, 0x0e, 0x36)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x24, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`.\n    function cloneDeterministic_PUSH0(address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        instance = cloneDeterministic_PUSH0(0, implementation, salt);\n    }\n\n    /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`.\n    /// Deposits `value` ETH during deployment.\n    function cloneDeterministic_PUSH0(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16\n            mstore(0x14, implementation) // 20\n            mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9\n            instance := create2(value, 0x0e, 0x36, salt)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x24, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Returns the initialization code of the PUSH0 clone of `implementation`.\n    function initCode_PUSH0(address implementation) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            mstore(add(result, 0x40), 0x5af43d5f5f3e6029573d5ffd5b3d5ff300000000000000000000) // 16\n            mstore(add(result, 0x26), implementation) // 20\n            mstore(add(result, 0x12), 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9\n            mstore(result, 0x36) // Store the length.\n            mstore(0x40, add(result, 0x60)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the PUSH0 clone of `implementation`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHash_PUSH0(address implementation) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16\n            mstore(0x14, implementation) // 20\n            mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9\n            hash := keccak256(0x0e, 0x36)\n            mstore(0x24, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Returns the address of the deterministic PUSH0 clone of `implementation`,\n    /// with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddress_PUSH0(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        bytes32 hash = initCodeHash_PUSH0(implementation);\n        predicted = predictDeterministicAddress(hash, salt, deployer);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*           CLONES WITH IMMUTABLE ARGS OPERATIONS            */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // Note: This implementation of CWIA differs from the original implementation.\n    // If the calldata is empty, it will emit a `ReceiveETH(uint256)` event and skip the `DELEGATECALL`.\n\n    /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`.\n    function clone(address implementation, bytes memory data) internal returns (address instance) {\n        instance = clone(0, implementation, data);\n    }\n\n    /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`.\n    /// Deposits `value` ETH during deployment.\n    function clone(uint256 value, address implementation, bytes memory data)\n        internal\n        returns (address instance)\n    {\n        assembly {\n            // Compute the boundaries of the data and cache the memory slots around it.\n            let mBefore3 := mload(sub(data, 0x60))\n            let mBefore2 := mload(sub(data, 0x40))\n            let mBefore1 := mload(sub(data, 0x20))\n            let dataLength := mload(data)\n            let dataEnd := add(add(data, 0x20), dataLength)\n            let mAfter1 := mload(dataEnd)\n\n            // +2 bytes for telling how much data there is appended to the call.\n            let extraLength := add(dataLength, 2)\n            // The `creationSize` is `extraLength + 108`\n            // The `runSize` is `creationSize - 10`.\n\n            /**\n             * ---------------------------------------------------------------------------------------------------+\n             * CREATION (10 bytes)                                                                                |\n             * ---------------------------------------------------------------------------------------------------|\n             * Opcode     | Mnemonic          | Stack     | Memory                                                |\n             * ---------------------------------------------------------------------------------------------------|\n             * 61 runSize | PUSH2 runSize     | r         |                                                       |\n             * 3d         | RETURNDATASIZE    | 0 r       |                                                       |\n             * 81         | DUP2              | r 0 r     |                                                       |\n             * 60 offset  | PUSH1 offset      | o r 0 r   |                                                       |\n             * 3d         | RETURNDATASIZE    | 0 o r 0 r |                                                       |\n             * 39         | CODECOPY          | 0 r       | [0..runSize): runtime code                            |\n             * f3         | RETURN            |           | [0..runSize): runtime code                            |\n             * ---------------------------------------------------------------------------------------------------|\n             * RUNTIME (98 bytes + extraLength)                                                                   |\n             * ---------------------------------------------------------------------------------------------------|\n             * Opcode   | Mnemonic       | Stack                    | Memory                                      |\n             * ---------------------------------------------------------------------------------------------------|\n             *                                                                                                    |\n             * ::: if no calldata, emit event & return w/o `DELEGATECALL` ::::::::::::::::::::::::::::::::::::::: |\n             * 36       | CALLDATASIZE   | cds                      |                                             |\n             * 60 0x2c  | PUSH1 0x2c     | 0x2c cds                 |                                             |\n             * 57       | JUMPI          |                          |                                             |\n             * 34       | CALLVALUE      | cv                       |                                             |\n             * 3d       | RETURNDATASIZE | 0 cv                     |                                             |\n             * 52       | MSTORE         |                          | [0..0x20): callvalue                        |\n             * 7f sig   | PUSH32 0x9e..  | sig                      | [0..0x20): callvalue                        |\n             * 59       | MSIZE          | 0x20 sig                 | [0..0x20): callvalue                        |\n             * 3d       | RETURNDATASIZE | 0 0x20 sig               | [0..0x20): callvalue                        |\n             * a1       | LOG1           |                          | [0..0x20): callvalue                        |\n             * 00       | STOP           |                          | [0..0x20): callvalue                        |\n             * 5b       | JUMPDEST       |                          |                                             |\n             *                                                                                                    |\n             * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36       | CALLDATASIZE   | cds                      |                                             |\n             * 3d       | RETURNDATASIZE | 0 cds                    |                                             |\n             * 3d       | RETURNDATASIZE | 0 0 cds                  |                                             |\n             * 37       | CALLDATACOPY   |                          | [0..cds): calldata                          |\n             *                                                                                                    |\n             * ::: keep some values in stack :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d       | RETURNDATASIZE | 0                        | [0..cds): calldata                          |\n             * 3d       | RETURNDATASIZE | 0 0                      | [0..cds): calldata                          |\n             * 3d       | RETURNDATASIZE | 0 0 0                    | [0..cds): calldata                          |\n             * 3d       | RETURNDATASIZE | 0 0 0 0                  | [0..cds): calldata                          |\n             * 61 extra | PUSH2 extra    | e 0 0 0 0                | [0..cds): calldata                          |\n             *                                                                                                    |\n             * ::: copy extra data to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 80       | DUP1           | e e 0 0 0 0              | [0..cds): calldata                          |\n             * 60 0x62  | PUSH1 0x62     | 0x62 e e 0 0 0 0         | [0..cds): calldata                          |\n             * 36       | CALLDATASIZE   | cds 0x62 e e 0 0 0 0     | [0..cds): calldata                          |\n             * 39       | CODECOPY       | e 0 0 0 0                | [0..cds): calldata, [cds..cds+e): extraData |\n             *                                                                                                    |\n             * ::: delegate call to the implementation contract ::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36       | CALLDATASIZE   | cds e 0 0 0 0            | [0..cds): calldata, [cds..cds+e): extraData |\n             * 01       | ADD            | cds+e 0 0 0 0            | [0..cds): calldata, [cds..cds+e): extraData |\n             * 3d       | RETURNDATASIZE | 0 cds+e 0 0 0 0          | [0..cds): calldata, [cds..cds+e): extraData |\n             * 73 addr  | PUSH20 addr    | addr 0 cds+e 0 0 0 0     | [0..cds): calldata, [cds..cds+e): extraData |\n             * 5a       | GAS            | gas addr 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData |\n             * f4       | DELEGATECALL   | success 0 0              | [0..cds): calldata, [cds..cds+e): extraData |\n             *                                                                                                    |\n             * ::: copy return data to memory ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d       | RETURNDATASIZE | rds success 0 0          | [0..cds): calldata, [cds..cds+e): extraData |\n             * 3d       | RETURNDATASIZE | rds rds success 0 0      | [0..cds): calldata, [cds..cds+e): extraData |\n             * 93       | SWAP4          | 0 rds success 0 rds      | [0..cds): calldata, [cds..cds+e): extraData |\n             * 80       | DUP1           | 0 0 rds success 0 rds    | [0..cds): calldata, [cds..cds+e): extraData |\n             * 3e       | RETURNDATACOPY | success 0 rds            | [0..rds): returndata                        |\n             *                                                                                                    |\n             * 60 0x60  | PUSH1 0x60     | 0x60 success 0 rds       | [0..rds): returndata                        |\n             * 57       | JUMPI          | 0 rds                    | [0..rds): returndata                        |\n             *                                                                                                    |\n             * ::: revert ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * fd       | REVERT         |                          | [0..rds): returndata                        |\n             *                                                                                                    |\n             * ::: return ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b       | JUMPDEST       | 0 rds                    | [0..rds): returndata                        |\n             * f3       | RETURN         |                          | [0..rds): returndata                        |\n             * ---------------------------------------------------------------------------------------------------+\n             */\n            mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data.\n            mstore(sub(data, 0x0d), implementation) // Write the address of the implementation.\n            // Write the rest of the bytecode.\n            mstore(\n                sub(data, 0x21),\n                or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73)\n            )\n            // `keccak256(\"ReceiveETH(uint256)\")`\n            mstore(\n                sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff\n            )\n            mstore(\n                // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e.\n                // The actual EVM limit may be smaller and may change over time.\n                sub(data, add(0x59, lt(extraLength, 0xff9e))),\n                or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f)\n            )\n            mstore(dataEnd, shl(0xf0, extraLength))\n\n            instance := create(value, sub(data, 0x4c), add(extraLength, 0x6c))\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n\n            // Restore the overwritten memory surrounding `data`.\n            mstore(dataEnd, mAfter1)\n            mstore(data, dataLength)\n            mstore(sub(data, 0x20), mBefore1)\n            mstore(sub(data, 0x40), mBefore2)\n            mstore(sub(data, 0x60), mBefore3)\n        }\n    }\n\n    /// @dev Deploys a deterministic clone of `implementation`\n    /// with immutable arguments encoded in `data` and `salt`.\n    function cloneDeterministic(address implementation, bytes memory data, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        instance = cloneDeterministic(0, implementation, data, salt);\n    }\n\n    /// @dev Deploys a deterministic clone of `implementation`\n    /// with immutable arguments encoded in `data` and `salt`.\n    function cloneDeterministic(\n        uint256 value,\n        address implementation,\n        bytes memory data,\n        bytes32 salt\n    ) internal returns (address instance) {\n        assembly {\n            // Compute the boundaries of the data and cache the memory slots around it.\n            let mBefore3 := mload(sub(data, 0x60))\n            let mBefore2 := mload(sub(data, 0x40))\n            let mBefore1 := mload(sub(data, 0x20))\n            let dataLength := mload(data)\n            let dataEnd := add(add(data, 0x20), dataLength)\n            let mAfter1 := mload(dataEnd)\n\n            // +2 bytes for telling how much data there is appended to the call.\n            let extraLength := add(dataLength, 2)\n\n            mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data.\n            mstore(sub(data, 0x0d), implementation) // Write the address of the implementation.\n            // Write the rest of the bytecode.\n            mstore(\n                sub(data, 0x21),\n                or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73)\n            )\n            // `keccak256(\"ReceiveETH(uint256)\")`\n            mstore(\n                sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff\n            )\n            mstore(\n                // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e.\n                // The actual EVM limit may be smaller and may change over time.\n                sub(data, add(0x59, lt(extraLength, 0xff9e))),\n                or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f)\n            )\n            mstore(dataEnd, shl(0xf0, extraLength))\n\n            instance := create2(value, sub(data, 0x4c), add(extraLength, 0x6c), salt)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n\n            // Restore the overwritten memory surrounding `data`.\n            mstore(dataEnd, mAfter1)\n            mstore(data, dataLength)\n            mstore(sub(data, 0x20), mBefore1)\n            mstore(sub(data, 0x40), mBefore2)\n            mstore(sub(data, 0x60), mBefore3)\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the clone of `implementation`\n    /// using immutable arguments encoded in `data`.\n    function initCode(address implementation, bytes memory data)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let dataLength := mload(data)\n\n            // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b.\n            // The actual EVM limit may be smaller and may change over time.\n            returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b))\n\n            let o := add(result, 0x8c)\n            let end := add(o, dataLength)\n\n            // Copy the `data` into `result`.\n            for { let d := sub(add(data, 0x20), o) } 1 {} {\n                mstore(o, mload(add(o, d)))\n                o := add(o, 0x20)\n                if iszero(lt(o, end)) { break }\n            }\n\n            // +2 bytes for telling how much data there is appended to the call.\n            let extraLength := add(dataLength, 2)\n\n            mstore(add(result, 0x6c), 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data.\n            mstore(add(result, 0x5f), implementation) // Write the address of the implementation.\n            // Write the rest of the bytecode.\n            mstore(\n                add(result, 0x4b),\n                or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73)\n            )\n            // `keccak256(\"ReceiveETH(uint256)\")`\n            mstore(\n                add(result, 0x32),\n                0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff\n            )\n            mstore(\n                add(result, 0x12),\n                or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f)\n            )\n            mstore(end, shl(0xf0, extraLength))\n            mstore(add(end, 0x02), 0) // Zeroize the slot after the result.\n            mstore(result, add(extraLength, 0x6c)) // Store the length.\n            mstore(0x40, add(0x22, end)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the clone of `implementation`\n    /// using immutable arguments encoded in `data`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHash(address implementation, bytes memory data)\n        internal\n        pure\n        returns (bytes32 hash)\n    {\n        assembly {\n            // Compute the boundaries of the data and cache the memory slots around it.\n            let mBefore3 := mload(sub(data, 0x60))\n            let mBefore2 := mload(sub(data, 0x40))\n            let mBefore1 := mload(sub(data, 0x20))\n            let dataLength := mload(data)\n            let dataEnd := add(add(data, 0x20), dataLength)\n            let mAfter1 := mload(dataEnd)\n\n            // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b.\n            // The actual EVM limit may be smaller and may change over time.\n            returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b))\n\n            // +2 bytes for telling how much data there is appended to the call.\n            let extraLength := add(dataLength, 2)\n\n            mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data.\n            mstore(sub(data, 0x0d), implementation) // Write the address of the implementation.\n            // Write the rest of the bytecode.\n            mstore(\n                sub(data, 0x21),\n                or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73)\n            )\n            // `keccak256(\"ReceiveETH(uint256)\")`\n            mstore(\n                sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff\n            )\n            mstore(\n                sub(data, 0x5a),\n                or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f)\n            )\n            mstore(dataEnd, shl(0xf0, extraLength))\n\n            hash := keccak256(sub(data, 0x4c), add(extraLength, 0x6c))\n\n            // Restore the overwritten memory surrounding `data`.\n            mstore(dataEnd, mAfter1)\n            mstore(data, dataLength)\n            mstore(sub(data, 0x20), mBefore1)\n            mstore(sub(data, 0x40), mBefore2)\n            mstore(sub(data, 0x60), mBefore3)\n        }\n    }\n\n    /// @dev Returns the address of the deterministic clone of\n    /// `implementation` using immutable arguments encoded in `data`, with `salt`, by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddress(\n        address implementation,\n        bytes memory data,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        bytes32 hash = initCodeHash(implementation, data);\n        predicted = predictDeterministicAddress(hash, salt, deployer);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*              MINIMAL ERC1967 PROXY OPERATIONS              */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // Note: The ERC1967 proxy here is intended to be upgraded with UUPS.\n    // This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic.\n\n    /// @dev Deploys a minimal ERC1967 proxy with `implementation`.\n    function deployERC1967(address implementation) internal returns (address instance) {\n        instance = deployERC1967(0, implementation);\n    }\n\n    /// @dev Deploys a minimal ERC1967 proxy with `implementation`.\n    /// Deposits `value` ETH during deployment.\n    function deployERC1967(uint256 value, address implementation)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            /**\n             * ---------------------------------------------------------------------------------+\n             * CREATION (34 bytes)                                                              |\n             * ---------------------------------------------------------------------------------|\n             * Opcode     | Mnemonic       | Stack            | Memory                          |\n             * ---------------------------------------------------------------------------------|\n             * 60 runSize | PUSH1 runSize  | r                |                                 |\n             * 3d         | RETURNDATASIZE | 0 r              |                                 |\n             * 81         | DUP2           | r 0 r            |                                 |\n             * 60 offset  | PUSH1 offset   | o r 0 r          |                                 |\n             * 3d         | RETURNDATASIZE | 0 o r 0 r        |                                 |\n             * 39         | CODECOPY       | 0 r              | [0..runSize): runtime code      |\n             * 73 impl    | PUSH20 impl    | impl 0 r         | [0..runSize): runtime code      |\n             * 60 slotPos | PUSH1 slotPos  | slotPos impl 0 r | [0..runSize): runtime code      |\n             * 51         | MLOAD          | slot impl 0 r    | [0..runSize): runtime code      |\n             * 55         | SSTORE         | 0 r              | [0..runSize): runtime code      |\n             * f3         | RETURN         |                  | [0..runSize): runtime code      |\n             * ---------------------------------------------------------------------------------|\n             * RUNTIME (61 bytes)                                                               |\n             * ---------------------------------------------------------------------------------|\n             * Opcode     | Mnemonic       | Stack            | Memory                          |\n             * ---------------------------------------------------------------------------------|\n             *                                                                                  |\n             * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36         | CALLDATASIZE   | cds              |                                 |\n             * 3d         | RETURNDATASIZE | 0 cds            |                                 |\n             * 3d         | RETURNDATASIZE | 0 0 cds          |                                 |\n             * 37         | CALLDATACOPY   |                  | [0..calldatasize): calldata     |\n             *                                                                                  |\n             * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | 0                |                                 |\n             * 3d         | RETURNDATASIZE | 0 0              |                                 |\n             * 36         | CALLDATASIZE   | cds 0 0          | [0..calldatasize): calldata     |\n             * 3d         | RETURNDATASIZE | 0 cds 0 0        | [0..calldatasize): calldata     |\n             * 7f slot    | PUSH32 slot    | s 0 cds 0 0      | [0..calldatasize): calldata     |\n             * 54         | SLOAD          | i 0 cds 0 0      | [0..calldatasize): calldata     |\n             * 5a         | GAS            | g i 0 cds 0 0    | [0..calldatasize): calldata     |\n             * f4         | DELEGATECALL   | succ             | [0..calldatasize): calldata     |\n             *                                                                                  |\n             * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | rds succ         | [0..calldatasize): calldata     |\n             * 60 0x00    | PUSH1 0x00     | 0 rds succ       | [0..calldatasize): calldata     |\n             * 80         | DUP1           | 0 0 rds succ     | [0..calldatasize): calldata     |\n             * 3e         | RETURNDATACOPY | succ             | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: |\n             * 60 0x38    | PUSH1 0x38     | dest succ        | [0..returndatasize): returndata |\n             * 57         | JUMPI          |                  | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | rds              | [0..returndatasize): returndata |\n             * 60 0x00    | PUSH1 0x00     | 0 rds            | [0..returndatasize): returndata |\n             * fd         | REVERT         |                  | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b         | JUMPDEST       |                  | [0..returndatasize): returndata |\n             * 3d         | RETURNDATASIZE | rds              | [0..returndatasize): returndata |\n             * 60 0x00    | PUSH1 0x00     | 0 rds            | [0..returndatasize): returndata |\n             * f3         | RETURN         |                  | [0..returndatasize): returndata |\n             * ---------------------------------------------------------------------------------+\n             */\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3)\n            mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076)\n            mstore(0x20, 0x6009)\n            mstore(0x1e, implementation)\n            mstore(0x0a, 0x603d3d8160223d3973)\n            instance := create(value, 0x21, 0x5f)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`.\n    function deployDeterministicERC1967(address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        instance = deployDeterministicERC1967(0, implementation, salt);\n    }\n\n    /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`.\n    /// Deposits `value` ETH during deployment.\n    function deployDeterministicERC1967(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3)\n            mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076)\n            mstore(0x20, 0x6009)\n            mstore(0x1e, implementation)\n            mstore(0x0a, 0x603d3d8160223d3973)\n            instance := create2(value, 0x21, 0x5f, salt)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`.\n    /// Note: This method is intended for use in ERC4337 factories,\n    /// which are expected to NOT revert if the proxy is already deployed.\n    function createDeterministicERC1967(address implementation, bytes32 salt)\n        internal\n        returns (bool alreadyDeployed, address instance)\n    {\n        return createDeterministicERC1967(0, implementation, salt);\n    }\n\n    /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`.\n    /// Deposits `value` ETH during deployment.\n    /// Note: This method is intended for use in ERC4337 factories,\n    /// which are expected to NOT revert if the proxy is already deployed.\n    function createDeterministicERC1967(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (bool alreadyDeployed, address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3)\n            mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076)\n            mstore(0x20, 0x6009)\n            mstore(0x1e, implementation)\n            mstore(0x0a, 0x603d3d8160223d3973)\n            // Compute and store the bytecode hash.\n            mstore(add(m, 0x35), keccak256(0x21, 0x5f))\n            mstore(m, shl(88, address()))\n            mstore8(m, 0xff) // Write the prefix.\n            mstore(add(m, 0x15), salt)\n            instance := keccak256(m, 0x55)\n            for {} 1 {} {\n                if iszero(extcodesize(instance)) {\n                    instance := create2(value, 0x21, 0x5f, salt)\n                    if iszero(instance) {\n                        mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                        revert(0x1c, 0x04)\n                    }\n                    break\n                }\n                alreadyDeployed := 1\n                if iszero(value) { break }\n                if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) {\n                    mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                    revert(0x1c, 0x04)\n                }\n                break\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation`.\n    function initCodeERC1967(address implementation) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            mstore(\n                add(result, 0x60),\n                0x3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f300\n            )\n            mstore(\n                add(result, 0x40),\n                0x55f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc\n            )\n            mstore(add(result, 0x20), or(shl(24, implementation), 0x600951))\n            mstore(add(result, 0x09), 0x603d3d8160223d3973)\n            mstore(result, 0x5f) // Store the length.\n            mstore(0x40, add(result, 0x80)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHashERC1967(address implementation) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3)\n            mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076)\n            mstore(0x20, 0x6009)\n            mstore(0x1e, implementation)\n            mstore(0x0a, 0x603d3d8160223d3973)\n            hash := keccak256(0x21, 0x5f)\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Returns the address of the deterministic ERC1967 proxy of `implementation`,\n    /// with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddressERC1967(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        bytes32 hash = initCodeHashERC1967(implementation);\n        predicted = predictDeterministicAddress(hash, salt, deployer);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                 ERC1967I PROXY OPERATIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // Note: This proxy has a special code path that activates if `calldatasize() == 1`.\n    // This code path skips the delegatecall and directly returns the `implementation` address.\n    // The returned implementation is guaranteed to be valid if the keccak256 of the\n    // proxy's code is equal to `ERC1967I_CODE_HASH`.\n\n    /// @dev Deploys a minimal ERC1967I proxy with `implementation`.\n    function deployERC1967I(address implementation) internal returns (address instance) {\n        instance = deployERC1967I(0, implementation);\n    }\n\n    /// @dev Deploys a ERC1967I proxy with `implementation`.\n    /// Deposits `value` ETH during deployment.\n    function deployERC1967I(uint256 value, address implementation)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            /**\n             * ---------------------------------------------------------------------------------+\n             * CREATION (34 bytes)                                                              |\n             * ---------------------------------------------------------------------------------|\n             * Opcode     | Mnemonic       | Stack            | Memory                          |\n             * ---------------------------------------------------------------------------------|\n             * 60 runSize | PUSH1 runSize  | r                |                                 |\n             * 3d         | RETURNDATASIZE | 0 r              |                                 |\n             * 81         | DUP2           | r 0 r            |                                 |\n             * 60 offset  | PUSH1 offset   | o r 0 r          |                                 |\n             * 3d         | RETURNDATASIZE | 0 o r 0 r        |                                 |\n             * 39         | CODECOPY       | 0 r              | [0..runSize): runtime code      |\n             * 73 impl    | PUSH20 impl    | impl 0 r         | [0..runSize): runtime code      |\n             * 60 slotPos | PUSH1 slotPos  | slotPos impl 0 r | [0..runSize): runtime code      |\n             * 51         | MLOAD          | slot impl 0 r    | [0..runSize): runtime code      |\n             * 55         | SSTORE         | 0 r              | [0..runSize): runtime code      |\n             * f3         | RETURN         |                  | [0..runSize): runtime code      |\n             * ---------------------------------------------------------------------------------|\n             * RUNTIME (82 bytes)                                                               |\n             * ---------------------------------------------------------------------------------|\n             * Opcode     | Mnemonic       | Stack            | Memory                          |\n             * ---------------------------------------------------------------------------------|\n             *                                                                                  |\n             * ::: check calldatasize ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36         | CALLDATASIZE   | cds              |                                 |\n             * 58         | PC             | 1 cds            |                                 |\n             * 14         | EQ             | eqs              |                                 |\n             * 60 0x43    | PUSH1 0x43     | dest eqs         |                                 |\n             * 57         | JUMPI          |                  |                                 |\n             *                                                                                  |\n             * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 36         | CALLDATASIZE   | cds              |                                 |\n             * 3d         | RETURNDATASIZE | 0 cds            |                                 |\n             * 3d         | RETURNDATASIZE | 0 0 cds          |                                 |\n             * 37         | CALLDATACOPY   |                  | [0..calldatasize): calldata     |\n             *                                                                                  |\n             * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | 0                |                                 |\n             * 3d         | RETURNDATASIZE | 0 0              |                                 |\n             * 36         | CALLDATASIZE   | cds 0 0          | [0..calldatasize): calldata     |\n             * 3d         | RETURNDATASIZE | 0 cds 0 0        | [0..calldatasize): calldata     |\n             * 7f slot    | PUSH32 slot    | s 0 cds 0 0      | [0..calldatasize): calldata     |\n             * 54         | SLOAD          | i 0 cds 0 0      | [0..calldatasize): calldata     |\n             * 5a         | GAS            | g i 0 cds 0 0    | [0..calldatasize): calldata     |\n             * f4         | DELEGATECALL   | succ             | [0..calldatasize): calldata     |\n             *                                                                                  |\n             * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | rds succ         | [0..calldatasize): calldata     |\n             * 60 0x00    | PUSH1 0x00     | 0 rds succ       | [0..calldatasize): calldata     |\n             * 80         | DUP1           | 0 0 rds succ     | [0..calldatasize): calldata     |\n             * 3e         | RETURNDATACOPY | succ             | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: |\n             * 60 0x3E    | PUSH1 0x3E     | dest succ        | [0..returndatasize): returndata |\n             * 57         | JUMPI          |                  | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 3d         | RETURNDATASIZE | rds              | [0..returndatasize): returndata |\n             * 60 0x00    | PUSH1 0x00     | 0 rds            | [0..returndatasize): returndata |\n             * fd         | REVERT         |                  | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b         | JUMPDEST       |                  | [0..returndatasize): returndata |\n             * 3d         | RETURNDATASIZE | rds              | [0..returndatasize): returndata |\n             * 60 0x00    | PUSH1 0x00     | 0 rds            | [0..returndatasize): returndata |\n             * f3         | RETURN         |                  | [0..returndatasize): returndata |\n             *                                                                                  |\n             * ::: implementation , return :::::::::::::::::::::::::::::::::::::::::::::::::::: |\n             * 5b         | JUMPDEST       |                  |                                 |\n             * 60 0x20    | PUSH1 0x20     | 32               |                                 |\n             * 60 0x0F    | PUSH1 0x0F     | o 32             |                                 |\n             * 3d         | RETURNDATASIZE | 0 o 32           |                                 |\n             * 39         | CODECOPY       |                  | [0..32): implementation slot    |\n             * 3d         | RETURNDATASIZE | 0                | [0..32): implementation slot    |\n             * 51         | MLOAD          | slot             | [0..32): implementation slot    |\n             * 54         | SLOAD          | impl             | [0..32): implementation slot    |\n             * 3d         | RETURNDATASIZE | 0 impl           | [0..32): implementation slot    |\n             * 52         | MSTORE         |                  | [0..32): implementation address |\n             * 59         | MSIZE          | 32               | [0..32): implementation address |\n             * 3d         | RETURNDATASIZE | 0 32             | [0..32): implementation address |\n             * f3         | RETURN         |                  | [0..32): implementation address |\n             *                                                                                  |\n             * ---------------------------------------------------------------------------------+\n             */\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3)\n            mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4)\n            mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894)\n            mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation))))\n            instance := create(value, 0x0c, 0x74)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`.\n    function deployDeterministicERC1967I(address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        instance = deployDeterministicERC1967I(0, implementation, salt);\n    }\n\n    /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`.\n    /// Deposits `value` ETH during deployment.\n    function deployDeterministicERC1967I(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3)\n            mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4)\n            mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894)\n            mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation))))\n            instance := create2(value, 0x0c, 0x74, salt)\n            if iszero(instance) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`.\n    /// Note: This method is intended for use in ERC4337 factories,\n    /// which are expected to NOT revert if the proxy is already deployed.\n    function createDeterministicERC1967I(address implementation, bytes32 salt)\n        internal\n        returns (bool alreadyDeployed, address instance)\n    {\n        return createDeterministicERC1967I(0, implementation, salt);\n    }\n\n    /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`.\n    /// Deposits `value` ETH during deployment.\n    /// Note: This method is intended for use in ERC4337 factories,\n    /// which are expected to NOT revert if the proxy is already deployed.\n    function createDeterministicERC1967I(uint256 value, address implementation, bytes32 salt)\n        internal\n        returns (bool alreadyDeployed, address instance)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3)\n            mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4)\n            mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894)\n            mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation))))\n            // Compute and store the bytecode hash.\n            mstore(add(m, 0x35), keccak256(0x0c, 0x74))\n            mstore(m, shl(88, address()))\n            mstore8(m, 0xff) // Write the prefix.\n            mstore(add(m, 0x15), salt)\n            instance := keccak256(m, 0x55)\n            for {} 1 {} {\n                if iszero(extcodesize(instance)) {\n                    instance := create2(value, 0x0c, 0x74, salt)\n                    if iszero(instance) {\n                        mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                        revert(0x1c, 0x04)\n                    }\n                    break\n                }\n                alreadyDeployed := 1\n                if iszero(value) { break }\n                if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) {\n                    mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                    revert(0x1c, 0x04)\n                }\n                break\n            }\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation`.\n    function initCodeERC1967I(address implementation) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            mstore(\n                add(result, 0x74),\n                0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3\n            )\n            mstore(\n                add(result, 0x54),\n                0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4\n            )\n            mstore(add(result, 0x34), 0x600f5155f3365814604357363d3d373d3d363d7f360894)\n            mstore(add(result, 0x1d), implementation)\n            mstore(add(result, 0x09), 0x60523d8160223d3973)\n            mstore(add(result, 0x94), 0)\n            mstore(result, 0x74) // Store the length.\n            mstore(0x40, add(result, 0xa0)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHashERC1967I(address implementation) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3)\n            mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4)\n            mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894)\n            mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation))))\n            hash := keccak256(0x0c, 0x74)\n            mstore(0x40, m) // Restore the free memory pointer.\n            mstore(0x60, 0) // Restore the zero slot.\n        }\n    }\n\n    /// @dev Returns the address of the deterministic ERC1967I proxy of `implementation`,\n    /// with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddressERC1967I(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        bytes32 hash = initCodeHashERC1967I(implementation);\n        predicted = predictDeterministicAddress(hash, salt, deployer);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      OTHER OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the address when a contract with initialization code hash,\n    /// `hash`, is deployed with `salt`, by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictDeterministicAddress(bytes32 hash, bytes32 salt, address deployer)\n        internal\n        pure\n        returns (address predicted)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and store the bytecode hash.\n            mstore8(0x00, 0xff) // Write the prefix.\n            mstore(0x35, hash)\n            mstore(0x01, shl(96, deployer))\n            mstore(0x15, salt)\n            predicted := keccak256(0x00, 0x55)\n            mstore(0x35, 0) // Restore the overwritten part of the free memory pointer.\n        }\n    }\n\n    /// @dev Requires that `salt` starts with either the zero address or `by`.\n    function checkStartsWith(bytes32 salt, address by) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If the salt does not start with the zero address or `by`.\n            if iszero(or(iszero(shr(96, salt)), eq(shr(96, shl(96, by)), shr(96, salt)))) {\n                mstore(0x00, 0x0c4549ef) // `SaltDoesNotStartWith()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n}\n"
      },
      "src/base/interfaces/IStrategy.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ninterface IStrategy {\n    function locker() external view returns (address);\n\n    function deposit(address _token, uint256 amount) external;\n    function withdraw(address _token, uint256 amount) external;\n\n    function claimProtocolFees() external;\n    function claimNativeRewards() external;\n    function harvest(address _asset, bool _distributeSDT, bool _claimExtra) external;\n\n    function rewardReceivers(address _gauge) external view returns (address);\n    function rewardDistributors(address _gauge) external view returns (address);\n\n    /// Factory functions\n    function toggleVault(address vault) external;\n    function setGauge(address token, address gauge) external;\n    function setLGtype(address gauge, uint256 gaugeType) external;\n    function addRewardToken(address _token, address _rewardDistributor) external;\n    function acceptRewardDistributorOwnership(address rewardDistributor) external;\n    function setRewardDistributor(address gauge, address rewardDistributor) external;\n    function addRewardReceiver(address gauge, address rewardReceiver) external;\n\n    function execute(address _to, uint256 _value, bytes calldata _data) external returns (bool, bytes memory);\n}\n"
      },
      "src/base/interfaces/IFallback.sol": {
        "content": "/// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.19;\n\ninterface IFallback {\n    function initialize() external;\n    function claim(bool _claimExtraRewards)\n        external\n        returns (uint256 rewardTokenAmount, uint256 fallbackRewardTokenAmount, uint256 protocolFees);\n    function balanceOf(address _asset) external view returns (uint256);\n    function deposit(address _asset, uint256 _amount) external;\n    function withdraw(address _asset, uint256 _amount) external;\n    function fallbackRewardToken() external view returns (address);\n}\n"
      },
      "src/base/interfaces/ILiquidityGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\ninterface ILiquidityGauge {\n    struct Reward {\n        address token;\n        address distributor;\n        uint256 period_finish;\n        uint256 rate;\n        uint256 last_update;\n        uint256 integral;\n    }\n\n    function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n\n    function claim_rewards_for(address _user, address _recipient) external;\n\n    function working_balances(address _address) external view returns (uint256);\n\n    function deposit(uint256 _value, address _addr) external;\n\n    function reward_tokens(uint256 _i) external view returns (address);\n\n    function reward_data(address _tokenReward) external view returns (Reward memory);\n\n    function balanceOf(address) external view returns (uint256);\n\n    function totalSupply() external view returns (uint256);\n\n    function claimable_reward(address _user, address _reward_token) external view returns (uint256);\n\n    function claimable_tokens(address _user) external returns (uint256);\n\n    function user_checkpoint(address _user) external returns (bool);\n\n    function commit_transfer_ownership(address) external;\n\n    function apply_transfer_ownership() external;\n\n    function claim_rewards(address) external;\n\n    function add_reward(address, address) external;\n\n    function set_claimer(address) external;\n\n    function admin() external view returns (address);\n\n    function set_reward_distributor(address _rewardToken, address _newDistrib) external;\n\n    function lp_token() external view returns (address);\n\n    function is_killed() external view returns (bool);\n\n    function staking_token() external view returns (address);\n}\n"
      },
      "src/base/interfaces/ISDLiquidityGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.19;\n\n/// Modified version of the liquidity for Stake DAO needs.\ninterface ISDLiquidityGauge {\n    struct Reward {\n        address token;\n        address distributor;\n        uint256 period_finish;\n        uint256 rate;\n        uint256 last_update;\n        uint256 integral;\n    }\n\n    // solhint-disable-next-line\n    function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n\n    // solhint-disable-next-line\n    function claim_rewards_for(address _user, address _recipient) external;\n\n    function claim_rewards() external;\n\n    function claim_rewards(address _user) external;\n\n    function claim_rewards(address _user, address _receiver) external;\n\n    // // solhint-disable-next-line\n    // function claim_rewards_for(address _user) external;\n\n    // solhint-disable-next-line\n    function deposit(uint256 _value, address _addr) external;\n\n    // solhint-disable-next-line\n    function reward_tokens(uint256 _i) external view returns (address);\n\n    function withdraw(uint256 _value, address _addr, bool _claim_rewards) external;\n\n    function withdraw(uint256 _value, address _addr) external;\n\n    function staking_token() external view returns (address);\n\n    function vault() external view returns (address);\n\n    // solhint-disable-next-line\n    function reward_data(address _tokenReward) external view returns (Reward memory);\n\n    function reward_count() external view returns (uint256);\n\n    function totalSupply() external view returns (uint256);\n\n    function balanceOf(address) external returns (uint256);\n\n    function claimable_reward(address _user, address _reward_token) external view returns (uint256);\n\n    function user_checkpoint(address _user) external returns (bool);\n\n    function commit_transfer_ownership(address) external;\n\n    function initialize(\n        address _staking_token,\n        address _admin,\n        address _SDT,\n        address _voting_escrow,\n        address _veBoost_proxy,\n        address _distributor,\n        address _vault,\n        string memory _symbol\n    ) external;\n\n    function add_reward(address, address) external;\n\n    function set_claimer(address) external;\n\n    function name() external view returns (string memory);\n\n    function symbol() external view returns (string memory);\n\n    function transfer(address _to, uint256 _value) external returns (bool);\n\n    function working_balances(address _address) external returns (uint256);\n\n    function set_reward_distributor(address _rewardToken, address _newDistrib) external;\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "solady/=lib/solady/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}