{"file_path":"src/USDat.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.34;\n\nimport {IERC20} from \"openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\n\nimport {ForcedTransferable} from \"@m-extensions/components/forcedTransferable/ForcedTransferable.sol\";\nimport {UIntMath} from \"common/libs/UIntMath.sol\";\n\nimport {MultiMint} from \"@pyusdx/platform/projects/MultiMint.sol\";\n\nimport {IUSDat} from \"./interfaces/IUSDat.sol\";\n\n/**\n * @title  USDat\n * @notice Upgrade-only PYUSDX extension. This implementation replaces the legacy JMIExtension (M-backed)\n *         implementation behind the existing USDat TransparentUpgradeableProxy. It is never deployed fresh,\n *         so it exposes `migrate` (a reinitializer) rather than `initialize`.\n */\ncontract USDat is IUSDat, MultiMint, ForcedTransferable {\n    /// @custom:storage-location erc7201:Saturn.storage.Whitelist\n    struct WhitelistStorage {\n        bool isEnabled;\n        mapping(address account => bool) isWhitelisted;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"Saturn.storage.Whitelist\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _WHITELIST_STORAGE_LOCATION =\n        0x1d6c3b82f2027bd0b336e517c3a50a0483eb4d2c5cd82c6a491448d31b621000;\n\n    // NOTE: Legacy slot preserved so MultiMint storage reads/writes land on the pre-upgrade JMIExtension data.\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.JMIExtension\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _LEGACY_JMI_STORAGE_LOCATION =\n        0x4717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b00;\n\n    // NOTE: Legacy slot preserved so YieldToOne storage reads/writes land on the pre-upgrade MYieldToOne data.\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.MYieldToOne\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _LEGACY_YIELD_TO_ONE_STORAGE_LOCATION =\n        0xee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af100;\n\n    function _getWhitelistStorage() private pure returns (WhitelistStorage storage $) {\n        assembly {\n            $.slot := _WHITELIST_STORAGE_LOCATION\n        }\n    }\n\n    /// @dev Point MultiMint storage at the pre-upgrade JMIExtension slot (layouts are append-only compatible).\n    function _getMultiMintStorage() internal pure override returns (MultiMintStorage storage $) {\n        assembly {\n            $.slot := _LEGACY_JMI_STORAGE_LOCATION\n        }\n    }\n\n    /// @dev Point YieldToOne storage at the pre-upgrade MYieldToOne slot (layouts are identical).\n    function _getYieldToOneStorage() internal pure override returns (YieldToOneStorage storage $) {\n        assembly {\n            $.slot := _LEGACY_YIELD_TO_ONE_STORAGE_LOCATION\n        }\n    }\n\n    /// @inheritdoc IUSDat\n    bytes32 public constant WHITELIST_MANAGER_ROLE = keccak256(\"WHITELIST_MANAGER_ROLE\");\n\n    /// @inheritdoc IUSDat\n    address public constant M_TOKEN = 0x866A2BF4E572CbcF37D5071A7a58503Bfb36be1b;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(address pyusdx_, address swapFacility_) MultiMint(pyusdx_, swapFacility_) {}\n\n    /* ============ Migration ============ */\n\n    /// @inheritdoc IUSDat\n    function migrate() external reinitializer(2) {\n        // NOTE: The held M must cover the M-backed portion `totalSupply - totalAssets`. M earning is\n        //       left on, so this balance already includes all yield accrued up to this block.\n        uint256 mBalance = IERC20(M_TOKEN).balanceOf(address(this));\n        uint256 backing = totalSupply() - totalAssets();\n\n        if (mBalance < backing) revert MReservesMismatch(mBalance, backing);\n\n        // NOTE: Realize any surplus (M yield accrued since the pre-upgrade `claimYield`, or M\n        //       donations) to the yield recipient — exactly as the legacy `claimYield` would have —\n        //       so M accruing between the `claimYield` and upgrade transactions cannot revert the\n        //       upgrade, and `totalSupply - totalAssets` matches the M being registered below.\n        uint256 surplus = mBalance - backing;\n\n        if (surplus != 0) {\n            emit YieldClaimed(surplus);\n            _mint(yieldRecipient(), surplus);\n        }\n\n        // NOTE: Register the held M as a replaceable alt-asset.\n        //       M can then be replaced with PYUSDX over time via `replaceAsset`.\n        MultiMintStorage storage $ = _getMultiMintStorage();\n\n        $.assets[M_TOKEN] = Asset({cap: mBalance, balance: UIntMath.safe240(mBalance), decimals: 6});\n        $.totalAssets += mBalance;\n\n        emit AssetCapSet(M_TOKEN, mBalance);\n    }\n\n    /* ============ M Yield Functions ============ */\n\n    /// @inheritdoc IUSDat\n    function claimMYield() external returns (uint256) {\n        if (!isAllowedAsset(M_TOKEN)) revert AssetNotAllowed(M_TOKEN);\n\n        address yieldRecipient = yieldRecipient();\n        _revertIfFrozen(yieldRecipient);\n\n        MultiMintStorage storage $ = _getMultiMintStorage();\n        uint256 surplus = _mSurplus($);\n\n        if (surplus == 0) return 0;\n\n        $.assets[M_TOKEN].balance += UIntMath.safe240(surplus);\n        $.totalAssets += surplus;\n\n        emit YieldClaimed(surplus);\n        _mint(yieldRecipient, surplus);\n\n        return surplus;\n    }\n\n    /// @inheritdoc IUSDat\n    function mYield() external view returns (uint256) {\n        if (!isAllowedAsset(M_TOKEN)) return 0;\n\n        return _mSurplus(_getMultiMintStorage());\n    }\n\n    /**\n     * @dev    Returns the held M not yet registered as backing — M yield accrued since the last claim,\n     *         plus any M donation.\n     * @param  $ The MultiMint storage pointer.\n     * @return The claimable M surplus.\n     */\n    function _mSurplus(MultiMintStorage storage $) internal view returns (uint256) {\n        uint256 balance = IERC20(M_TOKEN).balanceOf(address(this));\n        uint256 tracked = $.assets[M_TOKEN].balance;\n\n        return balance > tracked ? balance - tracked : 0;\n    }\n\n    /* ============ Version Pinning (disabled) ============ */\n\n    /// @dev USDat sits behind a TransparentUpgradeableProxy with no origin beacon, so version-pinning is\n    ///      meaningless and `unpinVersion` would zero the live implementation slot. Both are disabled.\n    function pinVersion(uint256) external pure override {\n        revert VersionPinningDisabled();\n    }\n\n    /// @dev Disabled — see `pinVersion`.\n    function unpinVersion() external pure override {\n        revert VersionPinningDisabled();\n    }\n\n    /* ============ Whitelist Functions ============ */\n\n    /// @inheritdoc IUSDat\n    function enableWhitelist() external onlyRole(WHITELIST_MANAGER_ROLE) {\n        WhitelistStorage storage $ = _getWhitelistStorage();\n        if ($.isEnabled) return;\n        $.isEnabled = true;\n        emit WhitelistEnabled(block.timestamp);\n    }\n\n    /// @inheritdoc IUSDat\n    function disableWhitelist() external onlyRole(WHITELIST_MANAGER_ROLE) {\n        WhitelistStorage storage $ = _getWhitelistStorage();\n        if (!$.isEnabled) return;\n        $.isEnabled = false;\n        emit WhitelistDisabled(block.timestamp);\n    }\n\n    /// @inheritdoc IUSDat\n    function whitelist(address account) external onlyRole(WHITELIST_MANAGER_ROLE) {\n        WhitelistStorage storage $ = _getWhitelistStorage();\n        if ($.isWhitelisted[account]) return;\n        $.isWhitelisted[account] = true;\n        emit Whitelisted(account, block.timestamp);\n    }\n\n    /// @inheritdoc IUSDat\n    function removeFromWhitelist(address account) external onlyRole(WHITELIST_MANAGER_ROLE) {\n        WhitelistStorage storage $ = _getWhitelistStorage();\n        if (!$.isWhitelisted[account]) return;\n        $.isWhitelisted[account] = false;\n        emit RemovedFromWhitelist(account, block.timestamp);\n    }\n\n    /// @inheritdoc IUSDat\n    function isWhitelistEnabled() public view returns (bool) {\n        return _getWhitelistStorage().isEnabled;\n    }\n\n    /// @inheritdoc IUSDat\n    function isWhitelisted(address account) public view returns (bool) {\n        return _getWhitelistStorage().isWhitelisted[account];\n    }\n\n    /* ============ Internal Functions ============ */\n\n    /**\n     * @dev   Hook called before wrapping PYUSDX into USDat.\n     *        Enforces whitelist requirements for both the depositor and recipient.\n     * @param account   The address initiating the wrap (depositor).\n     * @param recipient The address that will receive the minted USDat tokens.\n     * @param amount    The amount of tokens being wrapped.\n     */\n    function _beforeWrap(address account, address recipient, uint256 amount) internal view virtual override {\n        _revertIfNotWhitelisted(account);\n        _revertIfNotWhitelisted(recipient);\n        super._beforeWrap(account, recipient, amount);\n    }\n\n    /**\n     * @dev   Hook called before wrapping an allowed asset (via MultiMint) into USDat.\n     *        Enforces whitelist requirements for both the depositor and recipient.\n     * @param asset     The address of the asset being wrapped.\n     * @param account   The address initiating the wrap (depositor).\n     * @param recipient The address that will receive the minted USDat tokens.\n     * @param amount    The amount of tokens being wrapped.\n     */\n    function _beforeWrap(address asset, address account, address recipient, uint256 amount)\n        internal\n        view\n        virtual\n        override\n    {\n        _revertIfNotWhitelisted(account);\n        _revertIfNotWhitelisted(recipient);\n        super._beforeWrap(asset, account, recipient, amount);\n    }\n\n    /**\n     * @dev   Hook called before unwrapping USDat back into PYUSDX.\n     *        Enforces whitelist requirements for the account burning tokens.\n     * @param account The address initiating the unwrap (burning USDat).\n     * @param amount  The amount of USDat tokens being unwrapped.\n     */\n    function _beforeUnwrap(address account, uint256 amount) internal view virtual override {\n        _revertIfNotWhitelisted(account);\n        super._beforeUnwrap(account, amount);\n    }\n\n    /**\n     * @dev   Reverts if the whitelist is enabled and the account is not whitelisted.\n     *        This check is bypassed when the whitelist feature is disabled.\n     * @param account The address to check for whitelist status.\n     */\n    function _revertIfNotWhitelisted(address account) internal view {\n        WhitelistStorage storage $ = _getWhitelistStorage();\n        if ($.isEnabled && !$.isWhitelisted[account]) {\n            revert AccountNotWhitelisted(account);\n        }\n    }\n\n    /**\n     * @dev   Forcibly transfers tokens from a frozen account to a recipient.\n     *        Can only be called by an authorized compliance role (via ForcedTransferable).\n     *        Validates that the source account is frozen, the recipient is valid,\n     *        and the frozen account has sufficient balance.\n     * @param frozenAccount The frozen address from which tokens will be transferred.\n     * @param recipient     The address that will receive the tokens.\n     * @param amount        The amount of tokens to transfer.\n     */\n    function _forceTransfer(address frozenAccount, address recipient, uint256 amount) internal override {\n        _revertIfNotFrozen(frozenAccount);\n        _revertIfZeroAccount(recipient);\n\n        emit Transfer(frozenAccount, recipient, amount);\n        emit ForcedTransfer(frozenAccount, recipient, msg.sender, amount);\n\n        if (amount == 0) return;\n\n        _revertIfInsufficientBalance(frozenAccount, amount);\n\n        _update(frozenAccount, recipient, amount);\n    }\n}\n","deployed_bytecode":"0x6080806040526004361015610012575f80fd5b5f3560e01c90816301e1d114146132a95750806301ffc9a7146132545780630688cbdf1461320d57806306b3efd6146131ea57806306fdde03146131c0578063095ea7b31461319a5780630fe3bf7a146131805780631143a46914613143578063170e2070146130e657806318160ddd146130bd578063184d69ab1461308f57806323b872dd14612fdd578063248a9ca314612fa65780632859398414612efc5780632cfd442d14612ec25780632f2ff15d14612e7857806330adf81f14612e3e5780633123428714612e04578063313ce56714612dd857806332e7f35614612dad57806333bebb7714612d8e57806333e1c5ac14612d585780633644e51514612d3e57806336568abe14612cfa5780633664cd4914612cc05780633817cf5214612c925780633af32abf14612c615780633f4ba83a14612be3578063406cf22914612bc95780634259dff914612b8f578063438f942d14612b4857806345c8b1a614612b1f57806345cf012d14612aba5780634aa504d314612a935780634db82e5814612a78578063532992c514612a455780635a049a7014612a025780635c975abb146129d457806362355638146126d257806363f156491461269857806364c2a2651461266b5780636bb45eec1461237957806370a082311461234d5780637295ed93146123135780637ecebe00146122bc5780637f2eecc3146122825780638319833414611d175780638456cb5914611ca657806384b0196e14611bce57806388b7ab6314611ba45780638ab1d68114611b7b5780638d1fdf2f14611b575780638fd3ab801461186157806391d148541461180c57806394f5a66e146111fd57806395d89b411461110357806398abb5ea146110bf5780639b19251a146110965780639fd5a6cf1461103a578063a08cb48b1461100f578063a0cc6a6814610fd5578063a217fddf14610fbb578063a7d612be14610f9b578063a9059cbb14610f6a578063aad1202914610f08578063aafee97b14610ee9578063ace150a514610eb8578063ae06b7e414610e74578063b7b7289914610e23578063bf376c7a14610c9f578063c537bed014610c7c578063c956a3e314610bd8578063cc4c5b6414610ba4578063cdfb2b4e14610b84578063cf09299514610b54578063cfaa7b8314610b3b578063d505accf14610ae8578063d547741f14610a99578063d6b0f48414610a79578063d7a49f0b1461098f578063d916948714610955578063da6b76b814610911578063dd62ed3e146108ca578063de0e9a3e146106b9578063e366da2c1461068b578063e3ee160e1461065b578063e58398361461060a578063e63ab1e9146105d0578063e94a01021461057c578063ed4ef4641461055a578063ef55bec614610522578063fca7d533146104d95763fdf769781461041b575f80fd5b346104d5575f3660031901126104d5576040518060205f516020615c075f395f51905f5254928381520180925f516020615c075f395f51905f525f5260205f20905f5b8181106104bf575050508161047491038261340d565b604051918291602083019060208452518091526040830191905f5b81811061049d575050500390f35b82516001600160a01b031684528594506020938401939092019160010161048f565b825484526020909301926001928301920161045e565b5f80fd5b346104d5575f3660031901126104d5577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040516001600160a01b0390911615158152602090f35b346104d55761055861055361053636613541565b9161054d8486888a8c989e988e9a9e9d9b9d614f60565b85614edf565b6150cd565b005b346104d5575f3660031901126104d5576020610574613f35565b604051908152f35b346104d55760403660031901126104d5576105956132cf565b60018060a01b03165f525f516020615a075f395f51905f5260205260405f206024355f52602052602060ff60405f2054166040519015158152f35b346104d5575f3660031901126104d55760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b346104d55760203660031901126104d55760206106516106286132cf565b6001600160a01b03165f9081525f516020615ac75f395f51905f52602052604090205460ff1690565b6040519015158152f35b346104d55761055861068661066f36613541565b9161054d8486888a8c989e988e9a9e9d9b9d61524d565b6152c6565b346104d55760203660031901126104d55760206106ae6106a96132cf565b613f06565b60ff60405191168152f35b346104d55760203660031901126104d5576004357f0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc41736001600160a01b031633036108bb5760405163d737d0c760e01b8152602081600481335afa90811561083c575f9161088c575b50811561087d5761073282336153e0565b61073b81615908565b61074361417e565b808311610867575061075361560d565b60ff61075e8261360f565b5416610847576107d9602083805f516020615aa75f395f51905f5254035f516020615aa75f395f51905f525561079333613634565b8181540390555f6040518281525f516020615b675f395f51905f52843392a360405163a9059cbb60e01b8152336004820152602481019190915291829081906044820190565b03815f7f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03165af1801561083c5761081457005b6105589060203d602011610835575b61082d818361340d565b810190614f48565b503d610823565b6040513d5f823e3d90fd5b6327951b3f60e11b5f9081526001600160a01b0391909116600452602490fd5b826350828de360e11b5f5260045260245260445ffd5b631f2a200560e01b5f5260045ffd5b6108ae915060203d6020116108b4575b6108a6818361340d565b810190613b5a565b82610721565b503d61089c565b630aff86d760e21b5f5260045ffd5b346104d55760403660031901126104d5576108e36132cf565b6108f46108ee6132e5565b9161359f565b9060018060a01b03165f52602052602060405f2054604051908152f35b346104d5575f3660031901126104d5576040517f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03168152602090f35b346104d5575f3660031901126104d55760206040517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a15974298152f35b346104d55760603660031901126104d5576004356001600160401b0381116104d5576109bf9036906004016133a3565b6024356001600160401b0381116104d5576109de9036906004016133a3565b906044356001600160401b0381116104d5576109fe9036906004016133a3565b94610a07614217565b838514801590610a6f575b610a60575f5b858110610a2157005b80610a5a610a3a610a356001948a8761395c565b613980565b610a48610a35848a8a61395c565b610a53848c8961395c565b3591614afb565b01610a18565b63512509d360e11b5f5260045ffd5b5085851415610a12565b346104d5575f3660031901126104d557610a916143d3565b610558613eaf565b346104d55760403660031901126104d557610558600435610ab86132e5565b90610ae3610ade825f525f516020615b875f395f51905f52602052600160405f20015490565b614442565b614ca7565b346104d55760e03660031901126104d557610b016132cf565b610b096132e5565b906084359160ff831683036104d5576105589260c43592610b3560a43593606435906044359084615181565b90614edf565b346104d5576020610651610b4e366133d3565b91613e48565b346104d557610558610686610b683661348d565b610b7e828486888a8c989c9d979d9b999b61524d565b83614fd9565b346104d5575f3660031901126104d557610b9c6143d3565b610558613dee565b346104d5575f3660031901126104d5575f516020615a475f395f51905f52546040516001600160a01b039091168152602090f35b346104d55760403660031901126104d5576004356001600160401b0381116104d557610c089036906004016133a3565b906024356001600160401b0381116104d557610c289036906004016133a3565b919092610c33614286565b828103610a60575f5b818110610c4557005b610c53610a3582848661395c565b90610c5f81868861395c565b359182151583036104d557600192610c7691614ba9565b01610c3c565b346104d55760203660031901126104d5576020610651610c9a6132cf565b613dc6565b346104d55760403660031901126104d557610cb86132cf565b6024357f0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc41736001600160a01b031633036108bb5760405163d737d0c760e01b8152602081600481335afa90811561083c575f91610e04575b50610d19836153c1565b811561087d57610d2881615908565b610d3183615908565b610d3961560d565b60ff610d448261360f565b5416610847575060ff610d568361360f565b5416610de3576040516323b872dd60e01b815233600482015230602482015260448101829052916020836064815f6001600160a01b037f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d165af192831561083c5761055893610dc6575b50614123565b610dde9060203d6020116108355761082d818361340d565b610dc0565b506327951b3f60e11b5f9081526001600160a01b0391909116600452602490fd5b610e1d915060203d6020116108b4576108a6818361340d565b83610d0f565b346104d55760603660031901126104d557610e3c6132cf565b602435604435916001600160401b0383116104d557610e6f610e65610558943690600401613449565b610b7e8484614dc1565b614e77565b346104d5575f3660031901126104d5576040517f0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc41736001600160a01b03168152602090f35b346104d557610558610686610ecc366134f2565b90610ee3838587898b8d999d9e989e9c9a9c61524d565b84614e1a565b346104d5575f3660031901126104d5576322f9060160e11b5f5260045ffd5b346104d55760203660031901126104d5576004356001600160401b0381116104d557610f389036906004016133a3565b610f406141a8565b5f5b818110610f4b57005b80610f64610f5f610a35600194868861395c565b615108565b01610f42565b346104d55760403660031901126104d557610f90610f866132cf565b60243590336144ff565b602060405160018152f35b346104d55760203660031901126104d5576322f9060160e11b5f5260045ffd5b346104d5575f3660031901126104d55760206040515f8152f35b346104d5575f3660031901126104d55760206040517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22678152f35b346104d557610558610553611023366134f2565b90610ee3838587898b8d999d9e989e9c9a9c614f60565b346104d55760a03660031901126104d5576110536132cf565b61105b6132e5565b608435916001600160401b0383116104d557611090611081610558943690600401613449565b92606435906044359084615181565b90614fd9565b346104d55760203660031901126104d5576105586110b26132cf565b6110ba6143d3565b613d67565b346104d55760203660031901126104d5576001600160a01b036110e06132cf565b165f525f516020615a675f395f51905f52602052602060405f2054604051908152f35b346104d5575f3660031901126104d5576040515f5f516020615a875f395f51905f525461112f8161369e565b80845290600181169081156111d9575060011461116f575b61116b836111578185038261340d565b60405191829160208352602083019061337f565b0390f35b5f516020615a875f395f51905f525f9081527f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b939250905b8082106111bf57509091508101602001611157611147565b9192600181602092548385880101520191019092916111a7565b60ff191660208086019190915291151560051b840190910191506111579050611147565b346104d5576101003660031901126104d5576004356001600160401b0381116104d55761122e903690600401613449565b6024356001600160401b0381116104d55761124d903690600401613449565b6112556132fb565b9061125e613311565b91611267613327565b9161127061333d565b91611279613353565b93611282613369565b925f516020615be75f395f51905f5254976001600160401b0360ff8a60401c1615991680159081611804575b60011490816117fa575b1590816117f1575b506117e257886112ce613ccd565b6117b2575b6112db615634565b6001600160a01b038816156117a3576001600160a01b03871615611794576001600160a01b0385161561178557611310615634565b611318615634565b611320615634565b611328615634565b611330615634565b611338615634565b8051906001600160401b0382116116665781906113625f516020615b275f395f51905f525461369e565b601f8111611703575b50602090601f8311600114611685575f9261167a575b50508160011b915f199060031b1c1916175f516020615b275f395f51905f52555b467f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea100556113cd614c19565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10155600660ff195f516020615ae75f395f51905f525416175f516020615ae75f395f51905f52558051906001600160401b03821161166657819061143e5f516020615a875f395f51905f525461369e565b601f81116115e4575b50602090601f8311600114611566575f9261155b575b50508160011b915f199060031b1c1916175f516020615a875f395f51905f52555b611486615634565b6001600160a01b0381161561154c5761149e9061463c565b506114a7615634565b6001600160a01b0383161561153d576114e4946114d36114d8926114cd6114de966146f5565b50614d43565b6147ae565b50614845565b506148fe565b506114eb57005b60ff60401b195f516020615be75f395f51905f5254165f516020615be75f395f51905f52557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a1005b63042d717b60e01b5f5260045ffd5b636cbbd1d360e01b5f5260045ffd5b01519050898061145d565b5f516020615a875f395f51905f525f9081528281209350601f198516905b8181106115cc57509084600195949392106115b4575b505050811b015f516020615a875f395f51905f525561147e565b01515f1960f88460031b161c1916905589808061159a565b92936020600181928786015181550195019301611584565b82811115611447575f516020615a875f395f51905f525f52909150601f830160051c7f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b6020851061165e575b849392601f0160051c82900391015f5b82811061164e575050611447565b5f81830155859450600101611640565b5f9150611630565b634e487b7160e01b5f52604160045260245ffd5b015190508a80611381565b5f516020615b275f395f51905f525f9081528281209350601f198516905b8181106116eb57509084600195949392106116d3575b505050811b015f516020615b275f395f51905f52556113a2565b01515f1960f88460031b161c191690558a80806116b9565b929360206001819287860151815501950193016116a3565b8281111561136b575f516020615b275f395f51905f525f52909150601f830160051c7f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a86020851061177d575b849392601f0160051c82900391015f5b82811061176d57505061136b565b5f8183015585945060010161175f565b5f915061174f565b6318362d8b60e01b5f5260045ffd5b6309d50edf60e01b5f5260045ffd5b633944ed8760e11b5f5260045ffd5b600160401b60ff60401b195f516020615be75f395f51905f525416175f516020615be75f395f51905f52556112d3565b63f92ee8a960e01b5f5260045ffd5b9050158a6112c0565b303b1591506112b8565b8a91506112ae565b346104d55760403660031901126104d5576118256132e5565b6004355f525f516020615b875f395f51905f5260205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b346104d5575f3660031901126104d5575f516020615be75f395f51905f525460ff8160401c16908115611b42575b506117e2575f516020615be75f395f51905f52805468ffffffffffffffffff1916680100000000000000021790556040516370a0823160e01b815230600482015260208160248173866a2bf4e572cbcf37d5071a7a58503bfb36be1b5afa90811561083c575f91611b10575b506119235f516020615aa75f395f51905f52545f516020615bc75f395f51905f525490613d5a565b808210611afa576119349082613d5a565b80611aa9575b50611944816140fa565b6040519160608301908382106001600160401b038311176116665760409182528084526001600160f01b039283166020808601918252600693860193845273866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f8190525f516020615a675f395f51905f52825295517fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355590517fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36805494516001600160f81b0319909516919095161760f09390931b60ff60f01b16929092179092555f516020615b475f395f51905f5291611a41815f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f5255604051908152a260ff60401b195f516020615be75f395f51905f5254165f516020615be75f395f51905f52557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160028152a1005b611af4907fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051838152a15f516020615a475f395f51905f52546001600160a01b0316614123565b8161193a565b90631f6c26ed60e31b5f5260045260245260445ffd5b90506020813d602011611b3a575b81611b2b6020938361340d565b810103126104d55751816118fb565b3d9150611b1e565b600291506001600160401b031610158161188f565b346104d55760203660031901126104d557610558611b736132cf565b610f5f6141a8565b346104d55760203660031901126104d557610558611b976132cf565b611b9f6143d3565b613cfa565b346104d557610558610553611bb83661348d565b610b7e828486888a8c989c9d979d9b999b614f60565b346104d5575f3660031901126104d557611c4a6020604051611bf0828261340d565b5f81525f36813760405191611c0f83611c08816136d6565b038461340d565b611c58604051611c2060408261340d565b60018152603160f81b83820152604051958695600f60f81b875260e08588015260e087019061337f565b90858203604087015261337f565b4660608501523060808501525f60a085015283810360c08501528180845192838152019301915f5b828110611c8f57505050500390f35b835185528695509381019392810192600101611c80565b346104d5575f3660031901126104d557611cbe6142f5565b611cc661560d565b600160ff195f516020615ba75f395f51905f525416175f516020615ba75f395f51905f52557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b346104d5576101203660031901126104d5576004356001600160401b0381116104d557611d48903690600401613449565b6024356001600160401b0381116104d557611d67903690600401613449565b611d6f6132fb565b90611d78613311565b611d80613327565b91611d8961333d565b90611d92613353565b90611d9b613369565b92610104359160018060a01b038316988984036104d5575f516020615be75f395f51905f5254996001600160401b0360ff8c60401c16159b168015908161227a575b6001149081612270575b159081612267575b506117e2578a611dfd613ccd565b612237575b611e0a615634565b6001600160a01b0389161561222857611e21615634565b6001600160a01b038816156117a3576001600160a01b03871615611794571561178557611e4c615634565b611e54615634565b611e5c615634565b611e64615634565b611e6c615634565b611e74615634565b8051906001600160401b038211611666578190611e9e5f516020615b275f395f51905f525461369e565b601f81116121a6575b50602090601f8311600114612128575f9261211d575b50508160011b915f199060031b1c1916175f516020615b275f395f51905f52555b467f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10055611f09614c19565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10155600660ff195f516020615ae75f395f51905f525416175f516020615ae75f395f51905f52558051906001600160401b038211611666578190611f7a5f516020615a875f395f51905f525461369e565b601f811161209b575b50602090601f831160011461201d575f92612012575b50508160011b915f199060031b1c1916175f516020615a875f395f51905f52555b611fc2615634565b6001600160a01b0381161561154c57611fda9061463c565b50611fe3615634565b6001600160a01b0382161561153d576114d861200c946114d36114e4986114cd6114de966146f5565b506149b7565b015190508a80611f99565b5f516020615a875f395f51905f525f9081528281209350601f198516905b818110612083575090846001959493921061206b575b505050811b015f516020615a875f395f51905f5255611fba565b01515f1960f88460031b161c191690558a8080612051565b9293602060018192878601518155019501930161203b565b82811115611f83575f516020615a875f395f51905f525f52909150601f830160051c7f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b60208510612115575b849392601f0160051c82900391015f5b828110612105575050611f83565b5f818301558594506001016120f7565b5f91506120e7565b015190508b80611ebd565b5f516020615b275f395f51905f525f9081528281209350601f198516905b81811061218e5750908460019594939210612176575b505050811b015f516020615b275f395f51905f5255611ede565b01515f1960f88460031b161c191690558b808061215c565b92936020600181928786015181550195019301612146565b82811115611ea7575f516020615b275f395f51905f525f52909150601f830160051c7f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a860208510612220575b849392601f0160051c82900391015f5b828110612210575050611ea7565b5f81830155859450600101612202565b5f91506121f2565b638de68f0b60e01b5f5260045ffd5b600160401b60ff60401b195f516020615be75f395f51905f525416175f516020615be75f395f51905f5255611e02565b9050158c611def565b303b159150611de7565b8c9150611ddd565b346104d5575f3660031901126104d55760206040517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de88152f35b346104d55760203660031901126104d5576001600160a01b036122dd6132cf565b165f527f1b21ba3f0a2135d61c468900b54084f04af8111bce0f8bbb6ab8c46d11afbd00602052602060405f2054604051908152f35b346104d5575f3660031901126104d55760206040517f2a3dab589bcc9747970dd85ac3f222668741ae51f2a1bbb8f8355be28dd8a8688152f35b346104d55760203660031901126104d557602061237061236b6132cf565b613634565b54604051908152f35b346104d557612387366133d3565b91907f0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc41736001600160a01b031633036108bb576123c161560d565b6123ca82614eeb565b6123d382613dc6565b1561264a5760405163d737d0c760e01b8152602081600481335afa90811561083c575f9161262b575b506124068161537c565b1561260b5750612415816153c1565b821561087d5761242d8361242884613f06565b6154c9565b92831561087d5761243d8361366c565b8085116125e9575061244e846140fa565b6001600160a01b039093165f8181525f516020615a675f395f51905f52602052604090206001018054919490916001600160f01b03918216908216039081116125d55781546001600160f01b0319166001600160f01b03919091161790555f516020615bc75f395f51905f52546124c6908290613d5a565b5f516020615bc75f395f51905f52556040516323b872dd60e01b815233600482015230602482015260448101829052916020836064815f6001600160a01b037f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d165af191821561083c577feea0cfe70e73ef2022bd359d31ed861d5476282f9a6f68117191486f6a9b887b936040936125b8575b50825163a9059cbb60e01b60208201526001600160a01b0383166024820152604481018790526125a19061259b81606481015b03601f19810183528261340d565b8661595b565b825195865260208601526001600160a01b031693a3005b6125d09060203d6020116108355761082d818361340d565b61255a565b634e487b7160e01b5f52601160045260245ffd5b8484637c67815160e01b5f5260018060a01b031660045260245260445260645ffd5b6373aabd2960e11b5f9081526001600160a01b0391909116600452602490fd5b612644915060203d6020116108b4576108a6818361340d565b846123fc565b50630188053b60e41b5f9081526001600160a01b0391909116600452602490fd5b346104d55760403660031901126104d5576105586126876132cf565b61268f614286565b60243590613b79565b346104d5575f3660031901126104d55760206040517f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b358152f35b346104d5576126e0366133d3565b91907f0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc41736001600160a01b031633036108bb5760405163d737d0c760e01b815292602084600481335afa93841561083c575f946129b3575b5061274183614eeb565b61274a826153c1565b801561087d576127629061275d84613f06565b61545c565b91821561087d576127768361242883613f06565b9361278081615908565b61278983615908565b6127938583613af8565b15612992576127a061560d565b60ff6127ab8261360f565b5416610847575060ff6127bd8361360f565b5416610de3576040516370a0823160e01b81523060048201526001600160a01b03919091169290602081602481875afa90811561083c575f91612960575b506040516323b872dd60e01b60208201523360248201523060448201526064810186905261283690612830816084810161258d565b8561595b565b6040516370a0823160e01b815230600482015290602082602481885afa801561083c575f9061292c575b61286a9250613d5a565b84811061291257507f1f28ca77b3dd333cb25ceb5145a2af419a8ba913b5f6c591f04366e0ca5937f8916040916128a0866140fa565b5f8681525f516020615a675f395f51905f52602052849020600101805490916001600160f01b03916128d49190831661378d565b1661ffff60f01b8254161790556128f9815f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f52556125a18183614123565b84846383257a2960e01b5f5260045260245260445260645ffd5b506020823d602011612958575b816129466020938361340d565b810103126104d55761286a9151612860565b3d9150612939565b90506020813d60201161298a575b8161297b6020938361340d565b810103126104d55751856127fb565b3d915061296e565b50633a7848b160e11b5f9081526001600160a01b0391909116600452602490fd5b6129cd91945060203d6020116108b4576108a6818361340d565b9284612737565b346104d5575f3660031901126104d557602060ff5f516020615ba75f395f51905f5254166040519015158152f35b346104d55760a03660031901126104d557612a1b6132cf565b6024356044359160ff831683036104d557610e6f61055893608435906064359061054d8686614dc1565b346104d55760803660031901126104d557610558612a616132cf565b60243590610e6f606435604435610ee38585614dc1565b346104d5575f3660031901126104d557602060405160068152f35b346104d55760403660031901126104d5576020610651612ab16132cf565b60243590613af8565b346104d55760203660031901126104d557610558612ad66132cf565b612ade614364565b5f516020615a475f395f51905f52546001600160a01b03165f9081525f516020615ac75f395f51905f52602052604090205460ff16614d43576114cd6139e9565b346104d55760203660031901126104d557610558612b3b6132cf565b612b436141a8565b614488565b346104d5575f3660031901126104d5577f0db096ce50da19b63b97b47df5b0c87e2ed1677b3d801ad424e1bbfc0bb0c300546040516001600160a01b039091168152602090f35b346104d5575f3660031901126104d55760206040517f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca8152f35b346104d5575f3660031901126104d55760206105746139e9565b346104d5575f3660031901126104d557612bfb6142f5565b5f516020615ba75f395f51905f525460ff811615612c525760ff19165f516020615ba75f395f51905f52557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b346104d55760203660031901126104d557602060ff612c86612c816132cf565b6135d7565b54166040519015158152f35b346104d5575f3660031901126104d557602060405173866a2bf4e572cbcf37d5071a7a58503bfb36be1b8152f35b346104d5575f3660031901126104d55760206040517f7daa70daa195905862e9fca178089de90a69f7175eb24d1b44e833ee4d44856a8152f35b346104d55760403660031901126104d557612d136132e5565b336001600160a01b03821603612d2f5761055890600435614ca7565b63334bd91960e11b5f5260045ffd5b346104d5575f3660031901126104d5576020610574613994565b346104d55760403660031901126104d557612d716132cf565b60243580151581036104d55761055891612d89614286565b614ba9565b346104d557610558612d9f366133d3565b91612da8614217565b614afb565b346104d5575f3660031901126104d55760205f516020615c075f395f51905f52541515604051908152f35b346104d5575f3660031901126104d557602060ff5f516020615ae75f395f51905f525416604051908152f35b346104d5575f3660031901126104d55760206040517fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af8152f35b346104d5575f3660031901126104d55760206040517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98152f35b346104d55760403660031901126104d557610558600435612e976132e5565b90612ebd610ade825f525f516020615b875f395f51905f52602052600160405f20015490565b614a70565b346104d5575f3660031901126104d55760206040517fc66b3536568140ce119bcc21a4fa7e3449a56fb5f260d32ff8e719230264132c8152f35b346104d5575f3660031901126104d557612f146145a1565b60405163462914f160e01b81523060048201526020816024817f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03165afa90811561083c575f91612f73575b602061057483856137a6565b90506020813d602011612f9e575b81612f8e6020938361340d565b810103126104d557516020612f67565b3d9150612f81565b346104d55760203660031901126104d55760206105746004355f525f516020615b875f395f51905f52602052600160405f20015490565b346104d557612feb366133d3565b6001600160a01b0383165f9081527fcbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da100602090815260408083203384529091529020549290919060018401613044575b610f9093506144ff565b82841061307457610f90936130588261359f565b60018060a01b0333165f526020528360405f209103905561303a565b8284630c95cf2760e11b5f523360045260245260445260645ffd5b346104d5575f3660031901126104d557602060ff5f516020615b075f395f51905f5254166040519015158152f35b346104d5575f3660031901126104d55760205f516020615aa75f395f51905f5254604051908152f35b346104d55760203660031901126104d5576004356001600160401b0381116104d5576131169036906004016133a3565b61311e6141a8565b5f5b81811061312957005b8061313d612b43610a35600194868861395c565b01613120565b346104d55760203660031901126104d5576020600435801515908161316e575b506040519015158152f35b905061317861417e565b101582613163565b346104d5575f3660031901126104d55760206105746137b3565b346104d55760403660031901126104d557610f906131b66132cf565b6024359033613f90565b346104d5575f3660031901126104d55761116b604051611157816131e3816136d6565b038261340d565b346104d55760203660031901126104d55760206105746132086132cf565b61366c565b346104d5575f3660031901126104d5577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040516001600160a01b039091168152602090f35b346104d55760203660031901126104d55760043563ffffffff60e01b81168091036104d557602090637965db0b60e01b811490811561329857506040519015158152f35b6301ffc9a760e01b14905082613163565b346104d5575f3660031901126104d5576020905f516020615bc75f395f51905f52548152f35b600435906001600160a01b03821682036104d557565b602435906001600160a01b03821682036104d557565b604435906001600160a01b03821682036104d557565b606435906001600160a01b03821682036104d557565b608435906001600160a01b03821682036104d557565b60a435906001600160a01b03821682036104d557565b60c435906001600160a01b03821682036104d557565b60e435906001600160a01b03821682036104d557565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b9181601f840112156104d5578235916001600160401b0383116104d5576020808501948460051b0101116104d557565b60609060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590565b90601f801991011681019081106001600160401b0382111761166657604052565b6001600160401b03811161166657601f01601f191660200190565b81601f820112156104d5576020813591016134638261342e565b92613471604051948561340d565b828452828201116104d557815f92602092838601378301015290565b60e06003198201126104d5576004356001600160a01b03811681036104d557916024356001600160a01b03811681036104d5579160443591606435916084359160a4359160c435906001600160401b0382116104d5576134ef91600401613449565b90565b6101009060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590606435906084359060a4359060c4359060e43590565b6101209060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590606435906084359060a4359060c43560ff811681036104d5579060e435906101043590565b6001600160a01b03165f9081527fcbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da1006020526040902090565b6001600160a01b03165f9081527f1d6c3b82f2027bd0b336e517c3a50a0483eb4d2c5cd82c6a491448d31b6210016020526040902090565b6001600160a01b03165f9081525f516020615ac75f395f51905f526020526040902090565b6001600160a01b03165f9081527fee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1026020526040902090565b6001600160a01b03165f9081525f516020615a675f395f51905f5260205260409020600101546001600160f01b031690565b90600182811c921680156136cc575b60208310146136b857565b634e487b7160e01b5f52602260045260245ffd5b91607f16916136ad565b5f516020615b275f395f51905f52545f92916136f18261369e565b8082529160018116908115613771575060011461370c575050565b5f516020615b275f395f51905f525f9081529293509091907f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a85b838310613757575060209250010190565b600181602092949394548385870101520191019190613746565b9050602093945060ff929192191683830152151560051b010190565b6001600160f01b0391821690821601919082116125d557565b919082018092116125d557565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355415613935575f516020615a475f395f51905f52546001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff1661392357613843614025565b90811561391d57816134ef91613858826140fa565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36805490916001600160f01b03916138ba9190831661378d565b1661ffff60f01b8254161790556138df825f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f52557fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051848152a1614123565b50505f90565b6327951b3f60e11b5f5260045260245ffd5b630188053b60e41b5f5273866a2bf4e572cbcf37d5071a7a58503bfb36be1b60045260245ffd5b919081101561396c5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036104d55790565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea1005446036139e1577f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea1015490565b6134ef614c19565b6139f1614364565b5f516020615a475f395f51905f52546001600160a01b031660ff613a148261360f565b5416613923575060405163ddeae03360e01b81523060048201526060816024815f7f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03165af1801561083c57613acd575b50613a756145a1565b8015613ac8577fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051838152a15f516020615a475f395f51905f52546134ef9082906001600160a01b0316614123565b505f90565b606090813d8311613af1575b613ae3818361340d565b810103126104d5575f613a6c565b503d613ad9565b90801561391d57613b0c9061275d83613f06565b801561391d57613b22613b559161242884613f06565b6001600160a01b0383165f9081525f516020615a675f395f51905f52602052604090205492613b509061366c565b6137a6565b111590565b908160209103126104d557516001600160a01b03811681036104d55790565b613b8281614eeb565b6001600160a01b03165f8181525f516020615a675f395f51905f5260205260409020549091908114613cc957815f525f516020615a675f395f51905f5260205260ff600160405f20015460f01c1615613c09575b60205f516020615b475f395f51905f5291835f525f516020615a675f395f51905f5282528060405f2055604051908152a2565b60405163313ce56760e01b8152602081600481865afa90811561083c575f91613c80575b505f516020615b475f395f51905f5291613c78602092855f525f516020615a675f395f51905f528452600160405f20019081549060ff60f01b9060f01b169060ff60f01b1916179055565b915050613bd6565b90506020813d602011613cc1575b81613c9b6020938361340d565b810103126104d5575160ff811681036104d5575f516020615b475f395f51905f52613c2d565b3d9150613c8e565b5050565b60016001600160401b03195f516020615be75f395f51905f525416175f516020615be75f395f51905f5255565b60ff613d05826135d7565b541615613d5757613d15816135d7565b805460ff191690556040514281526001600160a01b03909116907f031e2f7b58119201ea1f3c2d1070d142de895fa9e98f585672341d0973c8d00a90602090a2565b50565b919082039182116125d557565b60ff613d72826135d7565b5416613d5757613d81816135d7565b805460ff191660011790556040514281526001600160a01b03909116907f6ea640312e182de387819fbeb13be00db3171a445412852248559054871c419990602090a2565b6001600160a01b03165f9081525f516020615a675f395f51905f526020526040902054151590565b5f516020615b075f395f51905f525460ff8116613d575760019060ff1916175f516020615b075f395f51905f52557f230e80be2bd3bf5b8d0c09919cfeb448962736c4a91f7659de6819c2e5ec06eb6020604051428152a1565b9190918115908115613e9d575b8115613e8c575b5061391d57613e6e9061242883613f06565b8015159182613e7c57505090565b613e8791925061366c565b101590565b613e96915061537c565b155f613e5c565b9050613ea883613dc6565b1590613e55565b5f516020615b075f395f51905f525460ff811615613d575760ff19165f516020615b075f395f51905f52557fbcc593968355aff8c89da92575758900df3be6484058e7126f658cda71f2367f6020604051428152a1565b6001600160a01b03165f9081525f516020615a675f395f51905f52602052604090206001015460f01c60ff1690565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355415613f8c576134ef614025565b5f90565b919060ff613f9d8461360f565b54166140075760ff613fae8261360f565b54166108475760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591613fe18561359f565b6001600160a01b039182165f8181529184526040918290208690559051948552941692a3565b6327951b3f60e11b5f9081526001600160a01b038416600452602490fd5b6040516370a0823160e01b815230600482015260208160248173866a2bf4e572cbcf37d5071a7a58503bfb36be1b5afa90811561083c575f916140c8575b5073866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36546001600160f01b03168082111561391d576134ef91613d5a565b90506020813d6020116140f2575b816140e36020938361340d565b810103126104d557515f614063565b3d91506140d6565b6001600160f01b038111614114576001600160f01b031690565b632a49c10d60e01b5f5260045ffd5b5f516020615b675f395f51905f5260205f9261414d855f516020615aa75f395f51905f52546137a6565b5f516020615aa75f395f51905f525561416581613634565b8054860190556040519485526001600160a01b031693a3565b5f516020615bc75f395f51905f52545f516020615aa75f395f51905f52548181111561391d570390565b335f9081527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea26614602052604090205460ff16156141e057565b63e2517d3f60e01b5f52336004527f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b3560245260445ffd5b335f9081527fc8c5404fa38229b37c25ed47149e73a9ea6a76c763e790fa27b00b250bb568c5602052604090205460ff161561424f57565b63e2517d3f60e01b5f52336004527fc66b3536568140ce119bcc21a4fa7e3449a56fb5f260d32ff8e719230264132c60245260445ffd5b335f9081527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d602052604090205460ff16156142be57565b63e2517d3f60e01b5f52336004527fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af60245260445ffd5b335f9081527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b602052604090205460ff161561432d57565b63e2517d3f60e01b5f52336004527f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a60245260445ffd5b335f9081527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e202452602052604090205460ff161561439c57565b63e2517d3f60e01b5f52336004527f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca60245260445ffd5b335f9081527fc726c2b4c97955c111bebcf26d23050c057419036fd6b131fd840def3e37a8b0602052604090205460ff161561440b57565b63e2517d3f60e01b5f52336004527f2a3dab589bcc9747970dd85ac3f222668741ae51f2a1bbb8f8355be28dd8a86860245260445ffd5b5f8181525f516020615b875f395f51905f526020908152604080832033845290915290205460ff16156144725750565b63e2517d3f60e01b5f523360045260245260445ffd5b6001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff1615613d5757805f525f516020615ac75f395f51905f5260205260405f2060ff1981541690557f07d647ad688e085159820c1d8d030e5765cdc5274d4ee4065c6066b388a2ef596020604051428152a2565b919061450a816153c1565b61451261560d565b60ff61451d3361360f565b541661458e5760ff61452e8461360f565b54166140075760ff61453f8261360f565b5416610847576040518281526001600160a01b0382811691908516905f516020615b675f395f51905f5290602090a38115614589578261458283614587956153e0565b615417565b565b505050565b6327951b3f60e11b5f523360045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03165afa90811561083c575f9161460a575b506145fd61417e565b908181111561391d570390565b90506020813d602011614634575b816146256020938361340d565b810103126104d557515f6145f4565b3d9150614618565b6001600160a01b0381165f9081527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea26614602052604090205460ff16613ac8576001600160a01b03165f8181527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea2661460205260408120805460ff191660011790553391907f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b35905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b602052604090205460ff16613ac8576001600160a01b03165f8181527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b60205260408120805460ff191660011790553391907f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d602052604090205460ff16613ac8576001600160a01b03165f8181527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d60205260408120805460ff191660011790553391905f5160206159e75f395f51905f528180a4600190565b6001600160a01b0381165f9081527f0c3ed9462fc953d240fea484f4676580de2bf475f9939ce7356d420c75b99885602052604090205460ff16613ac8576001600160a01b03165f8181527f0c3ed9462fc953d240fea484f4676580de2bf475f9939ce7356d420c75b9988560205260408120805460ff191660011790553391907f7daa70daa195905862e9fca178089de90a69f7175eb24d1b44e833ee4d44856a905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e202452602052604090205460ff16613ac8576001600160a01b03165f8181527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e20245260205260408120805460ff191660011790553391907f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d602052604090205460ff16613ac8576001600160a01b03165f8181527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d60205260408120805460ff191660011790553391907fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af905f5160206159e75f395f51905f529080a4600190565b5f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b038616845290915290205460ff1661391d575f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f8181525f516020615ac75f395f51905f5260205260409020549193929160ff1615614b9757614b34826153c1565b60018060a01b03821680825f516020615b675f395f51905f526020604051888152a3604051918483527f47cea260e2dfb95ed2ab59ad44fe2ac9cddb432afb828d2a1475936b5a2b829a60203394a48115614589578261458283614587956153e0565b63fc78247960e01b5f5260045260245ffd5b90614bb3826153c1565b8015614c0257614bcb6001600160a01b0383166157b5565b15613cc9571515906001600160a01b03167fd996de5928db1ae1098987738baabe68b0081b062d2dda6a58f1beb0c93ce3e65f80a3565b614c146001600160a01b038316615674565b614bcb565b604051614c29816131e3816136d6565b6020815191012060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a08152614ca160c08261340d565b51902090565b5f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b038616845290915290205460ff161561391d575f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b6001600160a01b03168015614db2575f516020615a475f395f51905f52546001600160a01b0381168214613cc9576001600160a01b03191681175f516020615a475f395f51905f52557f77f12a3c9f87d4602fe59bb8d2b68c7b516e0cacba414a53e74ea75d435dc18d5f80a2565b63177f500360e21b5f5260045ffd5b6134ef916040519060208201927f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429845260018060a01b03166040830152606082015260608152614e1260808261340d565b5190206154f9565b92614e3b926001600160ff1b03821692909160ff90811c601b011690615868565b6006821015614e63576145879282614e5c57614e57925061584d565b61552c565b505061552c565b634e487b7160e01b5f52602160045260245ffd5b614e8182826155c2565b6001600160a01b03165f8181525f516020615a075f395f51905f52602090815260408083208584529091528120805460ff191660011790557f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d819080a3565b9391614e3b9391615868565b6001600160a01b031680158015614f16575b614f045750565b6337bce3c560e11b5f5260045260245ffd5b507f000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d6001600160a01b03168114614efd565b908160209103126104d5575180151581036104d55790565b9390926134ef95926040519460208601967fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8885260018060a01b0316604087015260018060a01b03166060860152608085015260a084015260c083015260e0820152614e1261010082800301601f19810183528261340d565b91614fe481836159b3565b6006821015614e6357816150c657614ffd91508461584d565b925b6006841015614e635783156150c0575f9261258d61504385946040519283916020830195630b135d3f60e11b8752602484015260406044840152606483019061337f565b51915afa3d156150b9573d6150578161342e565b90615065604051928361340d565b81523d5f602083013e5b816150ab575b81615089575b50613d57576145879061552c565b90506020818051810103126104d55760200151630b135d3f60e11b145f61507b565b905060208151101590615075565b606061506f565b50505050565b5092614fff565b6001600160a01b03821696959493929190338890036150f1576145879697506152c6565b87631c5939f360e01b5f523360045260245260445ffd5b6001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff16613d5757805f525f516020615ac75f395f51905f5260205260405f20600160ff198254161790557f68e0d8c112165d0949ce87205b719ed7d98c7401866c34a159f7c67c6f5620e76020604051428152a2565b93929384421161523657938461519c84846134ef9798613f90565b60018060a01b031692835f527f1b21ba3f0a2135d61c468900b54084f04af8111bce0f8bbb6ab8c46d11afbd0060205260405f20908154916001830190556040519360208501957f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98752604086015260018060a01b03166060850152608084015260a083015260c082015260c08152614e1260e08261340d565b84630f88f04960e41b5f526004524260245260445ffd5b9390926134ef95926040519460208601967f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267885260018060a01b0316604087015260018060a01b03166060860152608085015260a084015260c083015260e0820152614e1261010082800301601f19810183528261340d565b9193959490928042111561536657508542101561534f576145879495506152ed81836155c2565b6001600160a01b0382165f8181525f516020615a075f395f51905f52602090815260408083208584529091528120805460ff191660011790557f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a59080a36144ff565b856359fe699f60e11b5f524260045260245260445ffd5b6324c7fcd160e11b5f524260045260245260445ffd5b5f516020615c075f395f51905f525415908115615397575090565b6001600160a01b03165f9081525f516020615a275f395f51905f5260205260409020541515919050565b6001600160a01b0316156153d157565b63bfcf3c0b60e01b5f5260045ffd5b6153e981613634565b54908282106153f757505050565b63db42144d60e01b5f5260018060a01b031660045260245260445260645ffd5b9061542461542f92613634565b838154039055613634565b908154019055565b9060ff8091169116039060ff82116125d557565b60ff16604d81116125d557600a0a90565b60ff8116600681146154c457600610156154a25761547e600661548392615437565b61544b565b90811561548e570490565b634e487b7160e01b5f52601260045260245ffd5b61547e6154b0916006615437565b908181029181830414901517156125d55790565b505090565b60ff8116806006146154c457600611156154eb5761547e615483916006615437565b61547e60066154b092615437565b615501613994565b9060405190602082019261190160f01b84526022830152604282015260428152614ca160628261340d565b906006821015614e635781156155be5750600181146155af57600281146155a0576003811461559157600481146155825760051461557357638baa579f60e01b5f5260045ffd5b6310c74b0360e01b5f5260045ffd5b63ff551e8960e01b5f5260045ffd5b6317e97eb760e31b5f5260045ffd5b634be6321b60e01b5f5260045ffd5b638baa579f60e01b5f5260045ffd5b9050565b60018060a01b0316805f525f516020615a075f395f51905f5260205260405f20825f5260205260ff60405f2054166155f8575050565b63d309466d60e01b5f5260045260245260445ffd5b60ff5f516020615ba75f395f51905f52541661562557565b63d93c066560e01b5f5260045ffd5b60ff5f516020615be75f395f51905f525460401c161561565057565b631afcd79f60e31b5f5260045ffd5b805482101561396c575f5260205f2001905f90565b5f8181525f516020615a275f395f51905f526020526040902054801561391d575f1981018181116125d5575f516020615c075f395f51905f52545f198101919082116125d557818103615743575b5050505f516020615c075f395f51905f5254801561572f575f19016156f4815f516020615c075f395f51905f5261565f565b8154905f199060031b1b191690555f516020615c075f395f51905f52555f525f516020615a275f395f51905f526020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b61579361576061577d935f516020615c075f395f51905f5261565f565b90549060031b1c9283925f516020615c075f395f51905f5261565f565b819391549060031b91821b915f19901b19161790565b90555f525f516020615a275f395f51905f5260205260405f20555f80806156c2565b805f525f516020615a275f395f51905f5260205260405f2054155f14613ac8575f516020615c075f395f51905f5254600160401b8110156116665761581e61577d8260018594015f516020615c075f395f51905f52555f516020615c075f395f51905f5261565f565b90555f516020615c075f395f51905f5254905f525f516020615a275f395f51905f5260205260405f2055600190565b6001600160a01b03908116911603615863575f90565b600590565b907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084116158fd5760ff1690601b821415806158f2575b6158e7576020935f93608093604051938452868401526040830152606082015282805260015afa1561083c575f516001600160a01b0316806158e357506001905f90565b5f91565b505050506004905f90565b50601c82141561589f565b505050506003905f90565b60ff5f516020615b075f395f51905f52541680615947575b6159275750565b636a95c69760e11b5f9081526001600160a01b0391909116600452602490fd5b5060ff615953826135d7565b541615615920565b905f602091828151910182855af11561083c575f513d6159aa57506001600160a01b0381163b155b61598a5750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b60011415615983565b9060418151036159dd576159d991602082015190606060408401519301515f1a90615868565b9091565b50506002905f9056fe2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d1116a1d33aa5fb91b2652b3b0fdb63704173742d6dbecaf4256ebe33a48886004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b03ee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1014717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b00cbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da102ee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1002fd5767309dce890c526ace85d7fe164825199d7dcd99c33588befc51b32ce00cbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da1011d6c3b82f2027bd0b336e517c3a50a0483eb4d2c5cd82c6a491448d31b621000103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10270b5c8a095bb680742b58d79cdc18b0477268ac25a3a49141caf92ee01af5247ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b01f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b02a26469706673582212201c4acef41f12016d13251ba4b2fbc1a635420faea1acb628ed48403239ca974c64736f6c63430008220033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["@pyusdx/=lib/PYUSDX/src/","@m-extensions/=lib/PYUSDX/lib/evm-m-extensions/src/","@openzeppelin/contracts-upgradeable/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/","@openzeppelin/contracts/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/","openzeppelin-contracts-upgradeable/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/","@ensdomains/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/node_modules/@ensdomains/","@uniswap/v4-core/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/","PYUSDX/=lib/PYUSDX/","common/=lib/PYUSDX/lib/evm-m-extensions/lib/common/src/","ds-test/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","evm-m-extensions/=lib/PYUSDX/lib/evm-m-extensions/","forge-gas-snapshot/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/permit2/lib/forge-gas-snapshot/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","hardhat/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/node_modules/hardhat/","openzeppelin-foundry-upgrades/=lib/PYUSDX/lib/evm-m-extensions/lib/openzeppelin-foundry-upgrades/src/","permit2/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/permit2/","safe-smart-account/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/safe-utils/lib/safe-smart-account/","safe-utils/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/safe-utils/src/","solidity-http/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/safe-utils/lib/solidity-http/src/","solidity-stringutils/=lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/safe-utils/lib/solidity-stringutils/","solmate/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/lib/solmate/","uniswap-v4-periphery/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/","v4-core/=lib/PYUSDX/lib/evm-m-extensions/lib/uniswap-v4-periphery/lib/v4-core/src/","wrapped-m-token/=lib/PYUSDX/lib/evm-m-extensions/lib/wrapped-m-token/"],"viaIR":true},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":[["0xeBDB0942cE16386Ab90718C7BD10C91CDb66b14d",{"internalType":"address","name":"pyusdx_","type":"address"}],["0x0bC305e7e13113cAEd3f5486849e9518a1cC4173",{"internalType":"address","name":"swapFacility_","type":"address"}]],"compiler_version":"v0.8.34+commit.80d5c536","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-12T20:57:33.086912Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60c03461019d57601f615e4638819003918201601f19168301916001600160401b038311848410176101a157808492604094855283398101031261019d57610052602061004b836101b5565b92016101b5565b6080829052906001600160a01b03161561018e5760a08190526001600160a01b03161561017f575f516020615e265f395f51905f525460ff8160401c16610170576002600160401b03196001600160401b0382160161011a575b604051615c5c90816101ca82396080518181816107de0152818161092601528181610d8e0152818161250701528181612f2f01528181613a37015281816145bc0152614f19015260a0518181816106cf01528181610cbd01528181610e890152818161238b01526126e40152f35b6001600160401b0319166001600160401b039081175f516020615e265f395f51905f52556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a15f6100ac565b63f92ee8a960e01b5f5260045ffd5b636880ffc960e11b5f5260045ffd5b6364ab2dc160e11b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361019d5756fe6080806040526004361015610012575f80fd5b5f3560e01c90816301e1d114146132a95750806301ffc9a7146132545780630688cbdf1461320d57806306b3efd6146131ea57806306fdde03146131c0578063095ea7b31461319a5780630fe3bf7a146131805780631143a46914613143578063170e2070146130e657806318160ddd146130bd578063184d69ab1461308f57806323b872dd14612fdd578063248a9ca314612fa65780632859398414612efc5780632cfd442d14612ec25780632f2ff15d14612e7857806330adf81f14612e3e5780633123428714612e04578063313ce56714612dd857806332e7f35614612dad57806333bebb7714612d8e57806333e1c5ac14612d585780633644e51514612d3e57806336568abe14612cfa5780633664cd4914612cc05780633817cf5214612c925780633af32abf14612c615780633f4ba83a14612be3578063406cf22914612bc95780634259dff914612b8f578063438f942d14612b4857806345c8b1a614612b1f57806345cf012d14612aba5780634aa504d314612a935780634db82e5814612a78578063532992c514612a455780635a049a7014612a025780635c975abb146129d457806362355638146126d257806363f156491461269857806364c2a2651461266b5780636bb45eec1461237957806370a082311461234d5780637295ed93146123135780637ecebe00146122bc5780637f2eecc3146122825780638319833414611d175780638456cb5914611ca657806384b0196e14611bce57806388b7ab6314611ba45780638ab1d68114611b7b5780638d1fdf2f14611b575780638fd3ab801461186157806391d148541461180c57806394f5a66e146111fd57806395d89b411461110357806398abb5ea146110bf5780639b19251a146110965780639fd5a6cf1461103a578063a08cb48b1461100f578063a0cc6a6814610fd5578063a217fddf14610fbb578063a7d612be14610f9b578063a9059cbb14610f6a578063aad1202914610f08578063aafee97b14610ee9578063ace150a514610eb8578063ae06b7e414610e74578063b7b7289914610e23578063bf376c7a14610c9f578063c537bed014610c7c578063c956a3e314610bd8578063cc4c5b6414610ba4578063cdfb2b4e14610b84578063cf09299514610b54578063cfaa7b8314610b3b578063d505accf14610ae8578063d547741f14610a99578063d6b0f48414610a79578063d7a49f0b1461098f578063d916948714610955578063da6b76b814610911578063dd62ed3e146108ca578063de0e9a3e146106b9578063e366da2c1461068b578063e3ee160e1461065b578063e58398361461060a578063e63ab1e9146105d0578063e94a01021461057c578063ed4ef4641461055a578063ef55bec614610522578063fca7d533146104d95763fdf769781461041b575f80fd5b346104d5575f3660031901126104d5576040518060205f516020615c075f395f51905f5254928381520180925f516020615c075f395f51905f525f5260205f20905f5b8181106104bf575050508161047491038261340d565b604051918291602083019060208452518091526040830191905f5b81811061049d575050500390f35b82516001600160a01b031684528594506020938401939092019160010161048f565b825484526020909301926001928301920161045e565b5f80fd5b346104d5575f3660031901126104d5577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040516001600160a01b0390911615158152602090f35b346104d55761055861055361053636613541565b9161054d8486888a8c989e988e9a9e9d9b9d614f60565b85614edf565b6150cd565b005b346104d5575f3660031901126104d5576020610574613f35565b604051908152f35b346104d55760403660031901126104d5576105956132cf565b60018060a01b03165f525f516020615a075f395f51905f5260205260405f206024355f52602052602060ff60405f2054166040519015158152f35b346104d5575f3660031901126104d55760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b346104d55760203660031901126104d55760206106516106286132cf565b6001600160a01b03165f9081525f516020615ac75f395f51905f52602052604090205460ff1690565b6040519015158152f35b346104d55761055861068661066f36613541565b9161054d8486888a8c989e988e9a9e9d9b9d61524d565b6152c6565b346104d55760203660031901126104d55760206106ae6106a96132cf565b613f06565b60ff60405191168152f35b346104d55760203660031901126104d5576004357f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036108bb5760405163d737d0c760e01b8152602081600481335afa90811561083c575f9161088c575b50811561087d5761073282336153e0565b61073b81615908565b61074361417e565b808311610867575061075361560d565b60ff61075e8261360f565b5416610847576107d9602083805f516020615aa75f395f51905f5254035f516020615aa75f395f51905f525561079333613634565b8181540390555f6040518281525f516020615b675f395f51905f52843392a360405163a9059cbb60e01b8152336004820152602481019190915291829081906044820190565b03815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561083c5761081457005b6105589060203d602011610835575b61082d818361340d565b810190614f48565b503d610823565b6040513d5f823e3d90fd5b6327951b3f60e11b5f9081526001600160a01b0391909116600452602490fd5b826350828de360e11b5f5260045260245260445ffd5b631f2a200560e01b5f5260045ffd5b6108ae915060203d6020116108b4575b6108a6818361340d565b810190613b5a565b82610721565b503d61089c565b630aff86d760e21b5f5260045ffd5b346104d55760403660031901126104d5576108e36132cf565b6108f46108ee6132e5565b9161359f565b9060018060a01b03165f52602052602060405f2054604051908152f35b346104d5575f3660031901126104d5576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346104d5575f3660031901126104d55760206040517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a15974298152f35b346104d55760603660031901126104d5576004356001600160401b0381116104d5576109bf9036906004016133a3565b6024356001600160401b0381116104d5576109de9036906004016133a3565b906044356001600160401b0381116104d5576109fe9036906004016133a3565b94610a07614217565b838514801590610a6f575b610a60575f5b858110610a2157005b80610a5a610a3a610a356001948a8761395c565b613980565b610a48610a35848a8a61395c565b610a53848c8961395c565b3591614afb565b01610a18565b63512509d360e11b5f5260045ffd5b5085851415610a12565b346104d5575f3660031901126104d557610a916143d3565b610558613eaf565b346104d55760403660031901126104d557610558600435610ab86132e5565b90610ae3610ade825f525f516020615b875f395f51905f52602052600160405f20015490565b614442565b614ca7565b346104d55760e03660031901126104d557610b016132cf565b610b096132e5565b906084359160ff831683036104d5576105589260c43592610b3560a43593606435906044359084615181565b90614edf565b346104d5576020610651610b4e366133d3565b91613e48565b346104d557610558610686610b683661348d565b610b7e828486888a8c989c9d979d9b999b61524d565b83614fd9565b346104d5575f3660031901126104d557610b9c6143d3565b610558613dee565b346104d5575f3660031901126104d5575f516020615a475f395f51905f52546040516001600160a01b039091168152602090f35b346104d55760403660031901126104d5576004356001600160401b0381116104d557610c089036906004016133a3565b906024356001600160401b0381116104d557610c289036906004016133a3565b919092610c33614286565b828103610a60575f5b818110610c4557005b610c53610a3582848661395c565b90610c5f81868861395c565b359182151583036104d557600192610c7691614ba9565b01610c3c565b346104d55760203660031901126104d5576020610651610c9a6132cf565b613dc6565b346104d55760403660031901126104d557610cb86132cf565b6024357f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036108bb5760405163d737d0c760e01b8152602081600481335afa90811561083c575f91610e04575b50610d19836153c1565b811561087d57610d2881615908565b610d3183615908565b610d3961560d565b60ff610d448261360f565b5416610847575060ff610d568361360f565b5416610de3576040516323b872dd60e01b815233600482015230602482015260448101829052916020836064815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af192831561083c5761055893610dc6575b50614123565b610dde9060203d6020116108355761082d818361340d565b610dc0565b506327951b3f60e11b5f9081526001600160a01b0391909116600452602490fd5b610e1d915060203d6020116108b4576108a6818361340d565b83610d0f565b346104d55760603660031901126104d557610e3c6132cf565b602435604435916001600160401b0383116104d557610e6f610e65610558943690600401613449565b610b7e8484614dc1565b614e77565b346104d5575f3660031901126104d5576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346104d557610558610686610ecc366134f2565b90610ee3838587898b8d999d9e989e9c9a9c61524d565b84614e1a565b346104d5575f3660031901126104d5576322f9060160e11b5f5260045ffd5b346104d55760203660031901126104d5576004356001600160401b0381116104d557610f389036906004016133a3565b610f406141a8565b5f5b818110610f4b57005b80610f64610f5f610a35600194868861395c565b615108565b01610f42565b346104d55760403660031901126104d557610f90610f866132cf565b60243590336144ff565b602060405160018152f35b346104d55760203660031901126104d5576322f9060160e11b5f5260045ffd5b346104d5575f3660031901126104d55760206040515f8152f35b346104d5575f3660031901126104d55760206040517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22678152f35b346104d557610558610553611023366134f2565b90610ee3838587898b8d999d9e989e9c9a9c614f60565b346104d55760a03660031901126104d5576110536132cf565b61105b6132e5565b608435916001600160401b0383116104d557611090611081610558943690600401613449565b92606435906044359084615181565b90614fd9565b346104d55760203660031901126104d5576105586110b26132cf565b6110ba6143d3565b613d67565b346104d55760203660031901126104d5576001600160a01b036110e06132cf565b165f525f516020615a675f395f51905f52602052602060405f2054604051908152f35b346104d5575f3660031901126104d5576040515f5f516020615a875f395f51905f525461112f8161369e565b80845290600181169081156111d9575060011461116f575b61116b836111578185038261340d565b60405191829160208352602083019061337f565b0390f35b5f516020615a875f395f51905f525f9081527f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b939250905b8082106111bf57509091508101602001611157611147565b9192600181602092548385880101520191019092916111a7565b60ff191660208086019190915291151560051b840190910191506111579050611147565b346104d5576101003660031901126104d5576004356001600160401b0381116104d55761122e903690600401613449565b6024356001600160401b0381116104d55761124d903690600401613449565b6112556132fb565b9061125e613311565b91611267613327565b9161127061333d565b91611279613353565b93611282613369565b925f516020615be75f395f51905f5254976001600160401b0360ff8a60401c1615991680159081611804575b60011490816117fa575b1590816117f1575b506117e257886112ce613ccd565b6117b2575b6112db615634565b6001600160a01b038816156117a3576001600160a01b03871615611794576001600160a01b0385161561178557611310615634565b611318615634565b611320615634565b611328615634565b611330615634565b611338615634565b8051906001600160401b0382116116665781906113625f516020615b275f395f51905f525461369e565b601f8111611703575b50602090601f8311600114611685575f9261167a575b50508160011b915f199060031b1c1916175f516020615b275f395f51905f52555b467f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea100556113cd614c19565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10155600660ff195f516020615ae75f395f51905f525416175f516020615ae75f395f51905f52558051906001600160401b03821161166657819061143e5f516020615a875f395f51905f525461369e565b601f81116115e4575b50602090601f8311600114611566575f9261155b575b50508160011b915f199060031b1c1916175f516020615a875f395f51905f52555b611486615634565b6001600160a01b0381161561154c5761149e9061463c565b506114a7615634565b6001600160a01b0383161561153d576114e4946114d36114d8926114cd6114de966146f5565b50614d43565b6147ae565b50614845565b506148fe565b506114eb57005b60ff60401b195f516020615be75f395f51905f5254165f516020615be75f395f51905f52557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a1005b63042d717b60e01b5f5260045ffd5b636cbbd1d360e01b5f5260045ffd5b01519050898061145d565b5f516020615a875f395f51905f525f9081528281209350601f198516905b8181106115cc57509084600195949392106115b4575b505050811b015f516020615a875f395f51905f525561147e565b01515f1960f88460031b161c1916905589808061159a565b92936020600181928786015181550195019301611584565b82811115611447575f516020615a875f395f51905f525f52909150601f830160051c7f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b6020851061165e575b849392601f0160051c82900391015f5b82811061164e575050611447565b5f81830155859450600101611640565b5f9150611630565b634e487b7160e01b5f52604160045260245ffd5b015190508a80611381565b5f516020615b275f395f51905f525f9081528281209350601f198516905b8181106116eb57509084600195949392106116d3575b505050811b015f516020615b275f395f51905f52556113a2565b01515f1960f88460031b161c191690558a80806116b9565b929360206001819287860151815501950193016116a3565b8281111561136b575f516020615b275f395f51905f525f52909150601f830160051c7f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a86020851061177d575b849392601f0160051c82900391015f5b82811061176d57505061136b565b5f8183015585945060010161175f565b5f915061174f565b6318362d8b60e01b5f5260045ffd5b6309d50edf60e01b5f5260045ffd5b633944ed8760e11b5f5260045ffd5b600160401b60ff60401b195f516020615be75f395f51905f525416175f516020615be75f395f51905f52556112d3565b63f92ee8a960e01b5f5260045ffd5b9050158a6112c0565b303b1591506112b8565b8a91506112ae565b346104d55760403660031901126104d5576118256132e5565b6004355f525f516020615b875f395f51905f5260205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b346104d5575f3660031901126104d5575f516020615be75f395f51905f525460ff8160401c16908115611b42575b506117e2575f516020615be75f395f51905f52805468ffffffffffffffffff1916680100000000000000021790556040516370a0823160e01b815230600482015260208160248173866a2bf4e572cbcf37d5071a7a58503bfb36be1b5afa90811561083c575f91611b10575b506119235f516020615aa75f395f51905f52545f516020615bc75f395f51905f525490613d5a565b808210611afa576119349082613d5a565b80611aa9575b50611944816140fa565b6040519160608301908382106001600160401b038311176116665760409182528084526001600160f01b039283166020808601918252600693860193845273866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f8190525f516020615a675f395f51905f52825295517fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355590517fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36805494516001600160f81b0319909516919095161760f09390931b60ff60f01b16929092179092555f516020615b475f395f51905f5291611a41815f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f5255604051908152a260ff60401b195f516020615be75f395f51905f5254165f516020615be75f395f51905f52557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160028152a1005b611af4907fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051838152a15f516020615a475f395f51905f52546001600160a01b0316614123565b8161193a565b90631f6c26ed60e31b5f5260045260245260445ffd5b90506020813d602011611b3a575b81611b2b6020938361340d565b810103126104d55751816118fb565b3d9150611b1e565b600291506001600160401b031610158161188f565b346104d55760203660031901126104d557610558611b736132cf565b610f5f6141a8565b346104d55760203660031901126104d557610558611b976132cf565b611b9f6143d3565b613cfa565b346104d557610558610553611bb83661348d565b610b7e828486888a8c989c9d979d9b999b614f60565b346104d5575f3660031901126104d557611c4a6020604051611bf0828261340d565b5f81525f36813760405191611c0f83611c08816136d6565b038461340d565b611c58604051611c2060408261340d565b60018152603160f81b83820152604051958695600f60f81b875260e08588015260e087019061337f565b90858203604087015261337f565b4660608501523060808501525f60a085015283810360c08501528180845192838152019301915f5b828110611c8f57505050500390f35b835185528695509381019392810192600101611c80565b346104d5575f3660031901126104d557611cbe6142f5565b611cc661560d565b600160ff195f516020615ba75f395f51905f525416175f516020615ba75f395f51905f52557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b346104d5576101203660031901126104d5576004356001600160401b0381116104d557611d48903690600401613449565b6024356001600160401b0381116104d557611d67903690600401613449565b611d6f6132fb565b90611d78613311565b611d80613327565b91611d8961333d565b90611d92613353565b90611d9b613369565b92610104359160018060a01b038316988984036104d5575f516020615be75f395f51905f5254996001600160401b0360ff8c60401c16159b168015908161227a575b6001149081612270575b159081612267575b506117e2578a611dfd613ccd565b612237575b611e0a615634565b6001600160a01b0389161561222857611e21615634565b6001600160a01b038816156117a3576001600160a01b03871615611794571561178557611e4c615634565b611e54615634565b611e5c615634565b611e64615634565b611e6c615634565b611e74615634565b8051906001600160401b038211611666578190611e9e5f516020615b275f395f51905f525461369e565b601f81116121a6575b50602090601f8311600114612128575f9261211d575b50508160011b915f199060031b1c1916175f516020615b275f395f51905f52555b467f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10055611f09614c19565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10155600660ff195f516020615ae75f395f51905f525416175f516020615ae75f395f51905f52558051906001600160401b038211611666578190611f7a5f516020615a875f395f51905f525461369e565b601f811161209b575b50602090601f831160011461201d575f92612012575b50508160011b915f199060031b1c1916175f516020615a875f395f51905f52555b611fc2615634565b6001600160a01b0381161561154c57611fda9061463c565b50611fe3615634565b6001600160a01b0382161561153d576114d861200c946114d36114e4986114cd6114de966146f5565b506149b7565b015190508a80611f99565b5f516020615a875f395f51905f525f9081528281209350601f198516905b818110612083575090846001959493921061206b575b505050811b015f516020615a875f395f51905f5255611fba565b01515f1960f88460031b161c191690558a8080612051565b9293602060018192878601518155019501930161203b565b82811115611f83575f516020615a875f395f51905f525f52909150601f830160051c7f35f9f04fad87e1ca84403b2d88a131772d2fa872029e0542adfffd075ac9353b60208510612115575b849392601f0160051c82900391015f5b828110612105575050611f83565b5f818301558594506001016120f7565b5f91506120e7565b015190508b80611ebd565b5f516020615b275f395f51905f525f9081528281209350601f198516905b81811061218e5750908460019594939210612176575b505050811b015f516020615b275f395f51905f5255611ede565b01515f1960f88460031b161c191690558b808061215c565b92936020600181928786015181550195019301612146565b82811115611ea7575f516020615b275f395f51905f525f52909150601f830160051c7f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a860208510612220575b849392601f0160051c82900391015f5b828110612210575050611ea7565b5f81830155859450600101612202565b5f91506121f2565b638de68f0b60e01b5f5260045ffd5b600160401b60ff60401b195f516020615be75f395f51905f525416175f516020615be75f395f51905f5255611e02565b9050158c611def565b303b159150611de7565b8c9150611ddd565b346104d5575f3660031901126104d55760206040517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de88152f35b346104d55760203660031901126104d5576001600160a01b036122dd6132cf565b165f527f1b21ba3f0a2135d61c468900b54084f04af8111bce0f8bbb6ab8c46d11afbd00602052602060405f2054604051908152f35b346104d5575f3660031901126104d55760206040517f2a3dab589bcc9747970dd85ac3f222668741ae51f2a1bbb8f8355be28dd8a8688152f35b346104d55760203660031901126104d557602061237061236b6132cf565b613634565b54604051908152f35b346104d557612387366133d3565b91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036108bb576123c161560d565b6123ca82614eeb565b6123d382613dc6565b1561264a5760405163d737d0c760e01b8152602081600481335afa90811561083c575f9161262b575b506124068161537c565b1561260b5750612415816153c1565b821561087d5761242d8361242884613f06565b6154c9565b92831561087d5761243d8361366c565b8085116125e9575061244e846140fa565b6001600160a01b039093165f8181525f516020615a675f395f51905f52602052604090206001018054919490916001600160f01b03918216908216039081116125d55781546001600160f01b0319166001600160f01b03919091161790555f516020615bc75f395f51905f52546124c6908290613d5a565b5f516020615bc75f395f51905f52556040516323b872dd60e01b815233600482015230602482015260448101829052916020836064815f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af191821561083c577feea0cfe70e73ef2022bd359d31ed861d5476282f9a6f68117191486f6a9b887b936040936125b8575b50825163a9059cbb60e01b60208201526001600160a01b0383166024820152604481018790526125a19061259b81606481015b03601f19810183528261340d565b8661595b565b825195865260208601526001600160a01b031693a3005b6125d09060203d6020116108355761082d818361340d565b61255a565b634e487b7160e01b5f52601160045260245ffd5b8484637c67815160e01b5f5260018060a01b031660045260245260445260645ffd5b6373aabd2960e11b5f9081526001600160a01b0391909116600452602490fd5b612644915060203d6020116108b4576108a6818361340d565b846123fc565b50630188053b60e41b5f9081526001600160a01b0391909116600452602490fd5b346104d55760403660031901126104d5576105586126876132cf565b61268f614286565b60243590613b79565b346104d5575f3660031901126104d55760206040517f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b358152f35b346104d5576126e0366133d3565b91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036108bb5760405163d737d0c760e01b815292602084600481335afa93841561083c575f946129b3575b5061274183614eeb565b61274a826153c1565b801561087d576127629061275d84613f06565b61545c565b91821561087d576127768361242883613f06565b9361278081615908565b61278983615908565b6127938583613af8565b15612992576127a061560d565b60ff6127ab8261360f565b5416610847575060ff6127bd8361360f565b5416610de3576040516370a0823160e01b81523060048201526001600160a01b03919091169290602081602481875afa90811561083c575f91612960575b506040516323b872dd60e01b60208201523360248201523060448201526064810186905261283690612830816084810161258d565b8561595b565b6040516370a0823160e01b815230600482015290602082602481885afa801561083c575f9061292c575b61286a9250613d5a565b84811061291257507f1f28ca77b3dd333cb25ceb5145a2af419a8ba913b5f6c591f04366e0ca5937f8916040916128a0866140fa565b5f8681525f516020615a675f395f51905f52602052849020600101805490916001600160f01b03916128d49190831661378d565b1661ffff60f01b8254161790556128f9815f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f52556125a18183614123565b84846383257a2960e01b5f5260045260245260445260645ffd5b506020823d602011612958575b816129466020938361340d565b810103126104d55761286a9151612860565b3d9150612939565b90506020813d60201161298a575b8161297b6020938361340d565b810103126104d55751856127fb565b3d915061296e565b50633a7848b160e11b5f9081526001600160a01b0391909116600452602490fd5b6129cd91945060203d6020116108b4576108a6818361340d565b9284612737565b346104d5575f3660031901126104d557602060ff5f516020615ba75f395f51905f5254166040519015158152f35b346104d55760a03660031901126104d557612a1b6132cf565b6024356044359160ff831683036104d557610e6f61055893608435906064359061054d8686614dc1565b346104d55760803660031901126104d557610558612a616132cf565b60243590610e6f606435604435610ee38585614dc1565b346104d5575f3660031901126104d557602060405160068152f35b346104d55760403660031901126104d5576020610651612ab16132cf565b60243590613af8565b346104d55760203660031901126104d557610558612ad66132cf565b612ade614364565b5f516020615a475f395f51905f52546001600160a01b03165f9081525f516020615ac75f395f51905f52602052604090205460ff16614d43576114cd6139e9565b346104d55760203660031901126104d557610558612b3b6132cf565b612b436141a8565b614488565b346104d5575f3660031901126104d5577f0db096ce50da19b63b97b47df5b0c87e2ed1677b3d801ad424e1bbfc0bb0c300546040516001600160a01b039091168152602090f35b346104d5575f3660031901126104d55760206040517f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca8152f35b346104d5575f3660031901126104d55760206105746139e9565b346104d5575f3660031901126104d557612bfb6142f5565b5f516020615ba75f395f51905f525460ff811615612c525760ff19165f516020615ba75f395f51905f52557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b346104d55760203660031901126104d557602060ff612c86612c816132cf565b6135d7565b54166040519015158152f35b346104d5575f3660031901126104d557602060405173866a2bf4e572cbcf37d5071a7a58503bfb36be1b8152f35b346104d5575f3660031901126104d55760206040517f7daa70daa195905862e9fca178089de90a69f7175eb24d1b44e833ee4d44856a8152f35b346104d55760403660031901126104d557612d136132e5565b336001600160a01b03821603612d2f5761055890600435614ca7565b63334bd91960e11b5f5260045ffd5b346104d5575f3660031901126104d5576020610574613994565b346104d55760403660031901126104d557612d716132cf565b60243580151581036104d55761055891612d89614286565b614ba9565b346104d557610558612d9f366133d3565b91612da8614217565b614afb565b346104d5575f3660031901126104d55760205f516020615c075f395f51905f52541515604051908152f35b346104d5575f3660031901126104d557602060ff5f516020615ae75f395f51905f525416604051908152f35b346104d5575f3660031901126104d55760206040517fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af8152f35b346104d5575f3660031901126104d55760206040517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98152f35b346104d55760403660031901126104d557610558600435612e976132e5565b90612ebd610ade825f525f516020615b875f395f51905f52602052600160405f20015490565b614a70565b346104d5575f3660031901126104d55760206040517fc66b3536568140ce119bcc21a4fa7e3449a56fb5f260d32ff8e719230264132c8152f35b346104d5575f3660031901126104d557612f146145a1565b60405163462914f160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561083c575f91612f73575b602061057483856137a6565b90506020813d602011612f9e575b81612f8e6020938361340d565b810103126104d557516020612f67565b3d9150612f81565b346104d55760203660031901126104d55760206105746004355f525f516020615b875f395f51905f52602052600160405f20015490565b346104d557612feb366133d3565b6001600160a01b0383165f9081527fcbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da100602090815260408083203384529091529020549290919060018401613044575b610f9093506144ff565b82841061307457610f90936130588261359f565b60018060a01b0333165f526020528360405f209103905561303a565b8284630c95cf2760e11b5f523360045260245260445260645ffd5b346104d5575f3660031901126104d557602060ff5f516020615b075f395f51905f5254166040519015158152f35b346104d5575f3660031901126104d55760205f516020615aa75f395f51905f5254604051908152f35b346104d55760203660031901126104d5576004356001600160401b0381116104d5576131169036906004016133a3565b61311e6141a8565b5f5b81811061312957005b8061313d612b43610a35600194868861395c565b01613120565b346104d55760203660031901126104d5576020600435801515908161316e575b506040519015158152f35b905061317861417e565b101582613163565b346104d5575f3660031901126104d55760206105746137b3565b346104d55760403660031901126104d557610f906131b66132cf565b6024359033613f90565b346104d5575f3660031901126104d55761116b604051611157816131e3816136d6565b038261340d565b346104d55760203660031901126104d55760206105746132086132cf565b61366c565b346104d5575f3660031901126104d5577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040516001600160a01b039091168152602090f35b346104d55760203660031901126104d55760043563ffffffff60e01b81168091036104d557602090637965db0b60e01b811490811561329857506040519015158152f35b6301ffc9a760e01b14905082613163565b346104d5575f3660031901126104d5576020905f516020615bc75f395f51905f52548152f35b600435906001600160a01b03821682036104d557565b602435906001600160a01b03821682036104d557565b604435906001600160a01b03821682036104d557565b606435906001600160a01b03821682036104d557565b608435906001600160a01b03821682036104d557565b60a435906001600160a01b03821682036104d557565b60c435906001600160a01b03821682036104d557565b60e435906001600160a01b03821682036104d557565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b9181601f840112156104d5578235916001600160401b0383116104d5576020808501948460051b0101116104d557565b60609060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590565b90601f801991011681019081106001600160401b0382111761166657604052565b6001600160401b03811161166657601f01601f191660200190565b81601f820112156104d5576020813591016134638261342e565b92613471604051948561340d565b828452828201116104d557815f92602092838601378301015290565b60e06003198201126104d5576004356001600160a01b03811681036104d557916024356001600160a01b03811681036104d5579160443591606435916084359160a4359160c435906001600160401b0382116104d5576134ef91600401613449565b90565b6101009060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590606435906084359060a4359060c4359060e43590565b6101209060031901126104d5576004356001600160a01b03811681036104d557906024356001600160a01b03811681036104d5579060443590606435906084359060a4359060c43560ff811681036104d5579060e435906101043590565b6001600160a01b03165f9081527fcbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da1006020526040902090565b6001600160a01b03165f9081527f1d6c3b82f2027bd0b336e517c3a50a0483eb4d2c5cd82c6a491448d31b6210016020526040902090565b6001600160a01b03165f9081525f516020615ac75f395f51905f526020526040902090565b6001600160a01b03165f9081527fee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1026020526040902090565b6001600160a01b03165f9081525f516020615a675f395f51905f5260205260409020600101546001600160f01b031690565b90600182811c921680156136cc575b60208310146136b857565b634e487b7160e01b5f52602260045260245ffd5b91607f16916136ad565b5f516020615b275f395f51905f52545f92916136f18261369e565b8082529160018116908115613771575060011461370c575050565b5f516020615b275f395f51905f525f9081529293509091907f965caeb9ae9b5911a7c1cc4dd8f2483deac0bff61c9b0615befcb27d395865a85b838310613757575060209250010190565b600181602092949394548385870101520191019190613746565b9050602093945060ff929192191683830152151560051b010190565b6001600160f01b0391821690821601919082116125d557565b919082018092116125d557565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355415613935575f516020615a475f395f51905f52546001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff1661392357613843614025565b90811561391d57816134ef91613858826140fa565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36805490916001600160f01b03916138ba9190831661378d565b1661ffff60f01b8254161790556138df825f516020615bc75f395f51905f52546137a6565b5f516020615bc75f395f51905f52557fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051848152a1614123565b50505f90565b6327951b3f60e11b5f5260045260245ffd5b630188053b60e41b5f5273866a2bf4e572cbcf37d5071a7a58503bfb36be1b60045260245ffd5b919081101561396c5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036104d55790565b7f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea1005446036139e1577f103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea1015490565b6134ef614c19565b6139f1614364565b5f516020615a475f395f51905f52546001600160a01b031660ff613a148261360f565b5416613923575060405163ddeae03360e01b81523060048201526060816024815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561083c57613acd575b50613a756145a1565b8015613ac8577fd1c22369a95f91ae16576036bba6372736ba109f257ad94dccb89e141762e2656020604051838152a15f516020615a475f395f51905f52546134ef9082906001600160a01b0316614123565b505f90565b606090813d8311613af1575b613ae3818361340d565b810103126104d5575f613a6c565b503d613ad9565b90801561391d57613b0c9061275d83613f06565b801561391d57613b22613b559161242884613f06565b6001600160a01b0383165f9081525f516020615a675f395f51905f52602052604090205492613b509061366c565b6137a6565b111590565b908160209103126104d557516001600160a01b03811681036104d55790565b613b8281614eeb565b6001600160a01b03165f8181525f516020615a675f395f51905f5260205260409020549091908114613cc957815f525f516020615a675f395f51905f5260205260ff600160405f20015460f01c1615613c09575b60205f516020615b475f395f51905f5291835f525f516020615a675f395f51905f5282528060405f2055604051908152a2565b60405163313ce56760e01b8152602081600481865afa90811561083c575f91613c80575b505f516020615b475f395f51905f5291613c78602092855f525f516020615a675f395f51905f528452600160405f20019081549060ff60f01b9060f01b169060ff60f01b1916179055565b915050613bd6565b90506020813d602011613cc1575b81613c9b6020938361340d565b810103126104d5575160ff811681036104d5575f516020615b475f395f51905f52613c2d565b3d9150613c8e565b5050565b60016001600160401b03195f516020615be75f395f51905f525416175f516020615be75f395f51905f5255565b60ff613d05826135d7565b541615613d5757613d15816135d7565b805460ff191690556040514281526001600160a01b03909116907f031e2f7b58119201ea1f3c2d1070d142de895fa9e98f585672341d0973c8d00a90602090a2565b50565b919082039182116125d557565b60ff613d72826135d7565b5416613d5757613d81816135d7565b805460ff191660011790556040514281526001600160a01b03909116907f6ea640312e182de387819fbeb13be00db3171a445412852248559054871c419990602090a2565b6001600160a01b03165f9081525f516020615a675f395f51905f526020526040902054151590565b5f516020615b075f395f51905f525460ff8116613d575760019060ff1916175f516020615b075f395f51905f52557f230e80be2bd3bf5b8d0c09919cfeb448962736c4a91f7659de6819c2e5ec06eb6020604051428152a1565b9190918115908115613e9d575b8115613e8c575b5061391d57613e6e9061242883613f06565b8015159182613e7c57505090565b613e8791925061366c565b101590565b613e96915061537c565b155f613e5c565b9050613ea883613dc6565b1590613e55565b5f516020615b075f395f51905f525460ff811615613d575760ff19165f516020615b075f395f51905f52557fbcc593968355aff8c89da92575758900df3be6484058e7126f658cda71f2367f6020604051428152a1565b6001600160a01b03165f9081525f516020615a675f395f51905f52602052604090206001015460f01c60ff1690565b73866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b355415613f8c576134ef614025565b5f90565b919060ff613f9d8461360f565b54166140075760ff613fae8261360f565b54166108475760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591613fe18561359f565b6001600160a01b039182165f8181529184526040918290208690559051948552941692a3565b6327951b3f60e11b5f9081526001600160a01b038416600452602490fd5b6040516370a0823160e01b815230600482015260208160248173866a2bf4e572cbcf37d5071a7a58503bfb36be1b5afa90811561083c575f916140c8575b5073866a2bf4e572cbcf37d5071a7a58503bfb36be1b5f525f516020615a675f395f51905f526020527fa4dcc4f5451c026fa140e6c6899d665a0b5bad76247e11d800e055b801b14b36546001600160f01b03168082111561391d576134ef91613d5a565b90506020813d6020116140f2575b816140e36020938361340d565b810103126104d557515f614063565b3d91506140d6565b6001600160f01b038111614114576001600160f01b031690565b632a49c10d60e01b5f5260045ffd5b5f516020615b675f395f51905f5260205f9261414d855f516020615aa75f395f51905f52546137a6565b5f516020615aa75f395f51905f525561416581613634565b8054860190556040519485526001600160a01b031693a3565b5f516020615bc75f395f51905f52545f516020615aa75f395f51905f52548181111561391d570390565b335f9081527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea26614602052604090205460ff16156141e057565b63e2517d3f60e01b5f52336004527f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b3560245260445ffd5b335f9081527fc8c5404fa38229b37c25ed47149e73a9ea6a76c763e790fa27b00b250bb568c5602052604090205460ff161561424f57565b63e2517d3f60e01b5f52336004527fc66b3536568140ce119bcc21a4fa7e3449a56fb5f260d32ff8e719230264132c60245260445ffd5b335f9081527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d602052604090205460ff16156142be57565b63e2517d3f60e01b5f52336004527fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af60245260445ffd5b335f9081527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b602052604090205460ff161561432d57565b63e2517d3f60e01b5f52336004527f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a60245260445ffd5b335f9081527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e202452602052604090205460ff161561439c57565b63e2517d3f60e01b5f52336004527f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca60245260445ffd5b335f9081527fc726c2b4c97955c111bebcf26d23050c057419036fd6b131fd840def3e37a8b0602052604090205460ff161561440b57565b63e2517d3f60e01b5f52336004527f2a3dab589bcc9747970dd85ac3f222668741ae51f2a1bbb8f8355be28dd8a86860245260445ffd5b5f8181525f516020615b875f395f51905f526020908152604080832033845290915290205460ff16156144725750565b63e2517d3f60e01b5f523360045260245260445ffd5b6001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff1615613d5757805f525f516020615ac75f395f51905f5260205260405f2060ff1981541690557f07d647ad688e085159820c1d8d030e5765cdc5274d4ee4065c6066b388a2ef596020604051428152a2565b919061450a816153c1565b61451261560d565b60ff61451d3361360f565b541661458e5760ff61452e8461360f565b54166140075760ff61453f8261360f565b5416610847576040518281526001600160a01b0382811691908516905f516020615b675f395f51905f5290602090a38115614589578261458283614587956153e0565b615417565b565b505050565b6327951b3f60e11b5f523360045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561083c575f9161460a575b506145fd61417e565b908181111561391d570390565b90506020813d602011614634575b816146256020938361340d565b810103126104d557515f6145f4565b3d9150614618565b6001600160a01b0381165f9081527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea26614602052604090205460ff16613ac8576001600160a01b03165f8181527f86aeab049e4c9249169ebb1ad21ce4f543d20ab83b761f8465d8c9c7aea2661460205260408120805460ff191660011790553391907f109b88c1c8d528799ca6f455418979dd2a552493f14553ce44443b23f7df8b35905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b602052604090205460ff16613ac8576001600160a01b03165f8181527f75442b0a96088b5456bc4ed01394c96a4feec0f883c9494257d76b96ab1c9b6b60205260408120805460ff191660011790553391907f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d602052604090205460ff16613ac8576001600160a01b03165f8181527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d60205260408120805460ff191660011790553391905f5160206159e75f395f51905f528180a4600190565b6001600160a01b0381165f9081527f0c3ed9462fc953d240fea484f4676580de2bf475f9939ce7356d420c75b99885602052604090205460ff16613ac8576001600160a01b03165f8181527f0c3ed9462fc953d240fea484f4676580de2bf475f9939ce7356d420c75b9988560205260408120805460ff191660011790553391907f7daa70daa195905862e9fca178089de90a69f7175eb24d1b44e833ee4d44856a905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e202452602052604090205460ff16613ac8576001600160a01b03165f8181527f2d49eff8835029d75ada43915f796d809ede52fdd349d69b8dd02ff64e20245260205260408120805460ff191660011790553391907f4a5e9eb1ba56d04185ff75ebf0f4f42a3d7c88c35b4a90fa278437e0c9bdceca905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f9081527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d602052604090205460ff16613ac8576001600160a01b03165f8181527f44bd628b83c90e1ac588893312a03f9119ef166b161366b2fe43c23424d17e8d60205260408120805460ff191660011790553391907fa56d2bdf254c8533e707144802f9ebe3f93e4c7e3dbd92488f75e6c593e0c2af905f5160206159e75f395f51905f529080a4600190565b5f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b038616845290915290205460ff1661391d575f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291905f5160206159e75f395f51905f529080a4600190565b6001600160a01b0381165f8181525f516020615ac75f395f51905f5260205260409020549193929160ff1615614b9757614b34826153c1565b60018060a01b03821680825f516020615b675f395f51905f526020604051888152a3604051918483527f47cea260e2dfb95ed2ab59ad44fe2ac9cddb432afb828d2a1475936b5a2b829a60203394a48115614589578261458283614587956153e0565b63fc78247960e01b5f5260045260245ffd5b90614bb3826153c1565b8015614c0257614bcb6001600160a01b0383166157b5565b15613cc9571515906001600160a01b03167fd996de5928db1ae1098987738baabe68b0081b062d2dda6a58f1beb0c93ce3e65f80a3565b614c146001600160a01b038316615674565b614bcb565b604051614c29816131e3816136d6565b6020815191012060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a08152614ca160c08261340d565b51902090565b5f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b038616845290915290205460ff161561391d575f8181525f516020615b875f395f51905f52602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b6001600160a01b03168015614db2575f516020615a475f395f51905f52546001600160a01b0381168214613cc9576001600160a01b03191681175f516020615a475f395f51905f52557f77f12a3c9f87d4602fe59bb8d2b68c7b516e0cacba414a53e74ea75d435dc18d5f80a2565b63177f500360e21b5f5260045ffd5b6134ef916040519060208201927f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429845260018060a01b03166040830152606082015260608152614e1260808261340d565b5190206154f9565b92614e3b926001600160ff1b03821692909160ff90811c601b011690615868565b6006821015614e63576145879282614e5c57614e57925061584d565b61552c565b505061552c565b634e487b7160e01b5f52602160045260245ffd5b614e8182826155c2565b6001600160a01b03165f8181525f516020615a075f395f51905f52602090815260408083208584529091528120805460ff191660011790557f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d819080a3565b9391614e3b9391615868565b6001600160a01b031680158015614f16575b614f045750565b6337bce3c560e11b5f5260045260245ffd5b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114614efd565b908160209103126104d5575180151581036104d55790565b9390926134ef95926040519460208601967fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8885260018060a01b0316604087015260018060a01b03166060860152608085015260a084015260c083015260e0820152614e1261010082800301601f19810183528261340d565b91614fe481836159b3565b6006821015614e6357816150c657614ffd91508461584d565b925b6006841015614e635783156150c0575f9261258d61504385946040519283916020830195630b135d3f60e11b8752602484015260406044840152606483019061337f565b51915afa3d156150b9573d6150578161342e565b90615065604051928361340d565b81523d5f602083013e5b816150ab575b81615089575b50613d57576145879061552c565b90506020818051810103126104d55760200151630b135d3f60e11b145f61507b565b905060208151101590615075565b606061506f565b50505050565b5092614fff565b6001600160a01b03821696959493929190338890036150f1576145879697506152c6565b87631c5939f360e01b5f523360045260245260445ffd5b6001600160a01b03165f8181525f516020615ac75f395f51905f52602052604090205460ff16613d5757805f525f516020615ac75f395f51905f5260205260405f20600160ff198254161790557f68e0d8c112165d0949ce87205b719ed7d98c7401866c34a159f7c67c6f5620e76020604051428152a2565b93929384421161523657938461519c84846134ef9798613f90565b60018060a01b031692835f527f1b21ba3f0a2135d61c468900b54084f04af8111bce0f8bbb6ab8c46d11afbd0060205260405f20908154916001830190556040519360208501957f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98752604086015260018060a01b03166060850152608084015260a083015260c082015260c08152614e1260e08261340d565b84630f88f04960e41b5f526004524260245260445ffd5b9390926134ef95926040519460208601967f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267885260018060a01b0316604087015260018060a01b03166060860152608085015260a084015260c083015260e0820152614e1261010082800301601f19810183528261340d565b9193959490928042111561536657508542101561534f576145879495506152ed81836155c2565b6001600160a01b0382165f8181525f516020615a075f395f51905f52602090815260408083208584529091528120805460ff191660011790557f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a59080a36144ff565b856359fe699f60e11b5f524260045260245260445ffd5b6324c7fcd160e11b5f524260045260245260445ffd5b5f516020615c075f395f51905f525415908115615397575090565b6001600160a01b03165f9081525f516020615a275f395f51905f5260205260409020541515919050565b6001600160a01b0316156153d157565b63bfcf3c0b60e01b5f5260045ffd5b6153e981613634565b54908282106153f757505050565b63db42144d60e01b5f5260018060a01b031660045260245260445260645ffd5b9061542461542f92613634565b838154039055613634565b908154019055565b9060ff8091169116039060ff82116125d557565b60ff16604d81116125d557600a0a90565b60ff8116600681146154c457600610156154a25761547e600661548392615437565b61544b565b90811561548e570490565b634e487b7160e01b5f52601260045260245ffd5b61547e6154b0916006615437565b908181029181830414901517156125d55790565b505090565b60ff8116806006146154c457600611156154eb5761547e615483916006615437565b61547e60066154b092615437565b615501613994565b9060405190602082019261190160f01b84526022830152604282015260428152614ca160628261340d565b906006821015614e635781156155be5750600181146155af57600281146155a0576003811461559157600481146155825760051461557357638baa579f60e01b5f5260045ffd5b6310c74b0360e01b5f5260045ffd5b63ff551e8960e01b5f5260045ffd5b6317e97eb760e31b5f5260045ffd5b634be6321b60e01b5f5260045ffd5b638baa579f60e01b5f5260045ffd5b9050565b60018060a01b0316805f525f516020615a075f395f51905f5260205260405f20825f5260205260ff60405f2054166155f8575050565b63d309466d60e01b5f5260045260245260445ffd5b60ff5f516020615ba75f395f51905f52541661562557565b63d93c066560e01b5f5260045ffd5b60ff5f516020615be75f395f51905f525460401c161561565057565b631afcd79f60e31b5f5260045ffd5b805482101561396c575f5260205f2001905f90565b5f8181525f516020615a275f395f51905f526020526040902054801561391d575f1981018181116125d5575f516020615c075f395f51905f52545f198101919082116125d557818103615743575b5050505f516020615c075f395f51905f5254801561572f575f19016156f4815f516020615c075f395f51905f5261565f565b8154905f199060031b1b191690555f516020615c075f395f51905f52555f525f516020615a275f395f51905f526020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b61579361576061577d935f516020615c075f395f51905f5261565f565b90549060031b1c9283925f516020615c075f395f51905f5261565f565b819391549060031b91821b915f19901b19161790565b90555f525f516020615a275f395f51905f5260205260405f20555f80806156c2565b805f525f516020615a275f395f51905f5260205260405f2054155f14613ac8575f516020615c075f395f51905f5254600160401b8110156116665761581e61577d8260018594015f516020615c075f395f51905f52555f516020615c075f395f51905f5261565f565b90555f516020615c075f395f51905f5254905f525f516020615a275f395f51905f5260205260405f2055600190565b6001600160a01b03908116911603615863575f90565b600590565b907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084116158fd5760ff1690601b821415806158f2575b6158e7576020935f93608093604051938452868401526040830152606082015282805260015afa1561083c575f516001600160a01b0316806158e357506001905f90565b5f91565b505050506004905f90565b50601c82141561589f565b505050506003905f90565b60ff5f516020615b075f395f51905f52541680615947575b6159275750565b636a95c69760e11b5f9081526001600160a01b0391909116600452602490fd5b5060ff615953826135d7565b541615615920565b905f602091828151910182855af11561083c575f513d6159aa57506001600160a01b0381163b155b61598a5750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b60011415615983565b9060418151036159dd576159d991602082015190606060408401519301515f1a90615868565b9091565b50506002905f9056fe2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d1116a1d33aa5fb91b2652b3b0fdb63704173742d6dbecaf4256ebe33a48886004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b03ee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1014717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b00cbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da102ee2f6fc7e2e5879b17985791e0d12536cba689bda43c77b8911497248f4af1002fd5767309dce890c526ace85d7fe164825199d7dcd99c33588befc51b32ce00cbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da1011d6c3b82f2027bd0b336e517c3a50a0483eb4d2c5cd82c6a491448d31b621000103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea10270b5c8a095bb680742b58d79cdc18b0477268ac25a3a49141caf92ee01af5247ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b01f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a004717d46f2e033163981fa31651301a35281b6b08316965d315fd1577bad94b02a26469706673582212201c4acef41f12016d13251ba4b2fbc1a635420faea1acb628ed48403239ca974c64736f6c63430008220033f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc4173","name":"USDat","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\n/**\n * @title  ERC20 Token Standard.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-20: https://eips.ethereum.org/EIPS/eip-20\n */\ninterface IERC20 {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when `spender` has been approved for `amount` of the token balance of `account`.\n     * @param  account The address of the account.\n     * @param  spender The address of the spender being approved for the allowance.\n     * @param  amount  The amount of the allowance being approved.\n     */\n    event Approval(address indexed account, address indexed spender, uint256 amount);\n\n    /**\n     * @notice Emitted when `amount` tokens is transferred from `sender` to `recipient`.\n     * @param  sender    The address of the sender who's token balance is decremented.\n     * @param  recipient The address of the recipient who's token balance is incremented.\n     * @param  amount    The amount of tokens being transferred.\n     */\n    event Transfer(address indexed sender, address indexed recipient, uint256 amount);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Allows a calling account to approve `spender` to spend up to `amount` of its token balance.\n     * @dev    MUST emit an `Approval` event.\n     * @param  spender The address of the account being allowed to spend up to the allowed amount.\n     * @param  amount  The amount of the allowance being approved.\n     * @return Whether or not the approval was successful.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @notice Allows a calling account to transfer `amount` tokens to `recipient`.\n     * @param  recipient The address of the recipient who's token balance will be incremented.\n     * @param  amount    The amount of tokens being transferred.\n     * @return Whether or not the transfer was successful.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @notice Allows a calling account to transfer `amount` tokens from `sender`, with allowance, to a `recipient`.\n     * @param  sender    The address of the sender who's token balance will be decremented.\n     * @param  recipient The address of the recipient who's token balance will be incremented.\n     * @param  amount    The amount of tokens being transferred.\n     * @return Whether or not the transfer was successful.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the allowance `spender` is allowed to spend on behalf of `account`.\n     * @param  account The address of the account who's token balance `spender` is allowed to spend.\n     * @param  spender The address of an account allowed to spend on behalf of `account`.\n     * @return The amount `spender` can spend on behalf of `account`.\n     */\n    function allowance(address account, address spender) external view returns (uint256);\n\n    /**\n     * @notice Returns the token balance of `account`.\n     * @param  account The address of some account.\n     * @return The token balance of `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /// @notice Returns the number of decimals UIs should assume all amounts have.\n    function decimals() external view returns (uint8);\n\n    /// @notice Returns the name of the contract/token.\n    function name() external view returns (string memory);\n\n    /// @notice Returns the symbol of the token.\n    function symbol() external view returns (string memory);\n\n    /// @notice Returns the current total supply of the token.\n    function totalSupply() external view returns (uint256);\n}\n"},{"file_path":"lib/PYUSDX/src/platform/interfaces/IExtensionBeacon.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\n/// @title  PYUSDX Extension Beacon interface.\n/// @notice Defines the interface for the extension implementation registry.\n///         Each beacon serves a single extension type (YieldToOne or MultiMint)\n///         and is fully ERC-1967 compliant.\n/// @author M0 Labs\ninterface IExtensionBeacon {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when a new implementation is registered.\n    /// @param  version        The version number assigned to the implementation.\n    /// @param  implementation The address of the registered implementation.\n    event ImplementationRegistered(uint256 indexed version, address indexed implementation);\n\n    /* ============ Errors ============ */\n\n    /// @notice Thrown if the implementation address is 0x0.\n    error ZeroImplementation();\n\n    /// @notice Thrown if PYUSDX is 0x0.\n    error ZeroPYUSDX();\n\n    /// @notice Thrown if swap facility is 0x0.\n    error ZeroSwapFacility();\n\n    /// @notice Thrown if the admin address is 0x0.\n    error ZeroAdmin();\n\n    /// @notice Thrown if the beacon manager address is 0x0.\n    error ZeroBeaconManager();\n\n    /// @notice Thrown if PYUSDX address does not match the one in SwapFacility.\n    error PYUSDXMismatch();\n\n    /// @notice Thrown if the extension address is invalid (e.g. wrong pyusdx/swapFacility wiring or not a contract).\n    error InvalidExtension();\n\n    /// @notice Thrown when querying an implementation for a version with no registration.\n    error NoImplementationRegistered();\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Registers a new implementation.\n    /// @dev    MUST only be callable by an address with the `BEACON_MANAGER_ROLE` role.\n    ///         Validates the implementation wiring and auto-increments the version.\n    /// @param  implementation The address of the implementation contract.\n    /// @return version        The version number assigned to the implementation.\n    function registerImplementation(address implementation) external returns (uint256 version);\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role identifier for the beacon manager role.\n    function BEACON_MANAGER_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the latest registered implementation (ERC-1967 standard zero-arg form).\n    /// @return The address of the latest implementation.\n    function implementation() external view returns (address);\n\n    /// @notice Returns the implementation for a specific version.\n    /// @param  version The version number.\n    /// @return The address of the implementation at the specified version.\n    function implementation(uint256 version) external view returns (address);\n\n    /// @notice Returns the latest version number.\n    /// @dev    Version numbering starts at 1 (the first registered implementation is version 1).\n    /// @return The latest version number.\n    function latestVersion() external view returns (uint256);\n\n    /// @notice The address of the PYUSDX token contract.\n    function pyusdx() external view returns (address);\n\n    /// @notice The address of the SwapFacility contract.\n    function swapFacility() external view returns (address);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IStatefulERC712.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IERC712Extended } from \"./IERC712Extended.sol\";\n\n/**\n * @title  Stateful Extension for EIP-712 typed structured data hashing and signing with nonces.\n * @author M^0 Labs\n */\ninterface IStatefulERC712 is IERC712Extended {\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Revert message when a signing account's nonce is not the expected current nonce.\n     * @param  nonce         The nonce used in the signature.\n     * @param  expectedNonce The expected nonce to be used in a signature by the signing account.\n     */\n    error InvalidAccountNonce(uint256 nonce, uint256 expectedNonce);\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the next nonce to be used in a signature by `account`.\n     * @param  account The address of some account.\n     * @return nonce   The next nonce to be used in a signature by `account`.\n     */\n    function nonces(address account) external view returns (uint256 nonce);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.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` from `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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/libs/SignatureChecker.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IERC1271 } from \"../interfaces/IERC1271.sol\";\n\n/**\n * @title  A library to handle ECDSA/secp256k1 and ERC1271 signatures, individually or in arbitrarily in combination.\n * @author M^0 Labs\n */\nlibrary SignatureChecker {\n    /* ============ Enums ============ */\n\n    /**\n     * @notice An enum representing the possible errors that can be emitted during signature validation.\n     * @param  NoError                No error occurred during signature validation.\n     * @param  InvalidSignature       The signature is invalid.\n     * @param  InvalidSignatureLength The signature length is invalid.\n     * @param  InvalidSignatureS      The signature parameter S is invalid.\n     * @param  InvalidSignatureV      The signature parameter V is invalid.\n     * @param  SignerMismatch         The signer does not match the recovered signer.\n     */\n    enum Error {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV,\n        SignerMismatch\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns whether a signature is valid (ECDSA/secp256k1 or ERC1271) for a signer and digest.\n     * @dev    Signatures must not be used as unique identifiers since the `ecrecover` EVM opcode\n     *         allows for malleable (non-unique) signatures.\n     *         See https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories/GHSA-4h98-2769-gh6h\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array signature.\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidSignature(address signer, bytes32 digest, bytes memory signature) internal view returns (bool) {\n        return isValidECDSASignature(signer, digest, signature) || isValidERC1271Signature(signer, digest, signature);\n    }\n\n    /**\n     * @dev    Returns whether an ERC1271 signature is valid for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ERC1271 signature.\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidERC1271Signature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (bool success_, bytes memory result_) = signer.staticcall(\n            abi.encodeCall(IERC1271.isValidSignature, (digest, signature))\n        );\n\n        return\n            success_ &&\n            result_.length >= 32 &&\n            abi.decode(result_, (bytes32)) == bytes32(IERC1271.isValidSignature.selector);\n    }\n\n    /**\n     * @dev    Decodes an ECDSA/secp256k1 signature from a byte array to standard v, r, and s parameters.\n     * @param  signature A byte array ECDSA/secp256k1 signature.\n     * @return v         An ECDSA/secp256k1 signature parameter.\n     * @return r         An ECDSA/secp256k1 signature parameter.\n     * @return s         An ECDSA/secp256k1 signature parameter.\n     */\n    function decodeECDSASignature(bytes memory signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {\n        // ecrecover takes the signature parameters, and they can be decoded using 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    }\n\n    /**\n     * @dev    Decodes an ECDSA/secp256k1 short signature as defined by EIP2098\n     *         from a byte array to standard v, r, and s parameters.\n     * @param  signature A byte array ECDSA/secp256k1 short signature.\n     * @return r         An ECDSA/secp256k1 signature parameter.\n     * @return vs        An ECDSA/secp256k1 short signature parameter.\n     */\n    function decodeShortECDSASignature(bytes memory signature) internal pure returns (bytes32 r, bytes32 vs) {\n        // ecrecover takes the signature parameters, and they can be decoded using assembly.\n        /// @solidity memory-safe-assembly\n        assembly {\n            r := mload(add(signature, 0x20))\n            vs := mload(add(signature, 0x40))\n        }\n    }\n\n    /**\n     * @dev    Returns whether an ECDSA/secp256k1 signature is valid for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     * @return           Whether the signature is valid or not.\n     */\n    function isValidECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal pure returns (bool) {\n        if (signature.length == 64) {\n            (bytes32 r, bytes32 vs) = decodeShortECDSASignature(signature);\n            return isValidECDSASignature(signer, digest, r, vs);\n        }\n\n        return validateECDSASignature(signer, digest, signature) == Error.NoError;\n    }\n\n    /**\n     * @dev    Returns whether an ECDSA/secp256k1 short signature is valid for a signer and digest.\n     * @param  signer The address of the account purported to have signed.\n     * @param  digest The hash of the data that was signed.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  vs     An ECDSA/secp256k1 short signature parameter.\n     * @return        Whether the signature is valid or not.\n     */\n    function isValidECDSASignature(address signer, bytes32 digest, bytes32 r, bytes32 vs) internal pure returns (bool) {\n        return validateECDSASignature(signer, digest, r, vs) == Error.NoError;\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 signature for some digest.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ECDSA/secp256k1 signature.\n     * @return           An error, if any, that occurred during the signer recovery.\n     * @return           The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(bytes32 digest, bytes memory signature) internal pure returns (Error, address) {\n        if (signature.length != 65) return (Error.InvalidSignatureLength, address(0));\n\n        (uint8 v, bytes32 r, bytes32 s) = decodeECDSASignature(signature);\n\n        return recoverECDSASigner(digest, v, r, s);\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 short signature for some digest.\n     * @dev    See https://eips.ethereum.org/EIPS/eip-2098\n     * @param  digest The hash of the data that was signed.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  vs     An ECDSA/secp256k1 short signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     * @return        The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(bytes32 digest, bytes32 r, bytes32 vs) internal pure returns (Error, address) {\n        unchecked {\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            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            return recoverECDSASigner(digest, v, r, s);\n        }\n    }\n\n    /**\n     * @dev    Returns the signer of an ECDSA/secp256k1 signature for some digest.\n     * @param  digest The hash of the data that was signed.\n     * @param  v      An ECDSA/secp256k1 signature parameter.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  s      An ECDSA/secp256k1 signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     * @return signer The address of the account recovered form the signature (0 if error).\n     */\n    function recoverECDSASigner(\n        bytes32 digest,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (Error, address signer) {\n        // 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}.\n        if (uint256(s) > uint256(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0))\n            return (Error.InvalidSignatureS, address(0));\n\n        if (v != 27 && v != 28) return (Error.InvalidSignatureV, address(0));\n\n        signer = ecrecover(digest, v, r, s);\n\n        return (signer == address(0)) ? (Error.InvalidSignature, address(0)) : (Error.NoError, signer);\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 signature for a signer and digest.\n     * @param  signer    The address of the account purported to have signed.\n     * @param  digest    The hash of the data that was signed.\n     * @param  signature A byte array ERC1271 signature.\n     * @return           An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes memory signature\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, signature);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 short signature for a signer and digest.\n     * @param  signer The address of the account purported to have signed.\n     * @param  digest The hash of the data that was signed.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  vs     An ECDSA/secp256k1 short signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, r, vs);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error, if any, in validating an ECDSA/secp256k1 signature for a signer and digest.\n     * @param  signer The address of the account purported to have signed.\n     * @param  digest The hash of the data that was signed.\n     * @param  v      An ECDSA/secp256k1 signature parameter.\n     * @param  r      An ECDSA/secp256k1 signature parameter.\n     * @param  s      An ECDSA/secp256k1 signature parameter.\n     * @return        An error, if any, that occurred during the signer recovery.\n     */\n    function validateECDSASignature(\n        address signer,\n        bytes32 digest,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (Error) {\n        (Error recoverError, address recoveredSigner) = recoverECDSASigner(digest, v, r, s);\n\n        return (recoverError == Error.NoError) ? validateRecoveredSigner(signer, recoveredSigner) : recoverError;\n    }\n\n    /**\n     * @dev    Returns an error if `signer` is not `recoveredSigner`.\n     * @param  signer          The address of the some signer.\n     * @param  recoveredSigner The address of the some recoveredSigner.\n     * @return                 An error if `signer` is not `recoveredSigner`.\n     */\n    function validateRecoveredSigner(address signer, address recoveredSigner) internal pure returns (Error) {\n        return (signer == recoveredSigner) ? Error.NoError : Error.SignerMismatch;\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Comparators.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides a set of functions to compare values.\n *\n * _Available since v5.1._\n */\nlibrary Comparators {\n    function lt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a < b;\n    }\n\n    function gt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a > b;\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/freezable/Freezable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\nimport { AccessControlUpgradeable } from \"../../../lib/common/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol\";\n\nimport { IFreezable } from \"./IFreezable.sol\";\n\nabstract contract FreezableStorageLayout {\n    /// @custom:storage-location erc7201:M0.storage.Freezable\n    struct FreezableStorageStruct {\n        mapping(address account => bool isFrozen) isFrozen;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.Freezable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _FREEZABLE_STORAGE_LOCATION =\n        0x2fd5767309dce890c526ace85d7fe164825199d7dcd99c33588befc51b32ce00;\n\n    function _getFreezableStorageLocation() internal pure returns (FreezableStorageStruct storage $) {\n        assembly {\n            $.slot := _FREEZABLE_STORAGE_LOCATION\n        }\n    }\n}\n\n/**\n * @title Freezable\n * @notice Upgradeable contract that allows for the freezing of accounts.\n * @dev This contract is used to prevent certain accounts from interacting with the contract.\n * @author M0 Labs\n */\nabstract contract Freezable is IFreezable, FreezableStorageLayout, AccessControlUpgradeable {\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IFreezable\n    bytes32 public constant FREEZE_MANAGER_ROLE = keccak256(\"FREEZE_MANAGER_ROLE\");\n\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the contract with the given freeze manager.\n     * @param freezeManager The address of a freeze manager.\n     */\n    function __Freezable_init(address freezeManager) internal onlyInitializing {\n        if (freezeManager == address(0)) revert ZeroFreezeManager();\n        _grantRole(FREEZE_MANAGER_ROLE, freezeManager);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IFreezable\n    function freeze(address account) external virtual onlyRole(FREEZE_MANAGER_ROLE) {\n        _freeze(_getFreezableStorageLocation(), account);\n    }\n\n    /// @inheritdoc IFreezable\n    function freezeAccounts(address[] calldata accounts) external virtual onlyRole(FREEZE_MANAGER_ROLE) {\n        FreezableStorageStruct storage $ = _getFreezableStorageLocation();\n        for (uint256 i; i < accounts.length; ++i) {\n            _freeze($, accounts[i]);\n        }\n    }\n\n    /// @inheritdoc IFreezable\n    function unfreeze(address account) external onlyRole(FREEZE_MANAGER_ROLE) {\n        _unfreeze(_getFreezableStorageLocation(), account);\n    }\n\n    /// @inheritdoc IFreezable\n    function unfreezeAccounts(address[] calldata accounts) external onlyRole(FREEZE_MANAGER_ROLE) {\n        FreezableStorageStruct storage $ = _getFreezableStorageLocation();\n\n        for (uint256 i; i < accounts.length; ++i) {\n            _unfreeze($, accounts[i]);\n        }\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IFreezable\n    function isFrozen(address account) public view returns (bool) {\n        return _getFreezableStorageLocation().isFrozen[account];\n    }\n\n    /* ============ Hooks For Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Hook called before freezing an account.\n     * @param account   The account to be frozen.\n     */\n    function _beforeFreeze(address account) internal virtual {}\n\n    /**\n     * @dev    Hook called before unfreezing an account.\n     * @param  account   The account to be unfrozen.\n     */\n    function _beforeUnfreeze(address account) internal virtual {}\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @notice Internal function that freezes an account.\n     * @param $ The storage location of the freezable contract.\n     * @param account The account to freeze.\n     */\n    function _freeze(FreezableStorageStruct storage $, address account) internal {\n        // Return early if the account is already frozen\n        if ($.isFrozen[account]) return;\n\n        _beforeFreeze(account);\n\n        $.isFrozen[account] = true;\n\n        emit Frozen(account, block.timestamp);\n    }\n\n    /**\n     * @notice Internal function that unfreezes an account.\n     * @param $ The storage location of the freezable contract.\n     * @param account The account to unfreeze.\n     */\n    function _unfreeze(FreezableStorageStruct storage $, address account) internal {\n        // Return early if the account is not frozen\n        if (!$.isFrozen[account]) return;\n\n        _beforeUnfreeze(account);\n\n        $.isFrozen[account] = false;\n\n        emit Unfrozen(account, block.timestamp);\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @notice Internal function that reverts if an account is frozen.\n     * @dev Called by inheriting contracts to check if an account is frozen.\n     * @param $ The storage location of the freezable contract.\n     * @param account The account to check.\n     */\n    function _revertIfFrozen(FreezableStorageStruct storage $, address account) internal view {\n        if ($.isFrozen[account]) revert AccountFrozen(account);\n    }\n\n    /**\n     * @notice Internal function that reverts if an account is frozen.\n     * @dev Called by inheriting contracts to check if an account is frozen.\n     * @param account The account to check.\n     */\n    function _revertIfFrozen(address account) internal view {\n        if (_getFreezableStorageLocation().isFrozen[account]) revert AccountFrozen(account);\n    }\n\n    /**\n     * @notice Internal function that reverts if an account is not frozen.\n     * @dev Called by inheriting contracts to check if an account is not frozen.\n     * @param $ The storage location of the freezable contract.\n     * @param account The account to check.\n     */\n    function _revertIfNotFrozen(FreezableStorageStruct storage $, address account) internal view {\n        if (!$.isFrozen[account]) revert AccountNotFrozen(account);\n    }\n\n    /**\n     * @notice Internal function that reverts if an account is not frozen.\n     * @dev Called by inheriting contracts to check if an account is not frozen.\n     * @param account The account to check.\n     */\n    function _revertIfNotFrozen(address account) internal view {\n        if (!_getFreezableStorageLocation().isFrozen[account]) revert AccountNotFrozen(account);\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.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 reinitialization) 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 Pointer to storage slot. Allows integrators to override it with a custom storage location.\n     *\n     * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n     */\n    function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n        return INITIALIZABLE_STORAGE;\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        bytes32 slot = _initializableStorageSlot();\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Arrays.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Arrays.sol)\n// This file was procedurally generated from scripts/generate/templates/Arrays.js.\n\npragma solidity ^0.8.20;\n\nimport {Comparators} from \"./Comparators.sol\";\nimport {SlotDerivation} from \"./SlotDerivation.sol\";\nimport {StorageSlot} from \"./StorageSlot.sol\";\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n    using SlotDerivation for bytes32;\n    using StorageSlot for bytes32;\n\n    /**\n     * @dev Sort an array of uint256 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        uint256[] memory array,\n        function(uint256, uint256) pure returns (bool) comp\n    ) internal pure returns (uint256[] memory) {\n        _quickSort(_begin(array), _end(array), comp);\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.\n     */\n    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {\n        sort(array, Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of address (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        address[] memory array,\n        function(address, address) pure returns (bool) comp\n    ) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of address in increasing order.\n     */\n    function sort(address[] memory array) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        bytes32[] memory array,\n        function(bytes32, bytes32) pure returns (bool) comp\n    ) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.\n     */\n    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops\n     * at end (exclusive). Sorting follows the `comp` comparator.\n     *\n     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.\n     *\n     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should\n     * be used only if the limits are within a memory array.\n     */\n    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {\n        unchecked {\n            if (end - begin < 0x40) return;\n\n            // Use first element as pivot\n            uint256 pivot = _mload(begin);\n            // Position where the pivot should be at the end of the loop\n            uint256 pos = begin;\n\n            for (uint256 it = begin + 0x20; it < end; it += 0x20) {\n                if (comp(_mload(it), pivot)) {\n                    // If the value stored at the iterator's position comes before the pivot, we increment the\n                    // position of the pivot and move the value there.\n                    pos += 0x20;\n                    _swap(pos, it);\n                }\n            }\n\n            _swap(begin, pos); // Swap pivot into place\n            _quickSort(begin, pos, comp); // Sort the left side of the pivot\n            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first element of `array`.\n     */\n    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {\n        assembly (\"memory-safe\") {\n            ptr := add(array, 0x20)\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word\n     * that comes just after the last element of the array.\n     */\n    function _end(uint256[] memory array) private pure returns (uint256 ptr) {\n        unchecked {\n            return _begin(array) + array.length * 0x20;\n        }\n    }\n\n    /**\n     * @dev Load memory word (as a uint256) at location `ptr`.\n     */\n    function _mload(uint256 ptr) private pure returns (uint256 value) {\n        assembly {\n            value := mload(ptr)\n        }\n    }\n\n    /**\n     * @dev Swaps the elements memory location `ptr1` and `ptr2`.\n     */\n    function _swap(uint256 ptr1, uint256 ptr2) private pure {\n        assembly {\n            let value1 := mload(ptr1)\n            let value2 := mload(ptr2)\n            mstore(ptr1, value2)\n            mstore(ptr2, value1)\n        }\n    }\n\n    /// @dev Helper: low level cast address memory array to uint256 memory array\n    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array\n    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast address comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(address, address) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(bytes32, bytes32) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /**\n     * @dev Searches a sorted `array` and returns the first index that contains\n     * a value greater or equal to `element`. If no such index exists (i.e. all\n     * values in the array are strictly less than `element`), the array length is\n     * returned. Time complexity O(log n).\n     *\n     * NOTE: The `array` is expected to be sorted in ascending order, and to\n     * contain no repeated elements.\n     *\n     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks\n     * support for repeated elements in the array. The {lowerBound} function should\n     * be used instead.\n     */\n    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n        if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n            return low - 1;\n        } else {\n            return low;\n        }\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value greater or equal than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].\n     */\n    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value strictly greater than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].\n     */\n    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {lowerBound}, but with an array in memory.\n     */\n    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {upperBound}, but with an array in memory.\n     */\n    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getAddressSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytes32Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getUint256Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(address[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(uint256[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.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 ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\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 *\n * TIP: Consider using this library along with {SlotDerivation}.\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 Int256Slot {\n        int256 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        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.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 ERC-20 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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/ERC712ExtendedUpgradeable.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { Initializable } from \"../lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\";\n\nimport { IERC712 } from \"./interfaces/IERC712.sol\";\nimport { IERC712Extended } from \"./interfaces/IERC712Extended.sol\";\n\nimport { SignatureChecker } from \"./libs/SignatureChecker.sol\";\n\nabstract contract ERC712ExtendedUpgradeableStorageLayout {\n    /// @custom:storage-location erc7201:M0.storage.ERC712Extended\n    struct ERC712ExtendedStorageStruct {\n        uint256 initialChainId;\n        bytes32 initialDomainSeparator;\n        string name;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.ERC712Extended\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _ERC712_EXTENDED_STORAGE_LOCATION =\n        0x103ce0bed7138196cdb0d79ef04042681b16e7a2c58d74b78443c813042ea100;\n\n    function _getERC712ExtendedStorageLocation() internal pure returns (ERC712ExtendedStorageStruct storage $) {\n        assembly {\n            $.slot := _ERC712_EXTENDED_STORAGE_LOCATION\n        }\n    }\n}\n\n/**\n * @title  Typed structured data hashing and signing via EIP-712, extended by EIP-5267.\n * @author M0 Labs\n * @dev    An abstract implementation to satisfy EIP-712: https://eips.ethereum.org/EIPS/eip-712\n */\nabstract contract ERC712ExtendedUpgradeable is ERC712ExtendedUpgradeableStorageLayout, IERC712Extended, Initializable {\n    /* ============ Variables ============ */\n\n    /// @dev keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")\n    bytes32 internal constant _EIP712_DOMAIN_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev keccak256(\"1\")\n    bytes32 internal constant _EIP712_VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;\n\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the ERC712ExtendedUpgradeable contract.\n     * @param  name_ The name of the contract.\n     */\n    function __ERC712ExtendedUpgradeable_init(string memory name_) internal onlyInitializing {\n        ERC712ExtendedStorageStruct storage $ = _getERC712ExtendedStorageLocation();\n\n        $.name = name_;\n        $.initialChainId = block.chainid;\n        $.initialDomainSeparator = _getDomainSeparator();\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC712Extended\n    function eip712Domain()\n        external\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        return (\n            hex\"0f\", // 01111\n            _getERC712ExtendedStorageLocation().name,\n            \"1\",\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /// @inheritdoc IERC712\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        ERC712ExtendedStorageStruct storage $ = _getERC712ExtendedStorageLocation();\n        return block.chainid == $.initialChainId ? $.initialDomainSeparator : _getDomainSeparator();\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Computes the EIP-712 domain separator.\n     * @return The EIP-712 domain separator.\n     */\n    function _getDomainSeparator() internal view returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    _EIP712_DOMAIN_HASH,\n                    keccak256(bytes(_getERC712ExtendedStorageLocation().name)),\n                    _EIP712_VERSION_HASH,\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).\n     * @param  internalDigest_ The internal digest.\n     * @return The digest to be signed.\n     */\n    function _getDigest(bytes32 internalDigest_) internal view returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", DOMAIN_SEPARATOR(), internalDigest_));\n    }\n\n    /**\n     * @dev   Revert if the signature is expired.\n     * @param expiry_ Timestamp at which the signature expires or max uint256 for no expiry.\n     */\n    function _revertIfExpired(uint256 expiry_) internal view {\n        if (block.timestamp > expiry_) revert SignatureExpired(expiry_, block.timestamp);\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @dev   We first validate if the signature is a valid ECDSA signature and return early if it is the case.\n     *        Then, we validate if it is a valid ERC-1271 signature, and return early if it is the case.\n     *        If not, we revert with the error from the ECDSA signature validation.\n     * @param signer_    The signer of the signature.\n     * @param digest_    The digest that was signed.\n     * @param signature_ The signature.\n     */\n    function _revertIfInvalidSignature(address signer_, bytes32 digest_, bytes memory signature_) internal view {\n        SignatureChecker.Error error_ = SignatureChecker.validateECDSASignature(signer_, digest_, signature_);\n\n        if (error_ == SignatureChecker.Error.NoError) return;\n\n        if (SignatureChecker.isValidERC1271Signature(signer_, digest_, signature_)) return;\n\n        _revertIfError(error_);\n    }\n\n    /**\n     * @dev    Returns the signer of a signed digest, via EIP-712, and reverts if the signature is invalid.\n     * @param  digest_ The digest that was signed.\n     * @param  v_      v of the signature.\n     * @param  r_      r of the signature.\n     * @param  s_      s of the signature.\n     * @return signer_ The signer of the digest.\n     */\n    function _getSignerAndRevertIfInvalidSignature(\n        bytes32 digest_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) internal pure returns (address signer_) {\n        SignatureChecker.Error error_;\n\n        (error_, signer_) = SignatureChecker.recoverECDSASigner(digest_, v_, r_, s_);\n\n        _revertIfError(error_);\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @param signer_ The signer of the signature.\n     * @param digest_ The digest that was signed.\n     * @param r_      An ECDSA/secp256k1 signature parameter.\n     * @param vs_     An ECDSA/secp256k1 short signature parameter.\n     */\n    function _revertIfInvalidSignature(address signer_, bytes32 digest_, bytes32 r_, bytes32 vs_) internal pure {\n        _revertIfError(SignatureChecker.validateECDSASignature(signer_, digest_, r_, vs_));\n    }\n\n    /**\n     * @dev   Revert if the signature is invalid.\n     * @param signer_ The signer of the signature.\n     * @param digest_ The digest that was signed.\n     * @param v_      v of the signature.\n     * @param r_      r of the signature.\n     * @param s_      s of the signature.\n     */\n    function _revertIfInvalidSignature(\n        address signer_,\n        bytes32 digest_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) internal pure {\n        _revertIfError(SignatureChecker.validateECDSASignature(signer_, digest_, v_, r_, s_));\n    }\n\n    /**\n     * @dev   Revert if error.\n     * @param error_ The SignatureChecker Error enum.\n     */\n    function _revertIfError(SignatureChecker.Error error_) private pure {\n        if (error_ == SignatureChecker.Error.NoError) return;\n        if (error_ == SignatureChecker.Error.InvalidSignature) revert InvalidSignature();\n        if (error_ == SignatureChecker.Error.InvalidSignatureLength) revert InvalidSignatureLength();\n        if (error_ == SignatureChecker.Error.InvalidSignatureS) revert InvalidSignatureS();\n        if (error_ == SignatureChecker.Error.InvalidSignatureV) revert InvalidSignatureV();\n        if (error_ == SignatureChecker.Error.SignerMismatch) revert SignerMismatch();\n\n        revert InvalidSignature();\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 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 to signal 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. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.20;\n\nimport {Arrays} from \"../Arrays.sol\";\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n * - Set can be cleared (all elements removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function _clear(Set storage set) private {\n        uint256 len = _length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/StatefulERC712Upgradeable.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IStatefulERC712 } from \"./interfaces/IStatefulERC712.sol\";\n\nimport { ERC712ExtendedUpgradeable } from \"./ERC712ExtendedUpgradeable.sol\";\n\nabstract contract StatefulERC712ExtendedUpgradeableStorageLayout {\n    /// @custom:storage-location erc7201:M0.storage.StatefulERC712Extended\n    struct StatefulERC712ExtendedStorageStruct {\n        mapping(address account => uint256 nonce) nonces; // Nonces for all signatures.\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.StatefulERC712Extended\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _STATEFUL_ERC712_EXTENDED_STORAGE_LOCATION =\n        0x1b21ba3f0a2135d61c468900b54084f04af8111bce0f8bbb6ab8c46d11afbd00;\n\n    function _getStatefulERC712ExtendedStorageLocation()\n        internal\n        pure\n        returns (StatefulERC712ExtendedStorageStruct storage $)\n    {\n        assembly {\n            $.slot := _STATEFUL_ERC712_EXTENDED_STORAGE_LOCATION\n        }\n    }\n}\n\n/**\n * @title  Stateful and upgradeable extension for EIP-712 typed structured data hashing and signing with nonces.\n * @author M0 Labs\n * @dev    An abstract implementation to satisfy stateful EIP-712 with nonces.\n */\nabstract contract StatefulERC712Upgradeable is\n    StatefulERC712ExtendedUpgradeableStorageLayout,\n    IStatefulERC712,\n    ERC712ExtendedUpgradeable\n{\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the StatefulERC712Upgradeable contract.\n     * @param  name The name of the contract.\n     */\n    function __StatefulERC712ExtendedUpgradeable_init(string memory name) internal onlyInitializing {\n        __ERC712ExtendedUpgradeable_init(name);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IStatefulERC712\n    function nonces(address account) external view returns (uint256) {\n        return _getStatefulERC712ExtendedStorageLocation().nonces[account];\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/platform/Extension.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\nimport { ERC20ExtendedUpgradeable } from \"../../lib/evm-m-extensions/lib/common/src/ERC20ExtendedUpgradeable.sol\";\n\nimport { IERC20 } from \"../../lib/evm-m-extensions/lib/common/src/interfaces/IERC20.sol\";\nimport { StorageSlot } from \"../../lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol\";\n\nimport { Freezable } from \"../../lib/evm-m-extensions/src/components/freezable/Freezable.sol\";\nimport { Pausable } from \"../../lib/evm-m-extensions/src/components/pausable/Pausable.sol\";\n\nimport { IERC1967 } from \"../../lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol\";\n\nimport { IExtension } from \"./interfaces/IExtension.sol\";\nimport { IExtensionBeacon } from \"./interfaces/IExtensionBeacon.sol\";\nimport { ISwapFacility } from \"../swap/interfaces/ISwapFacility.sol\";\n\n/// @title  Extension\n/// @notice Upgradeable ERC20 base contract for wrapping PYUSDX into a branded extension token.\n/// @author M0 Labs\nabstract contract Extension is IExtension, ERC20ExtendedUpgradeable, Freezable, Pausable {\n    /* ============ Constants ============ */\n\n    /// @dev ERC-1967 beacon storage slot (shared with ExtensionBeaconProxy).\n    ///      bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1)\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /// @dev ERC-1967 implementation storage slot (used for pinned mode, shared with ExtensionBeaconProxy).\n    ///      bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1)\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /// @dev Storage location for the origin beacon address (shared with ExtensionBeaconProxy).\n    ///      keccak256(abi.encode(uint256(keccak256(\"M0.storage.PYUSDXOriginBeacon\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 internal constant _ORIGIN_BEACON_SLOT = 0x0db096ce50da19b63b97b47df5b0c87e2ed1677b3d801ad424e1bbfc0bb0c300;\n\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IExtension\n    bytes32 public constant VERSION_MANAGER_ROLE = keccak256(\"VERSION_MANAGER_ROLE\");\n\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    /// @inheritdoc IExtension\n    address public immutable pyusdx;\n\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    /// @inheritdoc IExtension\n    address public immutable swapFacility;\n\n    /* ============ Modifiers ============ */\n\n    modifier onlySwapFacility() {\n        if (msg.sender != swapFacility) revert NotSwapFacility();\n        _;\n    }\n\n    /* ============ Constructor ============ */\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    /// @notice Constructs Extension Implementation contract.\n    /// @dev    Sets immutable storage.\n    /// @param  pyusdx_       The address of the PYUSDX token.\n    /// @param  swapFacility_ The address of the swap facility.\n    constructor(address pyusdx_, address swapFacility_) {\n        if ((pyusdx = pyusdx_) == address(0)) revert ZeroPYUSDX();\n        if ((swapFacility = swapFacility_) == address(0)) revert ZeroSwapFacility();\n\n        _disableInitializers();\n    }\n\n    /* ============ Initializer ============ */\n\n    /// @notice Initializes the generic PYUSDX extension token.\n    /// @param  name           The name of the token.\n    /// @param  symbol         The symbol of the token.\n    /// @param  freezeManager  The address of the freeze manager.\n    /// @param  pauser         The address of the pauser.\n    function __Extension_init(\n        string memory name,\n        string memory symbol,\n        address freezeManager,\n        address pauser\n    ) internal onlyInitializing {\n        __ERC20ExtendedUpgradeable_init(name, symbol, 6);\n        __Freezable_init(freezeManager);\n        __Pausable_init(pauser);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IExtension\n    function wrap(address recipient, uint256 amount) external onlySwapFacility {\n        _wrap(ISwapFacility(msg.sender).msgSender(), recipient, amount);\n    }\n\n    /// @inheritdoc IExtension\n    function unwrap(uint256 amount) external onlySwapFacility {\n        _unwrap(ISwapFacility(msg.sender).msgSender(), amount);\n    }\n\n    /// @inheritdoc IExtension\n    function pinVersion(uint256 version) external virtual onlyRole(VERSION_MANAGER_ROLE) {\n        if (version == 0) revert ZeroVersion();\n\n        address beacon = StorageSlot.getAddressSlot(_ORIGIN_BEACON_SLOT).value;\n        address implementation = IExtensionBeacon(beacon).implementation(version);\n\n        //  NOTE: Mutates both ERC-1967 slots to switch the proxy from beacon mode to direct mode,\n        //        so that external ERC-1967 readers (block explorers, tooling) detect a direct proxy\n        //        pointing at the pinned implementation, instead of resolving the latest version via the beacon.\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = address(0);\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = implementation;\n\n        emit IERC1967.BeaconUpgraded(address(0));\n        emit IERC1967.Upgraded(implementation);\n    }\n\n    /// @inheritdoc IExtension\n    function unpinVersion() external virtual onlyRole(VERSION_MANAGER_ROLE) {\n        if (StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value == address(0)) revert NotPinned();\n\n        address beacon = StorageSlot.getAddressSlot(_ORIGIN_BEACON_SLOT).value;\n\n        //  NOTE: Mutates both ERC-1967 slots to switch the proxy back to beacon mode,\n        //        so external ERC-1967 readers detect a beacon proxy again and\n        //        resolve the latest implementation via the beacon registry.\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = address(0);\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = beacon;\n\n        emit IERC1967.Upgraded(address(0));\n        emit IERC1967.BeaconUpgraded(beacon);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view virtual returns (uint256);\n\n    /// @inheritdoc IExtension\n    function pinnedImplementation() public view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /// @inheritdoc IExtension\n    function originBeacon() external view returns (address) {\n        return StorageSlot.getAddressSlot(_ORIGIN_BEACON_SLOT).value;\n    }\n\n    /// @inheritdoc IExtension\n    function isPinned() external view returns (bool) {\n        return pinnedImplementation() != address(0);\n    }\n\n    /* ============ Hooks For Internal Interactive Functions ============ */\n\n    /// @dev   Hook called before approval of PYUSDX Extension token.\n    /// @param account The sender's address.\n    /// @param spender The spender address.\n    function _beforeApprove(address account, address spender, uint256 /* amount */) internal view virtual {\n        FreezableStorageStruct storage $ = _getFreezableStorageLocation();\n        _revertIfFrozen($, account);\n        _revertIfFrozen($, spender);\n    }\n\n    /// @dev   Hook called before wrapping PYUSDX into PYUSDX Extension token.\n    /// @param account   The account from which PYUSDX is deposited.\n    /// @param recipient The account receiving the minted PYUSDX Extension token.\n    function _beforeWrap(address account, address recipient, uint256 /* amount */) internal view virtual {\n        _requireNotPaused();\n\n        FreezableStorageStruct storage $ = _getFreezableStorageLocation();\n        _revertIfFrozen($, account);\n        _revertIfFrozen($, recipient);\n    }\n\n    /// @dev   Hook called before unwrapping PYUSDX Extension token.\n    /// @param account The original caller (resolved via swap facility).\n    function _beforeUnwrap(address account, uint256 /* amount */) internal view virtual {\n        _requireNotPaused();\n\n        _revertIfFrozen(_getFreezableStorageLocation(), account);\n    }\n\n    /// @dev   Hook called before transferring PYUSDX Extension token.\n    /// @param sender    The sender's address.\n    /// @param recipient The recipient's address.\n    function _beforeTransfer(address sender, address recipient, uint256 /* amount */) internal view virtual {\n        _requireNotPaused();\n\n        FreezableStorageStruct storage $ = _getFreezableStorageLocation();\n        _revertIfFrozen($, msg.sender);\n        _revertIfFrozen($, sender);\n        _revertIfFrozen($, recipient);\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /// @dev   Approve `spender` to spend `amount` of tokens from `account`.\n    /// @param account The address approving the allowance.\n    /// @param spender The address approved to spend the tokens.\n    /// @param amount  The amount of tokens being approved for spending.\n    function _approve(address account, address spender, uint256 amount) internal override {\n        _beforeApprove(account, spender, amount);\n        super._approve(account, spender, amount);\n    }\n\n    /// @dev   Wraps `amount` PYUSDX from `account` into extension token for `recipient`.\n    /// @param account   The original caller (resolved via swap facility).\n    /// @param recipient The account receiving the minted extension token.\n    /// @param amount    The amount of PYUSDX deposited.\n    function _wrap(address account, address recipient, uint256 amount) internal {\n        _revertIfZeroAccount(recipient);\n        _revertIfZeroAmount(amount);\n\n        _beforeWrap(account, recipient, amount);\n\n        IERC20(pyusdx).transferFrom(msg.sender, address(this), amount);\n\n        _mint(recipient, amount);\n    }\n\n    /// @dev   Unwraps `amount` extension token from `account` into PYUSDX.\n    /// @param account The original caller (resolved via swap facility).\n    /// @param amount  The amount of extension token burned.\n    function _unwrap(address account, uint256 amount) internal {\n        _revertIfZeroAmount(amount);\n        _revertIfInsufficientBalance(msg.sender, amount);\n\n        _beforeUnwrap(account, amount);\n\n        _burn(msg.sender, amount);\n\n        IERC20(pyusdx).transfer(msg.sender, amount);\n    }\n\n    /// @dev   Mints `amount` tokens to `recipient`.\n    /// @param recipient The address to which the tokens will be minted.\n    /// @param amount    The amount of tokens to mint.\n    function _mint(address recipient, uint256 amount) internal virtual;\n\n    /// @dev   Burns `amount` tokens from `account`.\n    /// @param account The address from which the tokens will be burned.\n    /// @param amount  The amount of tokens to burn.\n    function _burn(address account, uint256 amount) internal virtual;\n\n    /// @dev   Internal balance update function that needs to be implemented by the inheriting contract.\n    /// @param sender    The sender's address.\n    /// @param recipient The recipient's address.\n    /// @param amount    The amount to be transferred.\n    function _update(address sender, address recipient, uint256 amount) internal virtual;\n\n    /// @dev   Internal ERC20 transfer function.\n    /// @param sender    The sender's address.\n    /// @param recipient The recipient's address.\n    /// @param amount    The amount to be transferred.\n    function _transfer(address sender, address recipient, uint256 amount) internal override {\n        _revertIfZeroAccount(recipient);\n\n        _beforeTransfer(sender, recipient, amount);\n\n        emit Transfer(sender, recipient, amount);\n\n        if (amount == 0) return;\n\n        _revertIfInsufficientBalance(sender, amount);\n\n        _update(sender, recipient, amount);\n    }\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /// @dev    Returns the PYUSDX balance of `account`.\n    /// @param  account The account being queried.\n    /// @return balance The PYUSDX balance of the account.\n    function _pyusdxBalanceOf(address account) internal view returns (uint256) {\n        return IERC20(pyusdx).balanceOf(account);\n    }\n\n    /// @dev   Reverts if `recipient` is address(0).\n    /// @param recipient Address of a recipient.\n    function _revertIfZeroAccount(address recipient) internal pure {\n        if (recipient == address(0)) revert ZeroAccount();\n    }\n\n    /// @dev   Reverts if `amount` is equal to 0.\n    /// @param amount Amount of token.\n    function _revertIfZeroAmount(uint256 amount) internal pure {\n        if (amount == 0) revert ZeroAmount();\n    }\n\n    /// @dev   Reverts if `account` balance is below `amount`.\n    /// @param account Address of an account.\n    /// @param amount  Amount to transfer or burn.\n    function _revertIfInsufficientBalance(address account, uint256 amount) internal view {\n        uint256 balance = balanceOf(account);\n\n        if (balance < amount) revert InsufficientBalance(account, balance, amount);\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/IPYUSDX.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\n/// @title  IPYUSDX\n/// @author M0 Labs\n/// @notice Interface for PYUSDX upgradeable ERC20 non-rebasing token with claimable yield\n/// @dev    PYUSDX is an upgradeable ERC20 token with:\n///         - Claimable yield via continuous indexing\n///         - Built-in pausing and compliance functionalities\n///         - Earner Manager controlled yield distribution\ninterface IPYUSDX {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when earning is started for an account.\n    /// @param  account The account that started earning.\n    event StartedEarning(address indexed account);\n\n    /// @notice Emitted when earning is stopped for an account.\n    /// @param  account The account that stopped earning.\n    event StoppedEarning(address indexed account);\n\n    /// @notice Emitted when account info is updated.\n    /// @param  account        The account that was updated.\n    /// @param  earnerRate     The new earner rate in basis points (0 = not earning).\n    /// @param  feeRate        The new fee rate in basis points.\n    /// @param  claimRecipient The new claim recipient address.\n    event AccountInfoUpdated(\n        address indexed account,\n        uint16 earnerRate,\n        uint16 feeRate,\n        address indexed claimRecipient\n    );\n\n    /// @notice Emitted when the earner manager is set or updated.\n    /// @param  earnerManager The address of the new earner manager.\n    event EarnerManagerSet(address indexed earnerManager);\n\n    /// @notice Emitted when an account's index is updated.\n    event IndexUpdated(address indexed account, uint128 currentIndex);\n\n    /// @notice Emitted when yield is claimed for an account.\n    event YieldClaimed(address indexed account, uint256 yieldNetOfFee);\n\n    /// @notice Emitted when a fee is claimed from an account's yield.\n    event FeeClaimed(address indexed account, address indexed recipient, uint256 fee);\n\n    /// @notice Emitted when earner manager distributed additional reward for an account.\n    event RewardDistributed(address indexed account, uint256 amount);\n\n    /* ============ Structs ============ */\n\n    /// @notice Parameters for initializing the PYUSDX contract.\n    struct InitializeParams {\n        string name;\n        string symbol;\n        address admin;\n        address pauser;\n        address freezeManager;\n        address forcedTransferManager;\n        address earnerManager;\n        address rateLimitManager;\n        address issuer;\n    }\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Thrown when the admin address is zero.\n    error ZeroAdmin();\n\n    /// @notice Thrown when the issuer address is zero.\n    error ZeroIssuer();\n\n    /// @notice Thrown when the earner manager address is zero.\n    error ZeroEarnerManager();\n\n    /// @notice Thrown when an account address is zero.\n    error ZeroAccount();\n\n    /// @notice Thrown when an amount is zero.\n    error ZeroAmount();\n\n    /// @notice Thrown when the caller is not the earner manager.\n    error NotEarnerManager();\n\n    /// @notice Thrown when account info is invalid (e.g., not earning but has fee rate).\n    error InvalidAccountInfo();\n\n    /// @notice Thrown when the fee rate exceeds the maximum.\n    error FeeRateTooHigh(uint16 feeRate);\n\n    /// @notice Thrown when the earner rate exceeds the maximum.\n    error EarnerRateTooHigh(uint16 earnerRate);\n\n    /// @notice Thrown when an input array is empty.\n    error ArrayLengthZero();\n\n    /// @notice Thrown when burn amount exceeds account balance.\n    error InsufficientBalance(address account, uint256 balance, uint256 amount);\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Mints PYUSDX to an account.\n    /// @dev    MUST only be callable by ISSUER_ROLE.\n    /// @dev    MUST revert if the contract is paused.\n    /// @dev    MUST revert if the account is frozen.\n    /// @param  account The account receiving the minted PYUSDX.\n    /// @param  amount  The amount of PYUSDX to mint.\n    function mint(address account, uint256 amount) external;\n\n    /// @notice Burns PYUSDX from an account.\n    /// @dev    MUST only be callable by ISSUER_ROLE.\n    /// @dev    MUST revert if the contract is paused.\n    /// @dev    MUST revert if the account is frozen.\n    /// @dev    `ISSUER_ROLE` is expected to be granted only to contracts that burn from their\n    ///         own non-earning balance (e.g., IssuerGateway, Portal). Burning directly from an\n    ///         earning account does not pre-claim accrued yield: `_subtractEarningAmount` rounds\n    ///         the consumed principal up (e.g. in favor of the protocol), so any unclaimed yield\n    ///         at the time of burn is subject to a sub-unit rounding loss in present value.\n    /// @param  account The account from which PYUSDX is burnt.\n    /// @param  amount  The amount of PYUSDX to burn.\n    function burn(address account, uint256 amount) external;\n\n    /// @notice Claims accrued yield for an account.\n    /// @dev    Anyone can call on behalf of any account.\n    /// @dev    MUST revert if the contract is paused.\n    /// @dev    MUST revert if the account is frozen.\n    /// @param  account The account to claim yield for.\n    /// @return yieldWithFee  The gross yield claimed.\n    /// @return fee           The fee deducted.\n    /// @return yieldNetOfFee The net yield after fee.\n    function claimFor(address account) external returns (uint256 yieldWithFee, uint256 fee, uint256 yieldNetOfFee);\n\n    /// @notice Claims accrued yield for multiple accounts.\n    /// @dev    MUST revert if the contract is paused or any account is frozen.\n    /// @param  accounts       The accounts to claim yield for.\n    /// @return yieldWithFees  The gross yield claimed per account.\n    /// @return fees           The fee deducted per account.\n    /// @return yieldNetOfFees The net yield per account.\n    function claimFor(\n        address[] calldata accounts\n    ) external returns (uint256[] memory yieldWithFees, uint256[] memory fees, uint256[] memory yieldNetOfFees);\n\n    /// @notice Sets account info for a single account.\n    /// @dev    MUST only be callable by the earner manager.\n    /// @dev    Callable while paused so the earner manager retains an emergency lever over\n    ///         earner configuration. When called while paused, any accrued yield is\n    ///         materialized onto `account`'s own balance and the `claimRecipient` routing and\n    ///         fee `_transfer` are skipped — the earner manager forgoes the fee for that call.\n    ///         The forgone fee is recoverable: `freeze(account)` followed by\n    ///         `forceTransfer(account, feeRecipient, amount)` can move the fee portion out of\n    ///         the earner's balance after the incident response.\n    /// @param  account        The account to configure.\n    /// @param  earnerRate     The earner rate in basis points (0 to stop earning).\n    /// @param  feeRate        The fee rate on yield (basis points, 0-10000).\n    /// @param  claimRecipient The address to receive claimed yield (address(0) to clear).\n    function setAccountInfo(address account, uint16 earnerRate, uint16 feeRate, address claimRecipient) external;\n\n    /// @notice Sets account info for multiple accounts.\n    /// @dev    MUST only be callable by the earner manager.\n    /// @dev    MUST revert if array lengths do not match.\n    /// @dev    Pause semantics match the single-account overload: yield materializes to each\n    ///         account's own balance, fee and `claimRecipient` routing are skipped per entry.\n    ///         The forgone fee on any entry is recoverable post-incident via `freeze` +\n    ///         `forceTransfer`.\n    /// @param  accounts        The accounts to configure.\n    /// @param  earnerRates     The earner rates for each account (basis points).\n    /// @param  feeRates        The fee rates for each account (basis points).\n    /// @param  claimRecipients The addresses to receive claimed yield.\n    function setAccountInfo(\n        address[] calldata accounts,\n        uint16[] calldata earnerRates,\n        uint16[] calldata feeRates,\n        address[] calldata claimRecipients\n    ) external;\n\n    /// @notice Distributes a reward to an account by minting new PYUSDX.\n    /// @dev    MUST only be callable by the earner manager.\n    /// @dev    MUST revert if the contract is paused.\n    /// @dev    MUST revert if the account is frozen.\n    /// @param  account The account to receive the reward.\n    /// @param  amount  The amount of PYUSDX to distribute.\n    function distributeReward(address account, uint256 amount) external;\n\n    /// @notice Sets the earner manager address.\n    /// @dev    MUST only be callable by DEFAULT_ADMIN_ROLE.\n    /// @param  earnerManager The new earner manager address.\n    function setEarnerManager(address earnerManager) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The maximum fee rate (10000 = 100%).\n    function ONE_HUNDRED_PERCENT() external view returns (uint16);\n\n    /// @notice Precision scaling for index calculations (1e12).\n    function EXP_SCALED_ONE() external view returns (uint128);\n\n    /// @notice The role that can issue (mint/burn) PYUSDX tokens.\n    function ISSUER_ROLE() external view returns (bytes32);\n\n    /// @notice The earner manager address.\n    function earnerManager() external view returns (address);\n\n    /// @notice Returns whether an account is earning.\n    /// @param  account The account to query.\n    /// @return True if the account is earning (earnerRate > 0).\n    function isEarning(address account) external view returns (bool);\n\n    /// @notice Returns the recipient of yield claims for an account.\n    /// @dev    Returns the account itself if no claim recipient is set.\n    /// @param  account The account to query.\n    /// @return The claim recipient address.\n    function claimRecipientFor(address account) external view returns (address);\n\n    /// @notice Returns earning configuration for an account.\n    /// @param  account The account to query.\n    /// @return earnerRate     The earner rate in basis points (0 = not earning).\n    /// @return feeRate        The fee rate on yield (basis points).\n    /// @return claimRecipient The address that receives claimed yield.\n    function getAccountEarningInfo(\n        address account\n    ) external view returns (uint16 earnerRate, uint16 feeRate, address claimRecipient);\n\n    /// @notice Returns accrued yield, fee, and net yield for an account.\n    /// @param  account The account to query.\n    /// @return yieldWithFee  The total accrued yield including fee.\n    /// @return fee           The fee portion of the accrued yield.\n    /// @return yieldNetOfFee The accrued yield net of fee.\n    function accruedYieldAndFeeOf(\n        address account\n    ) external view returns (uint256 yieldWithFee, uint256 fee, uint256 yieldNetOfFee);\n\n    /// @notice Returns the accrued but unclaimed yield (net of fee) for an account.\n    /// @param  account The account to query.\n    /// @return The accrued yield net of fee (0 if account not earning).\n    function accruedYieldOf(address account) external view returns (uint256);\n\n    /// @notice Returns the accrued yield that would be claimed by the account itself.\n    /// @param  account The account to query.\n    /// @return The accrued yield to self (0 if account not earning or yield is redirected).\n    function accruedYieldToSelfOf(address account) external view returns (uint256);\n\n    /// @notice Returns the accrued fee for an account.\n    /// @param  account The account to query.\n    /// @return The accrued fee (0 if account not earning).\n    function accruedFeeOf(address account) external view returns (uint256);\n\n    /// @notice Returns the token balance including any accrued yield.\n    /// @dev    Note: Claiming yield may not result in this balance if yield is redirected.\n    /// @param  account The account to query.\n    /// @return Balance plus accrued yield.\n    function balanceWithYieldOf(address account) external view returns (uint256);\n\n    /// @notice Returns the earning principal of an account.\n    /// @param  account The account to query.\n    /// @return The principal amount used for yield calculations.\n    function earningPrincipalOf(address account) external view returns (uint112);\n\n    /// @notice Returns the stored (last snapshotted) index for an account.\n    /// @param  account The account to query.\n    /// @return The last stored index value.\n    function lastIndexOf(address account) external view returns (uint128);\n\n    /// @notice Returns the computed current index for an account.\n    /// @dev    Returns EXP_SCALED_ONE (1e12) for non-earners.\n    /// @param  account The account to query.\n    /// @return The current index value.\n    function currentIndexOf(address account) external view returns (uint128);\n\n    /// @notice Returns the last update timestamp for an account.\n    /// @param  account The account to query.\n    /// @return The last update timestamp.\n    function lastUpdateTimestampOf(address account) external view returns (uint40);\n}\n"},{"file_path":"lib/PYUSDX/src/swap/interfaces/ISwapFacility.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\n/// @title  Swap Facility interface.\n/// @author M0 Labs\ninterface ISwapFacility {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when PYUSDX Extension is swapped for another PYUSDX Extension.\n    /// @param  extensionIn  The address of the input PYUSDX Extension.\n    /// @param  extensionOut The address of the output PYUSDX Extension.\n    /// @param  amount       The amount swapped.\n    /// @param  recipient    The address to receive the output PYUSDX Extension token.\n    event Swapped(address indexed extensionIn, address indexed extensionOut, uint256 amount, address indexed recipient);\n\n    /// @notice Emitted when PYUSDX token is swapped for PYUSDX Extension.\n    /// @param  token        The address of the PYUSDX token.\n    /// @param  extensionOut The address of the output PYUSDX Extension.\n    /// @param  amount       The amount swapped.\n    /// @param  recipient    The address to receive the output PYUSDX Extension token.\n    event SwappedIn(address indexed token, address indexed extensionOut, uint256 amount, address indexed recipient);\n\n    /// @notice Emitted when PYUSDX Extension is swapped for PYUSDX token.\n    /// @param  token       The address of the PYUSDX token.\n    /// @param  extensionIn The address of the input PYUSDX Extension.\n    /// @param  amount      The amount swapped.\n    /// @param  recipient   The address to receive the PYUSDX token.\n    event SwappedOut(address indexed extensionIn, address indexed token, uint256 amount, address indexed recipient);\n\n    /// @notice Emitted when PYUSDX token is swapped for MultiMint Extension.\n    /// @param  asset        The address of the asset.\n    /// @param  extensionOut The address of the MultiMint Extension.\n    /// @param  amount       The amount swapped.\n    /// @param  recipient    The address to receive the MultiMint Extension tokens.\n    event SwappedInMultiMint(\n        address indexed asset,\n        address indexed extensionOut,\n        uint256 amount,\n        address indexed recipient\n    );\n\n    /// @notice Emitted when `asset` is replaced with PYUSDX for a MultiMint Extension.\n    /// @param  asset        The address of an asset.\n    /// @param  extensionOut The address of a MultiMint Extension.\n    /// @param  amount       The amount of PYUSDX tokens deposited to replace `asset`.\n    /// @param  recipient    The address that received the `asset` tokens.\n    event MultiMintAssetReplaced(\n        address indexed asset,\n        address indexed extensionOut,\n        uint256 amount,\n        address indexed recipient\n    );\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Thrown in the constructor if the extension factory is 0x0.\n    error ZeroExtensionFactory();\n\n    /// @notice Thrown in the constructor if PYUSDX Token is 0x0.\n    error ZeroPYUSDXToken();\n\n    /// @notice Thrown in `swap` functions if an extension is not approved.\n    error NotApprovedExtension(address extension);\n\n    /// @notice Thrown in `swap` function if the provided tokens do not represent a valid swap path.\n    error InvalidSwapPath(address tokenIn, address tokenOut);\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Swaps between two tokens, which can be PYUSDX, PYUSDX Extensions, or an asset used by MultiMint Extensions.\n    /// @param  tokenIn   The address of the token to swap from.\n    /// @param  tokenOut  The address of the token to swap to.\n    /// @param  amount    The amount to swap.\n    /// @param  recipient The address to receive the swapped tokens.\n    function swap(address tokenIn, address tokenOut, uint256 amount, address recipient) external;\n\n    /// @notice Swaps between two tokens using permit.\n    /// @param  tokenIn   The address of the token to swap from.\n    /// @param  tokenOut  The address of the token to swap to.\n    /// @param  amount    The amount to swap.\n    /// @param  recipient The address to receive the swapped tokens.\n    /// @param  deadline  The last timestamp where the signature is still valid.\n    /// @param  v         An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    /// @param  r         An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    /// @param  s         An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    function swapWithPermit(\n        address tokenIn,\n        address tokenOut,\n        uint256 amount,\n        address recipient,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /// @notice Swaps between two tokens using permit.\n    /// @param  tokenIn   The address of the token to swap from.\n    /// @param  tokenOut  The address of the token to swap to.\n    /// @param  amount    The amount to swap.\n    /// @param  recipient The address to receive the swapped tokens.\n    /// @param  deadline  The last timestamp where the signature is still valid.\n    /// @param  signature An arbitrary signature (EIP-712).\n    function swapWithPermit(\n        address tokenIn,\n        address tokenOut,\n        uint256 amount,\n        address recipient,\n        uint256 deadline,\n        bytes calldata signature\n    ) external;\n\n    /// @notice Swaps PYUSDX token to PYUSDX Extension.\n    /// @param  extensionOut The address of the PYUSDX Extension to swap to.\n    /// @param  amount       The amount of PYUSDX token to swap.\n    /// @param  recipient    The address to receive the swapped PYUSDX Extension tokens.\n    function swapIn(address extensionOut, uint256 amount, address recipient) external;\n\n    /// @notice Swaps PYUSDX Extension to PYUSDX token.\n    /// @param  extensionIn The address of the PYUSDX Extension to swap from.\n    /// @param  amount      The amount of PYUSDX Extension tokens to swap.\n    /// @param  recipient   The address to receive PYUSDX tokens.\n    function swapOut(address extensionIn, uint256 amount, address recipient) external;\n\n    /// @notice Replaces `asset` held in a MultiMint Extension with `amount` of PYUSDX.\n    /// @param  asset        The address of the asset.\n    /// @param  tokenIn      The address of PYUSDX or a PYUSDX extension to provide PYUSDX from.\n    /// @param  extensionOut The address of a MultiMint Extension.\n    /// @param  amount       The amount of PYUSDX to replace.\n    /// @param  recipient    The address to receive `asset` tokens equivalent to `amount` of PYUSDX.\n    function replaceAsset(\n        address asset,\n        address tokenIn,\n        address extensionOut,\n        uint256 amount,\n        address recipient\n    ) external;\n\n    /// @notice Replaces `asset` held in a MultiMint Extension with `amount` of PYUSDX using permit.\n    /// @param  asset        The address of the asset.\n    /// @param  tokenIn      The address of PYUSDX or a PYUSDX extension to provide PYUSDX from.\n    /// @param  extensionOut The address of a MultiMint Extension.\n    /// @param  amount       The amount of PYUSDX to replace.\n    /// @param  recipient    The address to receive `asset` tokens equivalent to `amount` of PYUSDX.\n    /// @param  deadline     The last timestamp where the signature is still valid.\n    /// @param  v            An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    /// @param  r            An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    /// @param  s            An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n    function replaceAssetWithPermit(\n        address asset,\n        address tokenIn,\n        address extensionOut,\n        uint256 amount,\n        address recipient,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /// @notice Replaces `asset` held in a MultiMint Extension with `amount` of PYUSDX using permit.\n    /// @param  asset        The address of the asset.\n    /// @param  tokenIn      The address of PYUSDX or a PYUSDX extension to provide PYUSDX from.\n    /// @param  extensionOut The address of a MultiMint Extension.\n    /// @param  amount       The amount of PYUSDX to replace.\n    /// @param  recipient    The address to receive `asset` tokens equivalent to `amount` of PYUSDX.\n    /// @param  deadline     The last timestamp where the signature is still valid.\n    /// @param  signature    An arbitrary signature (EIP-712).\n    function replaceAssetWithPermit(\n        address asset,\n        address tokenIn,\n        address extensionOut,\n        uint256 amount,\n        address recipient,\n        uint256 deadline,\n        bytes calldata signature\n    ) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The address of the PYUSDX Token contract.\n    function pyusdx() external view returns (address);\n\n    /// @notice The address of the PYUSDX Extension Factory contract.\n    function extensionFactory() external view returns (address);\n\n    /// @notice Returns the address that called `swap`.\n    /// @dev    Must be used instead of `msg.sender` in PYUSDX Extensions contracts to get the original sender.\n    function msgSender() external view returns (address);\n\n    /// @notice Checks if the extension is approved.\n    /// @param  extension The extension address to check.\n    /// @return True if approved, false otherwise.\n    function isApprovedExtension(address extension) external view returns (bool);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/ERC20ExtendedUpgradeable.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { ERC3009Upgradeable } from \"./ERC3009Upgradeable.sol\";\n\nimport { IERC20 } from \"./interfaces/IERC20.sol\";\nimport { IERC20Extended } from \"./interfaces/IERC20Extended.sol\";\n\nabstract contract ERC20ExtendedUpgradeableStorageLayout {\n    /// @custom:storage-location erc7201:M0.storage.ERC20Extended\n    struct ERC20ExtendedStorageStruct {\n        mapping(address account => mapping(address spender => uint256 allowance)) allowance;\n        uint8 decimals;\n        string symbol;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.ERC20Extended\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _ERC20_EXTENDED_STORAGE_LOCATION =\n        0xcbbe23efb65c1eaba394256c463812c20abdb5376e247eba1d0e1e92054da100;\n\n    function _getERC20ExtendedStorageLocation() internal pure returns (ERC20ExtendedStorageStruct storage $) {\n        assembly {\n            $.slot := _ERC20_EXTENDED_STORAGE_LOCATION\n        }\n    }\n}\n\n/**\n * @title  An upgradeable ERC20 token extended with EIP-2612 permits for signed approvals\n *         (via EIP-712 and with EIP-1271 and EIP-5267 compatibility).\n * @author M0 Labs\n */\nabstract contract ERC20ExtendedUpgradeable is\n    ERC20ExtendedUpgradeableStorageLayout,\n    ERC3009Upgradeable,\n    IERC20Extended\n{\n    /* ============ Variables ============ */\n\n    /**\n     * @inheritdoc IERC20Extended\n     * @dev Keeping this constant, despite `permit` parameter name differences, to ensure max EIP-2612 compatibility.\n     *      keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\")\n     */\n    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n    /* ============ Initializer ============ */\n\n    function __ERC20ExtendedUpgradeable_init(\n        string memory name_,\n        string memory symbol_,\n        uint8 decimals_\n    ) internal onlyInitializing {\n        __ERC3009Upgradeable_init(name_);\n\n        ERC20ExtendedStorageStruct storage $ = _getERC20ExtendedStorageLocation();\n\n        $.decimals = decimals_;\n        $.symbol = symbol_;\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IERC20\n    function approve(address spender_, uint256 amount_) external returns (bool) {\n        _approve(msg.sender, spender_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20Extended\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        _revertIfInvalidSignature(owner_, _permitAndGetDigest(owner_, spender_, value_, deadline_), v_, r_, s_);\n    }\n\n    /// @inheritdoc IERC20Extended\n    function permit(\n        address owner_,\n        address spender_,\n        uint256 value_,\n        uint256 deadline_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(owner_, _permitAndGetDigest(owner_, spender_, value_, deadline_), signature_);\n    }\n\n    /// @inheritdoc IERC20\n    function transfer(address recipient_, uint256 amount_) external returns (bool) {\n        _transfer(msg.sender, recipient_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function transferFrom(address sender_, address recipient_, uint256 amount_) external returns (bool) {\n        ERC20ExtendedStorageStruct storage $ = _getERC20ExtendedStorageLocation();\n        uint256 spenderAllowance_ = $.allowance[sender_][msg.sender]; // Cache `spenderAllowance_` to stack.\n\n        if (spenderAllowance_ != type(uint256).max) {\n            if (spenderAllowance_ < amount_) revert InsufficientAllowance(msg.sender, spenderAllowance_, amount_);\n\n            unchecked {\n                _setAllowance($, sender_, msg.sender, spenderAllowance_ - amount_);\n            }\n        }\n\n        _transfer(sender_, recipient_, amount_);\n\n        return true;\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC20\n    function allowance(address account, address spender) public view returns (uint256) {\n        return _getERC20ExtendedStorageLocation().allowance[account][spender];\n    }\n\n    /// @inheritdoc IERC20\n    function decimals() external view virtual returns (uint8) {\n        return _getERC20ExtendedStorageLocation().decimals;\n    }\n\n    /// @inheritdoc IERC20\n    function name() external view virtual returns (string memory) {\n        return _getERC712ExtendedStorageLocation().name;\n    }\n\n    /// @inheritdoc IERC20\n    function symbol() external view virtual returns (string memory) {\n        return _getERC20ExtendedStorageLocation().symbol;\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev Approve `spender_` to spend `amount_` of tokens from `account_`.\n     * @param  account_ The address approving the allowance.\n     * @param  spender_ The address approved to spend the tokens.\n     * @param  amount_  The amount of tokens being approved for spending.\n     */\n    function _approve(address account_, address spender_, uint256 amount_) internal virtual {\n        _setAllowance(_getERC20ExtendedStorageLocation(), account_, spender_, amount_);\n        emit Approval(account_, spender_, amount_);\n    }\n\n    /**\n     * @dev Set the `amount_` of tokens `spender_` is allowed to spend from `account_`.\n     * @param $         ERC20Extended storage location.\n     * @param  account_ The address for which the allowance is set.\n     * @param  spender_ The address allowed to spend the tokens.\n     * @param  amount_  The amount of tokens being allowed for spending.\n     */\n    function _setAllowance(\n        ERC20ExtendedStorageStruct storage $,\n        address account_,\n        address spender_,\n        uint256 amount_\n    ) internal virtual {\n        $.allowance[account_][spender_] = amount_;\n    }\n\n    /**\n     * @dev    Performs the approval based on the permit info, validates the deadline, and returns the digest.\n     * @param  owner_    The address of the account approving the allowance.\n     * @param  spender_  The address of the account being allowed to spend the tokens.\n     * @param  amount_   The amount of tokens being approved for spending.\n     * @param  deadline_ The deadline by which the signature must be used.\n     * @return digest_   The EIP-712 digest of the permit.\n     */\n    function _permitAndGetDigest(\n        address owner_,\n        address spender_,\n        uint256 amount_,\n        uint256 deadline_\n    ) internal virtual returns (bytes32) {\n        _revertIfExpired(deadline_);\n\n        _approve(owner_, spender_, amount_);\n\n        unchecked {\n            // Nonce realistically cannot overflow.\n            return\n                _getDigest(\n                    keccak256(\n                        abi.encode(\n                            PERMIT_TYPEHASH,\n                            owner_,\n                            spender_,\n                            amount_,\n                            _getStatefulERC712ExtendedStorageLocation().nonces[owner_]++,\n                            deadline_\n                        )\n                    )\n                );\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/platform/projects/interfaces/IYieldToOne.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\n/// @title  PYUSDX Extension where all yield is claimable by a single recipient.\n/// @author M0 Labs\ninterface IYieldToOne {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when this contract's excess PYUSDX yield is claimed.\n    /// @param  yield The amount of yield claimed.\n    event YieldClaimed(uint256 yield);\n\n    /// @notice Emitted when the yield recipient is set.\n    /// @param  yieldRecipient The address of the new yield recipient.\n    event YieldRecipientSet(address indexed yieldRecipient);\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Emitted in initializer if Yield Recipient is 0x0.\n    error ZeroYieldRecipient();\n\n    /// @notice Emitted in initializer if Yield Recipient Manager is 0x0.\n    error ZeroYieldRecipientManager();\n\n    /// @notice Emitted in initializer if Version Manager is 0x0.\n    error ZeroVersionManager();\n\n    /// @notice Emitted in initializer if Admin is 0x0.\n    error ZeroAdmin();\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Claims accrued yield to the yield recipient.\n    /// @dev    MUST only be callable by the YIELD_RECIPIENT_MANAGER_ROLE.\n    /// @dev    Calls `pyusdx.claimFor(address(this))` to realize pending yield,\n    ///         then mints extension tokens for the resulting increase in totalSupply.\n    /// @dev    Callable while paused so the admin retains an emergency lever to rotate a\n    ///         compromised yield recipient mid-incident via `setYieldRecipient`. The\n    ///         freshly minted extension tokens cannot move while paused because transfer,\n    ///         wrap, and unwrap all revert, so the supply is economically inert until\n    ///         unpause.\n    /// @dev    Reverts if the current yield recipient is frozen. Use `setYieldRecipient`\n    ///         to rotate to a non-frozen recipient first; that path skips the internal\n    ///         claim so the pending yield stays as excess and accrues to the next\n    ///         recipient on their first claim.\n    function claimYield() external returns (uint256);\n\n    /// @notice Sets the yield recipient.\n    /// @dev    MUST only be callable by the YIELD_RECIPIENT_MANAGER_ROLE.\n    /// @dev    SHOULD revert if `yieldRecipient` is 0x0.\n    /// @dev    SHOULD return early if the `yieldRecipient` is already the actual yield recipient.\n    /// @dev    Internally calls `claimYield()` to pay out the outgoing recipient, unless\n    ///         the outgoing recipient is frozen. When frozen, the claim is skipped:\n    ///         pending PYUSDX yield remains as excess on the extension and is paid to\n    ///         the next recipient's first claim. Makes recipient rotation usable as an\n    ///         incident-response lever while a compromised recipient is frozen, at the\n    ///         cost of the outgoing recipient's pending slice.\n    /// @param  yieldRecipient The address of the new yield recipient.\n    function setYieldRecipient(address yieldRecipient) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role that can manage the yield recipient.\n    function YIELD_RECIPIENT_MANAGER_ROLE() external view returns (bytes32);\n\n    /// @notice The amount of pending accrued yield from PYUSDX.\n    function yield() external view returns (uint256);\n\n    /// @notice The address of the yield recipient.\n    function yieldRecipient() external view returns (address);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/libs/UIntMath.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\n/**\n * @title  Library to perform safe math operations on uint types\n * @author M^0 Labs\n */\nlibrary UIntMath {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint16.\n    error InvalidUInt16();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint32.\n    error InvalidUInt32();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint40.\n    error InvalidUInt40();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint48.\n    error InvalidUInt48();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint112.\n    error InvalidUInt112();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint128.\n    error InvalidUInt128();\n\n    /// @notice Emitted when a passed value is greater than the maximum value of uint240.\n    error InvalidUInt240();\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @notice Casts a uint256 value to a uint16, ensuring that it is less than or equal to the maximum uint16 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint16.\n     */\n    function safe16(uint256 n) internal pure returns (uint16) {\n        if (n > type(uint16).max) revert InvalidUInt16();\n        return uint16(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint32, ensuring that it is less than or equal to the maximum uint32 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint32.\n     */\n    function safe32(uint256 n) internal pure returns (uint32) {\n        if (n > type(uint32).max) revert InvalidUInt32();\n        return uint32(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint40, ensuring that it is less than or equal to the maximum uint40 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint40.\n     */\n    function safe40(uint256 n) internal pure returns (uint40) {\n        if (n > type(uint40).max) revert InvalidUInt40();\n        return uint40(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint48, ensuring that it is less than or equal to the maximum uint48 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint48.\n     */\n    function safe48(uint256 n) internal pure returns (uint48) {\n        if (n > type(uint48).max) revert InvalidUInt48();\n        return uint48(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint112, ensuring that it is less than or equal to the maximum uint112 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint112.\n     */\n    function safe112(uint256 n) internal pure returns (uint112) {\n        if (n > type(uint112).max) revert InvalidUInt112();\n        return uint112(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint128, ensuring that it is less than or equal to the maximum uint128 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint128.\n     */\n    function safe128(uint256 n) internal pure returns (uint128) {\n        if (n > type(uint128).max) revert InvalidUInt128();\n        return uint128(n);\n    }\n\n    /**\n     * @notice Casts a uint256 value to a uint240, ensuring that it is less than or equal to the maximum uint240 value.\n     * @param  n The value to cast.\n     * @return The value casted to uint240.\n     */\n    function safe240(uint256 n) internal pure returns (uint240) {\n        if (n > type(uint240).max) revert InvalidUInt240();\n        return uint240(n);\n    }\n\n    /**\n     * @notice Limits a uint256 value to the maximum uint32 value.\n     * @param  n The value to bound.\n     * @return The value limited to within uint32 bounds.\n     */\n    function bound32(uint256 n) internal pure returns (uint32) {\n        return uint32(min256(n, uint256(type(uint32).max)));\n    }\n\n    /**\n     * @notice Limits a uint256 value to the maximum uint112 value.\n     * @param  n The value to bound.\n     * @return The value limited to within uint112 bounds.\n     */\n    function bound112(uint256 n) internal pure returns (uint112) {\n        return uint112(min256(n, uint256(type(uint112).max)));\n    }\n\n    /**\n     * @notice Limits a uint256 value to the maximum uint128 value.\n     * @param  n The value to bound.\n     * @return The value limited to within uint128 bounds.\n     */\n    function bound128(uint256 n) internal pure returns (uint128) {\n        return uint128(min256(n, uint256(type(uint128).max)));\n    }\n\n    /**\n     * @notice Limits a uint256 value to the maximum uint240 value.\n     * @param  n The value to bound.\n     * @return The value limited to within uint240 bounds.\n     */\n    function bound240(uint256 n) internal pure returns (uint240) {\n        return uint240(min256(n, uint256(type(uint240).max)));\n    }\n\n    /**\n     * @notice Compares two uint32 values and returns the larger one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The larger value.\n     */\n    function max32(uint32 a, uint32 b) internal pure returns (uint32) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint40 values and returns the larger one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The larger value.\n     */\n    function max40(uint40 a, uint40 b) internal pure returns (uint40) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint128 values and returns the larger one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The larger value.\n     */\n    function max128(uint128 a, uint128 b) internal pure returns (uint128) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint240 values and returns the larger one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The larger value.\n     */\n    function max240(uint240 a, uint240 b) internal pure returns (uint240) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint32 values and returns the lesser one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The lesser value.\n     */\n    function min32(uint32 a, uint32 b) internal pure returns (uint32) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint40 values and returns the lesser one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The lesser value.\n     */\n    function min40(uint40 a, uint40 b) internal pure returns (uint40) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint240 values and returns the lesser one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The lesser value.\n     */\n    function min240(uint240 a, uint240 b) internal pure returns (uint240) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint112 values and returns the lesser one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The lesser value.\n     */\n    function min112(uint112 a, uint112 b) internal pure returns (uint112) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @notice Compares two uint256 values and returns the lesser one.\n     * @param  a Value to compare.\n     * @param  b Value to compare.\n     * @return The lesser value.\n     */\n    function min256(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/platform/projects/YieldToOne.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\nimport { IERC20 } from \"../../../lib/evm-m-extensions/lib/common/src/interfaces/IERC20.sol\";\n\nimport { IPYUSDX } from \"../../IPYUSDX.sol\";\n\nimport { Extension } from \"../Extension.sol\";\n\nimport { IYieldToOne } from \"./interfaces/IYieldToOne.sol\";\n\nabstract contract YieldToOneStorageLayout {\n    /// @custom:storage-location erc7201:PYUSDX.storage.YieldToOne\n    struct YieldToOneStorage {\n        uint256 totalSupply;\n        address yieldRecipient;\n        mapping(address account => uint256 balance) balanceOf;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"PYUSDX.storage.YieldToOne\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _YIELD_TO_ONE_STORAGE_LOCATION =\n        0xdeb0f77528a555c599f306cdb984f1f31ca08f014cad1aa7b02fa3fece5e2e00;\n\n    function _getYieldToOneStorage() internal pure virtual returns (YieldToOneStorage storage $) {\n        bytes32 location = _YIELD_TO_ONE_STORAGE_LOCATION;\n        assembly {\n            $.slot := location\n        }\n    }\n}\n\n/// @title  YieldToOne\n/// @notice Upgradeable ERC20 token wrapping PYUSDX into a branded non-rebasing stablecoin\n///         with all yield claimable by a single recipient.\n/// @dev    Yield accrues on the extension's PYUSDX balance via PYUSDX's per-account earning\n///         system. When the extension's pending yield is claimed, it is first realized from\n///         PYUSDX (net of PYUSDX's fee), then minted as extension tokens to the yield recipient.\n/// @author M0 Labs\ncontract YieldToOne is IYieldToOne, YieldToOneStorageLayout, Extension {\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IYieldToOne\n    bytes32 public constant YIELD_RECIPIENT_MANAGER_ROLE = keccak256(\"YIELD_RECIPIENT_MANAGER_ROLE\");\n\n    /* ============ Constructor ============ */\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    /// @param pyusdx_       The address of the PYUSDX token.\n    /// @param swapFacility_ The address of the swap facility.\n    constructor(address pyusdx_, address swapFacility_) Extension(pyusdx_, swapFacility_) {}\n\n    /* ============ Initializer ============ */\n\n    /// @notice Initializes the YieldToOne extension token.\n    /// @param  name                  The name of the token.\n    /// @param  symbol                The symbol of the token.\n    /// @param  yieldRecipient_       The address of the yield recipient.\n    /// @param  admin                 The address of the admin.\n    /// @param  freezeManager         The address of the freeze manager.\n    /// @param  pauser                The address of the pauser.\n    /// @param  yieldRecipientManager The address of the yield recipient manager.\n    /// @param  versionManager        The address of the version manager.\n    function initialize(\n        string memory name,\n        string memory symbol,\n        address yieldRecipient_,\n        address admin,\n        address freezeManager,\n        address pauser,\n        address yieldRecipientManager,\n        address versionManager\n    ) public virtual initializer {\n        __YieldToOne_init(\n            name,\n            symbol,\n            yieldRecipient_,\n            admin,\n            freezeManager,\n            pauser,\n            yieldRecipientManager,\n            versionManager\n        );\n    }\n\n    /// @dev   Internal initializer. Sets up ERC20 metadata, roles, and the\n    ///        yield recipient.\n    /// @param name                  The name of the token.\n    /// @param symbol                The symbol of the token.\n    /// @param yieldRecipient_       The address of the yield recipient.\n    /// @param admin                 The address of the admin.\n    /// @param freezeManager         The address of the freeze manager.\n    /// @param pauser                The address of the pauser.\n    /// @param yieldRecipientManager The address of the yield recipient manager.\n    /// @param versionManager        The address of the version manager.\n    function __YieldToOne_init(\n        string memory name,\n        string memory symbol,\n        address yieldRecipient_,\n        address admin,\n        address freezeManager,\n        address pauser,\n        address yieldRecipientManager,\n        address versionManager\n    ) internal onlyInitializing {\n        if (admin == address(0)) revert ZeroAdmin();\n        if (yieldRecipientManager == address(0)) revert ZeroYieldRecipientManager();\n        if (versionManager == address(0)) revert ZeroVersionManager();\n\n        __AccessControl_init();\n        __Extension_init(name, symbol, freezeManager, pauser);\n\n        _setYieldRecipient(yieldRecipient_);\n\n        _grantRole(DEFAULT_ADMIN_ROLE, admin);\n        _grantRole(VERSION_MANAGER_ROLE, versionManager);\n        _grantRole(YIELD_RECIPIENT_MANAGER_ROLE, yieldRecipientManager);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IYieldToOne\n    function claimYield() public virtual returns (uint256) {\n        _beforeClaimYield();\n\n        // NOTE: Realize any pending PYUSDX yield\n        IPYUSDX(pyusdx).claimFor(address(this));\n\n        // NOTE: Excess accounts for the newly claimed yield and any prior unclaimed yield\n        //       (i.e. PYUSDX donation or `claimFor()` the extension at the PYUSDX level)\n        uint256 excess = _excess();\n\n        if (excess == 0) return 0;\n\n        emit YieldClaimed(excess);\n\n        // NOTE: mint the excess PYUSDX as extension tokens\n        _mint(yieldRecipient(), excess);\n\n        return excess;\n    }\n\n    /// @inheritdoc IYieldToOne\n    function setYieldRecipient(address account) external virtual onlyRole(YIELD_RECIPIENT_MANAGER_ROLE) {\n        // NOTE: Skip the claim when the outgoing recipient is frozen — `_beforeClaimYield`\n        //       would otherwise revert on the freeze check, blocking the admin's ability\n        //       to rotate a compromised recipient mid-incident. Pending PYUSDX yield\n        //       remains as `_excess()` and is paid to the next recipient on their first\n        //       claim. The frozen recipient's forgone slice is an accepted cost of the\n        //       incident-response path.\n        if (!isFrozen(yieldRecipient())) claimYield();\n\n        _setYieldRecipient(account);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view override returns (uint256) {\n        return _getYieldToOneStorage().balanceOf[account];\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _getYieldToOneStorage().totalSupply;\n    }\n\n    /// @inheritdoc IYieldToOne\n    function yield() public view virtual returns (uint256) {\n        return _excess() + IPYUSDX(pyusdx).accruedYieldToSelfOf(address(this));\n    }\n\n    /// @inheritdoc IYieldToOne\n    function yieldRecipient() public view returns (address) {\n        return _getYieldToOneStorage().yieldRecipient;\n    }\n\n    /* ============ Hooks ============ */\n\n    /// @dev Hook called before claiming yield. Restricts the caller to\n    ///      `YIELD_RECIPIENT_MANAGER_ROLE` and reverts if the yield recipient is frozen.\n    ///      Intentionally omits `_requireNotPaused()` so the admin can rotate a compromised\n    ///      recipient mid-incident via `setYieldRecipient` (which calls `claimYield`\n    ///      internally). Minted extension tokens cannot move while paused —\n    ///      `_beforeTransfer`, `_beforeWrap`, and `_beforeUnwrap` all enforce the pause —\n    ///      so supply minted during pause is economically inert until unpause.\n    function _beforeClaimYield() internal view virtual onlyRole(YIELD_RECIPIENT_MANAGER_ROLE) {\n        _revertIfFrozen(_getFreezableStorageLocation(), yieldRecipient());\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /// @dev   Mints `amount` extension tokens to `recipient`.\n    /// @param recipient The address receiving the minted tokens.\n    /// @param amount    The amount of tokens to mint.\n    function _mint(address recipient, uint256 amount) internal override {\n        YieldToOneStorage storage $ = _getYieldToOneStorage();\n\n        $.totalSupply += amount;\n\n        unchecked {\n            $.balanceOf[recipient] += amount;\n        }\n\n        emit Transfer(address(0), recipient, amount);\n    }\n\n    /// @dev   Burns `amount` extension tokens from `account`.\n    /// @param account The address from which tokens are burned.\n    /// @param amount  The amount of tokens to burn.\n    function _burn(address account, uint256 amount) internal override {\n        YieldToOneStorage storage $ = _getYieldToOneStorage();\n\n        // NOTE: `amount` is verified to not exceed `$.balanceOf[account]` by the caller, so\n        //       subtraction cannot underflow. `totalSupply >= balanceOf[account]` by invariant.\n        unchecked {\n            $.totalSupply -= amount;\n            $.balanceOf[account] -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n    }\n\n    /// @dev   Internal balance update on transfer.\n    /// @param sender    The address sending tokens.\n    /// @param recipient The address receiving tokens.\n    /// @param amount    The amount to transfer.\n    function _update(address sender, address recipient, uint256 amount) internal override {\n        YieldToOneStorage storage $ = _getYieldToOneStorage();\n\n        // NOTE: `amount` is verified to not exceed `$.balanceOf[sender]` by the caller, so\n        //       subtraction cannot underflow. Addition cannot overflow because `totalSupply`\n        //       (which bounds the sum of all balances) fits in uint256.\n        unchecked {\n            $.balanceOf[sender] -= amount;\n            $.balanceOf[recipient] += amount;\n        }\n    }\n\n    /// @dev   Sets the yield recipient. Reverts if address(0).\n    /// @param yieldRecipient_ The address of the new yield recipient.\n    function _setYieldRecipient(address yieldRecipient_) internal {\n        if (yieldRecipient_ == address(0)) revert ZeroYieldRecipient();\n\n        YieldToOneStorage storage $ = _getYieldToOneStorage();\n\n        if ($.yieldRecipient == yieldRecipient_) return;\n\n        $.yieldRecipient = yieldRecipient_;\n\n        emit YieldRecipientSet(yieldRecipient_);\n    }\n\n    /* ============ Internal View Functions ============ */\n\n    /// @dev Returns the excess PYUSDX balance of the extension\n    function _excess() internal view virtual returns (uint256) {\n        uint256 pyusdxBalance = _pyusdxBalanceOf(address(this));\n        uint256 totalSupply_ = totalSupply();\n\n        unchecked {\n            return pyusdxBalance > totalSupply_ ? pyusdxBalance - totalSupply_ : 0;\n        }\n    }\n}\n"},{"file_path":"src/interfaces/IUSDat.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\n/**\n * @title  IUSDat\n * @notice Interface for the USDat token contract.\n * @dev Deposit and withdraw happen through the PYUSDX SwapFacility.\n */\ninterface IUSDat {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when the whitelist is enabled.\n    /// @param timestamp The block timestamp when the whitelist was enabled.\n    event WhitelistEnabled(uint256 timestamp);\n\n    /// @notice Emitted when the whitelist is disabled.\n    /// @param timestamp The block timestamp when the whitelist was disabled.\n    event WhitelistDisabled(uint256 timestamp);\n\n    /// @notice Emitted when an account is added to the whitelist.\n    /// @param account The address that was whitelisted.\n    /// @param timestamp The block timestamp when the account was whitelisted.\n    event Whitelisted(address indexed account, uint256 timestamp);\n\n    /// @notice Emitted when an account is removed from the whitelist.\n    /// @param account The address that was removed from the whitelist.\n    /// @param timestamp The block timestamp when the account was removed.\n    event RemovedFromWhitelist(address indexed account, uint256 timestamp);\n\n    /* ============ Errors ============ */\n\n    /// @notice Thrown when an account is not whitelisted and the whitelist is enabled.\n    /// @param account The address that is not whitelisted.\n    error AccountNotWhitelisted(address account);\n\n    /// @notice Thrown by `pinVersion`/`unpinVersion` — version-pinning is disabled for USDat\n    ///         (it sits behind a TransparentUpgradeableProxy, not a beacon proxy).\n    error VersionPinningDisabled();\n\n    /// @notice Thrown by `migrate` when the held M balance is below the M-backed portion\n    ///         (`totalSupply - totalAssets`), i.e. the state is corrupted or `mToken` is wrong.\n    /// @param  held    The M balance the contract holds.\n    /// @param  backing The minimum expected M-backed portion (`totalSupply - totalAssets`).\n    error MReservesMismatch(uint256 held, uint256 backing);\n\n    /* ============ Whitelist Admin Functions ============ */\n\n    /// @notice Enables the whitelist. Only whitelisted addresses can deposit when enabled.\n    /// @dev    Only callable by accounts with the WHITELIST_MANAGER_ROLE.\n    function enableWhitelist() external;\n\n    /// @notice Disables the whitelist. All addresses can deposit when disabled.\n    /// @dev    Only callable by accounts with the WHITELIST_MANAGER_ROLE.\n    function disableWhitelist() external;\n\n    /// @notice Adds an account to the whitelist.\n    /// @dev    Only callable by accounts with the WHITELIST_MANAGER_ROLE.\n    /// @param  account The address to add to the whitelist.\n    function whitelist(address account) external;\n\n    /// @notice Removes an account from the whitelist.\n    /// @dev    Only callable by accounts with the WHITELIST_MANAGER_ROLE.\n    /// @param  account The address to remove from the whitelist.\n    function removeFromWhitelist(address account) external;\n\n    /* ============ Whitelist View Functions ============ */\n\n    /// @notice Returns the role identifier for the whitelist manager.\n    /// @return The bytes32 role identifier.\n    function WHITELIST_MANAGER_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the address of the legacy M token held in reserve.\n    /// @return The M token address.\n    function M_TOKEN() external view returns (address);\n\n    /// @notice Returns whether the whitelist is currently enabled.\n    /// @return True if the whitelist is enabled, false otherwise.\n    function isWhitelistEnabled() external view returns (bool);\n\n    /// @notice Returns whether an account is whitelisted.\n    /// @param  account The address to check.\n    /// @return True if the account is whitelisted, false otherwise.\n    function isWhitelisted(address account) external view returns (bool);\n\n    /* ============ Migration ============ */\n\n    /// @notice One-shot migration run immediately after the JMIExtension → MultiMint implementation\n    ///         upgrade (atomically, as the `data` of `ProxyAdmin.upgradeAndCall`).\n    function migrate() external;\n\n    /* ============ M Yield Functions ============ */\n\n    /// @notice Mints the M yield accrued since the last claim to the yield recipient.\n    /// @return The amount of M yield claimed.\n    function claimMYield() external returns (uint256);\n\n    /// @notice Returns the M yield currently claimable by `claimMYield`.\n    /// @return The held M not yet registered as backing.\n    function mYield() external view returns (uint256);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/interfaces/IArrayErrors.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\n/**\n * @title  IArrayErrors\n * @notice Shared error declarations for array length validation.\n */\ninterface IArrayErrors {\n    /// @notice Error for array length mismatch.\n    error ArrayLengthMismatch();\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC712Extended.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IERC712 } from \"./IERC712.sol\";\n\n/**\n * @title  EIP-712 extended by EIP-5267.\n * @author M^0 Labs\n * @dev    The additional interface as defined by EIP-5267: https://eips.ethereum.org/EIPS/eip-5267\n */\ninterface IERC712Extended is IERC712 {\n    /* ============ Events ============ */\n\n    /// @notice MAY be emitted to signal that the domain could have changed.\n    event EIP712DomainChanged();\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the fields and values that describe the domain separator used by this contract for EIP-712.\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/pausable/IPausable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\n/**\n * @title Pausable interface.\n * @author M0 Labs\n */\ninterface IPausable {\n    /* ============ Errors ============ */\n\n    /// @notice Emitted if no pauser is set.\n    error ZeroPauser();\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Pauses the contract.\n     * @dev    Can only be called by an account with the PAUSER_ROLE.\n     * @dev    When paused, wrap/unwrap and transfer of tokens should be disabled.\n     *         Approval should still be enabled to allow users to change their allowances.\n     */\n    function pause() external;\n\n    /**\n     * @notice Unpauses the contract.\n     * @dev    Can only be called by an account with the PAUSER_ROLE.\n     */\n    function unpause() external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role that can pause/unpause the contract.\n    function PAUSER_ROLE() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/freezable/IFreezable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\n/**\n * @title Freezable interface.\n * @author M0 Labs\n */\ninterface IFreezable {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when an account is frozen.\n     * @param account The address of the frozen account.\n     * @param timestamp The timestamp at which the account was frozen.\n     */\n    event Frozen(address indexed account, uint256 timestamp);\n\n    /**\n     * @notice Emitted when an account is unfrozen.\n     * @param account The address of the unfrozen account.\n     * @param timestamp The timestamp at which the account was unfrozen.\n     */\n    event Unfrozen(address indexed account, uint256 timestamp);\n\n    /* ============ Errors ============ */\n\n    /**\n     * @notice Emitted when an account is already frozen.\n     * @param account The address of the frozen account.\n     */\n    error AccountFrozen(address account);\n\n    /**\n     * @notice Emitted when an account is not frozen.\n     * @param account The address of the account that is not frozen.\n     */\n    error AccountNotFrozen(address account);\n\n    /// @notice Emitted if no freeze manager is set.\n    error ZeroFreezeManager();\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Freezes an account.\n     * @dev MUST only be callable by the FREEZE_MANAGER_ROLE.\n     * @param account The address of the account to freeze.\n     */\n    function freeze(address account) external;\n\n    /**\n     * @notice Freezes multiple accounts.\n     * @dev MUST only be callable by the FREEZE_MANAGER_ROLE.\n     * @param accounts The list of addresses to freeze.\n     */\n    function freezeAccounts(address[] calldata accounts) external;\n\n    /**\n     * @notice Unfreezes an account.\n     * @dev MUST only be callable by the FREEZE_MANAGER_ROLE.\n     * @param account The address of the account to unfreeze.\n     */\n    function unfreeze(address account) external;\n\n    /**\n     * @notice Unfreezes multiple accounts.\n     * @dev MUST only be callable by the FREEZE_MANAGER_ROLE.\n     * @param accounts The list of addresses to unfreeze.\n     */\n    function unfreezeAccounts(address[] calldata accounts) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role that can manage the freezelist.\n    function FREEZE_MANAGER_ROLE() external view returns (bytes32);\n\n    /**\n     * @notice Returns whether an account is frozen or not.\n     * @param account The address of the account to check.\n     * @return True if the account is frozen, false otherwise.\n     */\n    function isFrozen(address account) external view returns (bool);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC712.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\n/**\n * @title  Typed structured data hashing and signing via EIP-712.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-712: https://eips.ethereum.org/EIPS/eip-712\n */\ninterface IERC712 {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Revert message when an invalid signature is detected.\n    error InvalidSignature();\n\n    /// @notice Revert message when a signature with invalid length is detected.\n    error InvalidSignatureLength();\n\n    /// @notice Revert message when the S portion of a signature is invalid.\n    error InvalidSignatureS();\n\n    /// @notice Revert message when the V portion of a signature is invalid.\n    error InvalidSignatureV();\n\n    /**\n     * @notice Revert message when a signature is being used beyond its deadline (i.e. expiry).\n     * @param  deadline  The last timestamp where the signature is still valid.\n     * @param  timestamp The current timestamp.\n     */\n    error SignatureExpired(uint256 deadline, uint256 timestamp);\n\n    /// @notice Revert message when a recovered signer does not match the account being purported to have signed.\n    error SignerMismatch();\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the EIP712 domain separator used in the encoding of a signed digest.\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC20Extended.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IERC20 } from \"./IERC20.sol\";\nimport { IERC3009 } from \"./IERC3009.sol\";\n\n/**\n * @title  An ERC20 token extended with EIP-2612 permits for signed approvals (via EIP-712\n *         and with EIP-1271 compatibility), and extended with EIP-3009 transfer with authorization (via EIP-712).\n * @author M^0 Labs\n * @dev    The additional interface as defined by EIP-2612: https://eips.ethereum.org/EIPS/eip-2612\n */\ninterface IERC20Extended is IERC20, IERC3009 {\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Revert message when spender's allowance is not sufficient.\n     * @param  spender    Address that may be allowed to operate on tokens without being their owner.\n     * @param  allowance  Amount of tokens a `spender` is allowed to operate with.\n     * @param  needed     Minimum amount required to perform a transfer.\n     */\n    error InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @notice Revert message emitted when the transferred amount is insufficient.\n     * @param  amount Amount transferred.\n     */\n    error InsufficientAmount(uint256 amount);\n\n    /**\n     * @notice Revert message emitted when the recipient of a token is invalid.\n     * @param  recipient Address of the invalid recipient.\n     */\n    error InvalidRecipient(address recipient);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Approves `spender` to spend up to `amount` of the token balance of `owner`, via a signature.\n     * @param  owner    The address of the account who's token balance is being approved to be spent by `spender`.\n     * @param  spender  The address of an account allowed to spend on behalf of `owner`.\n     * @param  value    The amount of the allowance being approved.\n     * @param  deadline The last timestamp where the signature is still valid.\n     * @param  v        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n     * @param  r        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\n     * @param  s        An ECDSA secp256k1 signature parameter (EIP-2612 via EIP-712).\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     * @notice Approves `spender` to spend up to `amount` of the token balance of `owner`, via a signature.\n     * @param  owner     The address of the account who's token balance is being approved to be spent by `spender`.\n     * @param  spender   The address of an account allowed to spend on behalf of `owner`.\n     * @param  value     The amount of the allowance being approved.\n     * @param  deadline  The last timestamp where the signature is still valid.\n     * @param  signature An arbitrary signature (EIP-712).\n     */\n    function permit(address owner, address spender, uint256 value, uint256 deadline, bytes memory signature) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice Returns the EIP712 typehash used in the encoding of the digest for the permit function.\n    function PERMIT_TYPEHASH() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)\n// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots\n * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by\n * the solidity language / compiler.\n *\n * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].\n *\n * Example usage:\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using StorageSlot for bytes32;\n *     using SlotDerivation for bytes32;\n *\n *     // Declare a namespace\n *     string private constant _NAMESPACE = \"<namespace>\"; // eg. OpenZeppelin.Slot\n *\n *     function setValueInNamespace(uint256 key, address newValue) internal {\n *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;\n *     }\n *\n *     function getValueInNamespace(uint256 key) internal view returns (address) {\n *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {StorageSlot}.\n *\n * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking\n * upgrade safety will ignore the slots accessed through this library.\n *\n * _Available since v5.1._\n */\nlibrary SlotDerivation {\n    /**\n     * @dev Derive an ERC-7201 slot from a string (namespace).\n     */\n    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))\n            slot := and(keccak256(0x00, 0x20), not(0xff))\n        }\n    }\n\n    /**\n     * @dev Add an offset to a slot to get the n-th element of a structure or an array.\n     */\n    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {\n        unchecked {\n            return bytes32(uint256(slot) + pos);\n        }\n    }\n\n    /**\n     * @dev Derive the location of the first element in an array from the slot where the length is stored.\n     */\n    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, slot)\n            result := keccak256(0x00, 0x20)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, and(key, shr(96, not(0))))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, iszero(iszero(key)))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/platform/interfaces/IExtension.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\nimport { IERC20Extended } from \"../../../lib/evm-m-extensions/lib/common/src/interfaces/IERC20Extended.sol\";\n\n/// @title  PYUSDX Extension interface extending Extended ERC20.\n/// @author M0 Labs\ninterface IExtension is IERC20Extended {\n    /* ============ Custom Errors ============ */\n\n    /// @notice Emitted when there is insufficient balance to decrement from `account`.\n    /// @param  account The account with insufficient balance.\n    /// @param  balance The balance of the account.\n    /// @param  amount  The amount to decrement.\n    error InsufficientBalance(address account, uint256 balance, uint256 amount);\n\n    /// @notice Emitted when the account is address(0).\n    error ZeroAccount();\n\n    /// @notice Emitted when the amount is 0.\n    error ZeroAmount();\n\n    /// @notice Emitted in constructor if PYUSDX is 0x0.\n    error ZeroPYUSDX();\n\n    /// @notice Emitted in constructor if swap facility is 0x0.\n    error ZeroSwapFacility();\n\n    /// @notice Emitted when the caller is not the swap facility.\n    error NotSwapFacility();\n\n    /// @notice Emitted when attempting to unpin a proxy that is not pinned.\n    error NotPinned();\n\n    /// @notice Emitted when pinning to version 0.\n    error ZeroVersion();\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Wraps `amount` PYUSDX from the caller into extension token for `recipient`.\n    /// @dev    Pulls PYUSDX from `msg.sender` via `transferFrom`. Only callable by the swap facility.\n    /// @param  recipient The account receiving the minted extension token.\n    /// @param  amount    The amount of extension token minted.\n    function wrap(address recipient, uint256 amount) external;\n\n    /// @notice Unwraps `amount` extension token from the caller back into PYUSDX.\n    /// @dev    Burns extension tokens from `msg.sender` and transfers PYUSDX to `msg.sender`.\n    ///         Only callable by the swap facility.\n    /// @param  amount The amount of extension token burned.\n    function unwrap(uint256 amount) external;\n\n    /// @notice Pins this proxy to a specific implementation version.\n    /// @dev    Only callable by an address with VERSION_MANAGER_ROLE.\n    /// @param  version The version number to pin to (must be > 0).\n    function pinVersion(uint256 version) external;\n\n    /// @notice Unpins this proxy, restoring beacon-follows-latest behavior.\n    /// @dev    Only callable by an address with VERSION_MANAGER_ROLE.\n    function unpinVersion() external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The address of the PYUSDX token contract.\n    function pyusdx() external view returns (address);\n\n    /// @notice The address of the swap facility contract.\n    function swapFacility() external view returns (address);\n\n    /// @notice Returns the origin beacon address (set at construction, never changes).\n    /// @return The origin beacon address.\n    function originBeacon() external view returns (address);\n\n    /// @notice Returns whether the proxy is currently pinned to a specific implementation.\n    /// @return True if pinned, false if following the beacon's latest.\n    function isPinned() external view returns (bool);\n\n    /// @notice Returns the pinned implementation address, or address(0) if not pinned.\n    /// @return The pinned implementation address.\n    function pinnedImplementation() external view returns (address);\n\n    /// @notice Role required to call `pinVersion` / `unpinVersion`.\n    function VERSION_MANAGER_ROLE() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.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 ERC-165 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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1967.sol)\n\npragma solidity >=0.4.11;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/ERC3009Upgradeable.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { Initializable } from \"../lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\";\nimport { IERC3009 } from \"./interfaces/IERC3009.sol\";\n\nimport { StatefulERC712Upgradeable } from \"./StatefulERC712Upgradeable.sol\";\n\nabstract contract ERC3009UpgradeableStorageLayout {\n    /// @custom:storage-location erc7201:M0.storage.ERC3009\n    struct ERC3009StorageStruct {\n        mapping(address authorizer => mapping(bytes32 nonce => bool isNonceUsed)) authorizationState;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"M0.storage.ERC3009\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _ERC3009_STORAGE_LOCATION =\n        0x1116a1d33aa5fb91b2652b3b0fdb63704173742d6dbecaf4256ebe33a4888600;\n\n    function _getERC3009StorageLocation() internal pure returns (ERC3009StorageStruct storage $) {\n        assembly {\n            $.slot := _ERC3009_STORAGE_LOCATION\n        }\n    }\n}\n\n/**\n * @title  ERC3009 implementation allowing the transfer of fungible assets via a signed authorization.\n * @author M0 Labs\n * @dev    Inherits from ERC712ExtendedUpgradeable and StatefulERC712Upgradeable.\n */\nabstract contract ERC3009Upgradeable is IERC3009, ERC3009UpgradeableStorageLayout, StatefulERC712Upgradeable {\n    /* ============ Variables ============ */\n\n    // solhint-disable-next-line max-line-length\n    /// @dev        keccak256(\"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    /// @inheritdoc IERC3009\n    bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =\n        0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;\n\n    // solhint-disable-next-line max-line-length\n    /// @dev        keccak256(\"ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\n    /// @inheritdoc IERC3009\n    bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH =\n        0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;\n\n    /**\n     * @inheritdoc IERC3009\n     * @dev        keccak256(\"CancelAuthorization(address authorizer,bytes32 nonce)\")\n     */\n    bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH =\n        0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;\n\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the ERC3009Upgradeable contract.\n     * @param  name_ The name of the contract.\n     */\n    function __ERC3009Upgradeable_init(string memory name_) internal onlyInitializing {\n        __StatefulERC712ExtendedUpgradeable_init(name_);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            signature_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes32 r_,\n        bytes32 vs_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            r_,\n            vs_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getTransferWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            v_,\n            r_,\n            s_\n        );\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes memory signature_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            signature_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        bytes32 r_,\n        bytes32 vs_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            r_,\n            vs_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_,\n        uint8 v_,\n        bytes32 r_,\n        bytes32 s_\n    ) external {\n        _revertIfInvalidSignature(\n            from_,\n            _getReceiveWithAuthorizationDigest(from_, to_, value_, validAfter_, validBefore_, nonce_),\n            v_,\n            r_,\n            s_\n        );\n\n        _receiveWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, bytes memory signature_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), signature_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, bytes32 r_, bytes32 vs_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), r_, vs_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /// @inheritdoc IERC3009\n    function cancelAuthorization(address authorizer_, bytes32 nonce_, uint8 v_, bytes32 r_, bytes32 s_) external {\n        _revertIfInvalidSignature(authorizer_, _getCancelAuthorizationDigest(authorizer_, nonce_), v_, r_, s_);\n        _cancelAuthorization(authorizer_, nonce_);\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IERC3009\n    function authorizationState(address authorizer, bytes32 nonce) public view returns (bool) {\n        return _getERC3009StorageLocation().authorizationState[authorizer][nonce];\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Common transfer function used by `transferWithAuthorization` and `_receiveWithAuthorization`.\n     * @param from_        Payer's address (Authorizer).\n     * @param to_          Payee's address.\n     * @param value_       Amount to be transferred.\n     * @param validAfter_  The time after which this is valid (unix time).\n     * @param validBefore_ The time before which this is valid (unix time).\n     * @param nonce_       Unique nonce.\n     */\n    function _transferWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal {\n        if (block.timestamp <= validAfter_) revert AuthorizationNotYetValid(block.timestamp, validAfter_);\n        if (block.timestamp >= validBefore_) revert AuthorizationExpired(block.timestamp, validBefore_);\n\n        _revertIfAuthorizationAlreadyUsed(from_, nonce_);\n\n        _getERC3009StorageLocation().authorizationState[from_][nonce_] = true;\n\n        emit AuthorizationUsed(from_, nonce_);\n\n        _transfer(from_, to_, value_);\n    }\n\n    /**\n     * @dev   Common receive function used by `receiveWithAuthorization`.\n     * @param from_        Payer's address (Authorizer).\n     * @param to_          Payee's address.\n     * @param value_       Amount to be transferred.\n     * @param validAfter_  The time after which this is valid (unix time).\n     * @param validBefore_ The time before which this is valid (unix time).\n     * @param nonce_       Unique nonce.\n     */\n    function _receiveWithAuthorization(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal {\n        if (msg.sender != to_) revert CallerMustBePayee(msg.sender, to_);\n\n        _transferWithAuthorization(from_, to_, value_, validAfter_, validBefore_, nonce_);\n    }\n\n    /**\n     * @dev   Common cancel function used by `cancelAuthorization`.\n     * @param authorizer_ Authorizer's address.\n     * @param nonce_      Nonce of the authorization.\n     */\n    function _cancelAuthorization(address authorizer_, bytes32 nonce_) internal {\n        _revertIfAuthorizationAlreadyUsed(authorizer_, nonce_);\n\n        _getERC3009StorageLocation().authorizationState[authorizer_][nonce_] = true;\n\n        emit AuthorizationCanceled(authorizer_, nonce_);\n    }\n\n    /**\n     * @dev   Internal ERC20 transfer function that needs to be implemented by the inheriting contract.\n     * @param sender_    The sender's address.\n     * @param recipient_ The recipient's address.\n     * @param amount_    The amount to be transferred.\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) internal virtual;\n\n    /* ============ Internal View/Pure Functions ============ */\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a transferWithAuthorization call.\n     * @param  from_        Payer's address (Authorizer).\n     * @param  to_          Payee's address.\n     * @param  value_       Amount to be transferred.\n     * @param  validAfter_  The time after which this is valid (unix time).\n     * @param  validBefore_ The time before which this is valid (unix time).\n     * @param  nonce_       Unique nonce.\n     * @return The internal EIP-712 digest.\n     */\n    function _getTransferWithAuthorizationDigest(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal view returns (bytes32) {\n        return\n            _getDigest(\n                keccak256(\n                    abi.encode(\n                        TRANSFER_WITH_AUTHORIZATION_TYPEHASH,\n                        from_,\n                        to_,\n                        value_,\n                        validAfter_,\n                        validBefore_,\n                        nonce_\n                    )\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a receiveWithAuthorization call.\n     * @param  from_        Payer's address (Authorizer).\n     * @param  to_          Payee's address.\n     * @param  value_       Amount to be transferred.\n     * @param  validAfter_  The time after which this is valid (unix time).\n     * @param  validBefore_ The time before which this is valid (unix time).\n     * @param  nonce_       Unique nonce.\n     * @return The internal EIP-712 digest.\n     */\n    function _getReceiveWithAuthorizationDigest(\n        address from_,\n        address to_,\n        uint256 value_,\n        uint256 validAfter_,\n        uint256 validBefore_,\n        bytes32 nonce_\n    ) internal view returns (bytes32) {\n        return\n            _getDigest(\n                keccak256(\n                    abi.encode(\n                        RECEIVE_WITH_AUTHORIZATION_TYPEHASH,\n                        from_,\n                        to_,\n                        value_,\n                        validAfter_,\n                        validBefore_,\n                        nonce_\n                    )\n                )\n            );\n    }\n\n    /**\n     * @dev    Returns the internal EIP-712 digest of a cancelAuthorization call.\n     * @param  authorizer_ Authorizer's address.\n     * @param  nonce_      Nonce of the authorization.\n     * @return The internal EIP-712 digest.\n     */\n    function _getCancelAuthorizationDigest(address authorizer_, bytes32 nonce_) internal view returns (bytes32) {\n        return _getDigest(keccak256(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer_, nonce_)));\n    }\n\n    /**\n     * @dev   Reverts if the authorization is already used.\n     * @param authorizer_ The authorizer's address.\n     * @param nonce_      The nonce of the authorization.\n     */\n    function _revertIfAuthorizationAlreadyUsed(address authorizer_, bytes32 nonce_) internal view {\n        if (authorizationState(authorizer_, nonce_)) revert AuthorizationAlreadyUsed(authorizer_, nonce_);\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC3009.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\nimport { IStatefulERC712 } from \"./IStatefulERC712.sol\";\n\n/**\n * @title  Transfer via signed authorization following EIP-3009 standard.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-3009: https://eips.ethereum.org/EIPS/eip-3009\n */\ninterface IERC3009 is IStatefulERC712 {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when an authorization has been canceled.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the canceled authorization.\n     */\n    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);\n\n    /**\n     * @notice Emitted when an authorization has been used.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the used authorization.\n     */\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\n\n    /* ============ Custom Errors ============ */\n\n    /**\n     * @notice Emitted when an authorization has already been used.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the used authorization.\n     */\n    error AuthorizationAlreadyUsed(address authorizer, bytes32 nonce);\n\n    /**\n     * @notice Emitted when an authorization is expired.\n     * @param  timestamp   Timestamp at which the transaction was submitted.\n     * @param  validBefore Timestamp before which the authorization would have been valid.\n     */\n    error AuthorizationExpired(uint256 timestamp, uint256 validBefore);\n\n    /**\n     * @notice Emitted when an authorization is not yet valid.\n     * @param  timestamp  Timestamp at which the transaction was submitted.\n     * @param  validAfter Timestamp after which the authorization will be valid.\n     */\n    error AuthorizationNotYetValid(uint256 timestamp, uint256 validAfter);\n\n    /**\n     * @notice Emitted when the caller of `receiveWithAuthorization` is not the payee.\n     * @param  caller Caller's address.\n     * @param  payee  Payee's address.\n     */\n    error CallerMustBePayee(address caller, address payee);\n\n    /* ============ Interactive Functions ============ */\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  signature   A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) external;\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  r           An ECDSA/secp256k1 signature parameter.\n     * @param  vs          An ECDSA/secp256k1 short signature parameter.\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes32 r,\n        bytes32 vs\n    ) external;\n\n    /**\n     * @notice Execute a transfer with a signed authorization.\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  v           v of the signature.\n     * @param  r           r of the signature.\n     * @param  s           s of the signature.\n     */\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  signature   A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes memory signature\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  r           An ECDSA/secp256k1 signature parameter.\n     * @param  vs          An ECDSA/secp256k1 short signature parameter.\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        bytes32 r,\n        bytes32 vs\n    ) external;\n\n    /**\n     * @notice Receive a transfer with a signed authorization from the payer.\n     * @dev    This has an additional check to ensure that the payee's address matches\n     *         the caller of this function to prevent front-running attacks.\n     *         (See security considerations)\n     * @param  from        Payer's address (Authorizer).\n     * @param  to          Payee's address.\n     * @param  value       Amount to be transferred.\n     * @param  validAfter  The time after which this is valid (unix time).\n     * @param  validBefore The time before which this is valid (unix time).\n     * @param  nonce       Unique nonce.\n     * @param  v           v of the signature.\n     * @param  r           r of the signature.\n     * @param  s           s of the signature.\n     */\n    function receiveWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  signature  A byte array ECDSA/secp256k1 signature (encoded r, s, v).\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, bytes memory signature) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  r          An ECDSA/secp256k1 signature parameter.\n     * @param  vs         An ECDSA/secp256k1 short signature parameter.\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, bytes32 r, bytes32 vs) external;\n\n    /**\n     * @notice Attempt to cancel an authorization.\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @param  v          v of the signature.\n     * @param  r          r of the signature.\n     * @param  s          s of the signature.\n     */\n    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /**\n     * @notice Returns the state of an authorization.\n     * @dev    Nonces are randomly generated 32-byte data unique to the authorizer's address\n     * @param  authorizer Authorizer's address.\n     * @param  nonce      Nonce of the authorization.\n     * @return True if the nonce is used.\n     */\n    function authorizationState(address authorizer, bytes32 nonce) external view returns (bool);\n\n    /// @notice Returns `transferWithAuthorization` typehash.\n    function TRANSFER_WITH_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n\n    /// @notice Returns `receiveWithAuthorization` typehash.\n    function RECEIVE_WITH_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n\n    /// @notice Returns `cancelAuthorization` typehash.\n    function CANCEL_AUTHORIZATION_TYPEHASH() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.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 allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable\n    struct PausableStorage {\n        bool _paused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Pausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;\n\n    function _getPausableStorage() private pure returns (PausableStorage storage $) {\n        assembly {\n            $.slot := PausableStorageLocation\n        }\n    }\n\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    function __Pausable_init() internal onlyInitializing {\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        PausableStorage storage $ = _getPausableStorage();\n        return $._paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\n        }\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.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/bool 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    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/forcedTransferable/IForcedTransferable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\nimport { IArrayErrors } from \"../../interfaces/IArrayErrors.sol\";\n\ninterface IForcedTransferable is IArrayErrors {\n    /* ============ Events ============ */\n\n    /**\n     * @notice Emitted when tokens are forcefully transferred from a frozen account.\n     */\n    event ForcedTransfer(\n        address indexed frozenAccount,\n        address indexed recipient,\n        address indexed forcedTransferManager,\n        uint256 amount\n    );\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Error for zero forced transfer manager address\n    error ZeroForcedTransferManager();\n\n    /* ============ Interactive Functions ============ */\n    /**\n     * @notice Forcefully transfers tokens from a frozen account to a recipient.\n     * @dev    MUST only be callable by the FORCE_TRANSFER_MANAGER_ROLE.\n     * @dev    SHOULD revert if `frozenAccount` is not frozen.\n     * @dev    SHOULD revert if `recipient` is the zero address.\n     * @dev    SHOULD revert if `amount` exceeds the balance of `frozenAccount`.\n     * @param  frozenAccount The address of the frozen account from which tokens are seized.\n     * @param  recipient     The address receiving the seized tokens.\n     * @param  amount        The amount of tokens to transfer.\n     */\n    function forceTransfer(address frozenAccount, address recipient, uint256 amount) external;\n\n    /**\n     * @notice Forcefully transfers tokens from multiple frozen accounts to multiple recipients.\n     * @dev    MUST only be callable by the FORCE_TRANSFER_MANAGER_ROLE.\n     * @dev    SHOULD revert if any `frozenAccount` is not frozen.\n     * @dev    SHOULD revert if array lengths do not match.\n     * @dev    SHOULD revert if any `recipient` is the zero address.\n     * @dev    SHOULD revert if any `amount` exceeds the balance of the corresponding `frozenAccount`.\n     * @param  frozenAccounts The array of frozen accounts from which tokens are seized.\n     * @param  recipients     The array of recipient addresses.\n     * @param  amounts        The array of amounts to transfer for each account.\n     */\n    function forceTransfers(\n        address[] calldata frozenAccounts,\n        address[] calldata recipients,\n        uint256[] calldata amounts\n    ) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role that can manage force transfers.\n    function FORCED_TRANSFER_MANAGER_ROLE() external view returns (bytes32);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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"},{"file_path":"lib/PYUSDX/src/platform/projects/MultiMint.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.34;\n\nimport { EnumerableSet } from \"../../../lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol\";\nimport { SafeERC20 } from \"../../../lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { UIntMath } from \"../../../lib/evm-m-extensions/lib/common/src/libs/UIntMath.sol\";\n\nimport { IERC20Metadata } from \"../../../lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { IERC20 } from \"../../../lib/evm-m-extensions/lib/common/src/interfaces/IERC20.sol\";\n\nimport { YieldToOne } from \"./YieldToOne.sol\";\n\nimport { IMultiMint } from \"./interfaces/IMultiMint.sol\";\nimport { ISwapFacility } from \"../../swap/interfaces/ISwapFacility.sol\";\n\nabstract contract MultiMintStorageLayout {\n    struct Asset {\n        uint256 cap;\n        uint240 balance;\n        uint8 decimals;\n    }\n\n    /// @custom:storage-location erc7201:PYUSDX.storage.MultiMint\n    struct MultiMintStorage {\n        mapping(address => Asset) assets;\n        uint256 totalAssets;\n        EnumerableSet.AddressSet replaceAssetWhitelist;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"PYUSDX.storage.MultiMint\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant _MULTI_MINT_STORAGE_LOCATION =\n        0x57e19e611dcbdde2876919e2fe591d15cb50f046f296d11a2b28e0b3b8b3f900;\n\n    function _getMultiMintStorage() internal pure virtual returns (MultiMintStorage storage $) {\n        bytes32 location = _MULTI_MINT_STORAGE_LOCATION;\n        assembly {\n            $.slot := location\n        }\n    }\n}\n\n/// @title  MultiMint\n/// @notice Upgradeable ERC20 token for wrapping PYUSDX or approved alternative stablecoins\n///         into a token with yield claimable by a single recipient.\n/// @dev    Extends YieldToOne with a multi-collateral backing model. Users\n///         can mint by depositing PYUSDX. Unwrapping always returns PYUSDX, other\n///         stablecoins can only be extracted via `replaceAsset`.\n/// @author M0 Labs\ncontract MultiMint is IMultiMint, MultiMintStorageLayout, YieldToOne {\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using SafeERC20 for IERC20Metadata;\n\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IMultiMint\n    bytes32 public constant ASSET_CAP_MANAGER_ROLE = keccak256(\"ASSET_CAP_MANAGER_ROLE\");\n\n    /// @inheritdoc IMultiMint\n    uint8 public constant PYUSDX_DECIMALS = 6;\n\n    /* ============ Constructor ============ */\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    /// @param pyusdx_       The address of the PYUSDX token.\n    /// @param swapFacility_ The address of the swap facility.\n    constructor(address pyusdx_, address swapFacility_) YieldToOne(pyusdx_, swapFacility_) {}\n\n    /* ============ Initializer ============ */\n\n    /// @notice Initializes the MultiMint extension token.\n    /// @param  name                  The name of the token.\n    /// @param  symbol                The symbol of the token.\n    /// @param  yieldRecipient_       The address of the yield recipient.\n    /// @param  admin                 The address of the admin.\n    /// @param  assetCapManager       The address of the asset cap manager.\n    /// @param  freezeManager         The address of the freeze manager.\n    /// @param  pauser                The address of the pauser.\n    /// @param  yieldRecipientManager The address of the yield recipient manager.\n    /// @param  versionManager        The address of the version manager.\n    function initialize(\n        string memory name,\n        string memory symbol,\n        address yieldRecipient_,\n        address admin,\n        address assetCapManager,\n        address freezeManager,\n        address pauser,\n        address yieldRecipientManager,\n        address versionManager\n    ) public virtual initializer {\n        __MultiMint_init(\n            name,\n            symbol,\n            yieldRecipient_,\n            admin,\n            assetCapManager,\n            freezeManager,\n            pauser,\n            yieldRecipientManager,\n            versionManager\n        );\n    }\n\n    /// @dev   Internal initializer for MultiMint. Grants ASSET_CAP_MANAGER_ROLE\n    ///        and delegates to `__YieldToOne_init`.\n    /// @param name                  The name of the token.\n    /// @param symbol                The symbol of the token.\n    /// @param yieldRecipient_       The address of the yield recipient.\n    /// @param admin                 The address of the admin.\n    /// @param assetCapManager       The address of the asset cap manager.\n    /// @param freezeManager         The address of the freeze manager.\n    /// @param pauser                The address of the pauser.\n    /// @param yieldRecipientManager The address of the yield recipient manager.\n    /// @param versionManager        The address of the version manager.\n    function __MultiMint_init(\n        string memory name,\n        string memory symbol,\n        address yieldRecipient_,\n        address admin,\n        address assetCapManager,\n        address freezeManager,\n        address pauser,\n        address yieldRecipientManager,\n        address versionManager\n    ) internal onlyInitializing {\n        if (assetCapManager == address(0)) revert ZeroAssetCapManager();\n\n        __YieldToOne_init(\n            name,\n            symbol,\n            yieldRecipient_,\n            admin,\n            freezeManager,\n            pauser,\n            yieldRecipientManager,\n            versionManager\n        );\n\n        _grantRole(ASSET_CAP_MANAGER_ROLE, assetCapManager);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IMultiMint\n    function wrap(address asset, address recipient, uint256 amount) external onlySwapFacility {\n        _wrapAsset(asset, ISwapFacility(msg.sender).msgSender(), recipient, amount);\n    }\n\n    /// @inheritdoc IMultiMint\n    function replaceAsset(address asset, address recipient, uint256 amount) external onlySwapFacility {\n        _replaceAsset(asset, recipient, amount);\n    }\n\n    /// @inheritdoc IMultiMint\n    function setAssetCap(address asset, uint256 cap) external onlyRole(ASSET_CAP_MANAGER_ROLE) {\n        _revertIfInvalidAsset(asset);\n\n        MultiMintStorage storage $ = _getMultiMintStorage();\n\n        if ($.assets[asset].cap == cap) return;\n\n        if ($.assets[asset].decimals == 0) $.assets[asset].decimals = IERC20Metadata(asset).decimals();\n\n        $.assets[asset].cap = cap;\n\n        emit AssetCapSet(asset, cap);\n    }\n\n    /// @inheritdoc IMultiMint\n    function setReplaceAssetWhitelistCaller(address caller, bool allowed) external onlyRole(ASSET_CAP_MANAGER_ROLE) {\n        _setReplaceAssetWhitelistCaller(caller, allowed);\n    }\n\n    /// @inheritdoc IMultiMint\n    function setReplaceAssetWhitelistCaller(\n        address[] calldata callers,\n        bool[] calldata allowed\n    ) external onlyRole(ASSET_CAP_MANAGER_ROLE) {\n        if (callers.length != allowed.length) revert ArrayLengthMismatch();\n\n        for (uint256 i; i < callers.length; ++i) {\n            _setReplaceAssetWhitelistCaller(callers[i], allowed[i]);\n        }\n    }\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @inheritdoc IMultiMint\n    function assetBalanceOf(address asset) public view returns (uint256) {\n        return _getMultiMintStorage().assets[asset].balance;\n    }\n\n    /// @inheritdoc IMultiMint\n    function assetCap(address asset) public view returns (uint256) {\n        return _getMultiMintStorage().assets[asset].cap;\n    }\n\n    /// @inheritdoc IMultiMint\n    function assetDecimals(address asset) public view returns (uint8) {\n        return _getMultiMintStorage().assets[asset].decimals;\n    }\n\n    /// @inheritdoc IMultiMint\n    function totalAssets() public view returns (uint256) {\n        return _getMultiMintStorage().totalAssets;\n    }\n\n    /// @inheritdoc IMultiMint\n    function isAllowedAsset(address asset) public view returns (bool) {\n        return assetCap(asset) != 0;\n    }\n\n    /// @inheritdoc IMultiMint\n    function isAllowedToWrap(address asset, uint256 amount) public view returns (bool) {\n        if (amount == 0) return false;\n\n        uint256 extensionAmount = _fromAssetToExtensionAmount(asset, amount);\n        if (extensionAmount == 0) return false;\n\n        uint256 effectiveAmount = _fromExtensionToAssetAmount(asset, extensionAmount);\n        return assetCap(asset) >= (assetBalanceOf(asset) + effectiveAmount);\n    }\n\n    /// @inheritdoc IMultiMint\n    function isAllowedToUnwrap(uint256 amount) external view returns (bool) {\n        return amount != 0 && _pyusdxBacking() >= amount;\n    }\n\n    /// @inheritdoc IMultiMint\n    function isReplaceAssetWhitelistEnabled() external view returns (bool) {\n        return _getMultiMintStorage().replaceAssetWhitelist.length() != 0;\n    }\n\n    /// @inheritdoc IMultiMint\n    function getReplaceAssetWhitelist() external view returns (address[] memory) {\n        return _getMultiMintStorage().replaceAssetWhitelist.values();\n    }\n\n    /// @inheritdoc IMultiMint\n    function isAllowedToReplaceAsset(address caller, address asset, uint256 amount) external view returns (bool) {\n        if (amount == 0 || !isAllowedAsset(asset) || !_isCallerAllowedToReplaceAsset(caller)) return false;\n\n        uint256 assetAmount = _fromExtensionToAssetAmount(asset, amount);\n        return assetAmount != 0 && assetBalanceOf(asset) >= assetAmount;\n    }\n\n    /* ============ Hooks ============ */\n\n    /// @dev   Hook called before wrapping `asset` into extension's tokens.\n    /// @param asset     Address of the asset being deposited.\n    /// @param account   The account initiating the wrap.\n    /// @param recipient The address that will receive extension tokens.\n    /// @param amount    The amount of `asset` being deposited.\n    function _beforeWrap(address asset, address account, address recipient, uint256 amount) internal view virtual {\n        if (!isAllowedToWrap(asset, amount)) revert AssetCapReached(asset);\n\n        super._beforeWrap(account, recipient, amount);\n    }\n\n    /// @dev   Hook called before unwrapping extension tokens for PYUSDX.\n    ///        Adds PYUSDX backing check before the inherited pause+freeze\n    ///        checks.\n    /// @param account The account from which tokens are burned.\n    /// @param amount  The amount of extension tokens to unwrap.\n    function _beforeUnwrap(address account, uint256 amount) internal view virtual override {\n        _revertIfInsufficientPYUSDXBacking(amount);\n\n        super._beforeUnwrap(account, amount);\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /// @dev   Mints extension tokens by pulling `asset` from `msg.sender`.\n    ///        Reverts on fee-on-transfer tokens or if the asset cap is reached.\n    ///        For assets with more decimals than the extension, only the\n    ///        non-dust portion is pulled; any dust is left with `msg.sender`\n    ///        so that `assetBalance == totalAssets * factor` always holds.\n    /// @param asset     Address of the asset to deposit.\n    /// @param account   The original caller (resolved via swap facility).\n    /// @param recipient Address that will receive the extension tokens.\n    /// @param amount    Amount of `asset` tokens to deposit (in asset decimals).\n    function _wrapAsset(address asset, address account, address recipient, uint256 amount) internal virtual {\n        _revertIfInvalidAsset(asset);\n        _revertIfZeroAccount(recipient);\n        _revertIfZeroAmount(amount);\n\n        // Convert to extension decimals and revert if it truncates to zero.\n        uint256 extensionAmount = _fromAssetToExtensionAmount(asset, amount);\n        _revertIfZeroAmount(extensionAmount);\n\n        // Round amount down to the largest non-dust multiple of factor. For\n        // assets with decimals <= 6 this equals `amount`; for higher decimals\n        // it discards the truncating-division dust so the asset/extension\n        // accounting stays exact across repeated wraps.\n        uint256 effectiveAmount = _fromExtensionToAssetAmount(asset, extensionAmount);\n\n        // Checks asset cap + pause + freeze via 4-arg hook.\n        _beforeWrap(asset, account, recipient, effectiveAmount);\n\n        uint256 assetBalanceBefore = IERC20Metadata(asset).balanceOf(address(this));\n\n        // Pull only the non-dust portion from caller.\n        IERC20Metadata(asset).safeTransferFrom(msg.sender, address(this), effectiveAmount);\n\n        // Fee-on-transfer detection.\n        uint256 amountReceived = IERC20Metadata(asset).balanceOf(address(this)) - assetBalanceBefore;\n\n        if (amountReceived < effectiveAmount) {\n            revert InsufficientAssetReceived(asset, effectiveAmount, amountReceived);\n        }\n\n        MultiMintStorage storage $ = _getMultiMintStorage();\n\n        // Update non-PYUSDX asset backing.\n        $.assets[asset].balance += UIntMath.safe240(effectiveAmount);\n        $.totalAssets += extensionAmount;\n\n        _mint(recipient, extensionAmount);\n\n        emit AssetWrapped(asset, effectiveAmount, recipient, extensionAmount);\n    }\n\n    /// @dev   Pulls PYUSDX from `msg.sender` and sends `asset` from reserves to `recipient`.\n    /// @param asset     Address of the asset to receive from reserves.\n    /// @param recipient Address that will receive the `asset` tokens.\n    /// @param amount    Amount of PYUSDX to deposit (in PYUSDX decimals).\n    function _replaceAsset(address asset, address recipient, uint256 amount) internal virtual {\n        _requireNotPaused();\n\n        _revertIfInvalidAsset(asset);\n        if (!isAllowedAsset(asset)) revert AssetNotAllowed(asset);\n\n        address caller = ISwapFacility(msg.sender).msgSender();\n        if (!_isCallerAllowedToReplaceAsset(caller)) revert CallerNotAllowed(caller);\n\n        _revertIfZeroAccount(recipient);\n        _revertIfZeroAmount(amount);\n\n        // Convert PYUSDX amount to asset decimals and revert if truncates to zero.\n        uint256 assetAmount = _fromExtensionToAssetAmount(asset, amount);\n\n        _revertIfZeroAmount(assetAmount);\n        _revertIfInsufficientAssetBacking(asset, assetAmount);\n\n        MultiMintStorage storage $ = _getMultiMintStorage();\n\n        // Update non-PYUSDX asset backing.\n        $.assets[asset].balance -= UIntMath.safe240(assetAmount);\n        $.totalAssets -= amount;\n\n        // Pull PYUSDX from caller.\n        IERC20(pyusdx).transferFrom(msg.sender, address(this), amount);\n\n        // Send alt-asset to recipient.\n        IERC20Metadata(asset).safeTransfer(recipient, assetAmount);\n\n        emit AssetReplaced(asset, assetAmount, recipient, amount);\n    }\n\n    /// @dev   Adds or removes `caller` from the replaceAsset whitelist.\n    ///        Emits `ReplaceAssetWhitelistCallerSet` only when state actually changes.\n    /// @param caller  The caller to add or remove.\n    /// @param allowed True to add, false to remove.\n    function _setReplaceAssetWhitelistCaller(address caller, bool allowed) internal {\n        _revertIfZeroAccount(caller);\n\n        EnumerableSet.AddressSet storage whitelist = _getMultiMintStorage().replaceAssetWhitelist;\n        bool changed = allowed ? whitelist.add(caller) : whitelist.remove(caller);\n\n        if (!changed) return;\n\n        emit ReplaceAssetWhitelistCallerSet(caller, allowed);\n    }\n\n    /* ============ Internal View Functions ============ */\n\n    /// @dev Returns the excess PYUSDX balance that is not backing extension tokens.\n    function _excess() internal view virtual override returns (uint256) {\n        uint256 pyusdxBalance = _pyusdxBalanceOf(address(this));\n        uint256 pyusdxBacking = _pyusdxBacking();\n\n        unchecked {\n            return pyusdxBalance > pyusdxBacking ? pyusdxBalance - pyusdxBacking : 0;\n        }\n    }\n\n    /// @dev Returns the current supply of PYUSDX backing the extension token excluding yield and donation amounts.\n    function _pyusdxBacking() internal view returns (uint256) {\n        uint256 totalAssets_ = totalAssets();\n        uint256 totalSupply_ = totalSupply();\n\n        unchecked {\n            return totalSupply_ > totalAssets_ ? totalSupply_ - totalAssets_ : 0;\n        }\n    }\n\n    /// @dev    Returns true if `caller` passes the whitelist gate.\n    /// @param  caller The address to check.\n    /// @return True if the whitelist is disabled or `caller` is whitelisted.\n    function _isCallerAllowedToReplaceAsset(address caller) internal view returns (bool) {\n        EnumerableSet.AddressSet storage whitelist = _getMultiMintStorage().replaceAssetWhitelist;\n\n        return whitelist.length() == 0 || whitelist.contains(caller);\n    }\n\n    /// @dev   Reverts if `asset` is address(0) or PYUSDX.\n    /// @param asset Address of the asset to validate.\n    function _revertIfInvalidAsset(address asset) internal view {\n        if (asset == address(0) || asset == pyusdx) revert InvalidAsset(asset);\n    }\n\n    /// @dev   Reverts if PYUSDX backing is insufficient for `amount`.\n    /// @param amount Amount of PYUSDX required.\n    function _revertIfInsufficientPYUSDXBacking(uint256 amount) internal view {\n        uint256 backing_ = _pyusdxBacking();\n        if (amount > backing_) revert InsufficientPYUSDXBacking(amount, backing_);\n    }\n\n    /// @dev   Reverts if the extension holds less than `amount` of `asset`.\n    /// @param asset  Address of the asset.\n    /// @param amount Amount of `asset` required (in asset decimals).\n    function _revertIfInsufficientAssetBacking(address asset, uint256 amount) internal view {\n        uint256 assetBacking_ = assetBalanceOf(asset);\n        if (amount > assetBacking_) revert InsufficientAssetBacking(asset, amount, assetBacking_);\n    }\n\n    /// @dev    Converts `amount` from asset decimals to extension decimals.\n    /// @param  asset  Address of the asset.\n    /// @param  amount Amount in asset decimals.\n    /// @return Amount in extension decimals.\n    function _fromAssetToExtensionAmount(address asset, uint256 amount) internal view returns (uint256) {\n        return _convertAmounts(assetDecimals(asset), PYUSDX_DECIMALS, amount);\n    }\n\n    /// @dev    Converts `amount` from extension decimals to asset decimals.\n    /// @param  asset  Address of the asset.\n    /// @param  amount Amount in extension decimals.\n    /// @return Amount in asset decimals.\n    function _fromExtensionToAssetAmount(address asset, uint256 amount) internal view returns (uint256) {\n        return _convertAmounts(PYUSDX_DECIMALS, assetDecimals(asset), amount);\n    }\n\n    /* ============ Internal Pure Functions ============ */\n\n    /// @dev    Converts `amount` between decimal representations.\n    /// @param  fromDecimals Decimals of the input amount.\n    /// @param  toDecimals   Decimals of the output amount.\n    /// @param  amount       The amount to convert.\n    /// @return The converted amount.\n    function _convertAmounts(uint8 fromDecimals, uint8 toDecimals, uint256 amount) internal pure returns (uint256) {\n        if (fromDecimals == toDecimals) return amount;\n\n        return\n            fromDecimals > toDecimals\n                ? amount / (10 ** (fromDecimals - toDecimals))\n                : amount * (10 ** (toDecimals - fromDecimals));\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/src/interfaces/IERC1271.sol","source_code":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.20 <0.9.0;\n\n/**\n * @title  Standard Signature Validation Method for Contracts via EIP-1271.\n * @author M^0 Labs\n * @dev    The interface as defined by EIP-1271: https://eips.ethereum.org/EIPS/eip-1271\n */\ninterface IERC1271 {\n    /**\n     * @dev    Returns a specific magic value if the provided signature is valid for the provided digest.\n     * @param  digest     Hash of the data purported to have been signed.\n     * @param  signature  Signature byte array associated with the digest.\n     * @return magicValue Magic value 0x1626ba7e if the signature is valid.\n     */\n    function isValidSignature(bytes32 digest, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\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 Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\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 ternary(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 ternary(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            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * 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            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 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 low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, 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 (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / 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 high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\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⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\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²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev 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        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\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     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/forcedTransferable/ForcedTransferable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\nimport { AccessControlUpgradeable } from \"../../../lib/common/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol\";\n\nimport { IForcedTransferable } from \"./IForcedTransferable.sol\";\n\n/**\n * @title  ForcedTransferable\n * @notice Upgradable contract that provides force transfer functionality.\n * @dev This contract is used to claw back funds from frozen accounts by authorized force transfer managers.\n * @author M0 Labs\n */\n\nabstract contract ForcedTransferable is IForcedTransferable, AccessControlUpgradeable {\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IForcedTransferable\n    bytes32 public constant FORCED_TRANSFER_MANAGER_ROLE = keccak256(\"FORCED_TRANSFER_MANAGER_ROLE\");\n\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the contract with the given force transfer manager.\n     * @param forcedTransferManager The address of a force transfer manager.\n     */\n    function __ForcedTransferable_init(address forcedTransferManager) internal onlyInitializing {\n        if (forcedTransferManager == address(0)) revert ZeroForcedTransferManager();\n        _grantRole(FORCED_TRANSFER_MANAGER_ROLE, forcedTransferManager);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IForcedTransferable\n    function forceTransfer(\n        address frozenAccount,\n        address recipient,\n        uint256 amount\n    ) external onlyRole(FORCED_TRANSFER_MANAGER_ROLE) {\n        _forceTransfer(frozenAccount, recipient, amount);\n    }\n\n    /// @inheritdoc IForcedTransferable\n    function forceTransfers(\n        address[] calldata frozenAccounts,\n        address[] calldata recipients,\n        uint256[] calldata amounts\n    ) external onlyRole(FORCED_TRANSFER_MANAGER_ROLE) {\n        uint256 len = frozenAccounts.length;\n        if (len != recipients.length || len != amounts.length) revert ArrayLengthMismatch();\n\n        for (uint256 i; i < len; ++i) {\n            _forceTransfer(frozenAccounts[i], recipients[i], amounts[i]);\n        }\n    }\n\n    /* ============ Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Internal ERC20 force transfer function to seize funds from a frozen account.\n     * @param frozenAccount The frozen account from which tokens are seized.\n     * @param recipient     The recipient's address.\n     * @param amount        The amount to be transferred.\n     */\n    function _forceTransfer(address frozenAccount, address recipient, uint256 amount) internal virtual {}\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.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 ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\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 *\n * TIP: Consider using this library along with {SlotDerivation}.\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 Int256Slot {\n        int256 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        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\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        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/src/components/pausable/Pausable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.26;\n\nimport { AccessControlUpgradeable } from \"../../../lib/common/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol\";\nimport { PausableUpgradeable } from \"../../../lib/common/lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol\";\n\nimport { IPausable } from \"./IPausable.sol\";\n\n/**\n * @title Pausable\n * @notice Upgradeable contract that allows to pause the inheriting contract.\n * @dev Relies on PausableUpgradeable from OpenZeppelin for pause functionality.\n * @author M0 Labs\n */\nabstract contract Pausable is IPausable, AccessControlUpgradeable, PausableUpgradeable {\n    /* ============ Variables ============ */\n\n    /// @inheritdoc IPausable\n    bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n    /* ============ Initializer ============ */\n\n    /**\n     * @notice Initializes the contract with the given pauser.\n     * @param pauser The address of a pauser.\n     */\n    function __Pausable_init(address pauser) internal onlyInitializing {\n        if (pauser == address(0)) revert ZeroPauser();\n        _grantRole(PAUSER_ROLE, pauser);\n    }\n\n    /* ============ Interactive Functions ============ */\n\n    /// @inheritdoc IPausable\n    function pause() external onlyRole(PAUSER_ROLE) {\n        _beforePause();\n        _pause();\n    }\n\n    /// @inheritdoc IPausable\n    function unpause() external onlyRole(PAUSER_ROLE) {\n        _beforeUnpause();\n        _unpause();\n    }\n\n    /* ============ Hooks For Internal Interactive Functions ============ */\n\n    /**\n     * @dev   Hook called before pausing the contract.\n     */\n    function _beforePause() internal virtual {}\n\n    /**\n     * @dev    Hook called before unpausing the contract.\n     */\n    function _beforeUnpause() internal virtual {}\n}\n"},{"file_path":"lib/PYUSDX/lib/evm-m-extensions/lib/common/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 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    /**\n     * @dev An operation with an ERC-20 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 Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(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     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\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     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\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     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\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 Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\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 silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\n}\n"},{"file_path":"lib/PYUSDX/src/platform/projects/interfaces/IMultiMint.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.34;\n\nimport { IArrayErrors } from \"evm-m-extensions/src/interfaces/IArrayErrors.sol\";\nimport { IYieldToOne } from \"./IYieldToOne.sol\";\n\ninterface IMultiMint is IYieldToOne, IArrayErrors {\n    /* ============ Events ============ */\n\n    /// @notice Emitted when asset cap is set.\n    /// @param  asset Address of the asset.\n    /// @param  cap   Maximum allowed amount of `asset` that can back the extension.\n    event AssetCapSet(address indexed asset, uint256 cap);\n\n    /// @notice Emitted when a caller's allow status on the replaceAsset whitelist changes.\n    /// @param  caller  The caller whose allow status changed.\n    /// @param  allowed The new allow status (true = whitelisted, false = removed).\n    event ReplaceAssetWhitelistCallerSet(address indexed caller, bool indexed allowed);\n\n    /// @notice Emitted when an asset is wrapped into extension tokens.\n    /// @param  asset           Address of the asset deposited.\n    /// @param  assetAmount     Amount of asset deposited (in asset decimals).\n    /// @param  recipient       Address that received the extension tokens.\n    /// @param  extensionAmount Amount of extension tokens minted.\n    event AssetWrapped(address indexed asset, uint256 assetAmount, address indexed recipient, uint256 extensionAmount);\n\n    /// @notice Emitted when an asset is replaced with PYUSDX.\n    /// @param  asset        Address of the asset.\n    /// @param  assetAmount  Amount of asset replaced.\n    /// @param  recipient    Address that received the asset.\n    /// @param  pyusdxAmount Amount of PYUSDX deposited.\n    event AssetReplaced(address indexed asset, uint256 assetAmount, address indexed recipient, uint256 pyusdxAmount);\n\n    /* ============ Custom Errors ============ */\n\n    /// @notice Emitted in initializer if Asset Cap Manager is 0x0.\n    error ZeroAssetCapManager();\n\n    /// @notice Emitted if the asset cap is reached.\n    /// @param  asset Address of the asset.\n    error AssetCapReached(address asset);\n\n    /// @notice Emitted if there is not enough of an asset to replace with PYUSDX.\n    /// @param  asset          Address of the asset.\n    /// @param  amount         Amount of asset requested.\n    /// @param  assetAvailable Amount of asset available.\n    error InsufficientAssetBacking(address asset, uint256 amount, uint256 assetAvailable);\n\n    /// @notice Emitted when wrapping an asset and receiving less than expected (fee-on-transfer).\n    /// @param  asset          Address of the asset.\n    /// @param  amountExpected Amount of asset expected.\n    /// @param  amountReceived Amount of asset received.\n    error InsufficientAssetReceived(address asset, uint256 amountExpected, uint256 amountReceived);\n\n    /// @notice Emitted if `unwrap()` is called but there is not enough PYUSDX backing.\n    /// @param  amount    Amount of PYUSDX to unwrap requested.\n    /// @param  available Amount of PYUSDX backing available.\n    error InsufficientPYUSDXBacking(uint256 amount, uint256 available);\n\n    /// @notice Emitted if an invalid asset is used.\n    /// @param  asset Address of the invalid asset.\n    error InvalidAsset(address asset);\n\n    /// @notice Emitted if `asset` has cap == 0 (unregistered or disabled).\n    /// @param  asset Address of the disallowed asset.\n    error AssetNotAllowed(address asset);\n\n    /// @notice Reverts when the caller is not permitted to perform the operation.\n    /// @param  caller The address that attempted the call.\n    error CallerNotAllowed(address caller);\n\n    /* ============ Interactive Functions ============ */\n\n    /// @notice Mint extension tokens by depositing `asset` tokens.\n    /// @dev    `amount` must be formatted in the `asset` token's decimals.\n    /// @param  asset     Address of the asset to deposit.\n    /// @param  recipient Address that will receive the extension tokens.\n    /// @param  amount    Amount of asset tokens to deposit.\n    function wrap(address asset, address recipient, uint256 amount) external;\n\n    /// @notice Allows depositing PYUSDX to receive `asset` tokens from reserves.\n    /// @dev    `amount` MUST be formatted in PYUSDX decimals (6).\n    /// @param  asset     Address of the asset to receive.\n    /// @param  recipient Address that will receive the `asset` token.\n    /// @param  amount    Amount of PYUSDX to deposit (in PYUSDX decimals).\n    function replaceAsset(address asset, address recipient, uint256 amount) external;\n\n    /// @notice Sets the asset cap for a given `asset`.\n    /// @dev    MUST only be callable by an account with the ASSET_CAP_MANAGER_ROLE.\n    ///         Setting `cap` to 0 disables both `wrap` and `replaceAsset` for this asset;\n    ///         existing balances remain unwrappable to PYUSDX.\n    /// @param  asset Address of the asset.\n    /// @param  cap   Maximum allowed amount of `asset` that can back the extension.\n    function setAssetCap(address asset, uint256 cap) external;\n\n    /// @notice Sets `caller`'s allow status on the replaceAsset whitelist.\n    /// @dev    MUST only be callable by ASSET_CAP_MANAGER_ROLE.\n    ///         No-op (no event) if the caller is already in the requested state.\n    /// @param  caller  The caller to add or remove.\n    /// @param  allowed True to add, false to remove.\n    function setReplaceAssetWhitelistCaller(address caller, bool allowed) external;\n\n    /// @notice Batch variant of setReplaceAssetWhitelistCaller.\n    /// @dev    MUST only be callable by ASSET_CAP_MANAGER_ROLE.\n    ///         Reverts on array length mismatch.\n    /// @param  callers The callers to add or remove.\n    /// @param  allowed The corresponding allow statuses.\n    function setReplaceAssetWhitelistCaller(address[] calldata callers, bool[] calldata allowed) external;\n\n    /* ============ View/Pure Functions ============ */\n\n    /// @notice The role that can set the assets cap.\n    function ASSET_CAP_MANAGER_ROLE() external view returns (bytes32);\n\n    /// @notice Number of decimals used by PYUSDX.\n    function PYUSDX_DECIMALS() external view returns (uint8);\n\n    /// @notice Gets the cached balance of a given asset held by the extension.\n    function assetBalanceOf(address asset) external view returns (uint256);\n\n    /// @notice Gets the asset cap for a given asset.\n    function assetCap(address asset) external view returns (uint256);\n\n    /// @notice Gets the cached decimals of a given asset.\n    function assetDecimals(address asset) external view returns (uint8);\n\n    /// @notice Gets the total non-PYUSDX assets held by the extension (in extension decimals).\n    function totalAssets() external view returns (uint256);\n\n    /// @notice Get the addresses allowed to call `replaceAsset`.\n    function getReplaceAssetWhitelist() external view returns (address[] memory);\n\n    /// @notice Checks if an asset is allowed as backing.\n    function isAllowedAsset(address asset) external view returns (bool);\n\n    /// @notice Checks if wrapping `amount` of `asset` is allowed.\n    /// @dev    `amount` MUST be formatted in `asset`'s decimals.\n    function isAllowedToWrap(address asset, uint256 amount) external view returns (bool);\n\n    /// @notice Checks if unwrapping `amount` of extension tokens is allowed.\n    /// @dev    `amount` MUST be formatted in extension's decimals (6).\n    function isAllowedToUnwrap(uint256 amount) external view returns (bool);\n\n    /// @notice Checks if `caller` is allowed to replace `asset` with `amount` of PYUSDX.\n    /// @dev    `amount` MUST be formatted in PYUSDX decimals.\n    /// @param  caller The address of the caller to check.\n    /// @param  asset  The address of the asset to replace.\n    /// @param  amount The amount of PYUSDX to deposit.\n    function isAllowedToReplaceAsset(address caller, address asset, uint256 amount) external view returns (bool);\n\n    /// @notice Whether the replaceAsset whitelist is currently enforced.\n    function isReplaceAssetWhitelistEnabled() external view returns (bool);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"pyusdx_","type":"address"},{"internalType":"address","name":"swapFacility_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountFrozen","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountNotFrozen","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AccountNotWhitelisted","type":"error"},{"inputs":[],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetCapReached","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationAlreadyUsed","type":"error"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"}],"name":"AuthorizationExpired","type":"error"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"}],"name":"AuthorizationNotYetValid","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"payee","type":"address"}],"name":"CallerMustBePayee","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerNotAllowed","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InsufficientAmount","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"assetAvailable","type":"uint256"}],"name":"InsufficientAssetBacking","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amountExpected","type":"uint256"},{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"name":"InsufficientAssetReceived","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"InsufficientPYUSDXBacking","type":"error"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expectedNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"InvalidAsset","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"InvalidSignatureS","type":"error"},{"inputs":[],"name":"InvalidSignatureV","type":"error"},{"inputs":[],"name":"InvalidUInt240","type":"error"},{"inputs":[{"internalType":"uint256","name":"held","type":"uint256"},{"internalType":"uint256","name":"backing","type":"uint256"}],"name":"MReservesMismatch","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotPinned","type":"error"},{"inputs":[],"name":"NotSwapFacility","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"SignerMismatch","type":"error"},{"inputs":[],"name":"VersionPinningDisabled","type":"error"},{"inputs":[],"name":"ZeroAccount","type":"error"},{"inputs":[],"name":"ZeroAdmin","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"inputs":[],"name":"ZeroAssetCapManager","type":"error"},{"inputs":[],"name":"ZeroForcedTransferManager","type":"error"},{"inputs":[],"name":"ZeroFreezeManager","type":"error"},{"inputs":[],"name":"ZeroPYUSDX","type":"error"},{"inputs":[],"name":"ZeroPauser","type":"error"},{"inputs":[],"name":"ZeroSwapFacility","type":"error"},{"inputs":[],"name":"ZeroVersion","type":"error"},{"inputs":[],"name":"ZeroVersionManager","type":"error"},{"inputs":[],"name":"ZeroYieldRecipient","type":"error"},{"inputs":[],"name":"ZeroYieldRecipientManager","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"}],"name":"AssetCapSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"pyusdxAmount","type":"uint256"}],"name":"AssetReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"extensionAmount","type":"uint256"}],"name":"AssetWrapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"frozenAccount","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"forcedTransferManager","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ForcedTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Frozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"bool","name":"allowed","type":"bool"}],"name":"ReplaceAssetWhitelistCallerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Unfrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhitelistDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WhitelistEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"yield","type":"uint256"}],"name":"YieldClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"yieldRecipient","type":"address"}],"name":"YieldRecipientSet","type":"event"},{"inputs":[],"name":"ASSET_CAP_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FORCED_TRANSFER_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"M_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PYUSDX_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECEIVE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YIELD_RECIPIENT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer_","type":"address"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"vs_","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer_","type":"address"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer_","type":"address"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimMYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields_","type":"bytes1"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"version_","type":"string"},{"internalType":"uint256","name":"chainId_","type":"uint256"},{"internalType":"address","name":"verifyingContract_","type":"address"},{"internalType":"bytes32","name":"salt_","type":"bytes32"},{"internalType":"uint256[]","name":"extensions_","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"frozenAccount","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"forceTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"frozenAccounts","type":"address[]"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"forceTransfers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"freezeAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReplaceAssetWhitelist","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"yieldRecipient_","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"assetCapManager","type":"address"},{"internalType":"address","name":"freezeManager","type":"address"},{"internalType":"address","name":"pauser","type":"address"},{"internalType":"address","name":"yieldRecipientManager","type":"address"},{"internalType":"address","name":"versionManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"yieldRecipient_","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"freezeManager","type":"address"},{"internalType":"address","name":"pauser","type":"address"},{"internalType":"address","name":"yieldRecipientManager","type":"address"},{"internalType":"address","name":"versionManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"isAllowedAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"isAllowedToReplaceAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"isAllowedToUnwrap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"isAllowedToWrap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPinned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReplaceAssetWhitelistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWhitelistEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"originBeacon","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pinVersion","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pinnedImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pyusdx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"vs_","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"replaceAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"setAssetCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setReplaceAssetWhitelistCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"allowed","type":"bool[]"}],"name":"setReplaceAssetWhitelistCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setYieldRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapFacility","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender_","type":"address"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"vs_","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"validAfter_","type":"uint256"},{"internalType":"uint256","name":"validBefore_","type":"uint256"},{"internalType":"bytes32","name":"nonce_","type":"bytes32"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"unfreezeAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpinVersion","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x000000000000000000000000ebdb0942ce16386ab90718c7bd10c91cdb66b14d0000000000000000000000000bc305e7e13113caed3f5486849e9518a1cc4173"}