creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/orders/OrderProcessor.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.25;\n\nimport {\n    UUPSUpgradeable,\n    Initializable\n} from \"openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol\";\nimport {EIP712Upgradeable} from \"openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol\";\nimport {MulticallUpgradeable} from \"openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol\";\nimport {SafeERC20, IERC20} from \"openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20Metadata} from \"openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {ECDSA} from \"openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\";\nimport {Address} from \"openzeppelin-contracts/contracts/utils/Address.sol\";\nimport {mulDiv, mulDiv18} from \"prb-math/Common.sol\";\nimport {SelfPermit} from \"../common/SelfPermit.sol\";\nimport {IOrderProcessor} from \"./IOrderProcessor.sol\";\nimport {IDShare} from \"../IDShare.sol\";\nimport {FeeLib} from \"../common/FeeLib.sol\";\nimport {OracleLib} from \"../common/OracleLib.sol\";\nimport {IDShareFactory} from \"../IDShareFactory.sol\";\n\n/// @notice Core contract managing orders for dShare tokens\n/// @dev Assumes dShare asset tokens have 18 decimals and payment tokens have .decimals()\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/orders/OrderProcessor.sol)\ncontract OrderProcessor is\n    Initializable,\n    UUPSUpgradeable,\n    Ownable2StepUpgradeable,\n    EIP712Upgradeable,\n    MulticallUpgradeable,\n    SelfPermit,\n    IOrderProcessor\n{\n    using SafeERC20 for IERC20;\n    using Address for address;\n\n    /// ------------------ Types ------------------ ///\n\n    // Order state cleared after order is fulfilled or cancelled.\n    struct OrderState {\n        // Account that requested the order\n        address requester;\n        // Amount of order token remaining to be used\n        uint256 unfilledAmount;\n        // Buy order fees escrowed\n        uint256 feesEscrowed;\n        // Cumulative fees taken for order\n        uint256 feesTaken;\n    }\n\n    struct PaymentTokenConfig {\n        bool enabled;\n        // Assumes token decimals do not change\n        uint8 decimals;\n        // Token blacklist method selectors\n        bytes4 blacklistCallSelector;\n        // Standard fee schedule per paymentToken\n        uint64 perOrderFeeBuy;\n        uint24 percentageFeeRateBuy;\n        uint64 perOrderFeeSell;\n        uint24 percentageFeeRateSell;\n    }\n\n    /// @dev Signature deadline expired\n    error ExpiredSignature();\n    /// @dev Zero address\n    error ZeroAddress();\n    /// @dev Orders are paused\n    error Paused();\n    /// @dev Zero value\n    error ZeroValue();\n    /// @dev Order does not exist\n    error OrderNotFound();\n    error ExistingOrder();\n    /// @dev Amount too large\n    error AmountTooLarge();\n    error UnsupportedToken(address token);\n    /// @dev blacklist address\n    error Blacklist();\n    /// @dev Thrown when assetTokenQuantity's precision doesn't match the expected precision in orderDecimals.\n    error InvalidPrecision();\n    error LimitPriceNotSet();\n    error OrderFillBelowLimitPrice();\n    error OrderFillAboveLimitPrice();\n    error NotOperator();\n    error NotRequester();\n\n    /// @dev Emitted when `treasury` is set\n    event TreasurySet(address indexed treasury);\n    /// @dev Emitted when `vault` is set\n    event VaultSet(address indexed vault);\n    /// @dev Emitted when orders are paused/unpaused\n    event OrdersPaused(bool paused);\n    event PaymentTokenSet(\n        address indexed paymentToken,\n        bytes4 blacklistCallSelector,\n        uint64 perOrderFeeBuy,\n        uint24 percentageFeeRateBuy,\n        uint64 perOrderFeeSell,\n        uint24 percentageFeeRateSell\n    );\n    event PaymentTokenRemoved(address indexed paymentToken);\n    event OrderDecimalReductionSet(address indexed assetToken, uint8 decimalReduction);\n    event OperatorSet(address indexed account, bool status);\n\n    /// ------------------ Constants ------------------ ///\n\n    bytes32 private constant ORDER_TYPEHASH = keccak256(\n        \"Order(uint64 requestTimestamp,address recipient,address assetToken,address paymentToken,bool sell,uint8 orderType,uint256 assetTokenQuantity,uint256 paymentTokenQuantity,uint256 price,uint8 tif)\"\n    );\n\n    bytes32 private constant ORDER_REQUEST_TYPEHASH = keccak256(\"OrderRequest(uint256 id,uint64 deadline)\");\n\n    bytes32 private constant FEE_QUOTE_TYPEHASH =\n        keccak256(\"FeeQuote(uint256 orderId,address requester,uint256 fee,uint64 timestamp,uint64 deadline)\");\n\n    /// ------------------ State ------------------ ///\n\n    struct OrderProcessorStorage {\n        // Address to receive fees\n        address _treasury;\n        // Address of payment vault\n        address _vault;\n        // DShareFactory contract\n        IDShareFactory _dShareFactory;\n        // Are orders paused?\n        bool _ordersPaused;\n        // Operators for filling and cancelling orders\n        mapping(address => bool) _operators;\n        // Status of order\n        mapping(uint256 => OrderStatus) _status;\n        // Active order state\n        mapping(uint256 => OrderState) _orders;\n        // Reduciton of order decimals for asset token, defaults to 0\n        mapping(address => uint8) _orderDecimalReduction;\n        // Payment token configuration data\n        mapping(address => PaymentTokenConfig) _paymentTokens;\n        // Latest pairwise price\n        mapping(bytes32 => PricePoint) _latestFillPrice;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"dinaricrypto.storage.OrderProcessor\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OrderProcessorStorageLocation =\n        0x8036d9ca2814a3bcd78d3e8aba96b71e7697006bd322a98e7f5f0f41b09a8b00;\n\n    function _getOrderProcessorStorage() private pure returns (OrderProcessorStorage storage $) {\n        assembly {\n            $.slot := OrderProcessorStorageLocation\n        }\n    }\n\n    /// ------------------ Initialization ------------------ ///\n\n    /// @notice Initialize contract\n    /// @param _owner Owner of contract\n    /// @param _treasury Address to receive fees\n    /// @param _vault Address of vault contract\n    /// @param _dShareFactory DShareFactory contract\n    /// @dev Treasury cannot be zero address\n    function initialize(address _owner, address _treasury, address _vault, IDShareFactory _dShareFactory)\n        public\n        virtual\n        initializer\n    {\n        __Ownable_init(_owner);\n        __EIP712_init(\"OrderProcessor\", \"1\");\n        __Multicall_init();\n\n        // Don't send fees to zero address\n        if (_treasury == address(0)) revert ZeroAddress();\n        if (_vault == address(0)) revert ZeroAddress();\n        if (address(_dShareFactory) == address(0)) revert ZeroAddress();\n\n        // Initialize\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._treasury = _treasury;\n        $._vault = _vault;\n        $._dShareFactory = _dShareFactory;\n    }\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    function _authorizeUpgrade(address) internal override onlyOwner {}\n\n    /// ------------------ Getters ------------------ ///\n\n    /// @notice Address to receive fees\n    function treasury() external view returns (address) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._treasury;\n    }\n\n    /// @notice Address of vault contract\n    function vault() external view returns (address) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._vault;\n    }\n\n    /// @notice DShareFactory contract\n    function dShareFactory() external view returns (IDShareFactory) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._dShareFactory;\n    }\n\n    /// @notice Are orders paused?\n    function ordersPaused() external view returns (bool) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._ordersPaused;\n    }\n\n    function isOperator(address account) external view returns (bool) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._operators[account];\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function getOrderStatus(uint256 id) external view returns (OrderStatus) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._status[id];\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function getUnfilledAmount(uint256 id) external view returns (uint256) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._orders[id].unfilledAmount;\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function getFeesEscrowed(uint256 id) external view returns (uint256) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._orders[id].feesEscrowed;\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function getFeesTaken(uint256 id) external view returns (uint256) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._orders[id].feesTaken;\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function orderDecimalReduction(address token) external view override returns (uint8) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._orderDecimalReduction[token];\n    }\n\n    function getPaymentTokenConfig(address paymentToken) public view returns (PaymentTokenConfig memory) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._paymentTokens[paymentToken];\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function getStandardFees(bool sell, address paymentToken) public view returns (uint256, uint24) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        PaymentTokenConfig memory paymentTokenConfig = $._paymentTokens[paymentToken];\n        if (!paymentTokenConfig.enabled) revert UnsupportedToken(paymentToken);\n        if (sell) {\n            return (\n                FeeLib.flatFeeForOrder(paymentTokenConfig.decimals, paymentTokenConfig.perOrderFeeSell),\n                paymentTokenConfig.percentageFeeRateSell\n            );\n        } else {\n            return (\n                FeeLib.flatFeeForOrder(paymentTokenConfig.decimals, paymentTokenConfig.perOrderFeeBuy),\n                paymentTokenConfig.percentageFeeRateBuy\n            );\n        }\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function totalStandardFee(bool sell, address paymentToken, uint256 paymentTokenQuantity)\n        public\n        view\n        returns (uint256)\n    {\n        (uint256 fee, uint24 percentageFeeRate) = getStandardFees(sell, paymentToken);\n        return FeeLib.applyPercentageFee(percentageFeeRate, paymentTokenQuantity) + fee;\n    }\n\n    function isTransferLocked(address token, address account) external view returns (bool) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        bytes4 selector = $._paymentTokens[token].blacklistCallSelector;\n        // if no selector is set, default to locked == false\n        if (selector == 0) return false;\n\n        return _checkTransferLocked(token, account, selector);\n    }\n\n    function _checkTransferLocked(address token, address account, bytes4 selector) internal view returns (bool) {\n        // assumes bool result\n        return abi.decode(token.functionStaticCall(abi.encodeWithSelector(selector, account)), (bool));\n    }\n\n    function _checkBlacklisted(address assetToken, address paymentToken, bytes4 blacklistCallSelector, address account)\n        internal\n        view\n    {\n        // Black list checker, assumes asset tokens are dShares\n        if (\n            IDShare(assetToken).isBlacklisted(account)\n                || (blacklistCallSelector != 0 && _checkTransferLocked(paymentToken, account, blacklistCallSelector))\n        ) revert Blacklist();\n    }\n\n    function latestFillPrice(address assetToken, address paymentToken) external view returns (PricePoint memory) {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        return $._latestFillPrice[OracleLib.pairIndex(assetToken, paymentToken)];\n    }\n\n    // slither-disable-next-line naming-convention\n    function DOMAIN_SEPARATOR() external view returns (bytes32) {\n        return _domainSeparatorV4();\n    }\n\n    /// ------------------ Administration ------------------ ///\n\n    /// @dev Check if orders are paused\n    modifier whenOrdersNotPaused() {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        if ($._ordersPaused) revert Paused();\n        _;\n    }\n\n    modifier onlyOperator() {\n        checkOperator(msg.sender);\n        _;\n    }\n\n    function checkOperator(address account) internal view {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        if (!$._operators[account]) revert NotOperator();\n    }\n\n    /// @notice Set treasury address\n    /// @param account Address to receive fees\n    /// @dev Only callable by admin\n    /// Treasury cannot be zero address\n    function setTreasury(address account) external onlyOwner {\n        // Don't send fees to zero address\n        if (account == address(0)) revert ZeroAddress();\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._treasury = account;\n        emit TreasurySet(account);\n    }\n\n    /// @notice Set vault address\n    /// @param account Address of vault contract\n    /// @dev Only callable by admin\n    /// Vault cannot be zero address\n    function setVault(address account) external onlyOwner {\n        // Don't send tokens to zero address\n        if (account == address(0)) revert ZeroAddress();\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._vault = account;\n        emit VaultSet(account);\n    }\n\n    /// @notice Pause/unpause orders\n    /// @param pause Pause orders if true, unpause if false\n    /// @dev Only callable by admin\n    function setOrdersPaused(bool pause) external onlyOwner {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._ordersPaused = pause;\n        emit OrdersPaused(pause);\n    }\n\n    /// @notice Set operator\n    /// @param account Operator address\n    /// @param status Operator status\n    /// @dev Only callable by admin\n    function setOperator(address account, bool status) external onlyOwner {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._operators[account] = status;\n        emit OperatorSet(account, status);\n    }\n\n    /// @notice Set payment token configuration information\n    /// @param paymentToken Payment token address\n    /// @param blacklistCallSelector Method selector for blacklist check\n    /// @param perOrderFeeBuy Flat fee for buy orders\n    /// @param percentageFeeRateBuy Percentage fee rate for buy orders\n    /// @param perOrderFeeSell Flat fee for sell orders\n    /// @param percentageFeeRateSell Percentage fee rate for sell orders\n    /// @dev Only callable by admin\n    function setPaymentToken(\n        address paymentToken,\n        bytes4 blacklistCallSelector,\n        uint64 perOrderFeeBuy,\n        uint24 percentageFeeRateBuy,\n        uint64 perOrderFeeSell,\n        uint24 percentageFeeRateSell\n    ) external onlyOwner {\n        FeeLib.checkPercentageFeeRate(percentageFeeRateBuy);\n        FeeLib.checkPercentageFeeRate(percentageFeeRateSell);\n        // Token contract must implement the selector, if specified\n        if (blacklistCallSelector != 0) _checkTransferLocked(paymentToken, address(this), blacklistCallSelector);\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._paymentTokens[paymentToken] = PaymentTokenConfig({\n            enabled: true,\n            decimals: IERC20Metadata(paymentToken).decimals(),\n            blacklistCallSelector: blacklistCallSelector,\n            perOrderFeeBuy: perOrderFeeBuy,\n            percentageFeeRateBuy: percentageFeeRateBuy,\n            perOrderFeeSell: perOrderFeeSell,\n            percentageFeeRateSell: percentageFeeRateSell\n        });\n        emit PaymentTokenSet(\n            paymentToken,\n            blacklistCallSelector,\n            perOrderFeeBuy,\n            percentageFeeRateBuy,\n            perOrderFeeSell,\n            percentageFeeRateSell\n        );\n    }\n\n    /// @notice Remove payment token configuration\n    /// @param paymentToken Payment token address\n    /// @dev Only callable by admin\n    function removePaymentToken(address paymentToken) external onlyOwner {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        delete $._paymentTokens[paymentToken];\n        emit PaymentTokenRemoved(paymentToken);\n    }\n\n    /// @notice Set the order decimal reduction for asset token\n    /// @param token Asset token\n    /// @param decimalReduction Reduces the max precision of the asset token quantity\n    /// @dev Only callable by admin\n    function setOrderDecimalReduction(address token, uint8 decimalReduction) external onlyOwner {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        $._orderDecimalReduction[token] = decimalReduction;\n        emit OrderDecimalReductionSet(token, decimalReduction);\n    }\n\n    /// ------------------ Order Lifecycle ------------------ ///\n\n    /// @inheritdoc IOrderProcessor\n    function createOrderWithSignature(\n        Order calldata order,\n        Signature calldata orderSignature,\n        FeeQuote calldata feeQuote,\n        bytes calldata feeQuoteSignature\n    ) external whenOrdersNotPaused onlyOperator returns (uint256 id) {\n        // Recover requester and validate order signature\n        if (orderSignature.deadline < block.timestamp) revert ExpiredSignature();\n        address requester =\n            ECDSA.recover(_hashTypedDataV4(hashOrderRequest(order, orderSignature.deadline)), orderSignature.signature);\n\n        _validateFeeQuote(requester, feeQuote, feeQuoteSignature);\n\n        // Create order\n        return _createOrder(order, requester, order.sell ? 0 : feeQuote.fee);\n    }\n\n    function _validateFeeQuote(address requester, FeeQuote calldata feeQuote, bytes calldata feeQuoteSignature)\n        private\n        view\n    {\n        if (feeQuote.requester != requester) revert NotRequester();\n        if (feeQuote.deadline < block.timestamp) revert ExpiredSignature();\n        address feeQuoteSigner = ECDSA.recover(_hashTypedDataV4(hashFeeQuote(feeQuote)), feeQuoteSignature);\n        checkOperator(feeQuoteSigner);\n    }\n\n    /// @dev Validate order, initialize order state, and pull tokens\n    // slither-disable-next-line cyclomatic-complexity\n    function _createOrder(Order calldata order, address requester, uint256 feesEscrowed) private returns (uint256 id) {\n        // ------------------ Checks ------------------ //\n\n        // Cheap checks first\n        if (order.recipient == address(0)) revert ZeroAddress();\n        uint256 orderAmount = (order.sell) ? order.assetTokenQuantity : order.paymentTokenQuantity;\n        // No zero orders\n        if (orderAmount == 0) revert ZeroValue();\n        // Ensure that price is set for limit orders\n        if (order.orderType == OrderType.LIMIT && order.price == 0) revert LimitPriceNotSet();\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n\n        // Order must not have existed\n        id = hashOrder(order);\n        if ($._status[id] != OrderStatus.NONE) revert ExistingOrder();\n\n        // Check for whitelisted tokens\n        if (!$._dShareFactory.isTokenDShare(order.assetToken)) revert UnsupportedToken(order.assetToken);\n        PaymentTokenConfig memory paymentTokenConfig = $._paymentTokens[order.paymentToken];\n        if (!paymentTokenConfig.enabled) revert UnsupportedToken(order.paymentToken);\n\n        // Precision checked for assetTokenQuantity, market buys excluded\n        if (order.sell || order.orderType == OrderType.LIMIT) {\n            uint8 decimalReduction = $._orderDecimalReduction[order.assetToken];\n            if (decimalReduction > 0 && (order.assetTokenQuantity % 10 ** (decimalReduction - 1)) != 0) {\n                revert InvalidPrecision();\n            }\n        }\n\n        _checkBlacklisted(order.assetToken, order.paymentToken, paymentTokenConfig.blacklistCallSelector, requester);\n        if (order.recipient != requester) {\n            _checkBlacklisted(\n                order.assetToken, order.paymentToken, paymentTokenConfig.blacklistCallSelector, order.recipient\n            );\n        }\n\n        // ------------------ Effects ------------------ //\n\n        // Initialize order state\n        $._orders[id] =\n            OrderState({requester: requester, unfilledAmount: orderAmount, feesEscrowed: feesEscrowed, feesTaken: 0});\n        $._status[id] = OrderStatus.ACTIVE;\n\n        emit OrderCreated(id, requester, order, feesEscrowed);\n\n        // ------------------ Interactions ------------------ //\n\n        // Move funds to vault for buys, burn assets for sells\n        if (order.sell) {\n            // Burn asset\n            IDShare(order.assetToken).burnFrom(requester, order.assetTokenQuantity);\n        } else {\n            // Sweep payment for purchase\n            IERC20(order.paymentToken).safeTransferFrom(requester, $._vault, order.paymentTokenQuantity);\n            // Escrow fees\n            IERC20(order.paymentToken).safeTransferFrom(requester, address(this), feesEscrowed);\n        }\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function createOrder(Order calldata order, FeeQuote calldata feeQuote, bytes calldata feeQuoteSignature)\n        external\n        whenOrdersNotPaused\n        returns (uint256 id)\n    {\n        _validateFeeQuote(msg.sender, feeQuote, feeQuoteSignature);\n\n        // Create order\n        return _createOrder(order, msg.sender, order.sell ? 0 : feeQuote.fee);\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function createOrderStandardFees(Order calldata order) external whenOrdersNotPaused returns (uint256 id) {\n        if (order.sell) {\n            return _createOrder(order, msg.sender, 0);\n        } else {\n            (uint256 flatFee, uint24 percentageFeeRate) = getStandardFees(false, order.paymentToken);\n            return _createOrder(\n                order, msg.sender, FeeLib.applyPercentageFee(percentageFeeRate, order.paymentTokenQuantity) + flatFee\n            );\n        }\n    }\n\n    function hashOrderRequest(Order calldata order, uint64 deadline) public pure returns (bytes32) {\n        return keccak256(abi.encode(ORDER_REQUEST_TYPEHASH, hashOrder(order), deadline));\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function hashOrder(Order calldata order) public pure returns (uint256) {\n        return uint256(\n            keccak256(\n                abi.encode(\n                    ORDER_TYPEHASH,\n                    order.requestTimestamp,\n                    order.recipient,\n                    order.assetToken,\n                    order.paymentToken,\n                    order.sell,\n                    order.orderType,\n                    order.assetTokenQuantity,\n                    order.paymentTokenQuantity,\n                    order.price,\n                    order.tif\n                )\n            )\n        );\n    }\n\n    function hashFeeQuote(FeeQuote calldata feeQuote) public pure returns (bytes32) {\n        return keccak256(\n            abi.encode(\n                FEE_QUOTE_TYPEHASH,\n                feeQuote.orderId,\n                feeQuote.requester,\n                feeQuote.fee,\n                feeQuote.timestamp,\n                feeQuote.deadline\n            )\n        );\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function fillOrder(Order calldata order, uint256 fillAmount, uint256 receivedAmount, uint256 fees)\n        external\n        onlyOperator\n    {\n        // No nonsense\n        if (fillAmount == 0) revert ZeroValue();\n        // Order ID\n        uint256 id = hashOrder(order);\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        OrderState memory orderState = $._orders[id];\n\n        // Order must exist\n        if (orderState.requester == address(0)) revert OrderNotFound();\n        // Fill cannot exceed remaining order\n        if (fillAmount > orderState.unfilledAmount) revert AmountTooLarge();\n\n        if (order.sell) {\n            _fillSellOrder(id, order, orderState, fillAmount, receivedAmount, fees);\n        } else {\n            _fillBuyOrder(id, order, orderState, receivedAmount, fillAmount, fees);\n        }\n\n        // If there are protocol fees from the order, transfer them to the treasury\n        if (fees > 0) {\n            IERC20(order.paymentToken).safeTransfer($._treasury, fees);\n        }\n    }\n\n    function _fillSellOrder(\n        uint256 id,\n        Order calldata order,\n        OrderState memory orderState,\n        uint256 assetAmount,\n        uint256 paymentAmount,\n        uint256 fees\n    ) private {\n        // ------------------ Checks ------------------ //\n\n        // Fees cannot exceed proceeds\n        if (fees > paymentAmount) revert AmountTooLarge();\n        // For limit sell orders, ensure that the received amount is greater or equal to limit price * fill amount, order price has ether decimals\n        if (order.orderType == OrderType.LIMIT && paymentAmount < mulDiv18(assetAmount, order.price)) {\n            revert OrderFillAboveLimitPrice();\n        }\n\n        // ------------------ Effects ------------------ //\n\n        _publishFill(id, orderState.requester, order, assetAmount, paymentAmount, fees);\n\n        _updateFillState(id, orderState, assetAmount, fees);\n\n        // Transfer the received amount from the filler to this contract\n        IERC20(order.paymentToken).safeTransferFrom(msg.sender, address(this), paymentAmount);\n\n        // If there are proceeds from the order, transfer them to the recipient\n        uint256 paymentEarned = paymentAmount - fees;\n        if (paymentEarned > 0) {\n            IERC20(order.paymentToken).safeTransfer(order.recipient, paymentEarned);\n        }\n    }\n\n    function _fillBuyOrder(\n        uint256 id,\n        Order calldata order,\n        OrderState memory orderState,\n        uint256 assetAmount,\n        uint256 paymentAmount,\n        uint256 fees\n    ) private {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n\n        // ------------------ Checks ------------------ //\n\n        // Fees cannot exceed remaining deposit\n        if (fees > orderState.feesEscrowed) revert AmountTooLarge();\n        // For limit buy orders, ensure that the received amount is greater or equal to fill amount / limit price, order price has ether decimals\n        if (order.orderType == OrderType.LIMIT && assetAmount < mulDiv(paymentAmount, 1 ether, order.price)) {\n            revert OrderFillBelowLimitPrice();\n        }\n\n        // ------------------ Effects ------------------ //\n\n        _publishFill(id, orderState.requester, order, assetAmount, paymentAmount, fees);\n\n        bool fulfilled = _updateFillState(id, orderState, paymentAmount, fees);\n\n        // Update fee escrow (and refund if eligible)\n        uint256 remainingFeesEscrowed = orderState.feesEscrowed - fees;\n        if (fulfilled) {\n            // Refund remaining fees\n            if (remainingFeesEscrowed > 0) {\n                // Interaction\n                IERC20(order.paymentToken).safeTransfer(orderState.requester, remainingFeesEscrowed);\n            }\n        } else {\n            $._orders[id].feesEscrowed = remainingFeesEscrowed;\n        }\n\n        // Mint asset\n        IDShare(order.assetToken).mint(order.recipient, assetAmount);\n    }\n\n    function _publishFill(\n        uint256 id,\n        address requester,\n        Order calldata order,\n        uint256 assetAmount,\n        uint256 paymentAmount,\n        uint256 fees\n    ) private {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n\n        // Update price oracle\n        bytes32 pairIndex = OracleLib.pairIndex(order.assetToken, order.paymentToken);\n        $._latestFillPrice[pairIndex] = PricePoint({\n            blocktime: uint64(block.timestamp),\n            price: order.orderType == OrderType.LIMIT\n                ? order.price\n                : OracleLib.calculatePrice(assetAmount, paymentAmount, $._paymentTokens[order.paymentToken].decimals)\n        });\n\n        // Notify order filled\n        emit OrderFill(\n            id, order.paymentToken, order.assetToken, requester, assetAmount, paymentAmount, fees, order.sell\n        );\n    }\n\n    function _updateFillState(uint256 id, OrderState memory orderState, uint256 fillAmount, uint256 fees)\n        private\n        returns (bool fulfilled)\n    {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n\n        // Update order state\n        uint256 newUnfilledAmount = orderState.unfilledAmount - fillAmount;\n        // If order is completely filled then clear order state\n        fulfilled = newUnfilledAmount == 0;\n        if (fulfilled) {\n            $._status[id] = OrderStatus.FULFILLED;\n            // Clear order state\n            delete $._orders[id];\n            // Notify order fulfilled\n            emit OrderFulfilled(id, orderState.requester);\n        } else {\n            // Otherwise update order state\n            $._orders[id].unfilledAmount = newUnfilledAmount;\n            $._orders[id].feesTaken = orderState.feesTaken + fees;\n        }\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function requestCancel(uint256 id) external {\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        // Order must exist\n        address requester = $._orders[id].requester;\n        if (requester == address(0)) revert OrderNotFound();\n        // Only requester can request cancellation\n        if (requester != msg.sender) revert NotRequester();\n\n        // Send cancel request to bridge\n        emit CancelRequested(id, requester);\n    }\n\n    /// @inheritdoc IOrderProcessor\n    function cancelOrder(Order calldata order, string calldata reason) external onlyOperator {\n        // ------------------ Checks ------------------ //\n\n        // Order ID\n        uint256 id = hashOrder(order);\n\n        OrderProcessorStorage storage $ = _getOrderProcessorStorage();\n        OrderState storage orderState = $._orders[id];\n        address requester = orderState.requester;\n        // Order must exist\n        if (requester == address(0)) revert OrderNotFound();\n\n        // ------------------ Effects ------------------ //\n\n        // If buy order, then refund fee deposit\n        uint256 feeRefund = order.sell ? 0 : orderState.feesEscrowed;\n        uint256 unfilledAmount = orderState.unfilledAmount;\n\n        // Order is cancelled\n        $._status[id] = OrderStatus.CANCELLED;\n\n        // Clear order state\n        delete $._orders[id];\n\n        // Notify order cancelled\n        emit OrderCancelled(id, requester, reason);\n\n        // ------------------ Interactions ------------------ //\n\n        // Return escrowed fees and unfilled amount\n        if (order.sell) {\n            // Mint unfilled\n            IDShare(order.assetToken).mint(requester, unfilledAmount);\n        } else {\n            // Return unfilled\n            IERC20(order.paymentToken).safeTransferFrom(msg.sender, requester, unfilledAmount);\n            if (feeRefund > 0) {\n                IERC20(order.paymentToken).safeTransfer(requester, feeRefund);\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol\";\nimport {Initializable} from \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable __self = address(this);\n\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev The call is from an unauthorized context.\n     */\n    error UUPSUnauthorizedCallContext();\n\n    /**\n     * @dev The storage `slot` is unsupported as a UUID.\n     */\n    error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        _checkProxy();\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        _checkNotDelegated();\n        _;\n    }\n\n    function __UUPSUpgradeable_init() internal onlyInitializing {\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n        return ERC1967Utils.IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data);\n    }\n\n    /**\n     * @dev Reverts if the execution is not performed via delegatecall or the execution\n     * context is not of a proxy with an ERC1967-compliant implementation pointing to self.\n     * See {_onlyProxy}.\n     */\n    function _checkProxy() internal view virtual {\n        if (\n            address(this) == __self || // Must be called through delegatecall\n            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n        ) {\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Reverts if the execution is performed via delegatecall.\n     * See {notDelegated}.\n     */\n    function _checkNotDelegated() internal view virtual {\n        if (address(this) != __self) {\n            // Must not be called through delegatecall\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n     *\n     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n     * is expected to be the implementation slot in ERC1967.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n                revert UUPSUnsupportedProxiableUUID(slot);\n            }\n            ERC1967Utils.upgradeToAndCall(newImplementation, data);\n        } catch {\n            // The implementation is not UUPS\n            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {OwnableUpgradeable} from \"./OwnableUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step\n    struct Ownable2StepStorage {\n        address _pendingOwner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable2Step\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;\n\n    function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {\n        assembly {\n            $.slot := Ownable2StepStorageLocation\n        }\n    }\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    function __Ownable2Step_init() internal onlyInitializing {\n    }\n\n    function __Ownable2Step_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\n        return $._pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\n        $._pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        Ownable2StepStorage storage $ = _getOwnable2StepStorage();\n        delete $._pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.20;\n\nimport {MessageHashUtils} from \"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\";\nimport {IERC5267} from \"@openzeppelin/contracts/interfaces/IERC5267.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\n * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\n    bytes32 private constant TYPE_HASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\n    struct EIP712Storage {\n        /// @custom:oz-renamed-from _HASHED_NAME\n        bytes32 _hashedName;\n        /// @custom:oz-renamed-from _HASHED_VERSION\n        bytes32 _hashedVersion;\n\n        string _name;\n        string _version;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.EIP712\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\n\n    function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\n        assembly {\n            $.slot := EIP712StorageLocation\n        }\n    }\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init_unchained(name, version);\n    }\n\n    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n        EIP712Storage storage $ = _getEIP712Storage();\n        $._name = name;\n        $._version = version;\n\n        // Reset prior values in storage if upgrading\n        $._hashedName = 0;\n        $._hashedVersion = 0;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        return _buildDomainSeparator();\n    }\n\n    function _buildDomainSeparator() private view returns (bytes32) {\n        return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n\n    /**\n     * @dev See {IERC-5267}.\n     */\n    function eip712Domain()\n        public\n        view\n        virtual\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        )\n    {\n        EIP712Storage storage $ = _getEIP712Storage();\n        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n        // and the EIP712 domain is not reliable, as it will be missing name and version.\n        require($._hashedName == 0 && $._hashedVersion == 0, \"EIP712: Uninitialized\");\n\n        return (\n            hex\"0f\", // 01111\n            _EIP712Name(),\n            _EIP712Version(),\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /**\n     * @dev The name parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Name() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._name;\n    }\n\n    /**\n     * @dev The version parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Version() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._version;\n    }\n\n    /**\n     * @dev The hash of the name parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n     */\n    function _EIP712NameHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory name = _EIP712Name();\n        if (bytes(name).length > 0) {\n            return keccak256(bytes(name));\n        } else {\n            // If the name is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n            bytes32 hashedName = $._hashedName;\n            if (hashedName != 0) {\n                return hashedName;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n\n    /**\n     * @dev The hash of the version parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n     */\n    function _EIP712VersionHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory version = _EIP712Version();\n        if (bytes(version).length > 0) {\n            return keccak256(bytes(version));\n        } else {\n            // If the version is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n            bytes32 hashedVersion = $._hashedVersion;\n            if (hashedVersion != 0) {\n                return hashedVersion;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Multicall.sol)\n\npragma solidity ^0.8.20;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides a function to batch together multiple calls in a single external call.\n */\nabstract contract MulticallUpgradeable is Initializable {\n    function __Multicall_init() internal onlyInitializing {\n    }\n\n    function __Multicall_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Receives and executes a batch of function calls on this contract.\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {\n        results = new bytes[](data.length);\n        for (uint256 i = 0; i < data.length; i++) {\n            results[i] = Address.functionDelegateCall(address(this), data[i]);\n        }\n        return results;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC20Permit} from \"../extensions/IERC20Permit.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev An operation with an ERC20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data);\n        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError, bytes32) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS, s);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\n     */\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error AddressInsufficientBalance(address account);\n\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedInnerCall();\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert AddressInsufficientBalance(address(this));\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert FailedInnerCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {FailedInnerCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert AddressInsufficientBalance(address(this));\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n     * unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {FailedInnerCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert FailedInnerCall();\n        }\n    }\n}\n"
      },
      "lib/prb-math/src/Common.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions needed by both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n                                CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n                                    FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n    unchecked {\n        // Start from 0.5 in the 192.64-bit fixed-point format.\n        result = 0x800000000000000000000000000000000000000000000000;\n\n        // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n        //\n        // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n        // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n        // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n        // we know that `x & 0xFF` is also 1.\n        if (x & 0xFF00000000000000 > 0) {\n            if (x & 0x8000000000000000 > 0) {\n                result = (result * 0x16A09E667F3BCC909) >> 64;\n            }\n            if (x & 0x4000000000000000 > 0) {\n                result = (result * 0x1306FE0A31B7152DF) >> 64;\n            }\n            if (x & 0x2000000000000000 > 0) {\n                result = (result * 0x1172B83C7D517ADCE) >> 64;\n            }\n            if (x & 0x1000000000000000 > 0) {\n                result = (result * 0x10B5586CF9890F62A) >> 64;\n            }\n            if (x & 0x800000000000000 > 0) {\n                result = (result * 0x1059B0D31585743AE) >> 64;\n            }\n            if (x & 0x400000000000000 > 0) {\n                result = (result * 0x102C9A3E778060EE7) >> 64;\n            }\n            if (x & 0x200000000000000 > 0) {\n                result = (result * 0x10163DA9FB33356D8) >> 64;\n            }\n            if (x & 0x100000000000000 > 0) {\n                result = (result * 0x100B1AFA5ABCBED61) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000000000 > 0) {\n            if (x & 0x80000000000000 > 0) {\n                result = (result * 0x10058C86DA1C09EA2) >> 64;\n            }\n            if (x & 0x40000000000000 > 0) {\n                result = (result * 0x1002C605E2E8CEC50) >> 64;\n            }\n            if (x & 0x20000000000000 > 0) {\n                result = (result * 0x100162F3904051FA1) >> 64;\n            }\n            if (x & 0x10000000000000 > 0) {\n                result = (result * 0x1000B175EFFDC76BA) >> 64;\n            }\n            if (x & 0x8000000000000 > 0) {\n                result = (result * 0x100058BA01FB9F96D) >> 64;\n            }\n            if (x & 0x4000000000000 > 0) {\n                result = (result * 0x10002C5CC37DA9492) >> 64;\n            }\n            if (x & 0x2000000000000 > 0) {\n                result = (result * 0x1000162E525EE0547) >> 64;\n            }\n            if (x & 0x1000000000000 > 0) {\n                result = (result * 0x10000B17255775C04) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000000000 > 0) {\n            if (x & 0x800000000000 > 0) {\n                result = (result * 0x1000058B91B5BC9AE) >> 64;\n            }\n            if (x & 0x400000000000 > 0) {\n                result = (result * 0x100002C5C89D5EC6D) >> 64;\n            }\n            if (x & 0x200000000000 > 0) {\n                result = (result * 0x10000162E43F4F831) >> 64;\n            }\n            if (x & 0x100000000000 > 0) {\n                result = (result * 0x100000B1721BCFC9A) >> 64;\n            }\n            if (x & 0x80000000000 > 0) {\n                result = (result * 0x10000058B90CF1E6E) >> 64;\n            }\n            if (x & 0x40000000000 > 0) {\n                result = (result * 0x1000002C5C863B73F) >> 64;\n            }\n            if (x & 0x20000000000 > 0) {\n                result = (result * 0x100000162E430E5A2) >> 64;\n            }\n            if (x & 0x10000000000 > 0) {\n                result = (result * 0x1000000B172183551) >> 64;\n            }\n        }\n\n        if (x & 0xFF00000000 > 0) {\n            if (x & 0x8000000000 > 0) {\n                result = (result * 0x100000058B90C0B49) >> 64;\n            }\n            if (x & 0x4000000000 > 0) {\n                result = (result * 0x10000002C5C8601CC) >> 64;\n            }\n            if (x & 0x2000000000 > 0) {\n                result = (result * 0x1000000162E42FFF0) >> 64;\n            }\n            if (x & 0x1000000000 > 0) {\n                result = (result * 0x10000000B17217FBB) >> 64;\n            }\n            if (x & 0x800000000 > 0) {\n                result = (result * 0x1000000058B90BFCE) >> 64;\n            }\n            if (x & 0x400000000 > 0) {\n                result = (result * 0x100000002C5C85FE3) >> 64;\n            }\n            if (x & 0x200000000 > 0) {\n                result = (result * 0x10000000162E42FF1) >> 64;\n            }\n            if (x & 0x100000000 > 0) {\n                result = (result * 0x100000000B17217F8) >> 64;\n            }\n        }\n\n        if (x & 0xFF000000 > 0) {\n            if (x & 0x80000000 > 0) {\n                result = (result * 0x10000000058B90BFC) >> 64;\n            }\n            if (x & 0x40000000 > 0) {\n                result = (result * 0x1000000002C5C85FE) >> 64;\n            }\n            if (x & 0x20000000 > 0) {\n                result = (result * 0x100000000162E42FF) >> 64;\n            }\n            if (x & 0x10000000 > 0) {\n                result = (result * 0x1000000000B17217F) >> 64;\n            }\n            if (x & 0x8000000 > 0) {\n                result = (result * 0x100000000058B90C0) >> 64;\n            }\n            if (x & 0x4000000 > 0) {\n                result = (result * 0x10000000002C5C860) >> 64;\n            }\n            if (x & 0x2000000 > 0) {\n                result = (result * 0x1000000000162E430) >> 64;\n            }\n            if (x & 0x1000000 > 0) {\n                result = (result * 0x10000000000B17218) >> 64;\n            }\n        }\n\n        if (x & 0xFF0000 > 0) {\n            if (x & 0x800000 > 0) {\n                result = (result * 0x1000000000058B90C) >> 64;\n            }\n            if (x & 0x400000 > 0) {\n                result = (result * 0x100000000002C5C86) >> 64;\n            }\n            if (x & 0x200000 > 0) {\n                result = (result * 0x10000000000162E43) >> 64;\n            }\n            if (x & 0x100000 > 0) {\n                result = (result * 0x100000000000B1721) >> 64;\n            }\n            if (x & 0x80000 > 0) {\n                result = (result * 0x10000000000058B91) >> 64;\n            }\n            if (x & 0x40000 > 0) {\n                result = (result * 0x1000000000002C5C8) >> 64;\n            }\n            if (x & 0x20000 > 0) {\n                result = (result * 0x100000000000162E4) >> 64;\n            }\n            if (x & 0x10000 > 0) {\n                result = (result * 0x1000000000000B172) >> 64;\n            }\n        }\n\n        if (x & 0xFF00 > 0) {\n            if (x & 0x8000 > 0) {\n                result = (result * 0x100000000000058B9) >> 64;\n            }\n            if (x & 0x4000 > 0) {\n                result = (result * 0x10000000000002C5D) >> 64;\n            }\n            if (x & 0x2000 > 0) {\n                result = (result * 0x1000000000000162E) >> 64;\n            }\n            if (x & 0x1000 > 0) {\n                result = (result * 0x10000000000000B17) >> 64;\n            }\n            if (x & 0x800 > 0) {\n                result = (result * 0x1000000000000058C) >> 64;\n            }\n            if (x & 0x400 > 0) {\n                result = (result * 0x100000000000002C6) >> 64;\n            }\n            if (x & 0x200 > 0) {\n                result = (result * 0x10000000000000163) >> 64;\n            }\n            if (x & 0x100 > 0) {\n                result = (result * 0x100000000000000B1) >> 64;\n            }\n        }\n\n        if (x & 0xFF > 0) {\n            if (x & 0x80 > 0) {\n                result = (result * 0x10000000000000059) >> 64;\n            }\n            if (x & 0x40 > 0) {\n                result = (result * 0x1000000000000002C) >> 64;\n            }\n            if (x & 0x20 > 0) {\n                result = (result * 0x10000000000000016) >> 64;\n            }\n            if (x & 0x10 > 0) {\n                result = (result * 0x1000000000000000B) >> 64;\n            }\n            if (x & 0x8 > 0) {\n                result = (result * 0x10000000000000006) >> 64;\n            }\n            if (x & 0x4 > 0) {\n                result = (result * 0x10000000000000003) >> 64;\n            }\n            if (x & 0x2 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n            if (x & 0x1 > 0) {\n                result = (result * 0x10000000000000001) >> 64;\n            }\n        }\n\n        // In the code snippet below, two operations are executed simultaneously:\n        //\n        // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n        // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n        // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n        //\n        // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n        // integer part, $2^n$.\n        result *= UNIT;\n        result >>= (191 - (x >> 64));\n    }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n///     x >>= 128;\n///     result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n    // 2^128\n    assembly (\"memory-safe\") {\n        let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^64\n    assembly (\"memory-safe\") {\n        let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^32\n    assembly (\"memory-safe\") {\n        let factor := shl(5, gt(x, 0xFFFFFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^16\n    assembly (\"memory-safe\") {\n        let factor := shl(4, gt(x, 0xFFFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^8\n    assembly (\"memory-safe\") {\n        let factor := shl(3, gt(x, 0xFF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^4\n    assembly (\"memory-safe\") {\n        let factor := shl(2, gt(x, 0xF))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^2\n    assembly (\"memory-safe\") {\n        let factor := shl(1, gt(x, 0x3))\n        x := shr(factor, x)\n        result := or(result, factor)\n    }\n    // 2^1\n    // No need to shift x any more.\n    assembly (\"memory-safe\") {\n        let factor := gt(x, 0x1)\n        result := or(result, factor)\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n    // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n    // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n    // variables such that product = prod1 * 2^256 + prod0.\n    uint256 prod0; // Least significant 256 bits of the product\n    uint256 prod1; // Most significant 256 bits of the product\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    // Handle non-overflow cases, 256 by 256 division.\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / denominator;\n        }\n    }\n\n    // Make sure the result is less than 2^256. Also prevents denominator == 0.\n    if (prod1 >= denominator) {\n        revert PRBMath_MulDiv_Overflow(x, y, denominator);\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    // 512 by 256 division\n    ////////////////////////////////////////////////////////////////////////////\n\n    // Make division exact by subtracting the remainder from [prod1 prod0].\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        // Compute remainder using the mulmod Yul instruction.\n        remainder := mulmod(x, y, denominator)\n\n        // Subtract 256 bit number from 512-bit number.\n        prod1 := sub(prod1, gt(remainder, prod0))\n        prod0 := sub(prod0, remainder)\n    }\n\n    unchecked {\n        // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n        // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n        // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n        uint256 lpotdod = denominator & (~denominator + 1);\n        uint256 flippedLpotdod;\n\n        assembly (\"memory-safe\") {\n            // Factor powers of two out of denominator.\n            denominator := div(denominator, lpotdod)\n\n            // Divide [prod1 prod0] by lpotdod.\n            prod0 := div(prod0, lpotdod)\n\n            // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n            // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n            // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n            flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n        }\n\n        // Shift in bits from prod1 into prod0.\n        prod0 |= prod1 * flippedLpotdod;\n\n        // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n        // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n        // four bits. That is, denominator * inv = 1 mod 2^4.\n        uint256 inverse = (3 * denominator) ^ 2;\n\n        // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n        // in modular arithmetic, doubling the correct bits in each step.\n        inverse *= 2 - denominator * inverse; // inverse mod 2^8\n        inverse *= 2 - denominator * inverse; // inverse mod 2^16\n        inverse *= 2 - denominator * inverse; // inverse mod 2^32\n        inverse *= 2 - denominator * inverse; // inverse mod 2^64\n        inverse *= 2 - denominator * inverse; // inverse mod 2^128\n        inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n        // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n        // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n        // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n        // is no longer required.\n        result = prod0 * inverse;\n    }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n///     x * y = MAX\\_UINT256 * UNIT \\\\\n///     (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n    uint256 prod0;\n    uint256 prod1;\n    assembly (\"memory-safe\") {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n    }\n\n    if (prod1 == 0) {\n        unchecked {\n            return prod0 / UNIT;\n        }\n    }\n\n    if (prod1 >= UNIT) {\n        revert PRBMath_MulDiv18_Overflow(x, y);\n    }\n\n    uint256 remainder;\n    assembly (\"memory-safe\") {\n        remainder := mulmod(x, y, UNIT)\n        result :=\n            mul(\n                or(\n                    div(sub(prod0, remainder), UNIT_LPOTD),\n                    mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n                ),\n                UNIT_INVERSE\n            )\n    }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n    if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n        revert PRBMath_MulDivSigned_InputTooSmall();\n    }\n\n    // Get hold of the absolute values of x, y and the denominator.\n    uint256 xAbs;\n    uint256 yAbs;\n    uint256 dAbs;\n    unchecked {\n        xAbs = x < 0 ? uint256(-x) : uint256(x);\n        yAbs = y < 0 ? uint256(-y) : uint256(y);\n        dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n    }\n\n    // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n    uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n    if (resultAbs > uint256(type(int256).max)) {\n        revert PRBMath_MulDivSigned_Overflow(x, y);\n    }\n\n    // Get the signs of x, y and the denominator.\n    uint256 sx;\n    uint256 sy;\n    uint256 sd;\n    assembly (\"memory-safe\") {\n        // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n        sx := sgt(x, sub(0, 1))\n        sy := sgt(y, sub(0, 1))\n        sd := sgt(denominator, sub(0, 1))\n    }\n\n    // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n    // If there are, the result should be negative. Otherwise, it should be positive.\n    unchecked {\n        result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n    }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n    if (x == 0) {\n        return 0;\n    }\n\n    // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n    //\n    // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n    //\n    // $$\n    // msb(x) <= x <= 2*msb(x)$\n    // $$\n    //\n    // We write $msb(x)$ as $2^k$, and we get:\n    //\n    // $$\n    // k = log_2(x)\n    // $$\n    //\n    // Thus, we can write the initial inequality as:\n    //\n    // $$\n    // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n    // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n    // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n    // $$\n    //\n    // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n    uint256 xAux = uint256(x);\n    result = 1;\n    if (xAux >= 2 ** 128) {\n        xAux >>= 128;\n        result <<= 64;\n    }\n    if (xAux >= 2 ** 64) {\n        xAux >>= 64;\n        result <<= 32;\n    }\n    if (xAux >= 2 ** 32) {\n        xAux >>= 32;\n        result <<= 16;\n    }\n    if (xAux >= 2 ** 16) {\n        xAux >>= 16;\n        result <<= 8;\n    }\n    if (xAux >= 2 ** 8) {\n        xAux >>= 8;\n        result <<= 4;\n    }\n    if (xAux >= 2 ** 4) {\n        xAux >>= 4;\n        result <<= 2;\n    }\n    if (xAux >= 2 ** 2) {\n        result <<= 1;\n    }\n\n    // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n    // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n    // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n    // precision into the expected uint128 result.\n    unchecked {\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n        result = (result + x / result) >> 1;\n\n        // If x is not a perfect square, round the result toward zero.\n        uint256 roundedResult = x / result;\n        if (result >= roundedResult) {\n            result = roundedResult;\n        }\n    }\n}\n"
      },
      "src/common/SelfPermit.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nimport {IERC20Permit} from \"openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\";\n\n/// @notice Functionality to call permit on any EIP-2612-compliant token\n/// @author Dinari (https://github.com/dinaricrypto/sbt-peripheral/blob/main/src/common/SelfPermit.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/v3-periphery/blob/master/contracts/base/SelfPermit.sol)\n/// This function is expected to be embedded in multicalls to allow EOAs to approve a contract and call a function\n/// that requires an approval in a single transaction.\nabstract contract SelfPermit {\n    /// @notice Permits this contract to spend a given token from `msg.sender`\n    /// @dev The `spender` is always address(this).\n    /// @param token The address of the token spent\n    /// @param owner The address of the holder of the token\n    /// @param value The amount that can be spent of token\n    /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp\n    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`\n    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`\n    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`\n    function selfPermit(address token, address owner, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        public\n    {\n        IERC20Permit(token).permit(owner, address(this), value, deadline, v, r, s);\n    }\n}\n"
      },
      "src/orders/IOrderProcessor.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @notice Interface for contracts processing orders for dShares\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/orders/IOrderProcessor.sol)\n/// This interface provides a standard Order type and order lifecycle events\n/// Orders are requested on-chain, processed off-chain, then fulfillment is submitted for on-chain settlement\ninterface IOrderProcessor {\n    /// ------------------ Types ------------------ ///\n\n    // Market or limit order\n    enum OrderType {\n        MARKET,\n        LIMIT\n    }\n\n    // Time in force\n    enum TIF {\n        // Good until end of day\n        DAY,\n        // Good until cancelled\n        GTC,\n        // Immediate or cancel\n        IOC,\n        // Fill or kill\n        FOK\n    }\n\n    // Order status enum\n    enum OrderStatus {\n        // Order has never existed\n        NONE,\n        // Order is active\n        ACTIVE,\n        // Order is completely filled\n        FULFILLED,\n        // Order is cancelled\n        CANCELLED\n    }\n\n    struct Order {\n        // Timestamp or other salt added to order hash for replay protection\n        uint64 requestTimestamp;\n        // Recipient of order fills\n        address recipient;\n        // Bridged asset token\n        address assetToken;\n        // Payment token\n        address paymentToken;\n        // Buy or sell\n        bool sell;\n        // Market or limit\n        OrderType orderType;\n        // Amount of asset token to be used for fills\n        uint256 assetTokenQuantity;\n        // Amount of payment token to be used for fills\n        uint256 paymentTokenQuantity;\n        // Price for limit orders in ether decimals\n        uint256 price;\n        // Time in force\n        TIF tif;\n    }\n\n    struct OrderRequest {\n        // Unique ID and hash of order data used to validate order details stored offchain\n        uint256 orderId;\n        // Signature expiration timestamp\n        uint64 deadline;\n    }\n\n    struct Signature {\n        // Signature expiration timestamp\n        uint64 deadline;\n        // Signature bytes (r, s, v)\n        bytes signature;\n    }\n\n    struct FeeQuote {\n        // Unique ID and hash of order data used to validate order details stored offchain\n        uint256 orderId;\n        // Requester of order\n        address requester;\n        // Fee amount in payment token\n        uint256 fee;\n        // Timestamp of fee quote\n        uint64 timestamp;\n        // Signature expiration timestamp\n        uint64 deadline;\n    }\n\n    struct PricePoint {\n        // Price specified with 18 decimals\n        uint256 price;\n        uint64 blocktime;\n    }\n\n    /// @dev Emitted order details and order ID for each order\n    event OrderCreated(uint256 indexed id, address indexed requester, Order order, uint256 feesEscrowed);\n    /// @dev Emitted for each fill\n    event OrderFill(\n        uint256 indexed id,\n        address indexed paymentToken,\n        address indexed assetToken,\n        address requester,\n        uint256 assetAmount,\n        uint256 paymentAmount,\n        uint256 feesTaken,\n        bool sell\n    );\n    /// @dev Emitted when order is completely filled, terminal\n    event OrderFulfilled(uint256 indexed id, address indexed requester);\n    /// @dev Emitted when order cancellation is requested\n    event CancelRequested(uint256 indexed id, address indexed requester);\n    /// @dev Emitted when order is cancelled, terminal\n    event OrderCancelled(uint256 indexed id, address indexed requester, string reason);\n\n    /// ------------------ Getters ------------------ ///\n\n    /// @notice Hash order data for validation and create unique order ID\n    /// @param order Order data\n    /// @dev EIP-712 typed data hash of order\n    function hashOrder(Order calldata order) external pure returns (uint256);\n\n    /// @notice Status of a given order\n    /// @param id Order ID\n    function getOrderStatus(uint256 id) external view returns (OrderStatus);\n\n    /// @notice Get remaining order quantity to fill\n    /// @param id Order ID\n    function getUnfilledAmount(uint256 id) external view returns (uint256);\n\n    /// @notice Get fees in payment token escrowed for a buy order\n    /// @param id Order ID\n    function getFeesEscrowed(uint256 id) external view returns (uint256);\n\n    /// @notice Get cumulative payment token fees taken for an order\n    /// @param id Order ID\n    /// @dev Only valid for ACTIVE orders\n    function getFeesTaken(uint256 id) external view returns (uint256);\n\n    /// @notice Reduces the precision allowed for the asset token quantity of an order\n    /// @param token The address of the token\n    function orderDecimalReduction(address token) external view returns (uint8);\n\n    /// @notice Get worst case fees for an order\n    /// @param sell Sell order\n    /// @param paymentToken Payment token for order\n    /// @return flatFee Flat fee for order\n    /// @return percentageFeeRate Percentage fee rate for order\n    function getStandardFees(bool sell, address paymentToken) external view returns (uint256, uint24);\n\n    /// @notice Get total standard fees for an order\n    /// @param sell Sell order\n    /// @param paymentToken Payment token for order\n    /// @param paymentTokenQuantity Payment token quantity for order\n    function totalStandardFee(bool sell, address paymentToken, uint256 paymentTokenQuantity)\n        external\n        view\n        returns (uint256);\n\n    /// @notice Check if an account is locked from transferring tokens\n    /// @param token Token to check\n    /// @param account Account to check\n    /// @dev Only used for payment tokens\n    function isTransferLocked(address token, address account) external view returns (bool);\n\n    /// @notice Get the latest fill price for a token pair\n    /// @param assetToken Asset token\n    /// @param paymentToken Payment token\n    /// @dev price specified with 18 decimals\n    function latestFillPrice(address assetToken, address paymentToken) external view returns (PricePoint memory);\n\n    /// ------------------ Actions ------------------ ///\n\n    /// @notice Lock tokens and initialize signed order\n    /// @param order Order request to initialize\n    /// @param orderSignature Signature and deadline for order\n    /// @param feeQuote Fee quote for order\n    /// @param feeQuoteSignature Signature for fee quote\n    /// @return id Order id\n    /// @dev Only callable by operator\n    function createOrderWithSignature(\n        Order calldata order,\n        Signature calldata orderSignature,\n        FeeQuote calldata feeQuote,\n        bytes calldata feeQuoteSignature\n    ) external returns (uint256);\n\n    /// @notice Request an order\n    /// @param order Order request to submit\n    /// @param feeQuote Fee quote for order\n    /// @param feeQuoteSignature Signature for fee quote\n    /// @return id Order id\n    /// @dev Emits OrderCreated event to be sent to fulfillment service (operator)\n    function createOrder(Order calldata order, FeeQuote calldata feeQuote, bytes calldata feeQuoteSignature)\n        external\n        returns (uint256);\n\n    /// @notice Request an order with standard fees\n    /// @param order Order request to submit\n    /// @return id Order id\n    /// @dev Emits OrderCreated event to be sent to fulfillment service (operator)\n    function createOrderStandardFees(Order calldata order) external returns (uint256);\n\n    /// @notice Fill an order\n    /// @param order Order request to fill\n    /// @param fillAmount Amount of order token to fill\n    /// @param receivedAmount Amount of received token\n    /// @dev Only callable by operator\n    function fillOrder(Order calldata order, uint256 fillAmount, uint256 receivedAmount, uint256 fees) external;\n\n    /// @notice Request to cancel an order\n    /// @param id Order id\n    /// @dev Only callable by initial order requester\n    /// @dev Emits CancelRequested event to be sent to fulfillment service (operator)\n    function requestCancel(uint256 id) external;\n\n    /// @notice Cancel an order\n    /// @param order Order request to cancel\n    /// @param reason Reason for cancellation\n    /// @dev Only callable by operator\n    function cancelOrder(Order calldata order, string calldata reason) external;\n}\n"
      },
      "src/IDShare.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {ITransferRestrictor} from \"./ITransferRestrictor.sol\";\n\n/// @notice Core token contract interface for bridged assets.\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/IDShare.sol)\n/// Minter, burner, and blacklist\ninterface IDShare {\n    /// @notice Contract to restrict transfers\n    function transferRestrictor() external view returns (ITransferRestrictor);\n\n    /// @notice Mint tokens\n    /// @param to Address to mint tokens to\n    /// @param value Amount of tokens to mint\n    /// @dev Only callable by approved minter and deployer\n    /// @dev Not callable after split\n    function mint(address to, uint256 value) external;\n\n    /// @notice Burn tokens\n    /// @param value Amount of tokens to burn\n    /// @dev Only callable by approved burner\n    /// @dev Deployer can always burn after split\n    function burn(uint256 value) external;\n    function burnFrom(address from, uint256 value) external;\n\n    /**\n     * @param account The address of the account\n     * @return Whether the account is blacklisted\n     * @dev Returns true if the account is blacklisted , if the account is the zero address\n     */\n    function isBlacklisted(address account) external view returns (bool);\n}\n"
      },
      "src/common/FeeLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nimport \"prb-math/Common.sol\" as PrbMath;\nimport {IERC20Metadata} from \"openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nlibrary FeeLib {\n    // 1_000_000 == 100%\n    uint24 private constant _ONEHUNDRED_PERCENT = 1_000_000;\n\n    uint64 private constant _FLAT_FEE_DECIMALS = 8;\n\n    /// @dev Fee is too large\n    error FeeTooLarge();\n    /// @dev Decimals are too large\n    error DecimalsTooLarge();\n\n    function checkPercentageFeeRate(uint24 _percentageFeeRate) internal pure {\n        if (_percentageFeeRate >= _ONEHUNDRED_PERCENT) revert FeeTooLarge();\n    }\n\n    function percentageFeeForValue(uint256 value, uint24 percentageFeeRate) internal pure returns (uint256) {\n        if (percentageFeeRate >= _ONEHUNDRED_PERCENT) revert FeeTooLarge();\n        return percentageFeeRate != 0 ? PrbMath.mulDiv(value, percentageFeeRate, _ONEHUNDRED_PERCENT) : 0;\n    }\n\n    function flatFeeForOrder(uint8 paymentTokenDecimals, uint64 perOrderFee) internal pure returns (uint256 flatFee) {\n        if (paymentTokenDecimals > 18) revert DecimalsTooLarge();\n        if (perOrderFee == 0) return 0;\n        if (paymentTokenDecimals > _FLAT_FEE_DECIMALS) {\n            flatFee = perOrderFee * 10 ** (paymentTokenDecimals - _FLAT_FEE_DECIMALS);\n        } else if (paymentTokenDecimals < _FLAT_FEE_DECIMALS) {\n            flatFee = perOrderFee / 10 ** (_FLAT_FEE_DECIMALS - paymentTokenDecimals);\n        } else {\n            flatFee = perOrderFee;\n        }\n    }\n\n    function applyPercentageFee(uint24 percentageFeeRate, uint256 orderValue) internal pure returns (uint256) {\n        return percentageFeeRate != 0 ? PrbMath.mulDiv(orderValue, percentageFeeRate, _ONEHUNDRED_PERCENT) : 0;\n    }\n}\n"
      },
      "src/common/OracleLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nimport \"./NumberUtils.sol\";\nimport {mulDiv} from \"prb-math/Common.sol\";\n\nlibrary OracleLib {\n    function pairIndex(address assetToken, address paymentToken) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(assetToken, paymentToken));\n    }\n\n    function calculatePrice(uint256 assetTokenQuantity, uint256 paymentTokenQuantity, uint8 paymentTokenDecimals)\n        internal\n        pure\n        returns (uint256)\n    {\n        uint256 decimalMult = 10 ** (18 - paymentTokenDecimals);\n        if (NumberUtils.mulDivCheckOverflow(paymentTokenQuantity, decimalMult, assetTokenQuantity)) return 0;\n        return mulDiv(paymentTokenQuantity, decimalMult, assetTokenQuantity);\n    }\n}\n"
      },
      "src/IDShareFactory.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport {TransferRestrictor} from \"./TransferRestrictor.sol\";\nimport {DShare} from \"./DShare.sol\";\nimport {WrappedDShare} from \"./WrappedDShare.sol\";\n\n///@notice Factory interface to create new dShares\n///@author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/IDShareFactory.sol)\ninterface IDShareFactory {\n    event DShareAdded(address indexed dShare, address indexed wrappedDShare, string indexed symbol, string name);\n\n    function isTokenDShare(address token) external view returns (bool);\n\n    function isTokenWrappedDShare(address token) external view returns (bool);\n\n    /// @notice Gets list of all dShares and wrapped dShares\n    /// @return dShares List of all dShares\n    /// @return wrappedDShares List of all wrapped dShares\n    /// @dev This function can be expensive\n    function getDShares() external view returns (address[] memory, address[] memory);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.20;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n */\nlibrary ERC1967Utils {\n    // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.\n    // This will be fixed in Solidity 0.8.21. At that point we should remove these events.\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)\n\npragma solidity ^0.8.20;\n\nimport {Strings} from \"../Strings.sol\";\n\n/**\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\n *\n * The library provides methods for generating a hash of a message that conforms to the\n * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\n * specifications.\n */\nlibrary MessageHashUtils {\n    /**\n     * @dev Returns the keccak256 digest of an EIP-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing a bytes32 `messageHash` with\n     * `\"\\x19Ethereum Signed Message:\\n32\"` and hashing the result. It corresponds with the\n     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\n     * keccak256, although any bytes32 value can be safely used because the final digest will\n     * be re-hashed.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\") // 32 is the bytes-length of messageHash\n            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\n            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\n        }\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an EIP-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing an arbitrary `message` with\n     * `\"\\x19Ethereum Signed Message:\\n\" + len(message)` and hashing the result. It corresponds with the\n     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\n        return\n            keccak256(bytes.concat(\"\\x19Ethereum Signed Message:\\n\", bytes(Strings.toString(message.length)), message));\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an EIP-191 signed data with version\n     * `0x00` (data with intended validator).\n     *\n     * The digest is calculated by prefixing an arbitrary `data` with `\"\\x19\\x00\"` and the intended\n     * `validator` address. Then hashing the result.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(hex\"19_00\", validator, data));\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).\n     *\n     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\n     * `\\x19\\x01` and hashing the result. It corresponds to the hash signed by the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, hex\"19_01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            digest := keccak256(ptr, 0x42)\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.20;\n\ninterface IERC5267 {\n    /**\n     * @dev MAY be emitted to signal that the domain could have changed.\n     */\n    event EIP712DomainChanged();\n\n    /**\n     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n     * signature.\n     */\n    function eip712Domain()\n        external\n        view\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        );\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\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    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "src/ITransferRestrictor.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\n/// @notice Enforces transfer restrictions\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/ITransferRestrictor.sol)\ninterface ITransferRestrictor {\n    /// @notice Checks if the transfer is allowed\n    /// @param from The address of the sender\n    /// @param to The address of the recipient\n    function requireNotRestricted(address from, address to) external view;\n\n    /// @notice Checks if the transfer is allowed\n    /// @param account The address of the account\n    function isBlacklisted(address account) external view returns (bool);\n}\n"
      },
      "src/common/NumberUtils.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nlibrary NumberUtils {\n    function addCheckOverflow(uint256 a, uint256 b) internal pure returns (bool) {\n        uint256 c = 0;\n        unchecked {\n            c = a + b;\n        }\n        return c < a || c < b;\n    }\n\n    function mulCheckOverflow(uint256 a, uint256 b) internal pure returns (bool) {\n        if (a == 0 || b == 0) {\n            return false;\n        }\n        uint256 c;\n        unchecked {\n            c = a * b;\n        }\n        return c / a != b;\n    }\n\n    function mulDivCheckOverflow(uint256 a, uint256 b, uint256 denominator) internal pure returns (bool) {\n        // Taken from prb - math\n        uint256 prod0; // Least significant 256 bits of the product\n        uint256 prod1; // Most significant 256 bits of the product\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            prod0 := mul(a, b)\n            prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n        }\n        return prod1 >= denominator;\n    }\n}\n"
      },
      "src/TransferRestrictor.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.25;\n\nimport {AccessControlDefaultAdminRules} from\n    \"openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol\";\nimport {ITransferRestrictor} from \"./ITransferRestrictor.sol\";\n\n/// @notice Enforces transfer restrictions\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/TransferRestrictor.sol)\n/// Maintains the `RESTRICTOR_ROLE` who can add or remove accounts from `isBlacklisted`\n/// Accounts may be restricted if they are suspected of malicious or illegal activity\ncontract TransferRestrictor is AccessControlDefaultAdminRules, ITransferRestrictor {\n    /// ------------------ Types ------------------ ///\n\n    /// @dev Account is restricted\n    error AccountRestricted();\n\n    /// @dev Emitted when `account` is added to `isBlacklisted`\n    event Restricted(address indexed account);\n    /// @dev Emitted when `account` is removed from `isBlacklisted`\n    event Unrestricted(address indexed account);\n\n    /// ------------------ Constants ------------------ ///\n\n    /// @notice Role for approved compliance administrators\n    bytes32 public constant RESTRICTOR_ROLE = keccak256(\"RESTRICTOR_ROLE\");\n\n    /// ------------------ State ------------------ ///\n\n    /// @notice Accounts in `isBlacklisted` cannot send or receive tokens\n    mapping(address => bool) public isBlacklisted;\n\n    /// ------------------ Initialization ------------------ ///\n\n    constructor(address owner) AccessControlDefaultAdminRules(0, owner) {}\n\n    /// ------------------ Setters ------------------ ///\n\n    /// @notice Restrict `account` from sending or receiving tokens\n    /// @dev Does not check if `account` is restricted\n    /// Can only be called by `RESTRICTOR_ROLE`\n    function restrict(address account) external onlyRole(RESTRICTOR_ROLE) {\n        isBlacklisted[account] = true;\n        emit Restricted(account);\n    }\n\n    /// @notice Unrestrict `account` from sending or receiving tokens\n    /// @dev Does not check if `account` is restricted\n    /// Can only be called by `RESTRICTOR_ROLE`\n    function unrestrict(address account) external onlyRole(RESTRICTOR_ROLE) {\n        isBlacklisted[account] = false;\n        emit Unrestricted(account);\n    }\n\n    /// ------------------ Transfer Restriction ------------------ ///\n\n    /// @inheritdoc ITransferRestrictor\n    function requireNotRestricted(address from, address to) external view virtual {\n        // Check if either account is restricted\n        if (isBlacklisted[from] || isBlacklisted[to]) {\n            revert AccountRestricted();\n        }\n        // Otherwise, do nothing\n    }\n}\n"
      },
      "src/DShare.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.25;\n\nimport {Initializable} from \"openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\";\nimport {AccessControlDefaultAdminRulesUpgradeable} from\n    \"openzeppelin-contracts-upgradeable/contracts/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol\";\nimport {IDShare, ITransferRestrictor} from \"./IDShare.sol\";\nimport {ERC20Rebasing} from \"./ERC20Rebasing.sol\";\n\n/// @notice Core token contract for bridged assets. Rebases on stock splits.\n/// ERC20 with minter, burner, and blacklist\n/// Uses solady ERC20 which allows EIP-2612 domain separator with `name` changes\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/dShare.sol)\ncontract DShare is IDShare, Initializable, ERC20Rebasing, AccessControlDefaultAdminRulesUpgradeable {\n    /// ------------------ Types ------------------ ///\n\n    error Unauthorized();\n    error ZeroValue();\n\n    /// @dev Emitted when `name` is set\n    event NameSet(string name);\n    /// @dev Emitted when `symbol` is set\n    event SymbolSet(string symbol);\n    /// @dev Emitted when transfer restrictor contract is set\n    event TransferRestrictorSet(ITransferRestrictor indexed transferRestrictor);\n    /// @dev Emitted when split factor is updated\n    event BalancePerShareSet(uint256 balancePerShare);\n\n    /// ------------------ Immutables ------------------ ///\n\n    /// @notice Role for approved minters\n    bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    /// @notice Role for approved burners\n    bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    /// ------------------ State ------------------ ///\n\n    struct dShareStorage {\n        string _name;\n        string _symbol;\n        ITransferRestrictor _transferRestrictor;\n        /// @dev Aggregate mult factor due to splits since deployment, ethers decimals\n        uint128 _balancePerShare;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"dinaricrypto.storage.DShare\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant dShareStorageLocation = 0x7315beb2381679795e06870021c0fca5deb85616e29e098c2e7b7e488f185800;\n\n    function _getdShareStorage() private pure returns (dShareStorage storage $) {\n        assembly {\n            $.slot := dShareStorageLocation\n        }\n    }\n\n    /// ------------------ Initialization ------------------ ///\n\n    function initialize(\n        address owner,\n        string memory _name,\n        string memory _symbol,\n        ITransferRestrictor _transferRestrictor\n    ) public initializer {\n        __AccessControlDefaultAdminRules_init_unchained(0, owner);\n\n        dShareStorage storage $ = _getdShareStorage();\n        $._name = _name;\n        $._symbol = _symbol;\n        $._transferRestrictor = _transferRestrictor;\n        $._balancePerShare = _INITIAL_BALANCE_PER_SHARE;\n    }\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /// ------------------ Getters ------------------ ///\n\n    /// @notice Token name\n    function name() public view override returns (string memory) {\n        dShareStorage storage $ = _getdShareStorage();\n        return $._name;\n    }\n\n    /// @notice Token symbol\n    function symbol() public view override returns (string memory) {\n        dShareStorage storage $ = _getdShareStorage();\n        return $._symbol;\n    }\n\n    /// @notice Contract to restrict transfers\n    function transferRestrictor() public view returns (ITransferRestrictor) {\n        dShareStorage storage $ = _getdShareStorage();\n        return $._transferRestrictor;\n    }\n\n    function balancePerShare() public view override returns (uint128) {\n        dShareStorage storage $ = _getdShareStorage();\n        uint128 _balancePerShare = $._balancePerShare;\n        // Override with default if not set due to upgrade\n        if (_balancePerShare == 0) return _INITIAL_BALANCE_PER_SHARE;\n        return _balancePerShare;\n    }\n\n    /// ------------------ Setters ------------------ ///\n\n    /// @notice Set token name\n    /// @dev Only callable by owner or deployer\n    function setName(string calldata newName) external onlyRole(DEFAULT_ADMIN_ROLE) {\n        dShareStorage storage $ = _getdShareStorage();\n        $._name = newName;\n        emit NameSet(newName);\n    }\n\n    /// @notice Set token symbol\n    /// @dev Only callable by owner or deployer\n    function setSymbol(string calldata newSymbol) external onlyRole(DEFAULT_ADMIN_ROLE) {\n        dShareStorage storage $ = _getdShareStorage();\n        $._symbol = newSymbol;\n        emit SymbolSet(newSymbol);\n    }\n\n    /// @notice Update split factor\n    /// @dev Relies on offchain computation of aggregate splits and reverse splits\n    function setBalancePerShare(uint128 balancePerShare_) external onlyRole(DEFAULT_ADMIN_ROLE) {\n        if (balancePerShare_ == 0) revert ZeroValue();\n\n        dShareStorage storage $ = _getdShareStorage();\n        $._balancePerShare = balancePerShare_;\n        emit BalancePerShareSet(balancePerShare_);\n    }\n\n    /// @notice Set transfer restrictor contract\n    /// @dev Only callable by owner\n    function setTransferRestrictor(ITransferRestrictor newRestrictor) external onlyRole(DEFAULT_ADMIN_ROLE) {\n        dShareStorage storage $ = _getdShareStorage();\n        $._transferRestrictor = newRestrictor;\n        emit TransferRestrictorSet(newRestrictor);\n    }\n\n    /// ------------------ Minting and Burning ------------------ ///\n\n    /// @notice Mint tokens\n    /// @param to Address to mint tokens to\n    /// @param value Amount of tokens to mint\n    /// @dev Only callable by approved minter\n    function mint(address to, uint256 value) external onlyRole(MINTER_ROLE) {\n        _mint(to, value);\n    }\n\n    /// @notice Burn tokens\n    /// @param value Amount of tokens to burn\n    /// @dev Only callable by approved burner\n    function burn(uint256 value) external onlyRole(BURNER_ROLE) {\n        _burn(msg.sender, value);\n    }\n\n    /// @notice Burn tokens from an account\n    /// @param account Address to burn tokens from\n    /// @param value Amount of tokens to burn\n    /// @dev Only callable by approved burner\n    function burnFrom(address account, uint256 value) external onlyRole(BURNER_ROLE) {\n        _spendAllowance(account, msg.sender, value);\n        _burn(account, value);\n    }\n\n    /// ------------------ Transfers ------------------ ///\n\n    function _beforeTokenTransfer(address from, address to, uint256) internal view override {\n        // If transferRestrictor is not set, no restrictions are applied\n        dShareStorage storage $ = _getdShareStorage();\n        ITransferRestrictor _transferRestrictor = $._transferRestrictor;\n        if (address(_transferRestrictor) != address(0)) {\n            // Check transfer restrictions\n            _transferRestrictor.requireNotRestricted(from, to);\n        }\n    }\n\n    /**\n     * @param account The address of the account\n     * @return Whether the account is blacklisted\n     * @dev Returns true if the account is blacklisted , if the account is the zero address\n     */\n    function isBlacklisted(address account) external view returns (bool) {\n        dShareStorage storage $ = _getdShareStorage();\n        ITransferRestrictor _transferRestrictor = $._transferRestrictor;\n        if (address(_transferRestrictor) == address(0)) return false;\n        return _transferRestrictor.isBlacklisted(account);\n    }\n}\n"
      },
      "src/WrappedDShare.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity 0.8.25;\n\nimport {DShare} from \"./DShare.sol\";\nimport {ITransferRestrictor} from \"./ITransferRestrictor.sol\";\nimport {ERC4626, SafeTransferLib} from \"solady/src/tokens/ERC4626.sol\";\nimport {Initializable} from \"openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\";\nimport {ReentrancyGuardUpgradeable} from\n    \"openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol\";\nimport {SafeERC20, IERC20} from \"openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/**\n * @title WrappedDShare Contract\n * @dev An ERC4626 vault wrapper around the rebasing dShare token.\n *      It accumulates the value of rebases and yield distributions.\n * @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/WrappedDShare.sol)\n */\n// slither-disable-next-line missing-inheritance\ncontract WrappedDShare is Initializable, ERC4626, OwnableUpgradeable, ReentrancyGuardUpgradeable {\n    /// ------------------- Types ------------------- ///\n\n    using SafeERC20 for IERC20;\n\n    event NameSet(string name);\n    event SymbolSet(string symbol);\n\n    /// ------------------- State ------------------- ///\n\n    struct WrappedDShareStorage {\n        DShare _underlyingDShare;\n        string _name;\n        string _symbol;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"dinaricrypto.storage.WrappeddShare\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant WrappedDShareStorageLocation =\n        0x152e99b50b5f6a0e49f31b9c18139e0eb82d89de09b8e6a3d245658cb9305300;\n\n    function _getWrappedDShareStorage() private pure returns (WrappedDShareStorage storage $) {\n        assembly {\n            $.slot := WrappedDShareStorageLocation\n        }\n    }\n\n    /// ------------------- Initialization ------------------- ///\n\n    function initialize(address owner, DShare dShare_, string memory name_, string memory symbol_) public initializer {\n        __Ownable_init_unchained(owner);\n        __ReentrancyGuard_init_unchained();\n\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        $._underlyingDShare = dShare_;\n        $._name = name_;\n        $._symbol = symbol_;\n    }\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /// ------------------- Administration ------------------- ///\n\n    /**\n     * @dev Sets the name of the WrappedDShare token.\n     * @param name_ The new name.\n     */\n    function setName(string memory name_) external onlyOwner {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        $._name = name_;\n        emit NameSet(name_);\n    }\n\n    /**\n     * @dev Sets the symbol of the WrappedDShare token.\n     * @param symbol_ The new symbol.\n     */\n    function setSymbol(string memory symbol_) external onlyOwner {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        $._symbol = symbol_;\n        emit SymbolSet(symbol_);\n    }\n\n    /// ------------------- Getters ------------------- ///\n    /**\n     * @dev Returns the name of the WrappedDShare token.\n     * @return A string representing the name.\n     */\n    function name() public view override returns (string memory) {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        return $._name;\n    }\n\n    /**\n     * @dev Returns the symbol of the WrappedDShare token.\n     * @return A string representing the symbol.\n     */\n    function symbol() public view override returns (string memory) {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        return $._symbol;\n    }\n\n    /**\n     * @dev Returns the address of the underlying asset.\n     * @return The address of the underlying dShare token.\n     */\n    function asset() public view override returns (address) {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        return address($._underlyingDShare);\n    }\n\n    /// ------------------- Transfer Restrictions ------------------- ///\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting and burning.\n     * @param from Address of the sender.\n     * @param to Address of the receiver.\n     */\n    function _beforeTokenTransfer(address from, address to, uint256) internal view override {\n        // Apply underlying transfer restrictions to this vault token.\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        ITransferRestrictor restrictor = $._underlyingDShare.transferRestrictor();\n        if (address(restrictor) != address(0)) {\n            restrictor.requireNotRestricted(from, to);\n        }\n    }\n\n    function isBlacklisted(address account) external view returns (bool) {\n        WrappedDShareStorage storage $ = _getWrappedDShareStorage();\n        ITransferRestrictor restrictor = $._underlyingDShare.transferRestrictor();\n        if (address(restrictor) == address(0)) return false;\n        return restrictor.isBlacklisted(account);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./math/Math.sol\";\nimport {SignedMath} from \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant HEX_DIGITS = \"0123456789abcdef\";\n    uint8 private constant ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value)));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        uint256 localValue = value;\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = HEX_DIGITS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\n     * representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControlDefaultAdminRules} from \"./IAccessControlDefaultAdminRules.sol\";\nimport {AccessControl, IAccessControl} from \"../AccessControl.sol\";\nimport {SafeCast} from \"../../utils/math/SafeCast.sol\";\nimport {Math} from \"../../utils/math/Math.sol\";\nimport {IERC5313} from \"../../interfaces/IERC5313.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows specifying special rules to manage\n * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions\n * over other roles that may potentially have privileged rights in the system.\n *\n * If a specific role doesn't have an admin role assigned, the holder of the\n * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it.\n *\n * This contract implements the following risk mitigations on top of {AccessControl}:\n *\n * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced.\n * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account.\n * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted.\n * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}.\n * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`.\n *\n * Example usage:\n *\n * ```solidity\n * contract MyToken is AccessControlDefaultAdminRules {\n *   constructor() AccessControlDefaultAdminRules(\n *     3 days,\n *     msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder\n *    ) {}\n * }\n * ```\n */\nabstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl {\n    // pending admin pair read/written together frequently\n    address private _pendingDefaultAdmin;\n    uint48 private _pendingDefaultAdminSchedule; // 0 == unset\n\n    uint48 private _currentDelay;\n    address private _currentDefaultAdmin;\n\n    // pending delay pair read/written together frequently\n    uint48 private _pendingDelay;\n    uint48 private _pendingDelaySchedule; // 0 == unset\n\n    /**\n     * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.\n     */\n    constructor(uint48 initialDelay, address initialDefaultAdmin) {\n        if (initialDefaultAdmin == address(0)) {\n            revert AccessControlInvalidDefaultAdmin(address(0));\n        }\n        _currentDelay = initialDelay;\n        _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC5313-owner}.\n     */\n    function owner() public view virtual returns (address) {\n        return defaultAdmin();\n    }\n\n    ///\n    /// Override AccessControl role management\n    ///\n\n    /**\n     * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-renounceRole}.\n     *\n     * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling\n     * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule\n     * has also passed when calling this function.\n     *\n     * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions.\n     *\n     * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin},\n     * thereby disabling any functionality that is only available for it, and the possibility of reassigning a\n     * non-administrated role.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();\n            if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n                revert AccessControlEnforcedDefaultAdminDelay(schedule);\n            }\n            delete _pendingDefaultAdminSchedule;\n        }\n        super.renounceRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_grantRole}.\n     *\n     * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the\n     * role has been previously renounced.\n     *\n     * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE`\n     * assignable again. Make sure to guarantee this is the expected behavior in your implementation.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            if (defaultAdmin() != address(0)) {\n                revert AccessControlEnforcedDefaultAdminRules();\n            }\n            _currentDefaultAdmin = account;\n        }\n        return super._grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_revokeRole}.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            delete _currentDefaultAdmin;\n        }\n        return super._revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super._setRoleAdmin(role, adminRole);\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules accessors\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdmin() public view virtual returns (address) {\n        return _currentDefaultAdmin;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) {\n        return (_pendingDefaultAdmin, _pendingDefaultAdminSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelay() public view virtual returns (uint48) {\n        uint48 schedule = _pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? _pendingDelay : _currentDelay;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) {\n        schedule = _pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? (_pendingDelay, schedule) : (0, 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) {\n        return 5 days;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _beginDefaultAdminTransfer(newAdmin);\n    }\n\n    /**\n     * @dev See {beginDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _beginDefaultAdminTransfer(address newAdmin) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay();\n        _setPendingDefaultAdmin(newAdmin, newSchedule);\n        emit DefaultAdminTransferScheduled(newAdmin, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _cancelDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {cancelDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _cancelDefaultAdminTransfer() internal virtual {\n        _setPendingDefaultAdmin(address(0), 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function acceptDefaultAdminTransfer() public virtual {\n        (address newDefaultAdmin, ) = pendingDefaultAdmin();\n        if (_msgSender() != newDefaultAdmin) {\n            // Enforce newDefaultAdmin explicit acceptance.\n            revert AccessControlInvalidDefaultAdmin(_msgSender());\n        }\n        _acceptDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {acceptDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _acceptDefaultAdminTransfer() internal virtual {\n        (address newAdmin, uint48 schedule) = pendingDefaultAdmin();\n        if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n            revert AccessControlEnforcedDefaultAdminDelay(schedule);\n        }\n        _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());\n        _grantRole(DEFAULT_ADMIN_ROLE, newAdmin);\n        delete _pendingDefaultAdmin;\n        delete _pendingDefaultAdminSchedule;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _changeDefaultAdminDelay(newDelay);\n    }\n\n    /**\n     * @dev See {changeDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _changeDefaultAdminDelay(uint48 newDelay) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay);\n        _setPendingDelay(newDelay, newSchedule);\n        emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _rollbackDefaultAdminDelay();\n    }\n\n    /**\n     * @dev See {rollbackDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _rollbackDefaultAdminDelay() internal virtual {\n        _setPendingDelay(0, 0);\n    }\n\n    /**\n     * @dev Returns the amount of seconds to wait after the `newDelay` will\n     * become the new {defaultAdminDelay}.\n     *\n     * The value returned guarantees that if the delay is reduced, it will go into effect\n     * after a wait that honors the previously set delay.\n     *\n     * See {defaultAdminDelayIncreaseWait}.\n     */\n    function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48) {\n        uint48 currentDelay = defaultAdminDelay();\n\n        // When increasing the delay, we schedule the delay change to occur after a period of \"new delay\" has passed, up\n        // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day\n        // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new\n        // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like\n        // using milliseconds instead of seconds.\n        //\n        // When decreasing the delay, we wait the difference between \"current delay\" and \"new delay\". This guarantees\n        // that an admin transfer cannot be made faster than \"current delay\" at the time the delay change is scheduled.\n        // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days.\n        return\n            newDelay > currentDelay\n                ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48\n                : currentDelay - newDelay;\n    }\n\n    ///\n    /// Private setters\n    ///\n\n    /**\n     * @dev Setter of the tuple for pending admin and its schedule.\n     *\n     * May emit a DefaultAdminTransferCanceled event.\n     */\n    function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private {\n        (, uint48 oldSchedule) = pendingDefaultAdmin();\n\n        _pendingDefaultAdmin = newAdmin;\n        _pendingDefaultAdminSchedule = newSchedule;\n\n        // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted.\n        if (_isScheduleSet(oldSchedule)) {\n            // Emit for implicit cancellations when another default admin was scheduled.\n            emit DefaultAdminTransferCanceled();\n        }\n    }\n\n    /**\n     * @dev Setter of the tuple for pending delay and its schedule.\n     *\n     * May emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private {\n        uint48 oldSchedule = _pendingDelaySchedule;\n\n        if (_isScheduleSet(oldSchedule)) {\n            if (_hasSchedulePassed(oldSchedule)) {\n                // Materialize a virtual delay\n                _currentDelay = _pendingDelay;\n            } else {\n                // Emit for implicit cancellations when another delay was scheduled.\n                emit DefaultAdminDelayChangeCanceled();\n            }\n        }\n\n        _pendingDelay = newDelay;\n        _pendingDelaySchedule = newSchedule;\n    }\n\n    ///\n    /// Private helpers\n    ///\n\n    /**\n     * @dev Defines if an `schedule` is considered set. For consistency purposes.\n     */\n    function _isScheduleSet(uint48 schedule) private pure returns (bool) {\n        return schedule != 0;\n    }\n\n    /**\n     * @dev Defines if an `schedule` is considered passed. For consistency purposes.\n     */\n    function _hasSchedulePassed(uint48 schedule) private view returns (bool) {\n        return schedule < block.timestamp;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControlDefaultAdminRules} from \"@openzeppelin/contracts/access/extensions/IAccessControlDefaultAdminRules.sol\";\nimport {AccessControlUpgradeable} from \"../AccessControlUpgradeable.sol\";\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {SafeCast} from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {IERC5313} from \"@openzeppelin/contracts/interfaces/IERC5313.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows specifying special rules to manage\n * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions\n * over other roles that may potentially have privileged rights in the system.\n *\n * If a specific role doesn't have an admin role assigned, the holder of the\n * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it.\n *\n * This contract implements the following risk mitigations on top of {AccessControl}:\n *\n * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced.\n * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account.\n * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted.\n * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}.\n * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`.\n *\n * Example usage:\n *\n * ```solidity\n * contract MyToken is AccessControlDefaultAdminRules {\n *   constructor() AccessControlDefaultAdminRules(\n *     3 days,\n *     msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder\n *    ) {}\n * }\n * ```\n */\nabstract contract AccessControlDefaultAdminRulesUpgradeable is Initializable, IAccessControlDefaultAdminRules, IERC5313, AccessControlUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlDefaultAdminRules\n    struct AccessControlDefaultAdminRulesStorage {\n        // pending admin pair read/written together frequently\n        address _pendingDefaultAdmin;\n        uint48 _pendingDefaultAdminSchedule; // 0 == unset\n\n        uint48 _currentDelay;\n        address _currentDefaultAdmin;\n\n        // pending delay pair read/written together frequently\n        uint48 _pendingDelay;\n        uint48 _pendingDelaySchedule; // 0 == unset\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControlDefaultAdminRules\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlDefaultAdminRulesStorageLocation = 0xeef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400;\n\n    function _getAccessControlDefaultAdminRulesStorage() private pure returns (AccessControlDefaultAdminRulesStorage storage $) {\n        assembly {\n            $.slot := AccessControlDefaultAdminRulesStorageLocation\n        }\n    }\n\n    /**\n     * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address.\n     */\n    function __AccessControlDefaultAdminRules_init(uint48 initialDelay, address initialDefaultAdmin) internal onlyInitializing {\n        __AccessControlDefaultAdminRules_init_unchained(initialDelay, initialDefaultAdmin);\n    }\n\n    function __AccessControlDefaultAdminRules_init_unchained(uint48 initialDelay, address initialDefaultAdmin) internal onlyInitializing {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        if (initialDefaultAdmin == address(0)) {\n            revert AccessControlInvalidDefaultAdmin(address(0));\n        }\n        $._currentDelay = initialDelay;\n        _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC5313-owner}.\n     */\n    function owner() public view virtual returns (address) {\n        return defaultAdmin();\n    }\n\n    ///\n    /// Override AccessControl role management\n    ///\n\n    /**\n     * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function grantRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super.revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-renounceRole}.\n     *\n     * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling\n     * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule\n     * has also passed when calling this function.\n     *\n     * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions.\n     *\n     * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin},\n     * thereby disabling any functionality that is only available for it, and the possibility of reassigning a\n     * non-administrated role.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin();\n            if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n                revert AccessControlEnforcedDefaultAdminDelay(schedule);\n            }\n            delete $._pendingDefaultAdminSchedule;\n        }\n        super.renounceRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_grantRole}.\n     *\n     * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the\n     * role has been previously renounced.\n     *\n     * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE`\n     * assignable again. Make sure to guarantee this is the expected behavior in your implementation.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        if (role == DEFAULT_ADMIN_ROLE) {\n            if (defaultAdmin() != address(0)) {\n                revert AccessControlEnforcedDefaultAdminRules();\n            }\n            $._currentDefaultAdmin = account;\n        }\n        return super._grantRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_revokeRole}.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) {\n            delete $._currentDefaultAdmin;\n        }\n        return super._revokeRole(role, account);\n    }\n\n    /**\n     * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override {\n        if (role == DEFAULT_ADMIN_ROLE) {\n            revert AccessControlEnforcedDefaultAdminRules();\n        }\n        super._setRoleAdmin(role, adminRole);\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules accessors\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdmin() public view virtual returns (address) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        return $._currentDefaultAdmin;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        return ($._pendingDefaultAdmin, $._pendingDefaultAdminSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelay() public view virtual returns (uint48) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        uint48 schedule = $._pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? $._pendingDelay : $._currentDelay;\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        schedule = $._pendingDelaySchedule;\n        return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? ($._pendingDelay, schedule) : (0, 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) {\n        return 5 days;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _beginDefaultAdminTransfer(newAdmin);\n    }\n\n    /**\n     * @dev See {beginDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _beginDefaultAdminTransfer(address newAdmin) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay();\n        _setPendingDefaultAdmin(newAdmin, newSchedule);\n        emit DefaultAdminTransferScheduled(newAdmin, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _cancelDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {cancelDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _cancelDefaultAdminTransfer() internal virtual {\n        _setPendingDefaultAdmin(address(0), 0);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function acceptDefaultAdminTransfer() public virtual {\n        (address newDefaultAdmin, ) = pendingDefaultAdmin();\n        if (_msgSender() != newDefaultAdmin) {\n            // Enforce newDefaultAdmin explicit acceptance.\n            revert AccessControlInvalidDefaultAdmin(_msgSender());\n        }\n        _acceptDefaultAdminTransfer();\n    }\n\n    /**\n     * @dev See {acceptDefaultAdminTransfer}.\n     *\n     * Internal function without access restriction.\n     */\n    function _acceptDefaultAdminTransfer() internal virtual {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        (address newAdmin, uint48 schedule) = pendingDefaultAdmin();\n        if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) {\n            revert AccessControlEnforcedDefaultAdminDelay(schedule);\n        }\n        _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin());\n        _grantRole(DEFAULT_ADMIN_ROLE, newAdmin);\n        delete $._pendingDefaultAdmin;\n        delete $._pendingDefaultAdminSchedule;\n    }\n\n    ///\n    /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay\n    ///\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _changeDefaultAdminDelay(newDelay);\n    }\n\n    /**\n     * @dev See {changeDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _changeDefaultAdminDelay(uint48 newDelay) internal virtual {\n        uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay);\n        _setPendingDelay(newDelay, newSchedule);\n        emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule);\n    }\n\n    /**\n     * @inheritdoc IAccessControlDefaultAdminRules\n     */\n    function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) {\n        _rollbackDefaultAdminDelay();\n    }\n\n    /**\n     * @dev See {rollbackDefaultAdminDelay}.\n     *\n     * Internal function without access restriction.\n     */\n    function _rollbackDefaultAdminDelay() internal virtual {\n        _setPendingDelay(0, 0);\n    }\n\n    /**\n     * @dev Returns the amount of seconds to wait after the `newDelay` will\n     * become the new {defaultAdminDelay}.\n     *\n     * The value returned guarantees that if the delay is reduced, it will go into effect\n     * after a wait that honors the previously set delay.\n     *\n     * See {defaultAdminDelayIncreaseWait}.\n     */\n    function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48) {\n        uint48 currentDelay = defaultAdminDelay();\n\n        // When increasing the delay, we schedule the delay change to occur after a period of \"new delay\" has passed, up\n        // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day\n        // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new\n        // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like\n        // using milliseconds instead of seconds.\n        //\n        // When decreasing the delay, we wait the difference between \"current delay\" and \"new delay\". This guarantees\n        // that an admin transfer cannot be made faster than \"current delay\" at the time the delay change is scheduled.\n        // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days.\n        return\n            newDelay > currentDelay\n                ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48\n                : currentDelay - newDelay;\n    }\n\n    ///\n    /// Private setters\n    ///\n\n    /**\n     * @dev Setter of the tuple for pending admin and its schedule.\n     *\n     * May emit a DefaultAdminTransferCanceled event.\n     */\n    function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        (, uint48 oldSchedule) = pendingDefaultAdmin();\n\n        $._pendingDefaultAdmin = newAdmin;\n        $._pendingDefaultAdminSchedule = newSchedule;\n\n        // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted.\n        if (_isScheduleSet(oldSchedule)) {\n            // Emit for implicit cancellations when another default admin was scheduled.\n            emit DefaultAdminTransferCanceled();\n        }\n    }\n\n    /**\n     * @dev Setter of the tuple for pending delay and its schedule.\n     *\n     * May emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private {\n        AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage();\n        uint48 oldSchedule = $._pendingDelaySchedule;\n\n        if (_isScheduleSet(oldSchedule)) {\n            if (_hasSchedulePassed(oldSchedule)) {\n                // Materialize a virtual delay\n                $._currentDelay = $._pendingDelay;\n            } else {\n                // Emit for implicit cancellations when another delay was scheduled.\n                emit DefaultAdminDelayChangeCanceled();\n            }\n        }\n\n        $._pendingDelay = newDelay;\n        $._pendingDelaySchedule = newSchedule;\n    }\n\n    ///\n    /// Private helpers\n    ///\n\n    /**\n     * @dev Defines if an `schedule` is considered set. For consistency purposes.\n     */\n    function _isScheduleSet(uint48 schedule) private pure returns (bool) {\n        return schedule != 0;\n    }\n\n    /**\n     * @dev Defines if an `schedule` is considered passed. For consistency purposes.\n     */\n    function _hasSchedulePassed(uint48 schedule) private view returns (bool) {\n        return schedule < block.timestamp;\n    }\n}\n"
      },
      "src/ERC20Rebasing.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.23;\n\nimport {ERC20} from \"solady/src/tokens/ERC20.sol\";\nimport {mulDiv, mulDiv18} from \"prb-math/Common.sol\";\nimport {NumberUtils} from \"./common/NumberUtils.sol\";\n\n/// @notice Rebasing ERC20 token as an in-place upgrade to solady erc20\n/// @author Dinari (https://github.com/dinaricrypto/sbt-contracts/blob/main/src/dShare.sol)\nabstract contract ERC20Rebasing is ERC20 {\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;\n\n    uint256 private constant _TOTAL_SUPPLY_SLOT = 0x05345cdf77eb68f44c;\n    uint256 private constant _BALANCE_SLOT_SEED = 0x87a211a2;\n\n    uint128 internal constant _INITIAL_BALANCE_PER_SHARE = 1 ether;\n\n    /**\n     * @dev Returns the number of tokens an internal share amount represents.\n     * This amount is assumed to have 18 decimals and is divided by 10 **18 when applied.\n     */\n    function balancePerShare() public view virtual returns (uint128);\n\n    function sharesToBalance(uint256 shares) public view returns (uint256) {\n        return mulDiv18(shares, balancePerShare()); // floor\n    }\n\n    function balanceToShares(uint256 balance) public view returns (uint256) {\n        return mulDiv(balance, _INITIAL_BALANCE_PER_SHARE, balancePerShare()); // floor\n    }\n\n    /// ------------------ ERC20 ------------------\n\n    function totalSupply() public view virtual override returns (uint256) {\n        return sharesToBalance(super.totalSupply());\n    }\n\n    function maxSupply() public view virtual returns (uint256) {\n        uint128 balancePerShare_ = balancePerShare();\n        if (balancePerShare_ < _INITIAL_BALANCE_PER_SHARE) {\n            return mulDiv18(type(uint256).max, balancePerShare_);\n        } else if (balancePerShare_ > _INITIAL_BALANCE_PER_SHARE) {\n            return mulDiv(type(uint256).max, _INITIAL_BALANCE_PER_SHARE, balancePerShare_);\n        }\n        return type(uint256).max;\n    }\n\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return sharesToBalance(super.balanceOf(account));\n    }\n\n    function sharesOf(address account) public view virtual returns (uint256) {\n        return super.balanceOf(account);\n    }\n\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        _transfer(msg.sender, to, amount);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        _spendAllowance(from, msg.sender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    // Convert to shares\n    function _transfer(address from, address to, uint256 amount) internal virtual override {\n        _beforeTokenTransfer(from, to, amount);\n        uint256 shares = balanceToShares(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(shares, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, shares))\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), shares))\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    // Convert to shares\n    function _mint(address to, uint256 amount) internal virtual override {\n        _beforeTokenTransfer(address(0), to, amount);\n        uint256 totalSharesBefore = super.totalSupply();\n        uint256 totalSupplyBefore = sharesToBalance(totalSharesBefore);\n        uint256 totalSupplyAfter = 0;\n        unchecked {\n            totalSupplyAfter = totalSupplyBefore + amount;\n            if (totalSupplyAfter < totalSupplyBefore) revert TotalSupplyOverflow();\n        }\n        if (NumberUtils.mulDivCheckOverflow(totalSupplyAfter, _INITIAL_BALANCE_PER_SHARE, balancePerShare())) {\n            revert TotalSupplyOverflow();\n        }\n        uint256 shares = balanceToShares(amount);\n        uint256 totalSharesAfter = 0;\n        unchecked {\n            totalSharesAfter = totalSharesBefore + shares;\n        }\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, totalSharesAfter)\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), shares))\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    // Convert to shares\n    function _burn(address from, uint256 amount) internal virtual override {\n        _beforeTokenTransfer(from, address(0), amount);\n        uint256 shares = balanceToShares(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(shares, fromBalance) {\n                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.\n                revert(0x1c, 0x04)\n            }\n            // Subtract and store the updated balance.\n            sstore(fromBalanceSlot, sub(fromBalance, shares))\n            // Subtract and store the updated total supply.\n            sstore(_TOTAL_SUPPLY_SLOT, sub(sload(_TOTAL_SUPPLY_SLOT), shares))\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"
      },
      "lib/solady/src/tokens/ERC4626.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {ERC20} from \"./ERC20.sol\";\nimport {FixedPointMathLib} from \"../utils/FixedPointMathLib.sol\";\nimport {SafeTransferLib} from \"../utils/SafeTransferLib.sol\";\n\n/// @notice Simple ERC4626 tokenized Vault implementation.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC4626.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol)\nabstract contract ERC4626 is ERC20 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The default underlying decimals.\n    uint8 internal constant _DEFAULT_UNDERLYING_DECIMALS = 18;\n\n    /// @dev The default decimals offset.\n    uint8 internal constant _DEFAULT_DECIMALS_OFFSET = 0;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Cannot deposit more than the max limit.\n    error DepositMoreThanMax();\n\n    /// @dev Cannot mint more than the max limit.\n    error MintMoreThanMax();\n\n    /// @dev Cannot withdraw more than the max limit.\n    error WithdrawMoreThanMax();\n\n    /// @dev Cannot redeem more than the max limit.\n    error RedeemMoreThanMax();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted during a mint call or deposit call.\n    event Deposit(address indexed by, address indexed owner, uint256 assets, uint256 shares);\n\n    /// @dev Emitted during a withdraw call or redeem call.\n    event Withdraw(\n        address indexed by,\n        address indexed to,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /// @dev `keccak256(bytes(\"Deposit(address,address,uint256,uint256)\"))`.\n    uint256 private constant _DEPOSIT_EVENT_SIGNATURE =\n        0xdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7;\n\n    /// @dev `keccak256(bytes(\"Withdraw(address,address,address,uint256,uint256)\"))`.\n    uint256 private constant _WITHDRAW_EVENT_SIGNATURE =\n        0xfbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     ERC4626 CONSTANTS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev To be overridden to return the address of the underlying asset.\n    ///\n    /// - MUST be an ERC20 token contract.\n    /// - MUST NOT revert.\n    function asset() public view virtual returns (address);\n\n    /// @dev To be overridden to return the number of decimals of the underlying asset.\n    /// Default: 18.\n    ///\n    /// - MUST NOT revert.\n    function _underlyingDecimals() internal view virtual returns (uint8) {\n        return _DEFAULT_UNDERLYING_DECIMALS;\n    }\n\n    /// @dev Override to return a non-zero value to make the inflation attack even more unfeasible.\n    /// Only used when {_useVirtualShares} returns true.\n    /// Default: 0.\n    ///\n    /// - MUST NOT revert.\n    function _decimalsOffset() internal view virtual returns (uint8) {\n        return _DEFAULT_DECIMALS_OFFSET;\n    }\n\n    /// @dev Returns whether virtual shares will be used to mitigate the inflation attack.\n    /// See: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3706\n    /// Override to return true or false.\n    /// Default: true.\n    ///\n    /// - MUST NOT revert.\n    function _useVirtualShares() internal view virtual returns (bool) {\n        return true;\n    }\n\n    /// @dev Returns the decimals places of the token.\n    ///\n    /// - MUST NOT revert.\n    function decimals() public view virtual override(ERC20) returns (uint8) {\n        if (!_useVirtualShares()) return _underlyingDecimals();\n        return _underlyingDecimals() + _decimalsOffset();\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                ASSET DECIMALS GETTER HELPER                */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Helper function to get the decimals of the underlying asset.\n    /// Useful for setting the return value of `_underlyingDecimals` during initialization.\n    /// If the retrieval succeeds, `success` will be true, and `result` will hold the result.\n    /// Otherwise, `success` will be false, and `result` will be zero.\n    ///\n    /// Example usage:\n    /// ```\n    /// (bool success, uint8 result) = _tryGetAssetDecimals(underlying);\n    /// _decimals = success ? result : _DEFAULT_UNDERLYING_DECIMALS;\n    /// ```\n    function _tryGetAssetDecimals(address underlying)\n        internal\n        view\n        returns (bool success, uint8 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Store the function selector of `decimals()`.\n            mstore(0x00, 0x313ce567)\n            // Arguments are evaluated last to first.\n            success :=\n                and(\n                    // Returned value is less than 256, at left-padded to 32 bytes.\n                    and(lt(mload(0x00), 0x100), gt(returndatasize(), 0x1f)),\n                    // The staticcall succeeds.\n                    staticcall(gas(), underlying, 0x1c, 0x04, 0x00, 0x20)\n                )\n            result := mul(mload(0x00), success)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ACCOUNTING LOGIC                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the total amount of the underlying asset managed by the Vault.\n    ///\n    /// - SHOULD include any compounding that occurs from the yield.\n    /// - MUST be inclusive of any fees that are charged against assets in the Vault.\n    /// - MUST NOT revert.\n    function totalAssets() public view virtual returns (uint256 assets) {\n        assets = SafeTransferLib.balanceOf(asset(), address(this));\n    }\n\n    /// @dev Returns the amount of shares that the Vault will exchange for the amount of\n    /// assets provided, in an ideal scenario where all conditions are met.\n    ///\n    /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n    /// - MUST NOT show any variations depending on the caller.\n    /// - MUST NOT reflect slippage or other on-chain conditions, during the actual exchange.\n    /// - MUST NOT revert.\n    ///\n    /// Note: This calculation MAY NOT reflect the \"per-user\" price-per-share, and instead\n    /// should reflect the \"average-user's\" price-per-share, i.e. what the average user should\n    /// expect to see when exchanging to and from.\n    function convertToShares(uint256 assets) public view virtual returns (uint256 shares) {\n        if (!_useVirtualShares()) {\n            uint256 supply = totalSupply();\n            return _eitherIsZero(assets, supply)\n                ? _initialConvertToShares(assets)\n                : FixedPointMathLib.fullMulDiv(assets, supply, totalAssets());\n        }\n        uint256 o = _decimalsOffset();\n        if (o == 0) {\n            return FixedPointMathLib.fullMulDiv(assets, totalSupply() + 1, _inc(totalAssets()));\n        }\n        return FixedPointMathLib.fullMulDiv(assets, totalSupply() + 10 ** o, _inc(totalAssets()));\n    }\n\n    /// @dev Returns the amount of assets that the Vault will exchange for the amount of\n    /// shares provided, in an ideal scenario where all conditions are met.\n    ///\n    /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n    /// - MUST NOT show any variations depending on the caller.\n    /// - MUST NOT reflect slippage or other on-chain conditions, during the actual exchange.\n    /// - MUST NOT revert.\n    ///\n    /// Note: This calculation MAY NOT reflect the \"per-user\" price-per-share, and instead\n    /// should reflect the \"average-user's\" price-per-share, i.e. what the average user should\n    /// expect to see when exchanging to and from.\n    function convertToAssets(uint256 shares) public view virtual returns (uint256 assets) {\n        if (!_useVirtualShares()) {\n            uint256 supply = totalSupply();\n            return supply == 0\n                ? _initialConvertToAssets(shares)\n                : FixedPointMathLib.fullMulDiv(shares, totalAssets(), supply);\n        }\n        uint256 o = _decimalsOffset();\n        if (o == 0) {\n            return FixedPointMathLib.fullMulDiv(shares, totalAssets() + 1, _inc(totalSupply()));\n        }\n        return FixedPointMathLib.fullMulDiv(shares, totalAssets() + 1, totalSupply() + 10 ** o);\n    }\n\n    /// @dev Allows an on-chain or off-chain user to simulate the effects of their deposit\n    /// at the current block, given current on-chain conditions.\n    ///\n    /// - MUST return as close to and no more than the exact amount of Vault shares that\n    ///   will be minted in a deposit call in the same transaction, i.e. deposit should\n    ///   return the same or more shares as `previewDeposit` if call in the same transaction.\n    /// - MUST NOT account for deposit limits like those returned from `maxDeposit` and should\n    ///   always act as if the deposit will be accepted, regardless of approvals, etc.\n    /// - MUST be inclusive of deposit fees. Integrators should be aware of this.\n    /// - MUST not revert.\n    ///\n    /// Note: Any unfavorable discrepancy between `convertToShares` and `previewDeposit` SHOULD\n    /// be considered slippage in share price or some other type of condition, meaning\n    /// the depositor will lose assets by depositing.\n    function previewDeposit(uint256 assets) public view virtual returns (uint256 shares) {\n        shares = convertToShares(assets);\n    }\n\n    /// @dev Allows an on-chain or off-chain user to simulate the effects of their mint\n    /// at the current block, given current on-chain conditions.\n    ///\n    /// - MUST return as close to and no fewer than the exact amount of assets that\n    ///   will be deposited in a mint call in the same transaction, i.e. mint should\n    ///   return the same or fewer assets as `previewMint` if called in the same transaction.\n    /// - MUST NOT account for mint limits like those returned from `maxMint` and should\n    ///   always act as if the mint will be accepted, regardless of approvals, etc.\n    /// - MUST be inclusive of deposit fees. Integrators should be aware of this.\n    /// - MUST not revert.\n    ///\n    /// Note: Any unfavorable discrepancy between `convertToAssets` and `previewMint` SHOULD\n    /// be considered slippage in share price or some other type of condition,\n    /// meaning the depositor will lose assets by minting.\n    function previewMint(uint256 shares) public view virtual returns (uint256 assets) {\n        if (!_useVirtualShares()) {\n            uint256 supply = totalSupply();\n            return supply == 0\n                ? _initialConvertToAssets(shares)\n                : FixedPointMathLib.fullMulDivUp(shares, totalAssets(), supply);\n        }\n        uint256 o = _decimalsOffset();\n        if (o == 0) {\n            return FixedPointMathLib.fullMulDivUp(shares, totalAssets() + 1, _inc(totalSupply()));\n        }\n        return FixedPointMathLib.fullMulDivUp(shares, totalAssets() + 1, totalSupply() + 10 ** o);\n    }\n\n    /// @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal\n    /// at the current block, given the current on-chain conditions.\n    ///\n    /// - MUST return as close to and no fewer than the exact amount of Vault shares that\n    ///   will be burned in a withdraw call in the same transaction, i.e. withdraw should\n    ///   return the same or fewer shares as `previewWithdraw` if call in the same transaction.\n    /// - MUST NOT account for withdrawal limits like those returned from `maxWithdraw` and should\n    ///   always act as if the withdrawal will be accepted, regardless of share balance, etc.\n    /// - MUST be inclusive of withdrawal fees. Integrators should be aware of this.\n    /// - MUST not revert.\n    ///\n    /// Note: Any unfavorable discrepancy between `convertToShares` and `previewWithdraw` SHOULD\n    /// be considered slippage in share price or some other type of condition,\n    /// meaning the depositor will lose assets by depositing.\n    function previewWithdraw(uint256 assets) public view virtual returns (uint256 shares) {\n        if (!_useVirtualShares()) {\n            uint256 supply = totalSupply();\n            return _eitherIsZero(assets, supply)\n                ? _initialConvertToShares(assets)\n                : FixedPointMathLib.fullMulDivUp(assets, supply, totalAssets());\n        }\n        uint256 o = _decimalsOffset();\n        if (o == 0) {\n            return FixedPointMathLib.fullMulDivUp(assets, totalSupply() + 1, _inc(totalAssets()));\n        }\n        return FixedPointMathLib.fullMulDivUp(assets, totalSupply() + 10 ** o, _inc(totalAssets()));\n    }\n\n    /// @dev Allows an on-chain or off-chain user to simulate the effects of their redemption\n    /// at the current block, given current on-chain conditions.\n    ///\n    /// - MUST return as close to and no more than the exact amount of assets that\n    ///   will be withdrawn in a redeem call in the same transaction, i.e. redeem should\n    ///   return the same or more assets as `previewRedeem` if called in the same transaction.\n    /// - MUST NOT account for redemption limits like those returned from `maxRedeem` and should\n    ///   always act as if the redemption will be accepted, regardless of approvals, etc.\n    /// - MUST be inclusive of withdrawal fees. Integrators should be aware of this.\n    /// - MUST NOT revert.\n    ///\n    /// Note: Any unfavorable discrepancy between `convertToAssets` and `previewRedeem` SHOULD\n    /// be considered slippage in share price or some other type of condition,\n    /// meaning the depositor will lose assets by depositing.\n    function previewRedeem(uint256 shares) public view virtual returns (uint256 assets) {\n        assets = convertToAssets(shares);\n    }\n\n    /// @dev Private helper to return if either value is zero.\n    function _eitherIsZero(uint256 a, uint256 b) private pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := or(iszero(a), iszero(b))\n        }\n    }\n\n    /// @dev Private helper to return the value plus one.\n    function _inc(uint256 x) private pure returns (uint256) {\n        unchecked {\n            return x + 1;\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*              DEPOSIT / WITHDRAWAL LIMIT LOGIC              */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the maximum amount of the underlying asset that can be deposited\n    /// into the Vault for `to`, via a deposit call.\n    ///\n    /// - MUST return a limited value if `to` is subject to some deposit limit.\n    /// - MUST return `2**256-1` if there is no maximum limit.\n    /// - MUST NOT revert.\n    function maxDeposit(address to) public view virtual returns (uint256 maxAssets) {\n        to = to; // Silence unused variable warning.\n        maxAssets = type(uint256).max;\n    }\n\n    /// @dev Returns the maximum amount of the Vault shares that can be minter for `to`,\n    /// via a mint call.\n    ///\n    /// - MUST return a limited value if `to` is subject to some mint limit.\n    /// - MUST return `2**256-1` if there is no maximum limit.\n    /// - MUST NOT revert.\n    function maxMint(address to) public view virtual returns (uint256 maxShares) {\n        to = to; // Silence unused variable warning.\n        maxShares = type(uint256).max;\n    }\n\n    /// @dev Returns the maximum amount of the underlying asset that can be withdrawn\n    /// from the `owner`'s balance in the Vault, via a withdraw call.\n    ///\n    /// - MUST return a limited value if `owner` is subject to some withdrawal limit or timelock.\n    /// - MUST NOT revert.\n    function maxWithdraw(address owner) public view virtual returns (uint256 maxAssets) {\n        maxAssets = convertToAssets(balanceOf(owner));\n    }\n\n    /// @dev Returns the maximum amount of Vault shares that can be redeemed\n    /// from the `owner`'s balance in the Vault, via a redeem call.\n    ///\n    /// - MUST return a limited value if `owner` is subject to some withdrawal limit or timelock.\n    /// - MUST return `balanceOf(owner)` otherwise.\n    /// - MUST NOT revert.\n    function maxRedeem(address owner) public view virtual returns (uint256 maxShares) {\n        maxShares = balanceOf(owner);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                 DEPOSIT / WITHDRAWAL LOGIC                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints `shares` Vault shares to `to` by depositing exactly `assets`\n    /// of underlying tokens.\n    ///\n    /// - MUST emit the {Deposit} event.\n    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault\n    ///   contract before the deposit execution, and are accounted for during deposit.\n    /// - MUST revert if all of `assets` cannot be deposited, such as due to deposit limit,\n    ///   slippage, insufficient approval, etc.\n    ///\n    /// Note: Most implementations will require pre-approval of the Vault with the\n    /// Vault's underlying `asset` token.\n    function deposit(uint256 assets, address to) public virtual returns (uint256 shares) {\n        if (assets > maxDeposit(to)) _revert(0xb3c61a83); // `DepositMoreThanMax()`.\n        shares = previewDeposit(assets);\n        _deposit(msg.sender, to, assets, shares);\n    }\n\n    /// @dev Mints exactly `shares` Vault shares to `to` by depositing `assets`\n    /// of underlying tokens.\n    ///\n    /// - MUST emit the {Deposit} event.\n    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault\n    ///   contract before the mint execution, and are accounted for during mint.\n    /// - MUST revert if all of `shares` cannot be deposited, such as due to deposit limit,\n    ///   slippage, insufficient approval, etc.\n    ///\n    /// Note: Most implementations will require pre-approval of the Vault with the\n    /// Vault's underlying `asset` token.\n    function mint(uint256 shares, address to) public virtual returns (uint256 assets) {\n        if (shares > maxMint(to)) _revert(0x6a695959); // `MintMoreThanMax()`.\n        assets = previewMint(shares);\n        _deposit(msg.sender, to, assets, shares);\n    }\n\n    /// @dev Burns `shares` from `owner` and sends exactly `assets` of underlying tokens to `to`.\n    ///\n    /// - MUST emit the {Withdraw} event.\n    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault\n    ///   contract before the withdraw execution, and are accounted for during withdraw.\n    /// - MUST revert if all of `assets` cannot be withdrawn, such as due to withdrawal limit,\n    ///   slippage, insufficient balance, etc.\n    ///\n    /// Note: Some implementations will require pre-requesting to the Vault before a withdrawal\n    /// may be performed. Those methods should be performed separately.\n    function withdraw(uint256 assets, address to, address owner)\n        public\n        virtual\n        returns (uint256 shares)\n    {\n        if (assets > maxWithdraw(owner)) _revert(0x936941fc); // `WithdrawMoreThanMax()`.\n        shares = previewWithdraw(assets);\n        _withdraw(msg.sender, to, owner, assets, shares);\n    }\n\n    /// @dev Burns exactly `shares` from `owner` and sends `assets` of underlying tokens to `to`.\n    ///\n    /// - MUST emit the {Withdraw} event.\n    /// - MAY support an additional flow in which the underlying tokens are owned by the Vault\n    ///   contract before the redeem execution, and are accounted for during redeem.\n    /// - MUST revert if all of shares cannot be redeemed, such as due to withdrawal limit,\n    ///   slippage, insufficient balance, etc.\n    ///\n    /// Note: Some implementations will require pre-requesting to the Vault before a redeem\n    /// may be performed. Those methods should be performed separately.\n    function redeem(uint256 shares, address to, address owner)\n        public\n        virtual\n        returns (uint256 assets)\n    {\n        if (shares > maxRedeem(owner)) _revert(0x4656425a); // `RedeemMoreThanMax()`.\n        assets = previewRedeem(shares);\n        _withdraw(msg.sender, to, owner, assets, shares);\n    }\n\n    /// @dev Internal helper for reverting efficiently.\n    function _revert(uint256 s) private pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, s)\n            revert(0x1c, 0x04)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      INTERNAL HELPERS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev For deposits and mints.\n    ///\n    /// Emits a {Deposit} event.\n    function _deposit(address by, address to, uint256 assets, uint256 shares) internal virtual {\n        SafeTransferLib.safeTransferFrom(asset(), by, address(this), assets);\n        _mint(to, shares);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Emit the {Deposit} event.\n            mstore(0x00, assets)\n            mstore(0x20, shares)\n            let m := shr(96, not(0))\n            log3(0x00, 0x40, _DEPOSIT_EVENT_SIGNATURE, and(m, by), and(m, to))\n        }\n        _afterDeposit(assets, shares);\n    }\n\n    /// @dev For withdrawals and redemptions.\n    ///\n    /// Emits a {Withdraw} event.\n    function _withdraw(address by, address to, address owner, uint256 assets, uint256 shares)\n        internal\n        virtual\n    {\n        if (by != owner) _spendAllowance(owner, by, shares);\n        _beforeWithdraw(assets, shares);\n        _burn(owner, shares);\n        SafeTransferLib.safeTransfer(asset(), to, assets);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Emit the {Withdraw} event.\n            mstore(0x00, assets)\n            mstore(0x20, shares)\n            let m := shr(96, not(0))\n            log4(0x00, 0x40, _WITHDRAW_EVENT_SIGNATURE, and(m, by), and(m, to), and(m, owner))\n        }\n    }\n\n    /// @dev Internal conversion function (from assets to shares) to apply when the Vault is empty.\n    /// Only used when {_useVirtualShares} returns false.\n    ///\n    /// Note: Make sure to keep this function consistent with {_initialConvertToAssets}\n    /// when overriding it.\n    function _initialConvertToShares(uint256 assets)\n        internal\n        view\n        virtual\n        returns (uint256 shares)\n    {\n        shares = assets;\n    }\n\n    /// @dev Internal conversion function (from shares to assets) to apply when the Vault is empty.\n    /// Only used when {_useVirtualShares} returns false.\n    ///\n    /// Note: Make sure to keep this function consistent with {_initialConvertToShares}\n    /// when overriding it.\n    function _initialConvertToAssets(uint256 shares)\n        internal\n        view\n        virtual\n        returns (uint256 assets)\n    {\n        assets = shares;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     HOOKS TO OVERRIDE                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any withdrawal or redemption.\n    function _beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}\n\n    /// @dev Hook that is called after any deposit or mint.\n    function _afterDeposit(uint256 assets, uint256 shares) internal virtual {}\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\n    struct ReentrancyGuardStorage {\n        uint256 _status;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\n        assembly {\n            $.slot := ReentrancyGuardStorageLocation\n        }\n    }\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if ($._status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        $._status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        return $._status == ENTERED;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Muldiv operation overflow.\n     */\n    error MathOverflowedMulDiv();\n\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            return a / b;\n        }\n\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                revert MathOverflowedMulDiv();\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/IAccessControlDefaultAdminRules.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlDefaultAdminRules declared to support ERC165 detection.\n */\ninterface IAccessControlDefaultAdminRules is IAccessControl {\n    /**\n     * @dev The new default admin is not a valid default admin.\n     */\n    error AccessControlInvalidDefaultAdmin(address defaultAdmin);\n\n    /**\n     * @dev At least one of the following rules was violated:\n     *\n     * - The `DEFAULT_ADMIN_ROLE` must only be managed by itself.\n     * - The `DEFAULT_ADMIN_ROLE` must only be held by one account at the time.\n     * - Any `DEFAULT_ADMIN_ROLE` transfer must be in two delayed steps.\n     */\n    error AccessControlEnforcedDefaultAdminRules();\n\n    /**\n     * @dev The delay for transferring the default admin delay is enforced and\n     * the operation must wait until `schedule`.\n     *\n     * NOTE: `schedule` can be 0 indicating there's no transfer scheduled.\n     */\n    error AccessControlEnforcedDefaultAdminDelay(uint48 schedule);\n\n    /**\n     * @dev Emitted when a {defaultAdmin} transfer is started, setting `newAdmin` as the next\n     * address to become the {defaultAdmin} by calling {acceptDefaultAdminTransfer} only after `acceptSchedule`\n     * passes.\n     */\n    event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule);\n\n    /**\n     * @dev Emitted when a {pendingDefaultAdmin} is reset if it was never accepted, regardless of its schedule.\n     */\n    event DefaultAdminTransferCanceled();\n\n    /**\n     * @dev Emitted when a {defaultAdminDelay} change is started, setting `newDelay` as the next\n     * delay to be applied between default admin transfer after `effectSchedule` has passed.\n     */\n    event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule);\n\n    /**\n     * @dev Emitted when a {pendingDefaultAdminDelay} is reset if its schedule didn't pass.\n     */\n    event DefaultAdminDelayChangeCanceled();\n\n    /**\n     * @dev Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.\n     */\n    function defaultAdmin() external view returns (address);\n\n    /**\n     * @dev Returns a tuple of a `newAdmin` and an accept schedule.\n     *\n     * After the `schedule` passes, the `newAdmin` will be able to accept the {defaultAdmin} role\n     * by calling {acceptDefaultAdminTransfer}, completing the role transfer.\n     *\n     * A zero value only in `acceptSchedule` indicates no pending admin transfer.\n     *\n     * NOTE: A zero address `newAdmin` means that {defaultAdmin} is being renounced.\n     */\n    function pendingDefaultAdmin() external view returns (address newAdmin, uint48 acceptSchedule);\n\n    /**\n     * @dev Returns the delay required to schedule the acceptance of a {defaultAdmin} transfer started.\n     *\n     * This delay will be added to the current timestamp when calling {beginDefaultAdminTransfer} to set\n     * the acceptance schedule.\n     *\n     * NOTE: If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this\n     * function returns the new delay. See {changeDefaultAdminDelay}.\n     */\n    function defaultAdminDelay() external view returns (uint48);\n\n    /**\n     * @dev Returns a tuple of `newDelay` and an effect schedule.\n     *\n     * After the `schedule` passes, the `newDelay` will get into effect immediately for every\n     * new {defaultAdmin} transfer started with {beginDefaultAdminTransfer}.\n     *\n     * A zero value only in `effectSchedule` indicates no pending delay change.\n     *\n     * NOTE: A zero value only for `newDelay` means that the next {defaultAdminDelay}\n     * will be zero after the effect schedule.\n     */\n    function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 effectSchedule);\n\n    /**\n     * @dev Starts a {defaultAdmin} transfer by setting a {pendingDefaultAdmin} scheduled for acceptance\n     * after the current timestamp plus a {defaultAdminDelay}.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * Emits a DefaultAdminRoleChangeStarted event.\n     */\n    function beginDefaultAdminTransfer(address newAdmin) external;\n\n    /**\n     * @dev Cancels a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}.\n     *\n     * A {pendingDefaultAdmin} not yet accepted can also be cancelled with this function.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * May emit a DefaultAdminTransferCanceled event.\n     */\n    function cancelDefaultAdminTransfer() external;\n\n    /**\n     * @dev Completes a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}.\n     *\n     * After calling the function:\n     *\n     * - `DEFAULT_ADMIN_ROLE` should be granted to the caller.\n     * - `DEFAULT_ADMIN_ROLE` should be revoked from the previous holder.\n     * - {pendingDefaultAdmin} should be reset to zero values.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the {pendingDefaultAdmin}'s `newAdmin`.\n     * - The {pendingDefaultAdmin}'s `acceptSchedule` should've passed.\n     */\n    function acceptDefaultAdminTransfer() external;\n\n    /**\n     * @dev Initiates a {defaultAdminDelay} update by setting a {pendingDefaultAdminDelay} scheduled for getting\n     * into effect after the current timestamp plus a {defaultAdminDelay}.\n     *\n     * This function guarantees that any call to {beginDefaultAdminTransfer} done between the timestamp this\n     * method is called and the {pendingDefaultAdminDelay} effect schedule will use the current {defaultAdminDelay}\n     * set before calling.\n     *\n     * The {pendingDefaultAdminDelay}'s effect schedule is defined in a way that waiting until the schedule and then\n     * calling {beginDefaultAdminTransfer} with the new delay will take at least the same as another {defaultAdmin}\n     * complete transfer (including acceptance).\n     *\n     * The schedule is designed for two scenarios:\n     *\n     * - When the delay is changed for a larger one the schedule is `block.timestamp + newDelay` capped by\n     * {defaultAdminDelayIncreaseWait}.\n     * - When the delay is changed for a shorter one, the schedule is `block.timestamp + (current delay - new delay)`.\n     *\n     * A {pendingDefaultAdminDelay} that never got into effect will be canceled in favor of a new scheduled change.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function changeDefaultAdminDelay(uint48 newDelay) external;\n\n    /**\n     * @dev Cancels a scheduled {defaultAdminDelay} change.\n     *\n     * Requirements:\n     *\n     * - Only can be called by the current {defaultAdmin}.\n     *\n     * May emit a DefaultAdminDelayChangeCanceled event.\n     */\n    function rollbackDefaultAdminDelay() external;\n\n    /**\n     * @dev Maximum time in seconds for an increase to {defaultAdminDelay} (that is scheduled using {changeDefaultAdminDelay})\n     * to take effect. Default to 5 days.\n     *\n     * When the {defaultAdminDelay} is scheduled to be increased, it goes into effect after the new delay has passed with\n     * the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds)\n     * that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can\n     * be overrode for a custom {defaultAdminDelay} increase scheduling.\n     *\n     * IMPORTANT: Make sure to add a reasonable amount of time while overriding this value, otherwise,\n     * there's a risk of setting a high new delay that goes into effect almost immediately without the\n     * possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds).\n     */\n    function defaultAdminDelayIncreaseWait() external view returns (uint48);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 role => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        return _roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (!hasRole(role, account)) {\n            _roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (hasRole(role, account)) {\n            _roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/interfaces/IERC5313.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5313.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface for the Light Contract Ownership Standard.\n *\n * A standardized minimal interface required to identify an account that controls a contract\n */\ninterface IERC5313 {\n    /**\n     * @dev Gets the address of the owner.\n     */\n    function owner() external view returns (address);\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"../utils/introspection/ERC165Upgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl\n    struct AccessControlStorage {\n        mapping(bytes32 role => RoleData) _roles;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControl\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;\n\n    function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {\n        assembly {\n            $.slot := AccessControlStorageLocation\n        }\n    }\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        $._roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (!hasRole(role, account)) {\n            $._roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (hasRole(role, account)) {\n            $._roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) 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"
      },
      "lib/solady/src/utils/FixedPointMathLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\nlibrary FixedPointMathLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\n    error ExpOverflow();\n\n    /// @dev The operation failed, as the output exceeds the maximum value of uint256.\n    error FactorialOverflow();\n\n    /// @dev The operation failed, due to an overflow.\n    error RPowOverflow();\n\n    /// @dev The mantissa is too big to fit.\n    error MantissaOverflow();\n\n    /// @dev The operation failed, due to an multiplication overflow.\n    error MulWadFailed();\n\n    /// @dev The operation failed, either due to a\n    /// multiplication overflow, or a division by a zero.\n    error DivWadFailed();\n\n    /// @dev The multiply-divide operation failed, either due to a\n    /// multiplication overflow, or a division by a zero.\n    error MulDivFailed();\n\n    /// @dev The division failed, as the denominator is zero.\n    error DivFailed();\n\n    /// @dev The full precision multiply-divide operation failed, either due\n    /// to the result being larger than 256 bits, or a division by a zero.\n    error FullMulDivFailed();\n\n    /// @dev The output is undefined, as the input is less-than-or-equal to zero.\n    error LnWadUndefined();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The scalar of ETH and most ERC20s.\n    uint256 internal constant WAD = 1e18;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*              SIMPLIFIED FIXED POINT OPERATIONS             */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded down.\n    function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\n            if mul(y, gt(x, div(not(0), y))) {\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, y), WAD)\n        }\n    }\n\n    /// @dev Equivalent to `(x * y) / WAD` rounded up.\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\n            if mul(y, gt(x, div(not(0), y))) {\n                mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded down.\n    function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, WAD), y)\n        }\n    }\n\n    /// @dev Equivalent to `(x * WAD) / y` rounded up.\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\n            if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\n                mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))\n        }\n    }\n\n    /// @dev Equivalent to `x` to the power of `y`.\n    /// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`.\n    function powWad(int256 x, int256 y) internal pure returns (int256) {\n        // Using `ln(x)` means `x` must be greater than 0.\n        return expWad((lnWad(x) * y) / int256(WAD));\n    }\n\n    /// @dev Returns `exp(x)`, denominated in `WAD`.\n    function expWad(int256 x) internal pure returns (int256 r) {\n        unchecked {\n            // When the result is < 0.5 we return zero. This happens when\n            // x <= floor(log(0.5e18) * 1e18) ~ -42e18\n            if (x <= -42139678854452767551) return r;\n\n            /// @solidity memory-safe-assembly\n            assembly {\n                // When the result is > (2**255 - 1) / 1e18 we can not represent it as an\n                // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135.\n                if iszero(slt(x, 135305999368893231589)) {\n                    mstore(0x00, 0xa37bfec9) // `ExpOverflow()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n\n            // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96\n            // for more intermediate precision and a binary basis. This base conversion\n            // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.\n            x = (x << 78) / 5 ** 18;\n\n            // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers\n            // of two such that exp(x) = exp(x') * 2**k, where k is an integer.\n            // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).\n            int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96;\n            x = x - k * 54916777467707473351141471128;\n\n            // k is in the range [-61, 195].\n\n            // Evaluate using a (6, 7)-term rational approximation.\n            // p is made monic, we'll multiply by a scale factor later.\n            int256 y = x + 1346386616545796478920950773328;\n            y = ((y * x) >> 96) + 57155421227552351082224309758442;\n            int256 p = y + x - 94201549194550492254356042504812;\n            p = ((p * y) >> 96) + 28719021644029726153956944680412240;\n            p = p * x + (4385272521454847904659076985693276 << 96);\n\n            // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n            int256 q = x - 2855989394907223263936484059900;\n            q = ((q * x) >> 96) + 50020603652535783019961831881945;\n            q = ((q * x) >> 96) - 533845033583426703283633433725380;\n            q = ((q * x) >> 96) + 3604857256930695427073651918091429;\n            q = ((q * x) >> 96) - 14423608567350463180887372962807573;\n            q = ((q * x) >> 96) + 26449188498355588339934803723976023;\n\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Div in assembly because solidity adds a zero check despite the unchecked.\n                // The q polynomial won't have zeros in the domain as all its roots are complex.\n                // No scaling is necessary because p is already 2**96 too large.\n                r := sdiv(p, q)\n            }\n\n            // r should be in the range (0.09, 0.25) * 2**96.\n\n            // We now need to multiply r by:\n            // * the scale factor s = ~6.031367120.\n            // * the 2**k factor from the range reduction.\n            // * the 1e18 / 2**96 factor for base conversion.\n            // We do this all at once, with an intermediate result in 2**213\n            // basis, so the final right shift is always by a positive amount.\n            r = int256(\n                (uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)\n            );\n        }\n    }\n\n    /// @dev Returns `ln(x)`, denominated in `WAD`.\n    function lnWad(int256 x) internal pure returns (int256 r) {\n        unchecked {\n            /// @solidity memory-safe-assembly\n            assembly {\n                if iszero(sgt(x, 0)) {\n                    mstore(0x00, 0x1615e638) // `LnWadUndefined()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n\n            // We want to convert x from 10**18 fixed point to 2**96 fixed point.\n            // We do this by multiplying by 2**96 / 10**18. But since\n            // ln(x * C) = ln(x) + ln(C), we can simply do nothing here\n            // and add ln(2**96 / 10**18) at the end.\n\n            // Compute k = log2(x) - 96, t = 159 - k = 255 - log2(x) = 255 ^ log2(x).\n            int256 t;\n            /// @solidity memory-safe-assembly\n            assembly {\n                t := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n                t := or(t, shl(6, lt(0xffffffffffffffff, shr(t, x))))\n                t := or(t, shl(5, lt(0xffffffff, shr(t, x))))\n                t := or(t, shl(4, lt(0xffff, shr(t, x))))\n                t := or(t, shl(3, lt(0xff, shr(t, x))))\n                // forgefmt: disable-next-item\n                t := xor(t, byte(and(0x1f, shr(shr(t, x), 0x8421084210842108cc6318c6db6d54be)),\n                    0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))\n            }\n\n            // Reduce range of x to (1, 2) * 2**96\n            // ln(2^k * x) = k * ln(2) + ln(x)\n            x = int256(uint256(x << uint256(t)) >> 159);\n\n            // Evaluate using a (8, 8)-term rational approximation.\n            // p is made monic, we will multiply by a scale factor later.\n            int256 p = x + 3273285459638523848632254066296;\n            p = ((p * x) >> 96) + 24828157081833163892658089445524;\n            p = ((p * x) >> 96) + 43456485725739037958740375743393;\n            p = ((p * x) >> 96) - 11111509109440967052023855526967;\n            p = ((p * x) >> 96) - 45023709667254063763336534515857;\n            p = ((p * x) >> 96) - 14706773417378608786704636184526;\n            p = p * x - (795164235651350426258249787498 << 96);\n\n            // We leave p in 2**192 basis so we don't need to scale it back up for the division.\n            // q is monic by convention.\n            int256 q = x + 5573035233440673466300451813936;\n            q = ((q * x) >> 96) + 71694874799317883764090561454958;\n            q = ((q * x) >> 96) + 283447036172924575727196451306956;\n            q = ((q * x) >> 96) + 401686690394027663651624208769553;\n            q = ((q * x) >> 96) + 204048457590392012362485061816622;\n            q = ((q * x) >> 96) + 31853899698501571402653359427138;\n            q = ((q * x) >> 96) + 909429971244387300277376558375;\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Div in assembly because solidity adds a zero check despite the unchecked.\n                // The q polynomial is known not to have zeros in the domain.\n                // No scaling required because p is already 2**96 too large.\n                r := sdiv(p, q)\n            }\n\n            // r is in the range (0, 0.125) * 2**96\n\n            // Finalization, we need to:\n            // * multiply by the scale factor s = 5.549…\n            // * add ln(2**96 / 10**18)\n            // * add k * ln(2)\n            // * multiply by 10**18 / 2**96 = 5**18 >> 78\n\n            // mul s * 5e18 * 2**96, base is now 5**18 * 2**192\n            r *= 1677202110996718588342820967067443963516166;\n            // add ln(2) * k * 5e18 * 2**192\n            r += 16597577552685614221487285958193947469193820559219878177908093499208371 * (159 - t);\n            // add ln(2**96 / 10**18) * 5e18 * 2**192\n            r += 600920179829731861736702779321621459595472258049074101567377883020018308;\n            // base conversion: mul 2**18 / 2**192\n            r >>= 174;\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  GENERAL NUMBER UTILITIES                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Calculates `floor(a * b / d)` with full precision.\n    /// Throws if result overflows a uint256 or when `d` is zero.\n    /// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv\n    function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                // 512-bit multiply `[p1 p0] = x * y`.\n                // Compute the product mod `2**256` and mod `2**256 - 1`\n                // then use the Chinese Remainder Theorem to reconstruct\n                // the 512 bit result. The result is stored in two 256\n                // variables such that `product = p1 * 2**256 + p0`.\n\n                // Least significant 256 bits of the product.\n                let p0 := mul(x, y)\n                let mm := mulmod(x, y, not(0))\n                // Most significant 256 bits of the product.\n                let p1 := sub(mm, add(p0, lt(mm, p0)))\n\n                // Handle non-overflow cases, 256 by 256 division.\n                if iszero(p1) {\n                    if iszero(d) {\n                        mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                        revert(0x1c, 0x04)\n                    }\n                    result := div(p0, d)\n                    break\n                }\n\n                // Make sure the result is less than `2**256`. Also prevents `d == 0`.\n                if iszero(gt(d, p1)) {\n                    mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                    revert(0x1c, 0x04)\n                }\n\n                /*------------------- 512 by 256 division --------------------*/\n\n                // Make division exact by subtracting the remainder from `[p1 p0]`.\n                // Compute remainder using mulmod.\n                let r := mulmod(x, y, d)\n                // `t` is the least significant bit of `d`.\n                // Always greater or equal to 1.\n                let t := and(d, sub(0, d))\n                // Divide `d` by `t`, which is a power of two.\n                d := div(d, t)\n                // Invert `d mod 2**256`\n                // Now that `d` is an odd number, it has an inverse\n                // modulo `2**256` such that `d * inv = 1 mod 2**256`.\n                // Compute the inverse by starting with a seed that is correct\n                // correct for four bits. That is, `d * inv = 1 mod 2**4`.\n                let inv := xor(mul(3, d), 2)\n                // Now use Newton-Raphson iteration to improve the precision.\n                // Thanks to Hensel's lifting lemma, this also works in modular\n                // arithmetic, doubling the correct bits in each step.\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64\n                inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128\n                result :=\n                    mul(\n                        // Divide [p1 p0] by the factors of two.\n                        // Shift in bits from `p1` into `p0`. For this we need\n                        // to flip `t` such that it is `2**256 / t`.\n                        or(mul(sub(p1, gt(r, p0)), add(div(sub(0, t), t), 1)), div(sub(p0, r), t)),\n                        // inverse mod 2**256\n                        mul(inv, sub(2, mul(d, inv)))\n                    )\n                break\n            }\n        }\n    }\n\n    /// @dev Calculates `floor(x * y / d)` with full precision, rounded up.\n    /// Throws if result overflows a uint256 or when `d` is zero.\n    /// Credit to Uniswap-v3-core under MIT license:\n    /// https://github.com/Uniswap/v3-core/blob/contracts/libraries/FullMath.sol\n    function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {\n        result = fullMulDiv(x, y, d);\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mulmod(x, y, d) {\n                result := add(result, 1)\n                if iszero(result) {\n                    mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /// @dev Returns `floor(x * y / d)`.\n    /// Reverts if `x * y` overflows, or `d` is zero.\n    function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := div(mul(x, y), d)\n        }\n    }\n\n    /// @dev Returns `ceil(x * y / d)`.\n    /// Reverts if `x * y` overflows, or `d` is zero.\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {\n                mstore(0x00, 0xad251c27) // `MulDivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(mul(x, y), d))), div(mul(x, y), d))\n        }\n    }\n\n    /// @dev Returns `ceil(x / d)`.\n    /// Reverts if `d` is zero.\n    function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(d) {\n                mstore(0x00, 0x65244e4e) // `DivFailed()`.\n                revert(0x1c, 0x04)\n            }\n            z := add(iszero(iszero(mod(x, d))), div(x, d))\n        }\n    }\n\n    /// @dev Returns `max(0, x - y)`.\n    function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(gt(x, y), sub(x, y))\n        }\n    }\n\n    /// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`.\n    /// Reverts if the computation overflows.\n    function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`.\n            if x {\n                z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x`\n                let half := shr(1, b) // Divide `b` by 2.\n                // Divide `y` by 2 every iteration.\n                for { y := shr(1, y) } y { y := shr(1, y) } {\n                    let xx := mul(x, x) // Store x squared.\n                    let xxRound := add(xx, half) // Round to the nearest number.\n                    // Revert if `xx + half` overflowed, or if `x ** 2` overflows.\n                    if or(lt(xxRound, xx), shr(128, x)) {\n                        mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\n                        revert(0x1c, 0x04)\n                    }\n                    x := div(xxRound, b) // Set `x` to scaled `xxRound`.\n                    // If `y` is odd:\n                    if and(y, 1) {\n                        let zx := mul(z, x) // Compute `z * x`.\n                        let zxRound := add(zx, half) // Round to the nearest number.\n                        // If `z * x` overflowed or `zx + half` overflowed:\n                        if or(xor(div(zx, x), z), lt(zxRound, zx)) {\n                            // Revert if `x` is non-zero.\n                            if iszero(iszero(x)) {\n                                mstore(0x00, 0x49f7642b) // `RPowOverflow()`.\n                                revert(0x1c, 0x04)\n                            }\n                        }\n                        z := div(zxRound, b) // Return properly scaled `zxRound`.\n                    }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the square root of `x`.\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // Let `y = x / 2**r`. We check `y >= 2**(k + 8)`\n            // but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffffff, shr(r, x))))\n            z := shl(shr(1, r), z)\n\n            // Goal was to get `z*z*y` within a small factor of `x`. More iterations could\n            // get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.\n            // We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.\n            // That's not possible if `x < 256` but we can just verify those cases exhaustively.\n\n            // Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.\n            // Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.\n            // Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.\n\n            // For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`\n            // is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,\n            // with largest error when `s = 1` and when `s = 256` or `1/256`.\n\n            // Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.\n            // Then we can estimate `sqrt(y)` using\n            // `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.\n\n            // There is no overflow risk here since `y < 2**136` after the first branch above.\n            z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If `x+1` is a perfect square, the Babylonian method cycles between\n            // `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    /// @dev Returns the cube root of `x`.\n    /// Credit to bout3fiddy and pcaversaccio under AGPLv3 license:\n    /// https://github.com/pcaversaccio/snekmate/blob/main/src/utils/Math.vy\n    function cbrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n\n            z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3)))\n\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n            z := div(add(add(div(x, mul(z, z)), z), z), 3)\n\n            z := sub(z, lt(div(x, mul(z, z)), z))\n        }\n    }\n\n    /// @dev Returns the square root of `x`, denominated in `WAD`.\n    function sqrtWad(uint256 x) internal pure returns (uint256 z) {\n        unchecked {\n            z = 10 ** 9;\n            if (x <= type(uint256).max / 10 ** 36 - 1) {\n                x *= 10 ** 18;\n                z = 1;\n            }\n            z *= sqrt(x);\n        }\n    }\n\n    /// @dev Returns the cube root of `x`, denominated in `WAD`.\n    function cbrtWad(uint256 x) internal pure returns (uint256 z) {\n        unchecked {\n            z = 10 ** 12;\n            if (x <= (type(uint256).max / 10 ** 36) * 10 ** 18 - 1) {\n                if (x >= type(uint256).max / 10 ** 36) {\n                    x *= 10 ** 18;\n                    z = 10 ** 6;\n                } else {\n                    x *= 10 ** 36;\n                    z = 1;\n                }\n            }\n            z *= cbrt(x);\n        }\n    }\n\n    /// @dev Returns the factorial of `x`.\n    function factorial(uint256 x) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(lt(x, 58)) {\n                mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            for { result := 1 } x { x := sub(x, 1) } { result := mul(result, x) }\n        }\n    }\n\n    /// @dev Returns the log2 of `x`.\n    /// Equivalent to computing the index of the most significant bit (MSB) of `x`.\n    /// Returns 0 if `x` is zero.\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            // forgefmt: disable-next-item\n            r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),\n                0x0706060506020504060203020504030106050205030304010505030400000000))\n        }\n    }\n\n    /// @dev Returns the log2 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log2Up(uint256 x) internal pure returns (uint256 r) {\n        r = log2(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(shl(r, 1), x))\n        }\n    }\n\n    /// @dev Returns the log10 of `x`.\n    /// Returns 0 if `x` is zero.\n    function log10(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(lt(x, 100000000000000000000000000000000000000)) {\n                x := div(x, 100000000000000000000000000000000000000)\n                r := 38\n            }\n            if iszero(lt(x, 100000000000000000000)) {\n                x := div(x, 100000000000000000000)\n                r := add(r, 20)\n            }\n            if iszero(lt(x, 10000000000)) {\n                x := div(x, 10000000000)\n                r := add(r, 10)\n            }\n            if iszero(lt(x, 100000)) {\n                x := div(x, 100000)\n                r := add(r, 5)\n            }\n            r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999)))))\n        }\n    }\n\n    /// @dev Returns the log10 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log10Up(uint256 x) internal pure returns (uint256 r) {\n        r = log10(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(exp(10, r), x))\n        }\n    }\n\n    /// @dev Returns the log256 of `x`.\n    /// Returns 0 if `x` is zero.\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))\n            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(shr(3, r), lt(0xff, shr(r, x)))\n        }\n    }\n\n    /// @dev Returns the log256 of `x`, rounded up.\n    /// Returns 0 if `x` is zero.\n    function log256Up(uint256 x) internal pure returns (uint256 r) {\n        r = log256(x);\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := add(r, lt(shl(shl(3, r), 1), x))\n        }\n    }\n\n    /// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`.\n    /// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).\n    function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mantissa := x\n            if mantissa {\n                if iszero(mod(mantissa, 1000000000000000000000000000000000)) {\n                    mantissa := div(mantissa, 1000000000000000000000000000000000)\n                    exponent := 33\n                }\n                if iszero(mod(mantissa, 10000000000000000000)) {\n                    mantissa := div(mantissa, 10000000000000000000)\n                    exponent := add(exponent, 19)\n                }\n                if iszero(mod(mantissa, 1000000000000)) {\n                    mantissa := div(mantissa, 1000000000000)\n                    exponent := add(exponent, 12)\n                }\n                if iszero(mod(mantissa, 1000000)) {\n                    mantissa := div(mantissa, 1000000)\n                    exponent := add(exponent, 6)\n                }\n                if iszero(mod(mantissa, 10000)) {\n                    mantissa := div(mantissa, 10000)\n                    exponent := add(exponent, 4)\n                }\n                if iszero(mod(mantissa, 100)) {\n                    mantissa := div(mantissa, 100)\n                    exponent := add(exponent, 2)\n                }\n                if iszero(mod(mantissa, 10)) {\n                    mantissa := div(mantissa, 10)\n                    exponent := add(exponent, 1)\n                }\n            }\n        }\n    }\n\n    /// @dev Convenience function for packing `x` into a smaller number using `sci`.\n    /// The `mantissa` will be in bits [7..255] (the upper 249 bits).\n    /// The `exponent` will be in bits [0..6] (the lower 7 bits).\n    /// Use `SafeCastLib` to safely ensure that the `packed` number is small\n    /// enough to fit in the desired unsigned integer type:\n    /// ```\n    ///     uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));\n    /// ```\n    function packSci(uint256 x) internal pure returns (uint256 packed) {\n        (x, packed) = sci(x); // Reuse for `mantissa` and `exponent`.\n        /// @solidity memory-safe-assembly\n        assembly {\n            if shr(249, x) {\n                mstore(0x00, 0xce30380c) // `MantissaOverflow()`.\n                revert(0x1c, 0x04)\n            }\n            packed := or(shl(7, x), packed)\n        }\n    }\n\n    /// @dev Convenience function for unpacking a packed number from `packSci`.\n    function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) {\n        unchecked {\n            unpacked = (packed >> 7) * 10 ** (packed & 0x7f);\n        }\n    }\n\n    /// @dev Returns the average of `x` and `y`.\n    function avg(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = (x & y) + ((x ^ y) >> 1);\n        }\n    }\n\n    /// @dev Returns the average of `x` and `y`.\n    function avg(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = (x >> 1) + (y >> 1) + (((x & 1) + (y & 1)) >> 1);\n        }\n    }\n\n    /// @dev Returns the absolute value of `x`.\n    function abs(int256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(sub(0, shr(255, x)), add(sub(0, shr(255, x)), x))\n        }\n    }\n\n    /// @dev Returns the absolute distance between `x` and `y`.\n    function dist(int256 x, int256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(mul(xor(sub(y, x), sub(x, y)), sgt(x, y)), sub(y, x))\n        }\n    }\n\n    /// @dev Returns the minimum of `x` and `y`.\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), lt(y, x)))\n        }\n    }\n\n    /// @dev Returns the minimum of `x` and `y`.\n    function min(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), slt(y, x)))\n        }\n    }\n\n    /// @dev Returns the maximum of `x` and `y`.\n    function max(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), gt(y, x)))\n        }\n    }\n\n    /// @dev Returns the maximum of `x` and `y`.\n    function max(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, y), sgt(y, x)))\n        }\n    }\n\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\n    function clamp(uint256 x, uint256 minValue, uint256 maxValue)\n        internal\n        pure\n        returns (uint256 z)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, minValue), gt(minValue, x)))\n            z := xor(z, mul(xor(z, maxValue), lt(maxValue, z)))\n        }\n    }\n\n    /// @dev Returns `x`, bounded to `minValue` and `maxValue`.\n    function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := xor(x, mul(xor(x, minValue), sgt(minValue, x)))\n            z := xor(z, mul(xor(z, maxValue), slt(maxValue, z)))\n        }\n    }\n\n    /// @dev Returns greatest common divisor of `x` and `y`.\n    function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { z := x } y {} {\n                let t := y\n                y := mod(z, y)\n                z := t\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RAW NUMBER OPERATIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns `x + y`, without checking for overflow.\n    function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x + y;\n        }\n    }\n\n    /// @dev Returns `x + y`, without checking for overflow.\n    function rawAdd(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x + y;\n        }\n    }\n\n    /// @dev Returns `x - y`, without checking for underflow.\n    function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x - y;\n        }\n    }\n\n    /// @dev Returns `x - y`, without checking for underflow.\n    function rawSub(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x - y;\n        }\n    }\n\n    /// @dev Returns `x * y`, without checking for overflow.\n    function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        unchecked {\n            z = x * y;\n        }\n    }\n\n    /// @dev Returns `x * y`, without checking for overflow.\n    function rawMul(int256 x, int256 y) internal pure returns (int256 z) {\n        unchecked {\n            z = x * y;\n        }\n    }\n\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\n    function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := div(x, y)\n        }\n    }\n\n    /// @dev Returns `x / y`, returning 0 if `y` is zero.\n    function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := sdiv(x, y)\n        }\n    }\n\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\n    function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mod(x, y)\n        }\n    }\n\n    /// @dev Returns `x % y`, returning 0 if `y` is zero.\n    function rawSMod(int256 x, int256 y) internal pure returns (int256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := smod(x, y)\n        }\n    }\n\n    /// @dev Returns `(x + y) % d`, return 0 if `d` if zero.\n    function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := addmod(x, y, d)\n        }\n    }\n\n    /// @dev Returns `(x * y) % d`, return 0 if `d` if zero.\n    function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            z := mulmod(x, y, d)\n        }\n    }\n}\n"
      },
      "lib/solady/src/utils/SafeTransferLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n///\n/// @dev Note:\n/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.\n/// - For ERC20s, this implementation won't check that a token has code,\n///   responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ETH transfer has failed.\n    error ETHTransferFailed();\n\n    /// @dev The ERC20 `transferFrom` has failed.\n    error TransferFromFailed();\n\n    /// @dev The ERC20 `transfer` has failed.\n    error TransferFailed();\n\n    /// @dev The ERC20 `approve` has failed.\n    error ApproveFailed();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.\n    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;\n\n    /// @dev Suggested gas stipend for contract receiving ETH to perform a few\n    /// storage reads and writes, but low enough to prevent griefing.\n    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       ETH OPERATIONS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.\n    //\n    // The regular variants:\n    // - Forwards all remaining gas to the target.\n    // - Reverts if the target reverts.\n    // - Reverts if the current contract has insufficient balance.\n    //\n    // The force variants:\n    // - Forwards with an optional gas stipend\n    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).\n    // - If the target reverts, or if the gas stipend is exhausted,\n    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.\n    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.\n    // - Reverts if the current contract has insufficient balance.\n    //\n    // The try variants:\n    // - Forwards with a mandatory gas stipend.\n    // - Instead of reverting, returns whether the transfer succeeded.\n\n    /// @dev Sends `amount` (in wei) ETH to `to`.\n    function safeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Sends all the ETH in the current contract to `to`.\n    function safeTransferAllETH(address to) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer all the ETH and check if it succeeded or not.\n            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if lt(selfbalance(), amount) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.\n    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.\n    function forceSafeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if lt(selfbalance(), amount) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.\n    function forceSafeTransferAllETH(address to) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // forgefmt: disable-next-item\n            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n                mstore(0x00, to) // Store the address in scratch space.\n                mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n            }\n        }\n    }\n\n    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)\n        internal\n        returns (bool success)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)\n        }\n    }\n\n    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.\n    function trySafeTransferAllETH(address to, uint256 gasStipend)\n        internal\n        returns (bool success)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC20 OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have at least `amount` approved for\n    /// the current contract to manage.\n    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x60, amount) // Store the `amount` argument.\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from `from` to `to`.\n    /// Reverts upon failure.\n    ///\n    /// The `from` account must have their entire balance approved for\n    /// the current contract to manage.\n    function safeTransferAllFrom(address token, address from, address to)\n        internal\n        returns (uint256 amount)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x40, to) // Store the `to` argument.\n            mstore(0x2c, shl(96, from)) // Store the `from` argument.\n            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n            // Read the balance, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.\n            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x60, 0) // Restore the zero slot to zero.\n            mstore(0x40, m) // Restore the free memory pointer.\n        }\n    }\n\n    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransfer(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sends all of ERC20 `token` from the current contract to `to`.\n    /// Reverts upon failure.\n    function safeTransferAll(address token, address to) internal returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.\n            mstore(0x20, address()) // Store the address of the current contract.\n            // Read the balance, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x14, to) // Store the `to` argument.\n            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.\n            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n            // Perform the transfer, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n    /// Reverts upon failure.\n    function safeApprove(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n            // Perform the approval, reverting upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,\n    /// then retries the approval again (some tokens, e.g. USDT, requires this).\n    /// Reverts upon failure.\n    function safeApproveWithRetry(address token, address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, to) // Store the `to` argument.\n            mstore(0x34, amount) // Store the `amount` argument.\n            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n            // Perform the approval, retrying upon failure.\n            if iszero(\n                and( // The arguments of `and` are evaluated from right to left.\n                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                )\n            ) {\n                mstore(0x34, 0) // Store 0 for the `amount`.\n                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.\n                mstore(0x34, amount) // Store back the original `amount`.\n                // Retry the approval, reverting upon failure.\n                if iszero(\n                    and(\n                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n                    )\n                ) {\n                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n        }\n    }\n\n    /// @dev Returns the amount of ERC20 `token` owned by `account`.\n    /// Returns zero if the `token` does not exist.\n    function balanceOf(address token, address account) internal view returns (uint256 amount) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x14, account) // Store the `account` argument.\n            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n            amount :=\n                mul(\n                    mload(0x20),\n                    and( // The arguments of `and` are evaluated from right to left.\n                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)\n                    )\n                )\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@axelar-network/=node_modules/@axelar-network/",
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@prb/test/=lib/prb-math/lib/prb-test/src/",
        "chainlink/=lib/chainlink/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "interchain-token-service/=lib/interchain-token-service/contracts/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "prb-math/=lib/prb-math/src/",
        "prb-test/=lib/prb-math/lib/prb-test/src/",
        "pyth-sdk-solidity/=lib/pyth-sdk-solidity/",
        "solady/=lib/solady/",
        "solidity-code-metrics/=node_modules/solidity-code-metrics/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "cancun",
      "viaIR": false,
      "libraries": {}
    }
  }}